@salesmind-ai/design-system 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/Anton-Regular-MLEXVTB2.woff2 +0 -0
- package/dist/admin/index.cjs +5 -61
- package/dist/admin/index.css +0 -3918
- package/dist/admin/index.css.map +1 -1
- package/dist/admin/index.d.cts +1 -422
- package/dist/admin/index.d.ts +1 -422
- package/dist/admin/index.js +1 -5
- package/dist/blog/index.cjs +13 -34
- package/dist/blog/index.css +0 -579
- package/dist/blog/index.css.map +1 -1
- package/dist/blog/index.d.cts +1 -54
- package/dist/blog/index.d.ts +1 -54
- package/dist/blog/index.js +5 -6
- package/dist/charts/index.cjs +0 -46
- package/dist/charts/index.d.cts +1 -452
- package/dist/charts/index.d.ts +1 -452
- package/dist/charts/index.js +1 -3
- package/dist/{chunk-HDVAMYSG.js → chunk-27Y5ESMM.js} +7 -2
- package/dist/chunk-27Y5ESMM.js.map +1 -0
- package/dist/{chunk-YTYDQBVY.cjs → chunk-2VVRZBUR.cjs} +4 -4
- package/dist/{chunk-GQELL2MF.cjs → chunk-3NS6X2R4.cjs} +20 -203
- package/dist/chunk-3NS6X2R4.cjs.map +1 -0
- package/dist/{chunk-XEX2AEZK.cjs → chunk-65DTHLVX.cjs} +66 -186
- package/dist/chunk-65DTHLVX.cjs.map +1 -0
- package/dist/{chunk-QALDZ7WQ.js → chunk-6BUS7RMS.js} +21 -198
- package/dist/chunk-6BUS7RMS.js.map +1 -0
- package/dist/{chunk-BJZ2DKS5.cjs → chunk-6QIQCUYC.cjs} +11 -10
- package/dist/chunk-6QIQCUYC.cjs.map +1 -0
- package/dist/{chunk-H2Y6BSTL.cjs → chunk-7EUR3AKV.cjs} +1 -1
- package/dist/chunk-7EUR3AKV.cjs.map +1 -0
- package/dist/{chunk-VFJZQQZU.js → chunk-AMNY5TS3.js} +11 -10
- package/dist/chunk-AMNY5TS3.js.map +1 -0
- package/dist/{chunk-YJ6C3EKW.js → chunk-CLXLQCNQ.js} +52 -168
- package/dist/chunk-CLXLQCNQ.js.map +1 -0
- package/dist/{chunk-H2KQ3WSH.cjs → chunk-CVLD5RQK.cjs} +12 -14
- package/dist/chunk-CVLD5RQK.cjs.map +1 -0
- package/dist/chunk-EPD4ZEPY.cjs +344 -0
- package/dist/chunk-EPD4ZEPY.cjs.map +1 -0
- package/dist/chunk-FXYOSA4E.cjs +118 -0
- package/dist/chunk-FXYOSA4E.cjs.map +1 -0
- package/dist/{chunk-ECXBTUH6.cjs → chunk-GPHQGLR5.cjs} +27 -204
- package/dist/chunk-GPHQGLR5.cjs.map +1 -0
- package/dist/{chunk-Y26OHHMX.js → chunk-HHQ6J7B6.js} +513 -888
- package/dist/chunk-HHQ6J7B6.js.map +1 -0
- package/dist/chunk-JPUJWI7F.cjs +73 -0
- package/dist/chunk-JPUJWI7F.cjs.map +1 -0
- package/dist/{chunk-6UNG76Y2.js → chunk-K526GN7P.js} +2 -2
- package/dist/{chunk-SICKWUWB.js → chunk-KJHPOB3J.js} +1 -1
- package/dist/chunk-KJHPOB3J.js.map +1 -0
- package/dist/chunk-KXVFFEGD.js +60 -0
- package/dist/chunk-KXVFFEGD.js.map +1 -0
- package/dist/chunk-LQB7QLD3.js +288 -0
- package/dist/chunk-LQB7QLD3.js.map +1 -0
- package/dist/chunk-LUD52ZJF.cjs +726 -0
- package/dist/chunk-LUD52ZJF.cjs.map +1 -0
- package/dist/{chunk-7UZ5DETZ.js → chunk-MBAG654R.js} +4 -216
- package/dist/chunk-MBAG654R.js.map +1 -0
- package/dist/chunk-OMP6FAZ6.cjs +183 -0
- package/dist/chunk-OMP6FAZ6.cjs.map +1 -0
- package/dist/{chunk-WYH4TKS5.js → chunk-PBYRTNQ5.js} +6 -8
- package/dist/chunk-PBYRTNQ5.js.map +1 -0
- package/dist/chunk-PYREXCZK.js +679 -0
- package/dist/chunk-PYREXCZK.js.map +1 -0
- package/dist/{chunk-6D22TFLA.cjs → chunk-R3ZECV5P.cjs} +9 -4
- package/dist/chunk-R3ZECV5P.cjs.map +1 -0
- package/dist/{chunk-P5BOFE5A.js → chunk-RSLA2FJN.js} +28 -183
- package/dist/chunk-RSLA2FJN.js.map +1 -0
- package/dist/chunk-S46SKHMD.js +173 -0
- package/dist/chunk-S46SKHMD.js.map +1 -0
- package/dist/chunk-SFXTB7JL.js +190 -0
- package/dist/chunk-SFXTB7JL.js.map +1 -0
- package/dist/chunk-SGYXYMKZ.cjs +214 -0
- package/dist/chunk-SGYXYMKZ.cjs.map +1 -0
- package/dist/chunk-UGKYP6F3.cjs +296 -0
- package/dist/chunk-UGKYP6F3.cjs.map +1 -0
- package/dist/chunk-WB6XDNU7.js +115 -0
- package/dist/chunk-WB6XDNU7.js.map +1 -0
- package/dist/{chunk-LTPTW2US.cjs → chunk-WE4QIIVN.cjs} +592 -974
- package/dist/chunk-WE4QIIVN.cjs.map +1 -0
- package/dist/core/index.cjs +144 -626
- package/dist/core/index.css +178 -3567
- package/dist/core/index.css.map +1 -1
- package/dist/core/index.d.cts +940 -902
- package/dist/core/index.d.ts +940 -902
- package/dist/core/index.js +6 -12
- package/dist/i18n/index.cjs +54 -49
- package/dist/i18n/index.d.cts +46 -11
- package/dist/i18n/index.d.ts +46 -11
- package/dist/i18n/index.js +2 -1
- package/dist/index-BJ8rBqrO.d.cts +1100 -0
- package/dist/index-BxMqCbqE.d.ts +1100 -0
- package/dist/index.cjs +507 -1001
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +6057 -16713
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +306 -21
- package/dist/index.d.ts +306 -21
- package/dist/index.js +274 -39
- package/dist/index.js.map +1 -1
- package/dist/marketing/index.cjs +33 -76
- package/dist/marketing/index.css +1896 -3234
- package/dist/marketing/index.css.map +1 -1
- package/dist/marketing/index.d.cts +3 -1351
- package/dist/marketing/index.d.ts +3 -1351
- package/dist/marketing/index.js +5 -8
- package/dist/motion/index.cjs +3 -20
- package/dist/motion/index.css +0 -580
- package/dist/motion/index.css.map +1 -1
- package/dist/motion/index.d.cts +1 -37
- package/dist/motion/index.d.ts +1 -37
- package/dist/motion/index.js +1 -2
- package/dist/nav/index.cjs +10 -35
- package/dist/nav/index.css +28 -580
- package/dist/nav/index.css.map +1 -1
- package/dist/nav/index.d.cts +2 -60
- package/dist/nav/index.d.ts +2 -60
- package/dist/nav/index.js +1 -2
- package/dist/report/index.cjs +1166 -175
- package/dist/report/index.cjs.map +1 -1
- package/dist/report/index.d.cts +208 -5
- package/dist/report/index.d.ts +208 -5
- package/dist/report/index.js +1141 -3
- package/dist/report/index.js.map +1 -1
- package/dist/sections/index.cjs +8 -10
- package/dist/sections/index.cjs.map +1 -1
- package/dist/sections/index.css +0 -206
- package/dist/sections/index.css.map +1 -1
- package/dist/sections/index.js +2 -4
- package/dist/sections/index.js.map +1 -1
- package/dist/social-media/index.cjs +4 -0
- package/dist/social-media/index.cjs.map +1 -0
- package/dist/social-media/index.d.cts +2 -0
- package/dist/social-media/index.d.ts +2 -0
- package/dist/social-media/index.js +3 -0
- package/dist/social-media/index.js.map +1 -0
- package/dist/social-proof/index.cjs +4 -36
- package/dist/social-proof/index.css +3 -1106
- package/dist/social-proof/index.css.map +1 -1
- package/dist/social-proof/index.d.cts +26 -171
- package/dist/social-proof/index.d.ts +26 -171
- package/dist/social-proof/index.js +1 -5
- package/dist/styles/styles.css +657 -2990
- package/dist/theme/index.cjs +12 -16
- package/dist/theme/index.css +1 -245
- package/dist/theme/index.css.map +1 -1
- package/dist/theme/index.d.cts +4 -1
- package/dist/theme/index.d.ts +4 -1
- package/dist/theme/index.js +2 -2
- package/dist/web/client/index.cjs +10 -10
- package/dist/web/client/index.css +118 -0
- package/dist/web/client/index.css.map +1 -1
- package/dist/web/client/index.js +2 -2
- package/dist/web/index.cjs +10 -10
- package/dist/web/index.css +118 -0
- package/dist/web/index.css.map +1 -1
- package/dist/web/index.js +2 -2
- package/package.json +10 -4
- package/dist/AppearancePanel-UT57J69V.d.cts +0 -51
- package/dist/AppearancePanel-UT57J69V.d.ts +0 -51
- package/dist/ExportMenu-A2TLFiVv.d.cts +0 -311
- package/dist/ExportMenu-C8qck5AT.d.ts +0 -311
- package/dist/Select-BdZmK0Lt.d.cts +0 -66
- package/dist/Select-BdZmK0Lt.d.ts +0 -66
- package/dist/chart-types-BGVVO-zl.d.cts +0 -208
- package/dist/chart-types-BGVVO-zl.d.ts +0 -208
- package/dist/charts/index.css +0 -1167
- package/dist/charts/index.css.map +0 -1
- package/dist/chunk-3BAQDW3V.cjs +0 -1207
- package/dist/chunk-3BAQDW3V.cjs.map +0 -1
- package/dist/chunk-3NKRFUAR.js +0 -37
- package/dist/chunk-3NKRFUAR.js.map +0 -1
- package/dist/chunk-3TGSIILM.cjs +0 -201
- package/dist/chunk-3TGSIILM.cjs.map +0 -1
- package/dist/chunk-4GM5BGBN.cjs +0 -801
- package/dist/chunk-4GM5BGBN.cjs.map +0 -1
- package/dist/chunk-5LA3T22E.cjs +0 -562
- package/dist/chunk-5LA3T22E.cjs.map +0 -1
- package/dist/chunk-5SN66B2X.js +0 -2542
- package/dist/chunk-5SN66B2X.js.map +0 -1
- package/dist/chunk-6D22TFLA.cjs.map +0 -1
- package/dist/chunk-6H4DSTXR.js +0 -786
- package/dist/chunk-6H4DSTXR.js.map +0 -1
- package/dist/chunk-6HKQ5ILL.cjs +0 -1624
- package/dist/chunk-6HKQ5ILL.cjs.map +0 -1
- package/dist/chunk-7PX2AZ6Y.js +0 -39
- package/dist/chunk-7PX2AZ6Y.js.map +0 -1
- package/dist/chunk-7UZ5DETZ.js.map +0 -1
- package/dist/chunk-B6AVAX4F.js +0 -1415
- package/dist/chunk-B6AVAX4F.js.map +0 -1
- package/dist/chunk-BJZ2DKS5.cjs.map +0 -1
- package/dist/chunk-BUTQSDQH.js +0 -200
- package/dist/chunk-BUTQSDQH.js.map +0 -1
- package/dist/chunk-C2BCDNAV.js +0 -24
- package/dist/chunk-C2BCDNAV.js.map +0 -1
- package/dist/chunk-CJ2MKVAF.cjs +0 -46
- package/dist/chunk-CJ2MKVAF.cjs.map +0 -1
- package/dist/chunk-E7D6EKJ4.cjs +0 -44
- package/dist/chunk-E7D6EKJ4.cjs.map +0 -1
- package/dist/chunk-ECXBTUH6.cjs.map +0 -1
- package/dist/chunk-FAFAP4L5.js +0 -183
- package/dist/chunk-FAFAP4L5.js.map +0 -1
- package/dist/chunk-G2XGBO5V.cjs +0 -2565
- package/dist/chunk-G2XGBO5V.cjs.map +0 -1
- package/dist/chunk-GQELL2MF.cjs.map +0 -1
- package/dist/chunk-H2KQ3WSH.cjs.map +0 -1
- package/dist/chunk-H2Y6BSTL.cjs.map +0 -1
- package/dist/chunk-HCZW5AJN.cjs +0 -234
- package/dist/chunk-HCZW5AJN.cjs.map +0 -1
- package/dist/chunk-HDVAMYSG.js.map +0 -1
- package/dist/chunk-HN4PHABT.js +0 -126
- package/dist/chunk-HN4PHABT.js.map +0 -1
- package/dist/chunk-LTPTW2US.cjs.map +0 -1
- package/dist/chunk-MDB2WCRQ.cjs +0 -137
- package/dist/chunk-MDB2WCRQ.cjs.map +0 -1
- package/dist/chunk-MQRB634A.cjs +0 -34
- package/dist/chunk-MQRB634A.cjs.map +0 -1
- package/dist/chunk-NN3TUHIH.js +0 -28
- package/dist/chunk-NN3TUHIH.js.map +0 -1
- package/dist/chunk-OWS2KAXZ.js +0 -701
- package/dist/chunk-OWS2KAXZ.js.map +0 -1
- package/dist/chunk-P5BOFE5A.js.map +0 -1
- package/dist/chunk-PUPSK3DI.cjs +0 -216
- package/dist/chunk-PUPSK3DI.cjs.map +0 -1
- package/dist/chunk-Q2MFGYTE.cjs +0 -1449
- package/dist/chunk-Q2MFGYTE.cjs.map +0 -1
- package/dist/chunk-Q75DBVDY.cjs +0 -68
- package/dist/chunk-Q75DBVDY.cjs.map +0 -1
- package/dist/chunk-QALDZ7WQ.js.map +0 -1
- package/dist/chunk-QWE2RNCS.js +0 -1195
- package/dist/chunk-QWE2RNCS.js.map +0 -1
- package/dist/chunk-RQUFZAZ7.js +0 -1608
- package/dist/chunk-RQUFZAZ7.js.map +0 -1
- package/dist/chunk-SICKWUWB.js.map +0 -1
- package/dist/chunk-TCFC7XTB.js +0 -212
- package/dist/chunk-TCFC7XTB.js.map +0 -1
- package/dist/chunk-UTVXGAQP.cjs +0 -2437
- package/dist/chunk-UTVXGAQP.cjs.map +0 -1
- package/dist/chunk-UVEMY3FQ.cjs +0 -717
- package/dist/chunk-UVEMY3FQ.cjs.map +0 -1
- package/dist/chunk-VFJZQQZU.js.map +0 -1
- package/dist/chunk-WH7PYHZY.cjs +0 -35
- package/dist/chunk-WH7PYHZY.cjs.map +0 -1
- package/dist/chunk-WYH4TKS5.js.map +0 -1
- package/dist/chunk-XEX2AEZK.cjs.map +0 -1
- package/dist/chunk-XPTVHPCN.js +0 -2320
- package/dist/chunk-XPTVHPCN.js.map +0 -1
- package/dist/chunk-XWPDRMZG.js +0 -62
- package/dist/chunk-XWPDRMZG.js.map +0 -1
- package/dist/chunk-Y26OHHMX.js.map +0 -1
- package/dist/chunk-YJ6C3EKW.js.map +0 -1
- package/dist/motion-C651Ry6d.d.cts +0 -832
- package/dist/motion-C651Ry6d.d.ts +0 -832
- package/dist/report/index.css +0 -1239
- package/dist/report/index.css.map +0 -1
- /package/dist/{chunk-6UNG76Y2.js.map → chunk-2VVRZBUR.cjs.map} +0 -0
- /package/dist/{chunk-YTYDQBVY.cjs.map → chunk-K526GN7P.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/report-engine/constants.ts","../src/report-engine/confidence.ts","../src/report-engine/context.tsx","../src/report-engine/chart-types.ts","../src/report-engine/validation.ts","../src/components/ConfidenceIndicator/ConfidenceIndicator.tsx","../src/components/DataCoverageBadge/DataCoverageBadge.tsx","../src/components/DataStateIndicator/DataStateIndicator.tsx"],"names":["React","getComponentName","isChart","jsx","clsx","jsxs"],"mappings":"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","sourcesContent":["/* ============================================================================\n REPORT ENGINE — CONSTANTS & CONFIGURATION\n ============================================================================ */\n\nimport type {\n ReportModeConfig,\n ConfidenceThreshold,\n InsightTypeContract,\n InsightType,\n} from './types';\n\n/**\n * Executive mode configuration - minimal detail, boardroom-ready.\n */\nexport const EXECUTIVE_MODE: ReportModeConfig = {\n mode: 'executive',\n features: {\n showMethodology: false,\n showConfidenceScores: false,\n showRawData: false,\n showStatisticalTests: false,\n chartDetailLevel: 'summary',\n maxInsightsShown: 5,\n allowDrilldown: false,\n },\n};\n\n/**\n * Analyst mode configuration - full detail, internal use.\n */\nexport const ANALYST_MODE: ReportModeConfig = {\n mode: 'analyst',\n features: {\n showMethodology: true,\n showConfidenceScores: true,\n showRawData: true,\n showStatisticalTests: true,\n chartDetailLevel: 'detailed',\n maxInsightsShown: 20,\n allowDrilldown: true,\n },\n};\n\n/**\n * Confidence level thresholds.\n */\nexport const CONFIDENCE_THRESHOLDS: ConfidenceThreshold[] = [\n { level: 'high', min: 90, max: 100, label: 'High Confidence', color: 'var(--status-success)' },\n {\n level: 'moderate',\n min: 70,\n max: 89,\n label: 'Moderate Confidence',\n color: 'var(--status-info)',\n },\n { level: 'low', min: 50, max: 69, label: 'Low Confidence', color: 'var(--status-warning)' },\n {\n level: 'insufficient',\n min: 0,\n max: 49,\n label: 'Insufficient Data',\n color: 'var(--status-error)',\n },\n];\n\n/**\n * Minimum sample sizes for different analysis types.\n */\nexport const MINIMUM_SAMPLE_SIZES = {\n overall: 30,\n segment: 30,\n mbtiType: 50,\n correlation: 100,\n timeSeries: 7,\n} as const;\n\n/**\n * Insight type contracts defining allowed charts and requirements.\n */\nexport const INSIGHT_TYPE_CONTRACTS: Record<InsightType, InsightTypeContract> = {\n 'performance-delta': {\n type: 'performance-delta',\n allowedCharts: ['BarChart', 'LineChart', 'KeyMetric'],\n requiredFields: ['metric_name', 'current_value', 'previous_value', 'time_period'],\n minSampleSize: 30,\n headlinePattern: '{metric} {direction} by {delta}% {timeframe}',\n recommendationFormats: ['maintain-strategy', 'investigate-decline', 'scale-success'],\n },\n 'behavioral-correlation': {\n type: 'behavioral-correlation',\n allowedCharts: ['HeatmapChart', 'BarChart'],\n requiredFields: ['variable_a', 'variable_b', 'correlation_coefficient'],\n minSampleSize: 100,\n headlinePattern: '{variable_a} correlates with {variable_b}',\n recommendationFormats: ['leverage-correlation', 'investigate-causation'],\n },\n 'funnel-leakage': {\n type: 'funnel-leakage',\n allowedCharts: ['FunnelChart', 'BarChart'],\n requiredFields: ['stages', 'stage_counts', 'drop_rates'],\n minSampleSize: 50,\n headlinePattern: '{drop_rate}% drop-off at {stage}',\n recommendationFormats: ['optimize-stage', 'remove-friction'],\n },\n 'audience-mismatch': {\n type: 'audience-mismatch',\n allowedCharts: ['BarChart', 'PieChart'],\n requiredFields: ['target_audience', 'actual_audience', 'overlap_percentage'],\n minSampleSize: 50,\n headlinePattern: 'Target audience differs by {mismatch}%',\n recommendationFormats: ['refine-targeting', 'expand-audience'],\n },\n 'message-fatigue': {\n type: 'message-fatigue',\n allowedCharts: ['LineChart', 'BarChart'],\n requiredFields: ['message_sequence', 'engagement_rates', 'fatigue_point'],\n minSampleSize: 100,\n headlinePattern: 'Engagement drops {drop}% after message {n}',\n recommendationFormats: ['reduce-frequency', 'vary-content'],\n },\n 'psychological-resonance': {\n type: 'psychological-resonance',\n allowedCharts: ['MBTIRadar', 'MBTITypeGrid', 'BarChart'],\n requiredFields: ['mbti_types', 'response_rates', 'message_type'],\n minSampleSize: 50,\n headlinePattern: '{mbti_type} responds {rate}% better to {message_type}',\n recommendationFormats: ['personalize-messaging', 'segment-by-type'],\n },\n 'timing-pattern': {\n type: 'timing-pattern',\n allowedCharts: ['HeatmapChart', 'LineChart'],\n requiredFields: ['time_slots', 'engagement_rates'],\n minSampleSize: 100,\n headlinePattern: 'Best engagement on {day} at {time}',\n recommendationFormats: ['optimize-timing', 'schedule-sends'],\n },\n 'segment-outperformance': {\n type: 'segment-outperformance',\n allowedCharts: ['BarChart', 'KeyMetric'],\n requiredFields: ['segments', 'performance_metrics', 'baseline'],\n minSampleSize: 30,\n headlinePattern: '{segment} outperforms by {delta}%',\n recommendationFormats: ['double-down', 'investigate-success'],\n },\n 'anomaly-detection': {\n type: 'anomaly-detection',\n allowedCharts: ['LineChart', 'BarChart'],\n requiredFields: ['metric', 'expected_value', 'actual_value', 'deviation'],\n minSampleSize: 30,\n headlinePattern: 'Unusual {direction} in {metric}',\n recommendationFormats: ['investigate', 'monitor'],\n },\n 'competitive-benchmark': {\n type: 'competitive-benchmark',\n allowedCharts: ['BarChart', 'KeyMetric'],\n requiredFields: ['metric', 'our_value', 'benchmark_value'],\n minSampleSize: 30,\n headlinePattern: '{position} industry benchmark by {delta}%',\n recommendationFormats: ['maintain-lead', 'close-gap'],\n },\n};\n\n/**\n * Analytical state metadata for UI rendering.\n */\nexport const ANALYTICAL_STATE_CONFIG = {\n VALID: {\n label: 'Valid',\n icon: 'check',\n color: 'var(--status-success)',\n action: null,\n },\n INSUFFICIENT_SAMPLE: {\n label: 'Insufficient Sample',\n icon: 'alert-triangle',\n color: 'var(--status-warning)',\n action: 'Add more data',\n },\n LOW_CONFIDENCE: {\n label: 'Low Confidence',\n icon: 'alert-circle',\n color: 'var(--status-warning)',\n action: 'Interpret with caution',\n },\n PARTIAL_TIME_WINDOW: {\n label: 'Partial Data',\n icon: 'clock',\n color: 'var(--status-info)',\n action: 'Expand date range',\n },\n DATA_SKEW_DETECTED: {\n label: 'Data Skew',\n icon: 'bar-chart-2',\n color: 'var(--status-warning)',\n action: 'Review methodology',\n },\n CONFLICTING_SIGNALS: {\n label: 'Conflicting Signals',\n icon: 'git-merge',\n color: 'var(--status-error)',\n action: 'Manual review needed',\n },\n INFERRED_NOT_OBSERVED: {\n label: 'AI Generated',\n icon: 'cpu',\n color: 'var(--status-info)',\n action: 'Verify with data',\n },\n STALE_DATA: {\n label: 'Stale Data',\n icon: 'clock',\n color: 'var(--status-warning)',\n action: 'Refresh data',\n },\n FIELD_MISSING: {\n label: 'Missing Field',\n icon: 'file-x',\n color: 'var(--status-error)',\n action: 'Upload complete data',\n },\n CALCULATION_ERROR: {\n label: 'Calculation Error',\n icon: 'x-circle',\n color: 'var(--status-error)',\n action: 'Contact support',\n },\n} as const;\n","/* ============================================================================\n REPORT ENGINE — CONFIDENCE SCORING\n ============================================================================ */\n\nimport type { ConfidenceLevel } from './types';\nimport { CONFIDENCE_THRESHOLDS } from './constants';\n\nexport interface ConfidenceParams {\n sampleSize: number;\n requiredSize: number;\n completeness: number; // 0-1: percentage of non-null fields\n recency: number; // 0-1: how recent the data is\n variance: number; // 0-1: normalized variance (higher = worse)\n aiInference: boolean; // Whether AI generated the insight\n}\n\n/**\n * Calculate confidence score based on data quality factors.\n * Returns a score from 0-100.\n */\nexport function calculateConfidence(params: ConfidenceParams): number {\n const { sampleSize, requiredSize, completeness, recency, variance, aiInference } = params;\n\n // Base score from sample size (0-40 points)\n const sampleScore = Math.min(40, (sampleSize / requiredSize) * 40);\n\n // Completeness bonus (0-20 points)\n const completenessScore = completeness * 20;\n\n // Recency bonus (0-20 points)\n const recencyScore = recency * 20;\n\n // Variance penalty (0-10 points deducted for high variance)\n const variancePenalty = variance * 10;\n\n // AI inference penalty (10 points if AI-generated)\n const aiPenalty = aiInference ? 10 : 0;\n\n const rawScore = sampleScore + completenessScore + recencyScore - variancePenalty - aiPenalty;\n\n return Math.max(0, Math.min(100, Math.round(rawScore)));\n}\n\n/**\n * Get confidence level from score.\n */\nexport function getConfidenceLevel(score: number): ConfidenceLevel {\n const threshold = CONFIDENCE_THRESHOLDS.find((t) => score >= t.min && score <= t.max);\n return threshold?.level ?? 'insufficient';\n}\n\n/**\n * Get confidence threshold config from score.\n */\nexport function getConfidenceThreshold(score: number) {\n return (\n CONFIDENCE_THRESHOLDS.find((t) => score >= t.min && score <= t.max) ??\n CONFIDENCE_THRESHOLDS[CONFIDENCE_THRESHOLDS.length - 1]\n );\n}\n\n/**\n * Calculate recency score based on data age.\n * @param dataDate - The date of the most recent data point\n * @param maxAgeDays - Maximum acceptable age in days (default 30)\n */\nexport function calculateRecency(dataDate: Date, maxAgeDays = 30): number {\n const now = new Date();\n const ageInDays = (now.getTime() - dataDate.getTime()) / (1000 * 60 * 60 * 24);\n\n if (ageInDays <= 0) return 1;\n if (ageInDays >= maxAgeDays) return 0;\n\n return 1 - ageInDays / maxAgeDays;\n}\n\n/**\n * Calculate data completeness from an array of records.\n * @param data - Array of data objects\n * @param requiredFields - Fields to check for completeness\n */\nexport function calculateCompleteness(\n data: Record<string, unknown>[],\n requiredFields: string[],\n): number {\n if (data.length === 0 || requiredFields.length === 0) return 0;\n\n let totalFields = 0;\n let filledFields = 0;\n\n for (const record of data) {\n for (const field of requiredFields) {\n totalFields++;\n const value = record[field];\n if (value !== null && value !== undefined && value !== '') {\n filledFields++;\n }\n }\n }\n\n return totalFields > 0 ? filledFields / totalFields : 0;\n}\n\n/**\n * Calculate normalized variance for a numeric dataset.\n * Returns 0-1 where 0 is low variance and 1 is high variance.\n */\nexport function calculateNormalizedVariance(values: number[]): number {\n if (values.length < 2) return 0;\n\n const mean = values.reduce((a, b) => a + b, 0) / values.length;\n const squaredDiffs = values.map((v) => Math.pow(v - mean, 2));\n const variance = squaredDiffs.reduce((a, b) => a + b, 0) / values.length;\n const stdDev = Math.sqrt(variance);\n\n // Coefficient of variation (CV) normalized to 0-1\n // CV > 1 is considered high variance\n const cv = mean !== 0 ? stdDev / Math.abs(mean) : 0;\n\n return Math.min(1, cv);\n}\n","/* ============================================================================\n REPORT ENGINE — CONTEXT & HOOKS\n ============================================================================ */\n\n/* eslint-disable react-refresh/only-export-components */\n// This is a library file exporting hooks alongside providers - fast refresh doesn't apply\n\nimport React, { createContext, useContext, useMemo } from 'react';\nimport type { ReportMode, ReportModeConfig, AnalyticalState, DataStateDetails } from './types';\nimport { EXECUTIVE_MODE, ANALYST_MODE, MINIMUM_SAMPLE_SIZES } from './constants';\nimport { calculateConfidence, getConfidenceLevel, type ConfidenceParams } from './confidence';\n\n/* --------------------------------------------------------------------------\n Report Mode Context\n -------------------------------------------------------------------------- */\n\ninterface ReportModeContextValue extends ReportModeConfig {\n setMode?: (mode: ReportMode) => void;\n}\n\nconst ReportModeContext = createContext<ReportModeContextValue | null>(null);\n\nexport interface ReportModeProviderProps {\n mode?: ReportMode;\n children: React.ReactNode;\n onModeChange?: (mode: ReportMode) => void;\n}\n\n/**\n * Provider for report mode context.\n * Wrap your report with this to control executive vs analyst mode.\n */\nexport function ReportModeProvider({\n mode = 'executive',\n children,\n onModeChange,\n}: ReportModeProviderProps) {\n const config = mode === 'executive' ? EXECUTIVE_MODE : ANALYST_MODE;\n\n const value = useMemo(\n () => ({\n ...config,\n setMode: onModeChange,\n }),\n [config, onModeChange],\n );\n\n return <ReportModeContext.Provider value={value}>{children}</ReportModeContext.Provider>;\n}\n\n/**\n * Hook to access report mode configuration.\n */\nexport function useReportMode(): ReportModeContextValue {\n const context = useContext(ReportModeContext);\n\n if (!context) {\n // Return default executive mode if used outside provider\n return EXECUTIVE_MODE;\n }\n\n return context;\n}\n\n/* --------------------------------------------------------------------------\n Data State Hook\n -------------------------------------------------------------------------- */\n\nexport interface UseDataStateParams {\n sampleSize: number;\n requiredSize?: number;\n completeness?: number;\n recency?: number;\n variance?: number;\n aiInferred?: boolean;\n missingFields?: string[];\n staleDays?: number;\n}\n\nexport interface UseDataStateResult {\n state: AnalyticalState;\n confidence: number;\n confidenceLevel: ReturnType<typeof getConfidenceLevel>;\n details: DataStateDetails;\n isValid: boolean;\n}\n\n/**\n * Hook to compute analytical state from data parameters.\n */\nexport function useDataState(params: UseDataStateParams): UseDataStateResult {\n const {\n sampleSize,\n requiredSize = MINIMUM_SAMPLE_SIZES.overall,\n completeness = 1,\n recency = 1,\n variance = 0,\n aiInferred = false,\n missingFields = [],\n staleDays,\n } = params;\n\n return useMemo(() => {\n // Calculate confidence\n const confidenceParams: ConfidenceParams = {\n sampleSize,\n requiredSize,\n completeness,\n recency,\n variance,\n aiInference: aiInferred,\n };\n\n const confidence = calculateConfidence(confidenceParams);\n const confidenceLevel = getConfidenceLevel(confidence);\n\n // Determine analytical state\n let state: AnalyticalState = 'VALID';\n\n if (missingFields.length > 0) {\n state = 'FIELD_MISSING';\n } else if (sampleSize < requiredSize) {\n state = 'INSUFFICIENT_SAMPLE';\n } else if (staleDays && staleDays > 30) {\n state = 'STALE_DATA';\n } else if (aiInferred) {\n state = 'INFERRED_NOT_OBSERVED';\n } else if (confidence < 50) {\n state = 'LOW_CONFIDENCE';\n } else if (variance > 0.7) {\n state = 'DATA_SKEW_DETECTED';\n } else if (recency < 0.3) {\n state = 'PARTIAL_TIME_WINDOW';\n }\n\n const details: DataStateDetails = {\n sampleSize,\n requiredSize,\n confidence,\n missingFields: missingFields.length > 0 ? missingFields : undefined,\n staleDays,\n };\n\n return {\n state,\n confidence,\n confidenceLevel,\n details,\n isValid: state === 'VALID',\n };\n }, [\n sampleSize,\n requiredSize,\n completeness,\n recency,\n variance,\n aiInferred,\n missingFields,\n staleDays,\n ]);\n}\n\n/* --------------------------------------------------------------------------\n Chart Data Validation Hook\n -------------------------------------------------------------------------- */\n\nexport interface UseChartDataParams<T> {\n data: T[];\n requiredFields: string[];\n minSampleSize?: number;\n insightType?: string;\n}\n\nexport interface UseChartDataResult<T> {\n data: T[];\n state: AnalyticalState;\n confidence: number;\n isRenderable: boolean;\n message?: string;\n}\n\n/**\n * Hook to validate chart data against data contracts.\n */\nexport function useChartData<T extends Record<string, unknown>>({\n data,\n requiredFields,\n minSampleSize = MINIMUM_SAMPLE_SIZES.overall,\n}: UseChartDataParams<T>): UseChartDataResult<T> {\n return useMemo(() => {\n // Check for missing required fields\n const missingFields: string[] = [];\n if (data.length > 0) {\n const firstRecord = data[0];\n for (const field of requiredFields) {\n if (!(field in firstRecord)) {\n missingFields.push(field);\n }\n }\n }\n\n // Calculate completeness\n let completeness = 1;\n if (data.length > 0 && requiredFields.length > 0) {\n let filled = 0;\n let total = 0;\n for (const record of data) {\n for (const field of requiredFields) {\n total++;\n const value = record[field];\n if (value !== null && value !== undefined && value !== '') {\n filled++;\n }\n }\n }\n completeness = total > 0 ? filled / total : 0;\n }\n\n // Determine state\n let state: AnalyticalState = 'VALID';\n let message: string | undefined;\n\n if (missingFields.length > 0) {\n state = 'FIELD_MISSING';\n message = `Missing fields: ${missingFields.join(', ')}`;\n } else if (data.length === 0) {\n state = 'INSUFFICIENT_SAMPLE';\n message = 'No data available';\n } else if (data.length < minSampleSize) {\n state = 'INSUFFICIENT_SAMPLE';\n message = `Sample size ${data.length} is below minimum ${minSampleSize}`;\n } else if (completeness < 0.7) {\n state = 'LOW_CONFIDENCE';\n message = `Data completeness is ${Math.round(completeness * 100)}%`;\n }\n\n // Calculate confidence\n const confidence = calculateConfidence({\n sampleSize: data.length,\n requiredSize: minSampleSize,\n completeness,\n recency: 1, // Assume fresh data if not specified\n variance: 0,\n aiInference: false,\n });\n\n const isRenderable = state === 'VALID' || state === 'LOW_CONFIDENCE';\n\n return {\n data,\n state,\n confidence,\n isRenderable,\n message,\n };\n }, [data, requiredFields, minSampleSize]);\n}\n","/* ============================================================================\n CHART ABSTRACTION LAYER — TYPE DEFINITIONS & CONTRACTS\n \n This module defines the governed chart system with:\n - Chart taxonomy (semantic families)\n - Data contracts per chart type\n - Switching rules\n - Guardrails and fallback behaviors\n ============================================================================ */\n\n/* ============================================================================\n CHART INTENT (Semantic Families)\n ============================================================================ */\n\n/**\n * Chart intent defines the semantic purpose of visualization.\n * This is the primary classifier that governs switching rules.\n */\nexport type ChartIntent =\n | 'trend' // Time-based evolution, deltas, momentum\n | 'comparison' // Comparing discrete categories\n | 'composition' // Proportions and distributions\n | 'distribution' // Statistical spread and density\n | 'relationship' // Correlation and clustering\n | 'geo'; // Geographic data\n\n/* ============================================================================\n CHART TYPE TAXONOMY\n ============================================================================ */\n\n/**\n * All supported chart types organized by intent.\n */\n\n// Trend charts (time-based)\nexport type TrendChartType = 'line' | 'smooth_line' | 'area' | 'stacked_area' | 'area_100pct';\n\n// Comparison charts (categorical)\nexport type ComparisonChartType =\n | 'bar'\n | 'column'\n | 'stacked_bar'\n | 'stacked_column'\n | 'column_100pct'\n | 'combo'; // Phase 2\n\n// Composition charts\nexport type CompositionChartType = 'pie' | 'donut' | 'treemap'; // Phase 2\n\n// Distribution charts\nexport type DistributionChartType = 'histogram' | 'radar'; // Phase 2\n\n// Relationship charts\nexport type RelationshipChartType =\n | 'scatter' // Phase 2\n | 'bubble' // Phase 2\n | 'heatmap';\n\n// Geographic charts\nexport type GeoChartType =\n | 'geo' // Phase 2\n | 'choropleth'; // Phase 2\n\n/**\n * Union of all chart types\n */\nexport type ChartTypeId =\n | TrendChartType\n | ComparisonChartType\n | CompositionChartType\n | DistributionChartType\n | RelationshipChartType\n | GeoChartType\n | 'funnel' // Special: conversion flows\n | 'waterfall' // Phase 2: sequential changes\n | 'timeline'; // Phase 2: event sequences\n\n/**\n * Chart phase classification\n */\nexport type ChartPhase = 'mvp' | 'phase2' | 'phase3';\n\n/* ============================================================================\n CHART METADATA & REGISTRY\n ============================================================================ */\n\nexport interface ChartTypeMetadata {\n id: ChartTypeId;\n name: string;\n description: string;\n intent: ChartIntent;\n phase: ChartPhase;\n\n // Data requirements\n contract: ChartDataContract;\n\n // Allowed switches within same intent\n switchableTo: ChartTypeId[];\n\n // Visual configuration\n supportsStacking: boolean;\n supportsMultipleSeries: boolean;\n requiresTimeAxis: boolean;\n maxCategories?: number;\n maxSlices?: number;\n}\n\nexport interface ChartDataContract {\n // Required data shape\n requiredDimensions: number; // e.g., 1 for pie, 2 for scatter\n requiredMeasures: number; // Number of numeric fields required\n\n // Sample size requirements\n minDataPoints: number;\n idealDataPoints: number;\n maxDataPoints?: number;\n\n // Value constraints\n allowNegativeValues: boolean;\n requireNonZeroTotal: boolean;\n\n // Warnings\n warningThresholds: {\n tooManyCategories?: number;\n imbalancedRatio?: number;\n sparseData?: number;\n };\n\n // Fallback behavior\n fallback: ChartFallbackBehavior;\n}\n\nexport type ChartFallbackBehavior =\n | { type: 'hide' }\n | { type: 'show_kpi'; message: string }\n | { type: 'aggregate'; strategy: 'other_bucket' | 'top_n' }\n | { type: 'warn'; message: string };\n\n/* ============================================================================\n CHART REGISTRY (Canonical List)\n ============================================================================ */\n\nexport const CHART_REGISTRY: Record<ChartTypeId, ChartTypeMetadata> = {\n // ══════════════════════════════════════════════════════════════════════════\n // TREND CHARTS (MVP)\n // ══════════════════════════════════════════════════════════════════════════\n line: {\n id: 'line',\n name: 'Line Chart',\n description: 'Shows trends over time with connected data points',\n intent: 'trend',\n phase: 'mvp',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 1,\n minDataPoints: 3,\n idealDataPoints: 7,\n allowNegativeValues: true,\n requireNonZeroTotal: false,\n warningThresholds: { sparseData: 3 },\n fallback: { type: 'show_kpi', message: 'Insufficient data for trend visualization' },\n },\n switchableTo: ['smooth_line', 'area', 'stacked_area'],\n supportsStacking: false,\n supportsMultipleSeries: true,\n requiresTimeAxis: true,\n },\n\n smooth_line: {\n id: 'smooth_line',\n name: 'Smooth Line Chart',\n description: 'Curved line chart for smoother trend visualization',\n intent: 'trend',\n phase: 'mvp',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 1,\n minDataPoints: 3,\n idealDataPoints: 7,\n allowNegativeValues: true,\n requireNonZeroTotal: false,\n warningThresholds: { sparseData: 3 },\n fallback: { type: 'show_kpi', message: 'Insufficient data for trend visualization' },\n },\n switchableTo: ['line', 'area', 'stacked_area'],\n supportsStacking: false,\n supportsMultipleSeries: true,\n requiresTimeAxis: true,\n },\n\n area: {\n id: 'area',\n name: 'Area Chart',\n description: 'Filled area under line, emphasizes volume over time',\n intent: 'trend',\n phase: 'mvp',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 1,\n minDataPoints: 3,\n idealDataPoints: 7,\n allowNegativeValues: false,\n requireNonZeroTotal: false,\n warningThresholds: { sparseData: 3 },\n fallback: { type: 'show_kpi', message: 'Insufficient data for area visualization' },\n },\n switchableTo: ['line', 'smooth_line', 'stacked_area', 'area_100pct'],\n supportsStacking: true,\n supportsMultipleSeries: true,\n requiresTimeAxis: true,\n },\n\n stacked_area: {\n id: 'stacked_area',\n name: 'Stacked Area Chart',\n description: 'Multiple series stacked to show cumulative trends',\n intent: 'trend',\n phase: 'mvp',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 2,\n minDataPoints: 3,\n idealDataPoints: 7,\n allowNegativeValues: false,\n requireNonZeroTotal: true,\n warningThresholds: { sparseData: 3 },\n fallback: { type: 'warn', message: 'Stacked area requires non-negative values' },\n },\n switchableTo: ['line', 'area', 'area_100pct'],\n supportsStacking: true,\n supportsMultipleSeries: true,\n requiresTimeAxis: true,\n },\n\n area_100pct: {\n id: 'area_100pct',\n name: '100% Stacked Area',\n description: 'Shows proportional contribution over time',\n intent: 'trend',\n phase: 'mvp',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 2,\n minDataPoints: 3,\n idealDataPoints: 7,\n allowNegativeValues: false,\n requireNonZeroTotal: true,\n warningThresholds: { sparseData: 3 },\n fallback: { type: 'warn', message: '100% stacked requires positive totals' },\n },\n switchableTo: ['stacked_area', 'area'],\n supportsStacking: true,\n supportsMultipleSeries: true,\n requiresTimeAxis: true,\n },\n\n // ══════════════════════════════════════════════════════════════════════════\n // COMPARISON CHARTS (MVP)\n // ══════════════════════════════════════════════════════════════════════════\n bar: {\n id: 'bar',\n name: 'Horizontal Bar Chart',\n description: 'Horizontal bars for comparing categories',\n intent: 'comparison',\n phase: 'mvp',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 1,\n minDataPoints: 2,\n idealDataPoints: 5,\n maxDataPoints: 15,\n allowNegativeValues: true,\n requireNonZeroTotal: false,\n warningThresholds: { tooManyCategories: 12 },\n fallback: { type: 'aggregate', strategy: 'top_n' },\n },\n switchableTo: ['column', 'stacked_bar', 'stacked_column'],\n supportsStacking: true,\n supportsMultipleSeries: true,\n requiresTimeAxis: false,\n },\n\n column: {\n id: 'column',\n name: 'Vertical Column Chart',\n description: 'Vertical bars for comparing categories',\n intent: 'comparison',\n phase: 'mvp',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 1,\n minDataPoints: 2,\n idealDataPoints: 5,\n maxDataPoints: 12,\n allowNegativeValues: true,\n requireNonZeroTotal: false,\n warningThresholds: { tooManyCategories: 10 },\n fallback: { type: 'aggregate', strategy: 'top_n' },\n },\n switchableTo: ['bar', 'stacked_column', 'stacked_bar'],\n supportsStacking: true,\n supportsMultipleSeries: true,\n requiresTimeAxis: false,\n },\n\n stacked_bar: {\n id: 'stacked_bar',\n name: 'Stacked Horizontal Bar',\n description: 'Horizontal stacked bars showing composition per category',\n intent: 'comparison',\n phase: 'mvp',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 2,\n minDataPoints: 2,\n idealDataPoints: 5,\n maxDataPoints: 10,\n allowNegativeValues: false,\n requireNonZeroTotal: true,\n warningThresholds: { tooManyCategories: 8, imbalancedRatio: 0.9 },\n fallback: { type: 'aggregate', strategy: 'other_bucket' },\n },\n switchableTo: ['bar', 'stacked_column', 'column_100pct'],\n supportsStacking: true,\n supportsMultipleSeries: true,\n requiresTimeAxis: false,\n },\n\n stacked_column: {\n id: 'stacked_column',\n name: 'Stacked Vertical Column',\n description: 'Vertical stacked columns showing composition per category',\n intent: 'comparison',\n phase: 'mvp',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 2,\n minDataPoints: 2,\n idealDataPoints: 5,\n maxDataPoints: 10,\n allowNegativeValues: false,\n requireNonZeroTotal: true,\n warningThresholds: { tooManyCategories: 8, imbalancedRatio: 0.9 },\n fallback: { type: 'aggregate', strategy: 'other_bucket' },\n },\n switchableTo: ['column', 'stacked_bar', 'column_100pct'],\n supportsStacking: true,\n supportsMultipleSeries: true,\n requiresTimeAxis: false,\n },\n\n column_100pct: {\n id: 'column_100pct',\n name: '100% Stacked Column',\n description: 'Shows proportional composition per category',\n intent: 'comparison',\n phase: 'mvp',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 2,\n minDataPoints: 2,\n idealDataPoints: 5,\n maxDataPoints: 10,\n allowNegativeValues: false,\n requireNonZeroTotal: true,\n warningThresholds: { tooManyCategories: 8 },\n fallback: { type: 'warn', message: '100% stacked requires positive totals' },\n },\n switchableTo: ['stacked_column', 'stacked_bar'],\n supportsStacking: true,\n supportsMultipleSeries: true,\n requiresTimeAxis: false,\n },\n\n combo: {\n id: 'combo',\n name: 'Combo Chart',\n description: 'Combines bars with line overlay (Phase 2)',\n intent: 'comparison',\n phase: 'phase2',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 2,\n minDataPoints: 3,\n idealDataPoints: 6,\n allowNegativeValues: true,\n requireNonZeroTotal: false,\n warningThresholds: { tooManyCategories: 10 },\n fallback: { type: 'warn', message: 'Combo chart requires dual measures' },\n },\n switchableTo: ['column', 'line'],\n supportsStacking: false,\n supportsMultipleSeries: true,\n requiresTimeAxis: false,\n },\n\n // ══════════════════════════════════════════════════════════════════════════\n // COMPOSITION CHARTS (MVP)\n // ══════════════════════════════════════════════════════════════════════════\n pie: {\n id: 'pie',\n name: 'Pie Chart',\n description: 'Shows proportional composition of a whole',\n intent: 'composition',\n phase: 'mvp',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 1,\n minDataPoints: 2,\n idealDataPoints: 4,\n maxDataPoints: 6,\n allowNegativeValues: false,\n requireNonZeroTotal: true,\n warningThresholds: { tooManyCategories: 6, imbalancedRatio: 0.95 },\n fallback: { type: 'aggregate', strategy: 'other_bucket' },\n },\n switchableTo: ['donut', 'column_100pct'],\n supportsStacking: false,\n supportsMultipleSeries: false,\n requiresTimeAxis: false,\n maxSlices: 6,\n },\n\n donut: {\n id: 'donut',\n name: 'Donut Chart',\n description: 'Pie chart with center cutout, can display total',\n intent: 'composition',\n phase: 'mvp',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 1,\n minDataPoints: 2,\n idealDataPoints: 4,\n maxDataPoints: 6,\n allowNegativeValues: false,\n requireNonZeroTotal: true,\n warningThresholds: { tooManyCategories: 6, imbalancedRatio: 0.95 },\n fallback: { type: 'aggregate', strategy: 'other_bucket' },\n },\n switchableTo: ['pie', 'column_100pct'],\n supportsStacking: false,\n supportsMultipleSeries: false,\n requiresTimeAxis: false,\n maxSlices: 6,\n },\n\n treemap: {\n id: 'treemap',\n name: 'Treemap',\n description: 'Nested rectangles showing hierarchical composition (Phase 2)',\n intent: 'composition',\n phase: 'phase2',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 1,\n minDataPoints: 3,\n idealDataPoints: 10,\n maxDataPoints: 50,\n allowNegativeValues: false,\n requireNonZeroTotal: true,\n warningThresholds: { tooManyCategories: 30 },\n fallback: { type: 'aggregate', strategy: 'top_n' },\n },\n switchableTo: ['pie', 'donut'],\n supportsStacking: false,\n supportsMultipleSeries: false,\n requiresTimeAxis: false,\n },\n\n // ══════════════════════════════════════════════════════════════════════════\n // DISTRIBUTION CHARTS (MVP)\n // ══════════════════════════════════════════════════════════════════════════\n histogram: {\n id: 'histogram',\n name: 'Histogram',\n description: 'Shows distribution of values across bins',\n intent: 'distribution',\n phase: 'mvp',\n contract: {\n requiredDimensions: 0,\n requiredMeasures: 1,\n minDataPoints: 10,\n idealDataPoints: 50,\n allowNegativeValues: true,\n requireNonZeroTotal: false,\n warningThresholds: { sparseData: 10 },\n fallback: { type: 'show_kpi', message: 'Insufficient data for distribution' },\n },\n switchableTo: ['radar'],\n supportsStacking: false,\n supportsMultipleSeries: false,\n requiresTimeAxis: false,\n },\n\n radar: {\n id: 'radar',\n name: 'Radar Chart',\n description: 'Multi-dimensional comparison in radial layout (Phase 2)',\n intent: 'distribution',\n phase: 'phase2',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 3,\n minDataPoints: 3,\n idealDataPoints: 6,\n maxDataPoints: 8,\n allowNegativeValues: false,\n requireNonZeroTotal: false,\n warningThresholds: { tooManyCategories: 8 },\n fallback: { type: 'warn', message: 'Radar works best with 3-8 dimensions' },\n },\n switchableTo: ['histogram'],\n supportsStacking: false,\n supportsMultipleSeries: true,\n requiresTimeAxis: false,\n },\n\n // ══════════════════════════════════════════════════════════════════════════\n // RELATIONSHIP CHARTS\n // ══════════════════════════════════════════════════════════════════════════\n heatmap: {\n id: 'heatmap',\n name: 'Heatmap',\n description: 'Color-coded matrix showing intensity',\n intent: 'relationship',\n phase: 'mvp',\n contract: {\n requiredDimensions: 2,\n requiredMeasures: 1,\n minDataPoints: 9,\n idealDataPoints: 25,\n allowNegativeValues: true,\n requireNonZeroTotal: false,\n warningThresholds: { sparseData: 9 },\n fallback: { type: 'warn', message: 'Heatmap requires grid data' },\n },\n switchableTo: ['scatter'],\n supportsStacking: false,\n supportsMultipleSeries: false,\n requiresTimeAxis: false,\n },\n\n scatter: {\n id: 'scatter',\n name: 'Scatter Plot',\n description: 'Shows correlation between two variables (Phase 2)',\n intent: 'relationship',\n phase: 'phase2',\n contract: {\n requiredDimensions: 0,\n requiredMeasures: 2,\n minDataPoints: 20,\n idealDataPoints: 100,\n allowNegativeValues: true,\n requireNonZeroTotal: false,\n warningThresholds: { sparseData: 20 },\n fallback: { type: 'show_kpi', message: 'Scatter requires 20+ points' },\n },\n switchableTo: ['bubble', 'heatmap'],\n supportsStacking: false,\n supportsMultipleSeries: true,\n requiresTimeAxis: false,\n },\n\n bubble: {\n id: 'bubble',\n name: 'Bubble Chart',\n description: 'Scatter with sized points for third dimension (Phase 2)',\n intent: 'relationship',\n phase: 'phase2',\n contract: {\n requiredDimensions: 0,\n requiredMeasures: 3,\n minDataPoints: 10,\n idealDataPoints: 50,\n allowNegativeValues: true,\n requireNonZeroTotal: false,\n warningThresholds: { sparseData: 10 },\n fallback: { type: 'show_kpi', message: 'Bubble requires 3 measures' },\n },\n switchableTo: ['scatter'],\n supportsStacking: false,\n supportsMultipleSeries: true,\n requiresTimeAxis: false,\n },\n\n // ══════════════════════════════════════════════════════════════════════════\n // GEOGRAPHIC CHARTS (Phase 2)\n // ══════════════════════════════════════════════════════════════════════════\n geo: {\n id: 'geo',\n name: 'Geographic Map',\n description: 'Map with regional data markers (Phase 2)',\n intent: 'geo',\n phase: 'phase2',\n contract: {\n requiredDimensions: 1, // geo dimension (country/region)\n requiredMeasures: 1,\n minDataPoints: 1,\n idealDataPoints: 10,\n allowNegativeValues: true,\n requireNonZeroTotal: false,\n warningThresholds: {},\n fallback: { type: 'hide' },\n },\n switchableTo: ['choropleth'],\n supportsStacking: false,\n supportsMultipleSeries: false,\n requiresTimeAxis: false,\n },\n\n choropleth: {\n id: 'choropleth',\n name: 'Choropleth Map',\n description: 'Color-shaded regions by value (Phase 2)',\n intent: 'geo',\n phase: 'phase2',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 1,\n minDataPoints: 3,\n idealDataPoints: 20,\n allowNegativeValues: false,\n requireNonZeroTotal: false,\n warningThresholds: {},\n fallback: { type: 'hide' },\n },\n switchableTo: ['geo'],\n supportsStacking: false,\n supportsMultipleSeries: false,\n requiresTimeAxis: false,\n },\n\n // ══════════════════════════════════════════════════════════════════════════\n // SPECIAL CHARTS\n // ══════════════════════════════════════════════════════════════════════════\n funnel: {\n id: 'funnel',\n name: 'Funnel Chart',\n description: 'Shows conversion through sequential stages',\n intent: 'comparison',\n phase: 'mvp',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 1,\n minDataPoints: 3,\n idealDataPoints: 5,\n maxDataPoints: 7,\n allowNegativeValues: false,\n requireNonZeroTotal: true,\n warningThresholds: { tooManyCategories: 7 },\n fallback: { type: 'warn', message: 'Funnel requires sequential stages' },\n },\n switchableTo: ['bar'],\n supportsStacking: false,\n supportsMultipleSeries: false,\n requiresTimeAxis: false,\n },\n\n waterfall: {\n id: 'waterfall',\n name: 'Waterfall Chart',\n description: 'Shows cumulative effect of sequential changes (Phase 2)',\n intent: 'comparison',\n phase: 'phase2',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 1,\n minDataPoints: 3,\n idealDataPoints: 6,\n maxDataPoints: 12,\n allowNegativeValues: true,\n requireNonZeroTotal: false,\n warningThresholds: { tooManyCategories: 10 },\n fallback: { type: 'warn', message: 'Waterfall requires sequential data' },\n },\n switchableTo: ['bar', 'column'],\n supportsStacking: false,\n supportsMultipleSeries: false,\n requiresTimeAxis: false,\n },\n\n timeline: {\n id: 'timeline',\n name: 'Timeline',\n description: 'Shows events along time axis (Phase 2)',\n intent: 'trend',\n phase: 'phase2',\n contract: {\n requiredDimensions: 1,\n requiredMeasures: 0,\n minDataPoints: 2,\n idealDataPoints: 10,\n allowNegativeValues: false,\n requireNonZeroTotal: false,\n warningThresholds: {},\n fallback: { type: 'hide' },\n },\n switchableTo: ['line'],\n supportsStacking: false,\n supportsMultipleSeries: false,\n requiresTimeAxis: true,\n },\n};\n\n/* ============================================================================\n CHART FAMILY SWITCHING RULES\n ============================================================================ */\n\n/**\n * Maps intent to allowed chart types for switching.\n * Users can ONLY switch within the same intent family.\n */\nexport const INTENT_CHART_FAMILIES: Record<ChartIntent, ChartTypeId[]> = {\n trend: ['line', 'smooth_line', 'area', 'stacked_area', 'area_100pct'],\n comparison: ['bar', 'column', 'stacked_bar', 'stacked_column', 'column_100pct', 'funnel'],\n composition: ['pie', 'donut'],\n distribution: ['histogram'],\n relationship: ['heatmap'],\n geo: [],\n};\n\n/**\n * Get allowed chart types for switching from a given type.\n */\nexport function getAllowedSwitchTargets(currentType: ChartTypeId): ChartTypeId[] {\n const metadata = CHART_REGISTRY[currentType];\n if (!metadata) return [];\n\n // Only return MVP charts that are in the same family\n return metadata.switchableTo.filter((type) => {\n const targetMeta = CHART_REGISTRY[type];\n return targetMeta && targetMeta.phase === 'mvp';\n });\n}\n\n/**\n * Check if switching from one chart type to another is allowed.\n */\nexport function canSwitchChart(from: ChartTypeId, to: ChartTypeId): boolean {\n const fromMeta = CHART_REGISTRY[from];\n const toMeta = CHART_REGISTRY[to];\n\n if (!fromMeta || !toMeta) return false;\n\n // Must be same intent\n if (fromMeta.intent !== toMeta.intent) return false;\n\n // Must be in allowed list\n return fromMeta.switchableTo.includes(to);\n}\n\n/* ============================================================================\n DATA VALIDATION\n ============================================================================ */\n\nexport interface ChartValidationResult {\n isValid: boolean;\n warnings: string[];\n errors: string[];\n suggestedType?: ChartTypeId;\n fallbackAction?: ChartFallbackBehavior;\n}\n\n/**\n * Validate data against a chart's contract.\n */\nexport function validateChartData(\n chartType: ChartTypeId,\n data: unknown[],\n dimensions: string[],\n measures: string[],\n): ChartValidationResult {\n const metadata = CHART_REGISTRY[chartType];\n if (!metadata) {\n return {\n isValid: false,\n warnings: [],\n errors: [`Unknown chart type: ${chartType}`],\n };\n }\n\n const contract = metadata.contract;\n const warnings: string[] = [];\n const errors: string[] = [];\n\n // Check data points\n if (data.length < contract.minDataPoints) {\n errors.push(`Requires at least ${contract.minDataPoints} data points, got ${data.length}`);\n }\n\n if (contract.maxDataPoints && data.length > contract.maxDataPoints) {\n warnings.push(`Chart works best with ≤${contract.maxDataPoints} items. Consider aggregating.`);\n }\n\n // Check dimensions\n if (dimensions.length < contract.requiredDimensions) {\n errors.push(`Requires ${contract.requiredDimensions} dimension(s), got ${dimensions.length}`);\n }\n\n // Check measures\n if (measures.length < contract.requiredMeasures) {\n errors.push(`Requires ${contract.requiredMeasures} measure(s), got ${measures.length}`);\n }\n\n // Check for negative values if not allowed\n if (!contract.allowNegativeValues && data.length > 0) {\n const hasNegative = data.some((row: unknown) => {\n if (typeof row !== 'object' || row === null) return false;\n return measures.some((m) => {\n const val = (row as Record<string, unknown>)[m];\n return typeof val === 'number' && val < 0;\n });\n });\n if (hasNegative) {\n errors.push('This chart type does not support negative values');\n }\n }\n\n // Check warnings\n if (\n contract.warningThresholds.tooManyCategories &&\n data.length > contract.warningThresholds.tooManyCategories\n ) {\n warnings.push(`Too many categories (${data.length}). Consider grouping smaller values.`);\n }\n\n return {\n isValid: errors.length === 0,\n warnings,\n errors,\n fallbackAction: errors.length > 0 ? contract.fallback : undefined,\n };\n}\n\n/* ============================================================================\n CHART SELECTION HELPERS\n ============================================================================ */\n\n/**\n * Get MVP charts for a given intent.\n */\nexport function getMVPChartsForIntent(intent: ChartIntent): ChartTypeMetadata[] {\n return Object.values(CHART_REGISTRY).filter(\n (meta) => meta.intent === intent && meta.phase === 'mvp',\n );\n}\n\n/**\n * Get the default chart type for an intent.\n */\nexport function getDefaultChartForIntent(intent: ChartIntent): ChartTypeId {\n const defaults: Record<ChartIntent, ChartTypeId> = {\n trend: 'line',\n comparison: 'column',\n composition: 'donut',\n distribution: 'histogram',\n relationship: 'heatmap',\n geo: 'geo',\n };\n return defaults[intent];\n}\n\n/**\n * Suggest the best chart type for given data characteristics.\n */\nexport function suggestChartType(params: {\n hasTimeAxis: boolean;\n dimensionCount: number;\n measureCount: number;\n dataPointCount: number;\n hasNegativeValues: boolean;\n isSequential: boolean;\n}): ChartTypeId {\n const {\n hasTimeAxis,\n dimensionCount,\n measureCount,\n dataPointCount,\n hasNegativeValues,\n isSequential,\n } = params;\n\n // Time-based → trend charts\n if (hasTimeAxis && measureCount >= 1) {\n if (measureCount > 1 && !hasNegativeValues) return 'stacked_area';\n return 'line';\n }\n\n // Sequential stages → funnel\n if (isSequential && !hasNegativeValues && dataPointCount <= 7) {\n return 'funnel';\n }\n\n // Single measure, few categories → composition\n if (measureCount === 1 && dataPointCount <= 6 && !hasNegativeValues) {\n return 'donut';\n }\n\n // Two dimensions → heatmap\n if (dimensionCount === 2 && measureCount === 1) {\n return 'heatmap';\n }\n\n // Default to column chart\n return 'column';\n}\n","/* ============================================================================\n REPORT ENGINE — COMPOSITION VALIDATION\n ============================================================================ */\n\nimport React from 'react';\n\nexport interface ValidationIssue {\n ruleId: string;\n severity: 'error' | 'warning';\n message: string;\n component?: string;\n}\n\nexport interface ReportValidationResult {\n isValid: boolean;\n issues: ValidationIssue[];\n}\n\n/**\n * Validates the structure of a report against narrative rules.\n *\n * Rules:\n * - R1: ExecutiveThesis MUST appear exactly once, at the top (or very near top)\n * - R2: InsightBlock MUST precede any chart it references (Charts must be inside or after insights)\n * - R3: Charts CANNOT appear without a parent InsightBlock (Orphan charts)\n * - R6: Max 3 charts per InsightBlock\n */\nexport function validateReportStructure(children: React.ReactNode): ReportValidationResult {\n const issues: ValidationIssue[] = [];\n const childArray = React.Children.toArray(children);\n\n let hasThesis = false;\n let thesisIndex = -1;\n\n // Helper to get component name safely\n const getComponentName = (child: React.ReactNode): string | undefined => {\n if (!React.isValidElement(child)) return undefined;\n\n const type = child.type as { displayName?: string; name?: string };\n return type.displayName || type.name;\n };\n\n const isChart = (name?: string) => {\n return (\n name &&\n (name.endsWith('Chart') ||\n name === 'MBTIRadar' ||\n name === 'MBTITypeGrid' ||\n name === 'KeyMetric') // Metric is evidence too\n );\n };\n\n // First pass: Top-level analysis\n childArray.forEach((child, index) => {\n const name = getComponentName(child);\n\n if (name === 'ExecutiveThesis') {\n if (hasThesis) {\n issues.push({\n ruleId: 'R1',\n severity: 'error',\n message: 'Only one ExecutiveThesis is allowed per report.',\n component: 'ExecutiveThesis',\n });\n }\n hasThesis = true;\n thesisIndex = index;\n }\n\n // Check for orphan charts at root level\n if (isChart(name)) {\n issues.push({\n ruleId: 'R3',\n severity: 'error',\n message: `Orphan chart detected: <${name} />. Charts must be placed inside an InsightBlock or EvidenceGroup.`,\n component: name,\n });\n }\n\n // Check InsightBlock constraints\n if (name === 'InsightBlock' && React.isValidElement(child)) {\n validateInsightBlock(child, issues);\n }\n });\n\n // R1: Check Thesis existence and position\n if (!hasThesis) {\n issues.push({\n ruleId: 'R1',\n severity: 'error',\n message: 'Report must contain an ExecutiveThesis.',\n });\n } else if (thesisIndex > 2) {\n // Allow some spacers/headers before it\n issues.push({\n ruleId: 'R1',\n severity: 'warning',\n message: 'ExecutiveThesis should be the first major component in the report.',\n });\n }\n\n return {\n isValid: issues.filter((i) => i.severity === 'error').length === 0,\n issues,\n };\n}\n\nfunction validateInsightBlock(node: React.ReactElement, issues: ValidationIssue[]) {\n const children = node.props.children;\n const childArray = React.Children.toArray(children);\n\n // Count charts inside this block (recursive check not strictly needed if structure is flat)\n let chartsInBlock = 0;\n\n const countCharts = (nodes: React.ReactNode[]) => {\n nodes.forEach((n) => {\n const name = getComponentName(n);\n if (isChart(name)) {\n chartsInBlock++;\n }\n // Check inside EvidenceGroup\n if (name === 'EvidenceGroup' && React.isValidElement(n)) {\n countCharts(React.Children.toArray(n.props.children));\n }\n });\n };\n\n countCharts(childArray);\n\n // R6: Max 3 charts\n if (chartsInBlock > 3) {\n issues.push({\n ruleId: 'R6',\n severity: 'warning',\n message: `InsightBlock contains ${chartsInBlock} charts. Recommended maximum is 3 to prevent data dumping.`,\n component: 'InsightBlock',\n });\n }\n}\n\n// Duplicate helper for local scope\nconst getComponentName = (child: React.ReactNode): string | undefined => {\n if (!React.isValidElement(child)) return undefined;\n const type = child.type as { displayName?: string; name?: string };\n return type.displayName || type.name;\n};\n\nconst isChart = (name?: string) => {\n return (\n name &&\n (name.endsWith('Chart') ||\n name === 'MBTIRadar' ||\n name === 'MBTITypeGrid' ||\n name === 'KeyMetric')\n );\n};\n","import React from 'react';\nimport clsx from 'clsx';\nimport { getConfidenceThreshold } from '../../report-engine';\nimport './ConfidenceIndicator.css';\n\nexport interface ConfidenceIndicatorProps {\n /** Confidence score (0-100) */\n score: number;\n /** Show the numeric score */\n showScore?: boolean;\n /** Show the label */\n showLabel?: boolean;\n /** Size variant */\n size?: 'sm' | 'md' | 'lg';\n /** Additional CSS class */\n className?: string;\n}\n\n/**\n * ConfidenceIndicator displays the reliability score of an insight or data point.\n * This is a guardrail component that helps users understand data quality.\n */\nexport const ConfidenceIndicator = React.forwardRef<HTMLDivElement, ConfidenceIndicatorProps>(\n ({ score, showScore = true, showLabel = true, size = 'md', className, ...props }, ref) => {\n const threshold = getConfidenceThreshold(score);\n const normalizedScore = Math.max(0, Math.min(100, score));\n\n return (\n <div\n ref={ref}\n className={clsx(\n 'ds-confidence-indicator',\n `ds-confidence-indicator--${size}`,\n `ds-confidence-indicator--${threshold.level}`,\n className,\n )}\n role=\"meter\"\n aria-valuenow={normalizedScore}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={`Confidence: ${threshold.label} (${normalizedScore}%)`}\n {...props}\n >\n <div className=\"ds-confidence-indicator__bar\">\n <div className=\"ds-confidence-indicator__fill\" style={{ width: `${normalizedScore}%` }} />\n </div>\n <div className=\"ds-confidence-indicator__text\">\n {showScore && <span className=\"ds-confidence-indicator__score\">{normalizedScore}%</span>}\n {showLabel && <span className=\"ds-confidence-indicator__label\">{threshold.label}</span>}\n </div>\n </div>\n );\n },\n);\n\nConfidenceIndicator.displayName = 'ConfidenceIndicator';\n","import React from 'react';\nimport clsx from 'clsx';\nimport './DataCoverageBadge.css';\n\nexport interface DataCoverageBadgeProps {\n /** Current sample size */\n sampleSize: number;\n /** Required minimum sample size */\n requiredSize?: number;\n /** Date range covered */\n dateRange?: {\n start: string;\n end: string;\n };\n /** Show date range */\n showDateRange?: boolean;\n /** Size variant */\n size?: 'sm' | 'md';\n /** Additional CSS class */\n className?: string;\n}\n\n/**\n * DataCoverageBadge shows the sample size and optionally the date range of the data.\n * This is a guardrail component that helps users understand data coverage.\n */\nexport const DataCoverageBadge = React.forwardRef<HTMLDivElement, DataCoverageBadgeProps>(\n (\n { sampleSize, requiredSize, dateRange, showDateRange = true, size = 'md', className, ...props },\n ref,\n ) => {\n const isSufficient = !requiredSize || sampleSize >= requiredSize;\n const percentage = requiredSize\n ? Math.min(100, Math.round((sampleSize / requiredSize) * 100))\n : 100;\n\n return (\n <div\n ref={ref}\n className={clsx(\n 'ds-data-coverage-badge',\n `ds-data-coverage-badge--${size}`,\n !isSufficient && 'ds-data-coverage-badge--insufficient',\n className,\n )}\n {...props}\n >\n <div className=\"ds-data-coverage-badge__sample\">\n <span className=\"ds-data-coverage-badge__icon\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\" />\n <circle cx=\"9\" cy=\"7\" r=\"4\" />\n <path d=\"M23 21v-2a4 4 0 0 0-3-3.87\" />\n <path d=\"M16 3.13a4 4 0 0 1 0 7.75\" />\n </svg>\n </span>\n <span className=\"ds-data-coverage-badge__count\">n={sampleSize.toLocaleString()}</span>\n {requiredSize && (\n <span className=\"ds-data-coverage-badge__required\">\n ({percentage}% of min {requiredSize})\n </span>\n )}\n </div>\n\n {showDateRange && dateRange && (\n <div className=\"ds-data-coverage-badge__date\">\n <span className=\"ds-data-coverage-badge__icon\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\" />\n <line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\" />\n <line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\" />\n </svg>\n </span>\n <span>\n {dateRange.start} – {dateRange.end}\n </span>\n </div>\n )}\n </div>\n );\n },\n);\n\nDataCoverageBadge.displayName = 'DataCoverageBadge';\n","import React from 'react';\nimport clsx from 'clsx';\nimport type { AnalyticalState, DataStateDetails } from '../../report-engine';\nimport { ANALYTICAL_STATE_CONFIG } from '../../report-engine';\nimport './DataStateIndicator.css';\n\nexport interface DataStateIndicatorProps {\n /** Current analytical state */\n state: AnalyticalState;\n /** Additional details about the state */\n details?: DataStateDetails;\n /** Show full details or compact */\n variant?: 'compact' | 'full';\n /** Action button handler */\n onAction?: () => void;\n /** Additional CSS class */\n className?: string;\n}\n\n/**\n * DataStateIndicator shows the analytical state of data (valid, insufficient, etc.).\n * This is a guardrail component that prevents misleading outputs.\n */\nexport const DataStateIndicator = React.forwardRef<HTMLDivElement, DataStateIndicatorProps>(\n ({ state, details, variant = 'compact', onAction, className, ...props }, ref) => {\n const config = ANALYTICAL_STATE_CONFIG[state];\n\n // Don't render if valid and compact\n if (state === 'VALID' && variant === 'compact') {\n return null;\n }\n\n const renderIcon = () => {\n switch (config.icon) {\n case 'check':\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <polyline points=\"20,6 9,17 4,12\" />\n </svg>\n );\n case 'alert-triangle':\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\" />\n <line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\" />\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\n </svg>\n );\n case 'alert-circle':\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>\n );\n case 'x-circle':\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\" />\n <line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\" />\n </svg>\n );\n case 'cpu':\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" ry=\"2\" />\n <rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" />\n <line x1=\"9\" y1=\"1\" x2=\"9\" y2=\"4\" />\n <line x1=\"15\" y1=\"1\" x2=\"15\" y2=\"4\" />\n <line x1=\"9\" y1=\"20\" x2=\"9\" y2=\"23\" />\n <line x1=\"15\" y1=\"20\" x2=\"15\" y2=\"23\" />\n <line x1=\"20\" y1=\"9\" x2=\"23\" y2=\"9\" />\n <line x1=\"20\" y1=\"14\" x2=\"23\" y2=\"14\" />\n <line x1=\"1\" y1=\"9\" x2=\"4\" y2=\"9\" />\n <line x1=\"1\" y1=\"14\" x2=\"4\" y2=\"14\" />\n </svg>\n );\n default:\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\" />\n </svg>\n );\n }\n };\n\n return (\n <div\n ref={ref}\n className={clsx(\n 'ds-data-state-indicator',\n `ds-data-state-indicator--${variant}`,\n `ds-data-state-indicator--${state.toLowerCase().replace(/_/g, '-')}`,\n className,\n )}\n role=\"status\"\n aria-live=\"polite\"\n {...props}\n >\n <span className=\"ds-data-state-indicator__icon\" style={{ color: config.color }}>\n {renderIcon()}\n </span>\n\n <div className=\"ds-data-state-indicator__content\">\n <span className=\"ds-data-state-indicator__label\">{config.label}</span>\n\n {variant === 'full' && details && (\n <span className=\"ds-data-state-indicator__details\">\n {details.message}\n {details.sampleSize !== undefined && details.requiredSize !== undefined && (\n <>\n {' '}\n (n={details.sampleSize}/{details.requiredSize})\n </>\n )}\n {details.confidence !== undefined && <> • {details.confidence}% confidence</>}\n {details.missingFields && details.missingFields.length > 0 && (\n <> • Missing: {details.missingFields.join(', ')}</>\n )}\n </span>\n )}\n </div>\n\n {config.action && onAction && (\n <button type=\"button\" className=\"ds-data-state-indicator__action\" onClick={onAction}>\n {config.action}\n </button>\n )}\n </div>\n );\n },\n);\n\nDataStateIndicator.displayName = 'DataStateIndicator';\n"]}
|
package/dist/chunk-Q75DBVDY.cjs
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var react = require('react');
|
|
4
|
-
var clsx = require('clsx');
|
|
5
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
-
|
|
7
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
-
|
|
9
|
-
var clsx__default = /*#__PURE__*/_interopDefault(clsx);
|
|
10
|
-
|
|
11
|
-
// src/components/BrowserFrame/BrowserFrame.tsx
|
|
12
|
-
var BrowserFrame = react.forwardRef(
|
|
13
|
-
({
|
|
14
|
-
variant = "browser",
|
|
15
|
-
children,
|
|
16
|
-
url,
|
|
17
|
-
showControls,
|
|
18
|
-
withGlow = false,
|
|
19
|
-
aspectRatio = "16/9",
|
|
20
|
-
className,
|
|
21
|
-
...props
|
|
22
|
-
}, ref) => {
|
|
23
|
-
const hasControls = showControls ?? (variant === "browser" || variant === "app");
|
|
24
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
25
|
-
"div",
|
|
26
|
-
{
|
|
27
|
-
ref,
|
|
28
|
-
className: clsx__default.default(
|
|
29
|
-
"ds-browser-frame",
|
|
30
|
-
`ds-browser-frame--${variant}`,
|
|
31
|
-
withGlow && "ds-browser-frame--glow",
|
|
32
|
-
className
|
|
33
|
-
),
|
|
34
|
-
...props,
|
|
35
|
-
children: [
|
|
36
|
-
variant !== "minimal" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ds-browser-frame__chrome", children: [
|
|
37
|
-
hasControls && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ds-browser-frame__controls", "aria-hidden": "true", children: [
|
|
38
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ds-browser-frame__dot ds-browser-frame__dot--red" }),
|
|
39
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ds-browser-frame__dot ds-browser-frame__dot--yellow" }),
|
|
40
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ds-browser-frame__dot ds-browser-frame__dot--green" })
|
|
41
|
-
] }),
|
|
42
|
-
variant === "browser" && url && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ds-browser-frame__url-bar", children: [
|
|
43
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", className: "ds-browser-frame__lock", children: [
|
|
44
|
-
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 5V4a3 3 0 116 0v1", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round" }),
|
|
45
|
-
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "2", y: "5", width: "8", height: "6", rx: "1.5", stroke: "currentColor", strokeWidth: "1.2" })
|
|
46
|
-
] }),
|
|
47
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ds-browser-frame__url-text", children: url })
|
|
48
|
-
] })
|
|
49
|
-
] }),
|
|
50
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
51
|
-
"div",
|
|
52
|
-
{
|
|
53
|
-
className: "ds-browser-frame__content",
|
|
54
|
-
style: aspectRatio !== "auto" ? { aspectRatio } : void 0,
|
|
55
|
-
children
|
|
56
|
-
}
|
|
57
|
-
),
|
|
58
|
-
variant === "mobile" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ds-browser-frame__notch", "aria-hidden": "true" })
|
|
59
|
-
]
|
|
60
|
-
}
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
);
|
|
64
|
-
BrowserFrame.displayName = "BrowserFrame";
|
|
65
|
-
|
|
66
|
-
exports.BrowserFrame = BrowserFrame;
|
|
67
|
-
//# sourceMappingURL=out.js.map
|
|
68
|
-
//# sourceMappingURL=chunk-Q75DBVDY.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/BrowserFrame/BrowserFrame.tsx"],"names":[],"mappings":";AAAA,SAAgB,kBAAkB;AAClC,OAAO,UAAU;AAoEH,SACE,KADF;AA/BP,IAAM,eAAe;AAAA,EAC1B,CACE;AAAA,IACE,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,cAAc;AAAA,IACd;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,cAAc,iBAAiB,YAAY,aAAa,YAAY;AAE1E,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA,qBAAqB,OAAO;AAAA,UAC5B,YAAY;AAAA,UACZ;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAGH;AAAA,sBAAY,aACX,qBAAC,SAAI,WAAU,4BACZ;AAAA,2BACC,qBAAC,SAAI,WAAU,8BAA6B,eAAY,QACtD;AAAA,kCAAC,UAAK,WAAU,oDAAmD;AAAA,cACnE,oBAAC,UAAK,WAAU,uDAAsD;AAAA,cACtE,oBAAC,UAAK,WAAU,sDAAqD;AAAA,eACvE;AAAA,YAED,YAAY,aAAa,OACxB,qBAAC,SAAI,WAAU,6BACb;AAAA,mCAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,eAAY,QAAO,WAAU,0BACvF;AAAA,oCAAC,UAAK,GAAE,wBAAuB,QAAO,gBAAe,aAAY,OAAM,eAAc,SAAQ;AAAA,gBAC7F,oBAAC,UAAK,GAAE,KAAI,GAAE,KAAI,OAAM,KAAI,QAAO,KAAI,IAAG,OAAM,QAAO,gBAAe,aAAY,OAAM;AAAA,iBAC1F;AAAA,cACA,oBAAC,UAAK,WAAU,8BAA8B,eAAI;AAAA,eACpD;AAAA,aAEJ;AAAA,UAIF;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,gBAAgB,SAAS,EAAE,YAAY,IAAI;AAAA,cAEjD;AAAA;AAAA,UACH;AAAA,UAGC,YAAY,YACX,oBAAC,SAAI,WAAU,2BAA0B,eAAY,QAAO;AAAA;AAAA;AAAA,IAEhE;AAAA,EAEJ;AACF;AAEA,aAAa,cAAc","sourcesContent":["import React, { forwardRef } from 'react';\nimport clsx from 'clsx';\nimport './BrowserFrame.css';\n\n/* ============================================================================\n BROWSER FRAME\n ============================================================================\n Realistic browser/device mockup frame for product screenshots and videos.\n Makes static screenshots feel like live product demos.\n\n Strategic objective: Trust (product visualization builds desire)\n ============================================================================ */\n\nexport interface BrowserFrameProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Frame type */\n variant?: 'browser' | 'app' | 'mobile' | 'minimal';\n /** Content to frame (image, video, or React element) */\n children: React.ReactNode;\n /** Optional URL bar text */\n url?: string;\n /** Show traffic light dots (default: true for browser/app) */\n showControls?: boolean;\n /** Optional glow effect behind frame */\n withGlow?: boolean;\n /** Aspect ratio */\n aspectRatio?: '16/9' | '4/3' | '3/2' | 'auto';\n}\n\n/**\n * Device mockup frame for product screenshots.\n *\n * @example\n * ```tsx\n * <BrowserFrame variant=\"browser\" url=\"app.sales-mind.ai\" withGlow>\n * <img src=\"/screenshot.png\" alt=\"SalesMind dashboard\" />\n * </BrowserFrame>\n * ```\n */\nexport const BrowserFrame = forwardRef<HTMLDivElement, BrowserFrameProps>(\n (\n {\n variant = 'browser',\n children,\n url,\n showControls,\n withGlow = false,\n aspectRatio = '16/9',\n className,\n ...props\n },\n ref,\n ) => {\n const hasControls = showControls ?? (variant === 'browser' || variant === 'app');\n\n return (\n <div\n ref={ref}\n className={clsx(\n 'ds-browser-frame',\n `ds-browser-frame--${variant}`,\n withGlow && 'ds-browser-frame--glow',\n className,\n )}\n {...props}\n >\n {/* Chrome header */}\n {variant !== 'minimal' && (\n <div className=\"ds-browser-frame__chrome\">\n {hasControls && (\n <div className=\"ds-browser-frame__controls\" aria-hidden=\"true\">\n <span className=\"ds-browser-frame__dot ds-browser-frame__dot--red\" />\n <span className=\"ds-browser-frame__dot ds-browser-frame__dot--yellow\" />\n <span className=\"ds-browser-frame__dot ds-browser-frame__dot--green\" />\n </div>\n )}\n {variant === 'browser' && url && (\n <div className=\"ds-browser-frame__url-bar\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\" className=\"ds-browser-frame__lock\">\n <path d=\"M3 5V4a3 3 0 116 0v1\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" />\n <rect x=\"2\" y=\"5\" width=\"8\" height=\"6\" rx=\"1.5\" stroke=\"currentColor\" strokeWidth=\"1.2\" />\n </svg>\n <span className=\"ds-browser-frame__url-text\">{url}</span>\n </div>\n )}\n </div>\n )}\n\n {/* Content area */}\n <div\n className=\"ds-browser-frame__content\"\n style={aspectRatio !== 'auto' ? { aspectRatio } : undefined}\n >\n {children}\n </div>\n\n {/* Mobile notch */}\n {variant === 'mobile' && (\n <div className=\"ds-browser-frame__notch\" aria-hidden=\"true\" />\n )}\n </div>\n );\n },\n);\n\nBrowserFrame.displayName = 'BrowserFrame';\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Navbar/NavbarMobileHelpers.tsx","../src/components/Navbar/NavbarMegaMenu.tsx","../src/components/NavbarV2/NavbarV2.tsx","../src/components/SiteFooter/SiteFooter.tsx","../src/components/LocaleDropdown/LocaleDropdown.tsx","../src/components/OutboundLink/MDXOutboundLink.tsx"],"names":["forwardRef","clsx","jsx","useState","useRef","useEffect","useCallback","jsxs","ChevronDown","focusable","useId"],"mappings":"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","sourcesContent":["import React, { forwardRef, HTMLAttributes } from 'react';\nimport clsx from 'clsx';\nimport './Navbar.css';\n\n/* ============================================================================\n Mobile Menu Helpers — shared by NavbarV2 consumers\n ============================================================================\n These lightweight presentational components are used inside mobile menu\n overlays. They were originally part of Navbar V1 but are framework-agnostic\n and continue to be consumed by NavbarV2-based layouts.\n ============================================================================ */\n\nexport interface NavbarMobileNavItemProps extends HTMLAttributes<HTMLElement> {\n as?: React.ElementType;\n active?: boolean;\n href?: string;\n}\n\n/** Full-width touch-friendly nav item for the mobile menu. */\nexport const NavbarMobileNavItem = forwardRef<HTMLElement, NavbarMobileNavItemProps>(\n ({ as: Component = 'a', className, active, children, ...props }, ref) => (\n <Component\n ref={ref}\n className={clsx(\n 'ds-navbar__mobile-nav-item',\n active && 'ds-navbar__mobile-nav-item--active',\n className,\n )}\n aria-current={active ? 'page' : undefined}\n {...props}\n >\n {children}\n </Component>\n ),\n);\nNavbarMobileNavItem.displayName = 'NavbarMobileNavItem';\n\n/** Visual separator line inside the mobile menu. */\nexport function NavbarMobileSeparator({ className }: { className?: string }) {\n return <div className={clsx('ds-navbar__mobile-separator', className)} role=\"separator\" />;\n}\nNavbarMobileSeparator.displayName = 'NavbarMobileSeparator';\n\n/** Actions group at the bottom of the mobile menu (CTAs, auth). */\nexport const NavbarMobileActions = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, children, ...props }, ref) => (\n <div ref={ref} className={clsx('ds-navbar__mobile-actions', className)} {...props}>\n {children}\n </div>\n ),\n);\nNavbarMobileActions.displayName = 'NavbarMobileActions';\n","import React, { forwardRef, useState, useRef, useEffect, useCallback } from 'react';\nimport clsx from 'clsx';\nimport { Container } from '../LayoutPrimitives';\nimport './NavbarMegaMenu.css';\n\n/* ============================================================================\n Icons\n ============================================================================ */\n\nconst ChevronDown = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M4 6L8 10L12 6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\n/* ============================================================================\n NavbarMegaMenu\n ============================================================================ */\n\nexport interface NavbarMegaMenuProps {\n /** The text or element that toggles the menu */\n trigger: React.ReactNode;\n /** The content to display inside the mega menu */\n children: React.ReactNode;\n /** Optional class name */\n className?: string;\n /** Whether the menu is controlled */\n isOpen?: boolean;\n /** Change handler for controlled state */\n onOpenChange?: (isOpen: boolean) => void;\n /** Presentation style of the menu */\n variant?: 'fullWidth' | 'floating';\n}\n\nexport const NavbarMegaMenu = forwardRef<HTMLDivElement, NavbarMegaMenuProps>(\n (\n { trigger, children, className, isOpen: controlledOpen, onOpenChange, variant = 'fullWidth' },\n ref,\n ) => {\n const [internalOpen, setInternalOpen] = useState(false);\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const timeoutRef = useRef<number | null>(null);\n\n const handleOpen = useCallback(() => {\n const newState = true;\n if (isOpen !== newState) {\n if (!isControlled) setInternalOpen(newState);\n onOpenChange?.(newState);\n }\n }, [isOpen, isControlled, onOpenChange]);\n\n const handleClose = useCallback(() => {\n const newState = false;\n if (isOpen !== newState) {\n if (!isControlled) setInternalOpen(newState);\n onOpenChange?.(newState);\n }\n }, [isOpen, isControlled, onOpenChange]);\n\n const handleToggle = useCallback(() => {\n if (isOpen) {\n handleClose();\n } else {\n handleOpen();\n }\n }, [isOpen, handleClose, handleOpen]);\n\n const handleMouseEnter = useCallback(() => {\n if (timeoutRef.current) {\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n handleOpen();\n }, [handleOpen]);\n\n const handleMouseLeave = useCallback(() => {\n if (timeoutRef.current) {\n window.clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = window.setTimeout(() => {\n handleClose();\n }, 150);\n }, [handleClose]);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) window.clearTimeout(timeoutRef.current);\n };\n }, []);\n\n // Close on click outside\n useEffect(() => {\n if (!isOpen) return;\n\n const handleClickOutside = (event: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target as Node) &&\n triggerRef.current &&\n !triggerRef.current.contains(event.target as Node)\n ) {\n handleClose();\n }\n };\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [isOpen, handleClose]);\n\n // Close on Escape key\n useEffect(() => {\n if (!isOpen) return;\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape') handleClose();\n };\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [isOpen, handleClose]);\n\n return (\n <div\n className={clsx('ds-navbar-mega-menu', `ds-navbar-mega-menu--${variant}`, className)}\n ref={ref}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n <button\n ref={triggerRef}\n className=\"ds-navbar-mega-menu__trigger\"\n onClick={handleToggle}\n aria-expanded={isOpen}\n aria-haspopup=\"true\"\n >\n {trigger}\n <span\n className=\"ds-navbar-mega-menu__chevron\"\n data-state={isOpen ? 'open' : 'closed'}\n >\n <ChevronDown />\n </span>\n </button>\n\n {/* Content panel — always mounted, CSS transitions handle show/hide */}\n <div ref={containerRef}>\n <div\n className={clsx(\n 'ds-navbar-mega-menu__content',\n `ds-navbar-mega-menu__content--${variant}`,\n )}\n data-state={isOpen ? 'open' : 'closed'}\n >\n {variant === 'fullWidth' ? <Container>{children}</Container> : children}\n </div>\n </div>\n </div>\n );\n },\n);\n\nNavbarMegaMenu.displayName = 'NavbarMegaMenu';\n\n/* ============================================================================\n NavbarMegaMenuSection — Column with heading\n ============================================================================ */\n\nexport interface NavbarMegaMenuSectionProps {\n /** Section heading */\n heading?: string;\n /** Section children (NavbarMegaMenuItems) */\n children: React.ReactNode;\n /** Optional class name */\n className?: string;\n}\n\nexport function NavbarMegaMenuSection({ heading, children, className }: NavbarMegaMenuSectionProps) {\n return (\n <div className={clsx('ds-navbar-mega-menu__section', className)}>\n {heading && <p className=\"ds-navbar-mega-menu__section-heading\">{heading}</p>}\n <div className=\"ds-navbar-mega-menu__section-items\">{children}</div>\n </div>\n );\n}\n\nNavbarMegaMenuSection.displayName = 'NavbarMegaMenuSection';\n\n/* ============================================================================\n NavbarMegaMenuItem — Link with icon, label, description\n ============================================================================ */\n\nexport interface NavbarMegaMenuItemProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n /** Icon element (e.g. lucide-react icon) */\n icon?: React.ReactNode;\n /** Item label */\n label: string;\n /** Optional description */\n description?: string;\n /** Render as custom element (for Next.js Link) */\n as?: React.ElementType;\n /** Whether this item represents the current page */\n active?: boolean;\n}\n\nexport const NavbarMegaMenuItem = forwardRef<HTMLAnchorElement, NavbarMegaMenuItemProps>(\n ({ icon, label, description, className, as: Comp = 'a', active, ...rest }, ref) => {\n return (\n <div className=\"ds-navbar-mega-menu__item-wrapper\">\n <Comp\n ref={ref}\n className={clsx('ds-navbar-mega-menu__item', active && 'ds-navbar-mega-menu__item--active', className)}\n aria-current={active ? 'page' : undefined}\n {...rest}\n >\n {icon && <span className=\"ds-navbar-mega-menu__item-icon\">{icon}</span>}\n <span className=\"ds-navbar-mega-menu__item-text\">\n <span className=\"ds-navbar-mega-menu__item-label\">{label}</span>\n {description && (\n <span className=\"ds-navbar-mega-menu__item-description\">{description}</span>\n )}\n </span>\n </Comp>\n </div>\n );\n },\n);\n\nNavbarMegaMenuItem.displayName = 'NavbarMegaMenuItem';\n","import React, {\n forwardRef,\n useState,\n useRef,\n useEffect,\n useCallback,\n useContext,\n createContext,\n useMemo,\n useId,\n} from 'react';\nimport clsx from 'clsx';\nimport './NavbarV2.css';\n\n/* ============================================================================\n Icons\n ============================================================================ */\n\nconst ChevronDown = () => (\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M4 6L8 10L12 6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\n/* ============================================================================\n Scroll State Context — lets children (e.g. NavbarV2Tabs) know when\n the outer container has activated its glass surface, so they can\n demote their own glass to avoid glass-on-glass visual noise.\n ============================================================================ */\n\ninterface ScrollContextValue {\n /** Whether the navbar container is in the scrolled (glass) state. */\n scrolled: boolean;\n}\n\nconst ScrollContext = createContext<ScrollContextValue>({ scrolled: false });\n\n/* ============================================================================\n Mutual Exclusion Context — only one mega menu open at a time\n ============================================================================ */\n\ninterface TabsContextValue {\n /** ID of the currently open menu (null = all closed). */\n activeMenuId: string | null;\n /** Request to open a menu. Closes any other open menu. */\n openMenu: (id: string) => void;\n /** Request to close a specific menu. */\n closeMenu: (id: string) => void;\n}\n\nconst TabsContext = createContext<TabsContextValue>({\n activeMenuId: null,\n openMenu: () => {},\n closeMenu: () => {},\n});\n\n/* ============================================================================\n Focus Trap Hook — traps Tab/Shift+Tab inside a container\n ============================================================================ */\n\nfunction useFocusTrap(containerRef: React.RefObject<HTMLElement | null>, active: boolean) {\n useEffect(() => {\n if (!active || !containerRef.current) return;\n\n const container = containerRef.current;\n const FOCUSABLE =\n 'a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Tab') return;\n\n const focusable = Array.from(container.querySelectorAll<HTMLElement>(FOCUSABLE));\n if (focusable.length === 0) {\n e.preventDefault();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n if (e.shiftKey) {\n if (document.activeElement === first) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n };\n\n // Focus first element on trap activation\n const focusable = container.querySelectorAll<HTMLElement>(FOCUSABLE);\n if (focusable.length > 0) {\n focusable[0].focus();\n }\n\n container.addEventListener('keydown', handleKeyDown);\n return () => container.removeEventListener('keydown', handleKeyDown);\n }, [active, containerRef]);\n}\n\n/* ============================================================================\n NavbarV2 — Floating Glass Pill Tab Navigation\n ============================================================================\n A centered floating glass pill with vertical icon+label tabs,\n flanked by brand (left) and actions (right).\n\n On scroll, an outer container activates a subtle glass surface with\n border, wrapping all content (brand + tabs + actions). The inner\n tabs pill demotes its own glass to avoid double-glass visual noise.\n\n Composition:\n <NavbarV2>\n <NavbarV2Brand />\n <NavbarV2Tabs>\n <NavbarV2Tab /> // simple link/button\n <NavbarV2TabMenu /> // tab with mega menu dropdown\n </NavbarV2Tabs>\n <NavbarV2Actions />\n </NavbarV2>\n ============================================================================ */\n\nexport interface NavbarV2Props extends React.HTMLAttributes<HTMLElement> {\n /** Content rendered inside the mobile menu overlay when open. */\n mobileContent?: React.ReactNode;\n /** Accessible labels for mobile toggle. Override for i18n. */\n mobileToggleLabels?: { open: string; close: string };\n /** Controlled mobile menu open state. */\n isMenuOpen?: boolean;\n /** Callback when mobile menu open state changes. */\n onMenuOpenChange?: (isOpen: boolean) => void;\n /** Enable scroll-aware glass container with border. @default true */\n scrollBorder?: boolean;\n /** Scroll distance (px) before glass activates. @default 32 */\n scrollThreshold?: number;\n}\n\n/** Hysteresis lower-bound ratio — glass disappears when scroll drops below threshold × this */\nconst HYSTERESIS_RATIO = 0.25;\n\nexport const NavbarV2 = forwardRef<HTMLElement, NavbarV2Props>(\n (\n {\n className,\n mobileContent,\n mobileToggleLabels,\n isMenuOpen,\n onMenuOpenChange,\n scrollBorder = true,\n scrollThreshold = 32,\n children,\n ...props\n },\n ref,\n ) => {\n const [internalMenuOpen, setInternalMenuOpen] = useState(false);\n const isMobileMenuOpen = isMenuOpen !== undefined ? isMenuOpen : internalMenuOpen;\n\n const navRef = useRef<HTMLElement>(null);\n const overlayRef = useRef<HTMLDivElement>(null);\n const [navHeight, setNavHeight] = useState(64);\n\n const openLabel = mobileToggleLabels?.open ?? 'Open menu';\n const closeLabel = mobileToggleLabels?.close ?? 'Close menu';\n\n /* ── Scroll detection with hysteresis ──────────────────────────────\n Glass appears at scrollThreshold (32px default).\n Glass disappears only when scrolling back above threshold × 0.25 (8px).\n This prevents flicker when hovering near the threshold.\n Initial state is always false to match SSR — the useEffect below\n corrects it on mount before the browser paints. */\n\n const [scrolled, setScrolled] = useState(false);\n\n useEffect(() => {\n if (!scrollBorder) return;\n\n const lowerBound = scrollThreshold * HYSTERESIS_RATIO;\n\n const handleScroll = () => {\n const y = window.scrollY;\n setScrolled((prev) => {\n if (!prev && y > scrollThreshold) return true;\n if (prev && y < lowerBound) return false;\n return prev;\n });\n };\n\n // SSR flash guard — set correct state on mount\n handleScroll();\n\n window.addEventListener('scroll', handleScroll, { passive: true });\n return () => window.removeEventListener('scroll', handleScroll);\n }, [scrollBorder, scrollThreshold]);\n\n const isScrolled = scrollBorder && scrolled;\n\n const scrollCtx = useMemo<ScrollContextValue>(\n () => ({ scrolled: isScrolled }),\n [isScrolled],\n );\n\n const handleToggle = () => {\n const newState = !isMobileMenuOpen;\n setInternalMenuOpen(newState);\n onMenuOpenChange?.(newState);\n };\n\n /* Measure navbar height for mobile overlay positioning + CSS overlap var */\n useEffect(() => {\n const el = navRef.current;\n if (!el) return;\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const h = entry.contentRect.height;\n setNavHeight(h);\n /* Expose height as CSS custom property for layout overlap tricks */\n el.style.setProperty('--navbar-overlap', `${h}px`);\n }\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, []);\n\n /* Lock body scroll when mobile menu is open */\n useEffect(() => {\n if (isMobileMenuOpen) {\n document.body.style.overflow = 'hidden';\n return () => {\n document.body.style.overflow = '';\n };\n }\n }, [isMobileMenuOpen]);\n\n /* Close on Escape */\n useEffect(() => {\n if (!isMobileMenuOpen) return;\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setInternalMenuOpen(false);\n onMenuOpenChange?.(false);\n }\n };\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [isMobileMenuOpen, onMenuOpenChange]);\n\n /* Focus trap for mobile overlay */\n useFocusTrap(overlayRef, isMobileMenuOpen);\n\n /* Merge refs: forwardRef + internal navRef */\n const mergedRef = useMergedRef(ref, navRef);\n\n return (\n <ScrollContext.Provider value={scrollCtx}>\n <nav\n ref={mergedRef}\n className={clsx(\n 'ds-navbar-v2',\n isScrolled && 'ds-navbar-v2--scrolled',\n className,\n )}\n {...props}\n >\n {/* Inner container — receives glass treatment on scroll */}\n <div className=\"ds-navbar-v2__container\">\n {children}\n\n {/* Mobile Toggle */}\n <button\n className=\"ds-navbar-v2__toggle\"\n onClick={handleToggle}\n aria-label={isMobileMenuOpen ? closeLabel : openLabel}\n aria-expanded={isMobileMenuOpen}\n >\n {isMobileMenuOpen ? (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n ) : (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\" />\n </svg>\n )}\n </button>\n </div>\n\n {/* Mobile Menu Overlay — always mounted, CSS transitions handle show/hide */}\n <div\n ref={overlayRef}\n className=\"ds-navbar-v2__mobile-overlay\"\n style={{ top: navHeight }}\n data-state={isMobileMenuOpen ? 'open' : 'closed'}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={closeLabel}\n >\n <div className=\"ds-navbar-v2__mobile-content\">\n {mobileContent}\n </div>\n </div>\n </nav>\n </ScrollContext.Provider>\n );\n },\n);\n\nNavbarV2.displayName = 'NavbarV2';\n\n/* ============================================================================\n NavbarV2Brand — Logo area (left of pill)\n ============================================================================ */\n\nexport interface NavbarV2BrandProps extends React.HTMLAttributes<HTMLElement> {\n /** Render as custom element (e.g. Next.js Link). @default 'a' */\n as?: React.ElementType;\n href?: string;\n}\n\nexport const NavbarV2Brand = forwardRef<HTMLElement, NavbarV2BrandProps>(\n ({ as: Component = 'a', className, children, ...props }, ref) => (\n <Component ref={ref} className={clsx('ds-navbar-v2__brand', className)} {...props}>\n {children}\n </Component>\n ),\n);\n\nNavbarV2Brand.displayName = 'NavbarV2Brand';\n\n/* ============================================================================\n NavbarV2Tabs — The floating glass pill containing tab items\n Provides mutual-exclusion context so only one mega menu is open at a time.\n Reads ScrollContext to demote glass when outer container is active.\n ============================================================================ */\n\nexport const NavbarV2Tabs = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, children, ...props }, ref) => {\n const [activeMenuId, setActiveMenuId] = useState<string | null>(null);\n const { scrolled } = useContext(ScrollContext);\n\n const ctxValue = useMemo<TabsContextValue>(\n () => ({\n activeMenuId,\n openMenu: (id: string) => setActiveMenuId(id),\n closeMenu: (id: string) =>\n setActiveMenuId((prev) => (prev === id ? null : prev)),\n }),\n [activeMenuId],\n );\n\n return (\n <TabsContext.Provider value={ctxValue}>\n {/* No role — parent <nav> already declares navigation landmark */}\n <div\n ref={ref}\n className={clsx(\n 'ds-navbar-v2__tabs',\n scrolled && 'ds-navbar-v2__tabs--demoted',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </TabsContext.Provider>\n );\n },\n);\n\nNavbarV2Tabs.displayName = 'NavbarV2Tabs';\n\n/* ============================================================================\n NavbarV2Tab — Vertical icon + label tab (simple link or button)\n ============================================================================ */\n\nexport interface NavbarV2TabProps extends React.HTMLAttributes<HTMLElement> {\n /** Render as custom element (e.g. Next.js Link). @default 'button' */\n as?: React.ElementType;\n /** Whether this tab is the current page. */\n active?: boolean;\n /** Icon element (rendered above label). */\n icon?: React.ReactNode;\n /** Tab label text (rendered below icon). */\n label?: string;\n href?: string;\n}\n\nexport const NavbarV2Tab = forwardRef<HTMLElement, NavbarV2TabProps>(\n ({ as: Component = 'button', active, icon, label, className, children, ...props }, ref) => (\n <Component\n ref={ref}\n className={clsx('ds-navbar-v2__tab', active && 'ds-navbar-v2__tab--active', className)}\n aria-current={active ? 'page' : undefined}\n {...(Component === 'button' ? { type: 'button' } : {})}\n {...props}\n >\n {icon && <span className=\"ds-navbar-v2__tab-icon\">{icon}</span>}\n {label && <span className=\"ds-navbar-v2__tab-label\">{label}</span>}\n {children}\n </Component>\n ),\n);\n\nNavbarV2Tab.displayName = 'NavbarV2Tab';\n\n/* ============================================================================\n NavbarV2TabMenu — Vertical tab that triggers a mega menu dropdown\n ============================================================================ */\n\nexport interface NavbarV2TabMenuProps {\n /** Icon for the tab trigger (rendered above label). */\n icon?: React.ReactNode;\n /** Label for the tab trigger (rendered below icon). */\n label: string;\n /** Whether this tab represents the current section. */\n active?: boolean;\n /** Mega menu panel content. */\n children: React.ReactNode;\n /** Optional class name. */\n className?: string;\n /** Controlled open state. */\n isOpen?: boolean;\n /** Controlled open change handler. */\n onOpenChange?: (isOpen: boolean) => void;\n}\n\nexport const NavbarV2TabMenu = forwardRef<HTMLDivElement, NavbarV2TabMenuProps>(\n (\n {\n icon,\n label,\n active,\n children,\n className,\n isOpen: controlledOpen,\n onOpenChange,\n },\n ref,\n ) => {\n /* Stable ID for mutual exclusion + aria-controls */\n const instanceId = useId();\n const panelId = `navbar-v2-panel-${instanceId}`;\n\n /* Mutual exclusion via context */\n const { activeMenuId, openMenu, closeMenu } = useContext(TabsContext);\n\n /* Support both controlled (isOpen prop) and context-driven state */\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : activeMenuId === instanceId;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const timeoutRef = useRef<number | null>(null);\n\n const handleOpen = useCallback(() => {\n if (!isOpen) {\n if (!isControlled) openMenu(instanceId);\n onOpenChange?.(true);\n }\n }, [isOpen, isControlled, openMenu, instanceId, onOpenChange]);\n\n const handleClose = useCallback(() => {\n if (isOpen) {\n if (!isControlled) closeMenu(instanceId);\n onOpenChange?.(false);\n }\n }, [isOpen, isControlled, closeMenu, instanceId, onOpenChange]);\n\n const handleToggle = useCallback(() => {\n if (isOpen) handleClose();\n else handleOpen();\n }, [isOpen, handleClose, handleOpen]);\n\n const handleMouseEnter = useCallback(() => {\n if (timeoutRef.current) {\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n handleOpen();\n }, [handleOpen]);\n\n const handleMouseLeave = useCallback(() => {\n if (timeoutRef.current) window.clearTimeout(timeoutRef.current);\n timeoutRef.current = window.setTimeout(handleClose, 150);\n }, [handleClose]);\n\n /* Cleanup timeout on unmount */\n useEffect(() => {\n return () => {\n if (timeoutRef.current) window.clearTimeout(timeoutRef.current);\n };\n }, []);\n\n /* Click outside → close */\n useEffect(() => {\n if (!isOpen) return;\n const handleClickOutside = (event: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target as Node) &&\n triggerRef.current &&\n !triggerRef.current.contains(event.target as Node)\n ) {\n handleClose();\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [isOpen, handleClose]);\n\n /* Escape → close */\n useEffect(() => {\n if (!isOpen) return;\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n handleClose();\n triggerRef.current?.focus();\n }\n };\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [isOpen, handleClose]);\n\n /* Viewport edge clamping — nudge panel so it doesn't overflow */\n useEffect(() => {\n if (!isOpen || !panelRef.current) return;\n\n const clampToViewport = () => {\n const panel = panelRef.current;\n if (!panel) return;\n\n // Reset any previous nudge\n panel.style.setProperty('--panel-nudge', '0px');\n\n const rect = panel.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const EDGE_PADDING = 16;\n\n if (rect.right > viewportWidth - EDGE_PADDING) {\n const overflow = rect.right - (viewportWidth - EDGE_PADDING);\n panel.style.setProperty('--panel-nudge', `${-overflow}px`);\n } else if (rect.left < EDGE_PADDING) {\n const overflow = EDGE_PADDING - rect.left;\n panel.style.setProperty('--panel-nudge', `${overflow}px`);\n }\n };\n\n // Clamp after render + animation start\n requestAnimationFrame(clampToViewport);\n window.addEventListener('resize', clampToViewport);\n return () => window.removeEventListener('resize', clampToViewport);\n }, [isOpen]);\n\n /* Merge refs for panel: containerRef (click-outside) + panelRef (clamping) */\n const panelRefCallback = useCallback((node: HTMLDivElement | null) => {\n (containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n (panelRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }, []);\n\n return (\n <div\n ref={ref}\n className={clsx('ds-navbar-v2__tab-menu', className)}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n <button\n ref={triggerRef}\n className={clsx(\n 'ds-navbar-v2__tab',\n (active || isOpen) && 'ds-navbar-v2__tab--active',\n )}\n onClick={handleToggle}\n aria-expanded={isOpen}\n aria-haspopup=\"true\"\n aria-controls={isOpen ? panelId : undefined}\n type=\"button\"\n >\n {icon && <span className=\"ds-navbar-v2__tab-icon\">{icon}</span>}\n <span className=\"ds-navbar-v2__tab-label-row\">\n <span className=\"ds-navbar-v2__tab-label\">{label}</span>\n <span\n className=\"ds-navbar-v2__tab-chevron\"\n data-state={isOpen ? 'open' : 'closed'}\n >\n <ChevronDown />\n </span>\n </span>\n </button>\n\n {/* Mega panel — mount only when open to keep the global DOM budget low. */}\n {isOpen ? (\n <div\n ref={panelRefCallback}\n id={panelId}\n className=\"ds-navbar-v2__mega-panel\"\n data-state=\"open\"\n role=\"region\"\n aria-label={`${label} menu`}\n >\n {children}\n </div>\n ) : null}\n </div>\n );\n },\n);\n\nNavbarV2TabMenu.displayName = 'NavbarV2TabMenu';\n\n/* ============================================================================\n NavbarV2Actions — Right-side actions (right of pill)\n ============================================================================ */\n\nexport const NavbarV2Actions = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, children, ...props }, ref) => (\n <div ref={ref} className={clsx('ds-navbar-v2__actions', className)} {...props}>\n {children}\n </div>\n ),\n);\n\nNavbarV2Actions.displayName = 'NavbarV2Actions';\n\n/* ============================================================================\n Utility — merge multiple refs (forwardRef + internal ref)\n ============================================================================ */\n\nfunction useMergedRef<T>(\n ...refs: (React.Ref<T> | React.MutableRefObject<T | null> | null | undefined)[]\n): React.RefCallback<T> {\n return useCallback(\n (value: T | null) => {\n for (const ref of refs) {\n if (typeof ref === 'function') {\n ref(value);\n } else if (ref && typeof ref === 'object') {\n (ref as React.MutableRefObject<T | null>).current = value;\n }\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n refs,\n );\n}\n","import React, { forwardRef, HTMLAttributes, useState } from 'react';\nimport clsx from 'clsx';\nimport { Container } from '../LayoutPrimitives';\nimport './SiteFooter.css';\n\n/* ============================================================================\n Types\n ============================================================================ */\n\nexport interface FooterLink {\n label: string;\n href: string;\n /** Visual \"NEW\" indicator badge. */\n isNew?: boolean;\n}\n\nexport interface FooterSection {\n title: string;\n links: FooterLink[];\n}\n\nexport interface FooterCTA {\n /** Primary headline (e.g., \"Install Your Sales Operating System.\") */\n headline: string;\n /** Supporting subtext below the headline. */\n subtext?: string;\n /** Primary CTA slot (e.g., a <Button> component). */\n primaryCta?: React.ReactNode;\n /** Secondary CTA slot (e.g., a ghost <Button>). */\n secondaryCta?: React.ReactNode;\n /** Micro trust line below the CTA actions. */\n trustLine?: string;\n}\n\nexport interface FooterTrustBadge {\n /** Badge label (e.g., \"GDPR-ready\"). */\n label: string;\n}\n\nexport interface SiteFooterProps extends HTMLAttributes<HTMLElement> {\n /* ── Zone 1: Strategic CTA ─────────────────────────────────────────── */\n\n /** Strategic CTA rendered at the top of the footer. */\n cta?: FooterCTA;\n\n /* ── Zone 2: Structured Navigation Grid ────────────────────────────── */\n\n /** Navigation sections rendered as a 5-column grid on desktop. */\n sections?: FooterSection[];\n /** Quick orientation line above the navigation grid. */\n orientationLine?: React.ReactNode;\n /**\n * Custom element to render for each link (e.g., Next.js locale-aware Link).\n * Must accept `href`, `className`, and `children` props.\n * @default 'a'\n */\n linkAs?: React.ElementType;\n\n /* ── Zone 3: Authority Layer ───────────────────────────────────────── */\n\n /** Brand logo or name slot. */\n brand?: React.ReactNode;\n /** Tagline below the brand. */\n tagline?: React.ReactNode;\n /** Social icons slot. */\n socials?: React.ReactNode;\n /** Trust amplifier badges (e.g., \"Built for B2B Teams\", \"GDPR-ready\"). */\n trustBadges?: FooterTrustBadge[];\n\n /* ── Zone 4: System Controls ───────────────────────────────────────── */\n\n /** System controls slot (language switcher, theme toggle, etc.). */\n controls?: React.ReactNode;\n\n /* ── Zone 5: Legal + Ownership ─────────────────────────────────────── */\n\n /** Legal links rendered in the bottom bar. */\n legalLinks?: FooterLink[];\n /** Copyright text. Falls back to a default with the current year. */\n copyright?: React.ReactNode;\n /** Company registration or legal entity info line. */\n companyInfo?: string;\n /** Extra content rendered below the legal bar (e.g., AI summary links). */\n bottomExtra?: React.ReactNode;\n\n /* ── Deprecated ────────────────────────────────────────────────────── */\n\n /** @deprecated Use `controls` instead. Slot rendered in the bottom bar. */\n bottomActions?: React.ReactNode;\n}\n\n/* ============================================================================\n Internal: Mobile Accordion Item\n ============================================================================ */\n\ninterface FooterAccordionItemProps {\n section: FooterSection;\n LinkComponent: React.ElementType;\n}\n\nfunction FooterAccordionItem({ section, LinkComponent }: FooterAccordionItemProps) {\n const [isOpen, setIsOpen] = useState(false);\n\n return (\n <div\n className={clsx(\n 'ds-footer__accordion-item',\n isOpen && 'ds-footer__accordion-item--open',\n )}\n >\n <button\n type=\"button\"\n className=\"ds-footer__accordion-trigger\"\n aria-expanded={isOpen}\n onClick={() => setIsOpen((prev) => !prev)}\n >\n <span>{section.title}</span>\n <svg\n className=\"ds-footer__accordion-chevron\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n <div className=\"ds-footer__accordion-panel\" hidden={!isOpen}>\n <ul className=\"ds-footer__links\">\n {section.links.map((link, idx) => (\n <li key={idx}>\n <LinkComponent href={link.href} className=\"ds-footer__link\">\n {link.label}\n {link.isNew && <span className=\"ds-footer__badge\">NEW</span>}\n </LinkComponent>\n </li>\n ))}\n </ul>\n </div>\n </div>\n );\n}\n\n/* ============================================================================\n Component\n ============================================================================ */\n\nexport const SiteFooter = forwardRef<HTMLElement, SiteFooterProps>(\n (\n {\n cta,\n sections = [],\n orientationLine,\n linkAs,\n brand,\n tagline,\n socials,\n trustBadges,\n controls,\n legalLinks = [],\n copyright,\n companyInfo,\n bottomExtra,\n bottomActions,\n className,\n ...props\n },\n ref,\n ) => {\n const currentYear = new Date().getFullYear();\n const defaultCopyright = copyright || `© ${currentYear}. All rights reserved.`;\n const resolvedControls = controls || bottomActions;\n const LinkComponent = linkAs || 'a';\n\n return (\n <footer ref={ref} className={clsx('ds-footer', className)} {...props}>\n {/* ── Zone 1: Strategic CTA ──────────────────────────────────── */}\n {cta && (\n <div className=\"ds-footer__cta\" data-footer-zone=\"cta\">\n <Container>\n <div className=\"ds-footer__cta-content\">\n <h2 className=\"ds-footer__cta-headline\">{cta.headline}</h2>\n {cta.subtext && (\n <p className=\"ds-footer__cta-subtext\">{cta.subtext}</p>\n )}\n {(cta.primaryCta || cta.secondaryCta) && (\n <div className=\"ds-footer__cta-actions\">\n {cta.primaryCta}\n {cta.secondaryCta}\n </div>\n )}\n {cta.trustLine && (\n <p className=\"ds-footer__cta-trust\">{cta.trustLine}</p>\n )}\n </div>\n </Container>\n </div>\n )}\n\n {/* ── Zone 2: Navigation Grid ────────────────────────────────── */}\n {sections.length > 0 && (\n <div className=\"ds-footer__nav\" data-footer-zone=\"navigation\">\n <Container>\n {orientationLine && (\n <div className=\"ds-footer__orientation\">\n {orientationLine}\n </div>\n )}\n\n {/* Desktop: Grid layout */}\n <nav\n className=\"ds-footer__grid\"\n aria-label=\"Footer navigation\"\n >\n {sections.map((section, idx) => (\n <div\n key={idx}\n className=\"ds-footer__column\"\n data-footer-section={section.title\n .toLowerCase()\n .replace(/\\s+/g, '-')}\n >\n <p className=\"ds-footer__heading\">{section.title}</p>\n <ul className=\"ds-footer__links\">\n {section.links.map((link, linkIdx) => (\n <li key={linkIdx}>\n <LinkComponent\n href={link.href}\n className=\"ds-footer__link\"\n >\n {link.label}\n {link.isNew && (\n <span className=\"ds-footer__badge\">NEW</span>\n )}\n </LinkComponent>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </nav>\n\n {/* Mobile: Accordion layout */}\n <nav\n className=\"ds-footer__mobile-nav\"\n aria-label=\"Footer navigation (mobile)\"\n >\n {sections.map((section, idx) => (\n <FooterAccordionItem\n key={idx}\n section={section}\n LinkComponent={LinkComponent}\n />\n ))}\n </nav>\n </Container>\n </div>\n )}\n\n {/* ── Zone 3: Authority Layer ────────────────────────────────── */}\n {(brand || socials || trustBadges) && (\n <div className=\"ds-footer__authority\" data-footer-zone=\"authority\">\n <Container>\n <div className=\"ds-footer__authority-content\">\n <div className=\"ds-footer__brand\">\n {brand && <div className=\"ds-footer__logo\">{brand}</div>}\n {tagline && (\n <p className=\"ds-footer__tagline\">{tagline}</p>\n )}\n {socials && (\n <div className=\"ds-footer__socials\">{socials}</div>\n )}\n </div>\n {trustBadges && trustBadges.length > 0 && (\n <div className=\"ds-footer__trust-badges\">\n {trustBadges.map((badge, idx) => (\n <span key={idx} className=\"ds-footer__trust-badge\">\n {badge.label}\n </span>\n ))}\n </div>\n )}\n </div>\n </Container>\n </div>\n )}\n\n {/* ── Zone 4 + 5: Controls + Legal ───────────────────────────── */}\n <div className=\"ds-footer__bottom\" data-footer-zone=\"legal\">\n <Container>\n <div className=\"ds-footer__bottom-content\">\n <div className=\"ds-footer__copyright\">\n {copyright || defaultCopyright}\n </div>\n {resolvedControls && (\n <div className=\"ds-footer__controls\">\n {resolvedControls}\n </div>\n )}\n {legalLinks.length > 0 && (\n <div className=\"ds-footer__legal\">\n {legalLinks.map((link, idx) => (\n <LinkComponent\n key={idx}\n href={link.href}\n className=\"ds-footer__legal-link\"\n >\n {link.label}\n </LinkComponent>\n ))}\n </div>\n )}\n </div>\n {bottomExtra && (\n <div className=\"ds-footer__bottom-extra\">{bottomExtra}</div>\n )}\n {companyInfo && (\n <p className=\"ds-footer__company-info\">{companyInfo}</p>\n )}\n </Container>\n </div>\n </footer>\n );\n },\n);\nSiteFooter.displayName = 'SiteFooter';\n","import React, {\n forwardRef,\n useState,\n useRef,\n useEffect,\n useCallback,\n useId,\n} from 'react';\nimport clsx from 'clsx';\nimport './LocaleDropdown.css';\n\n/* ============================================================================\n Icons\n ============================================================================ */\n\nconst GlobeIcon = () => (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M2 12h20\" />\n <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\" />\n </svg>\n);\n\nconst ChevronDownIcon = () => (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M4 6L8 10L12 6\" />\n </svg>\n);\n\nconst CheckIcon = () => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n);\n\n/* ============================================================================\n Types\n ============================================================================ */\n\nexport interface LocaleOption {\n /** ISO code, e.g. 'en', 'fr', 'es'. */\n code: string;\n /** Full display name, e.g. 'English', 'Français'. */\n label: string;\n /** Emoji flag or SVG component. Optional. */\n flag?: React.ReactNode;\n /** Short display code, e.g. 'EN', 'FR'. Used in the trigger. */\n shortLabel?: string;\n}\n\nexport interface LocaleDropdownProps {\n /** Available locales. */\n locales: LocaleOption[];\n /** Currently active locale code. */\n activeLocale: string;\n /** Called when user selects a locale. */\n onLocaleChange?: (code: string) => void;\n /**\n * Custom element for dropdown options (e.g. Next.js Link).\n * Receives `href` from `getHref`. @default 'button'\n */\n optionAs?: React.ElementType;\n /** Generate href for each locale option. Used with `optionAs`. */\n getHref?: (code: string) => string;\n /** Additional class name. */\n className?: string;\n /** Direction the dropdown should open. Defaults to 'down'. */\n direction?: 'up' | 'down';\n /** Alignment of the dropdown panel relative to the trigger. Defaults to 'right'. */\n align?: 'left' | 'right' | 'center';\n}\n\n/* ============================================================================\n LocaleDropdown — Globe + flag trigger with dropdown panel\n ============================================================================\n A compact locale selector showing the current locale with a globe icon\n and emoji flag. Clicking opens a dropdown with all available locales.\n\n Features:\n - Click outside / Escape to close\n - Keyboard navigation (ArrowUp/Down, Enter, Escape)\n - Active locale highlighted with checkmark\n - Animated chevron rotation via CSS\n - Supports polymorphic option elements (buttons or links)\n - Full ARIA: aria-haspopup, aria-expanded, aria-activedescendant\n - prefers-reduced-motion respected via CSS\n - Uses DS tokens only (no hardcoded colors)\n ============================================================================ */\n\nexport const LocaleDropdown = forwardRef<HTMLDivElement, LocaleDropdownProps>(\n (\n {\n locales,\n activeLocale,\n onLocaleChange,\n optionAs: OptionComponent = 'button',\n getHref,\n className,\n direction = 'down',\n align = 'right',\n },\n ref,\n ) => {\n const [isOpen, setIsOpen] = useState(false);\n const [focusIndex, setFocusIndex] = useState(-1);\n const containerRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const instanceId = useId();\n const listboxId = `locale-dropdown-${instanceId}`;\n\n const currentLocale = locales.find((l) => l.code === activeLocale) ?? locales[0];\n\n const handleToggle = useCallback(() => {\n setIsOpen((prev) => {\n if (!prev) setFocusIndex(-1);\n return !prev;\n });\n }, []);\n\n const handleClose = useCallback(() => {\n setIsOpen(false);\n setFocusIndex(-1);\n triggerRef.current?.focus();\n }, []);\n\n const handleSelect = useCallback(\n (code: string) => {\n onLocaleChange?.(code);\n handleClose();\n },\n [onLocaleChange, handleClose],\n );\n\n /* Click outside → close */\n useEffect(() => {\n if (!isOpen) return;\n const handleClickOutside = (e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n handleClose();\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [isOpen, handleClose]);\n\n /* Keyboard navigation */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (!isOpen) {\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setIsOpen(true);\n setFocusIndex(0);\n }\n return;\n }\n\n switch (e.key) {\n case 'Escape':\n e.preventDefault();\n handleClose();\n break;\n case 'ArrowDown':\n e.preventDefault();\n setFocusIndex((prev) => (prev + 1) % locales.length);\n break;\n case 'ArrowUp':\n e.preventDefault();\n setFocusIndex((prev) => (prev - 1 + locales.length) % locales.length);\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n if (focusIndex >= 0 && focusIndex < locales.length) {\n handleSelect(locales[focusIndex].code);\n }\n break;\n case 'Home':\n e.preventDefault();\n setFocusIndex(0);\n break;\n case 'End':\n e.preventDefault();\n setFocusIndex(locales.length - 1);\n break;\n case 'Tab':\n handleClose();\n break;\n }\n },\n [isOpen, focusIndex, locales, handleClose, handleSelect],\n );\n\n /* Scroll focused item into view */\n useEffect(() => {\n if (!isOpen || focusIndex < 0 || !listRef.current) return;\n const items = listRef.current.querySelectorAll('[role=\"option\"]');\n items[focusIndex]?.scrollIntoView({ block: 'nearest' });\n }, [isOpen, focusIndex]);\n\n const activeDescendantId =\n isOpen && focusIndex >= 0 ? `${listboxId}-option-${focusIndex}` : undefined;\n\n return (\n <div\n ref={ref}\n className={clsx(\n 'ds-locale-dropdown',\n direction === 'up' && 'ds-locale-dropdown--up',\n align === 'left' && 'ds-locale-dropdown--align-left',\n align === 'center' && 'ds-locale-dropdown--align-center',\n className\n )}\n >\n <div ref={containerRef} className=\"ds-locale-dropdown__wrapper\">\n {/* Trigger */}\n <button\n ref={triggerRef}\n type=\"button\"\n className=\"ds-locale-dropdown__trigger\"\n onClick={handleToggle}\n onKeyDown={handleKeyDown}\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n aria-controls={isOpen ? listboxId : undefined}\n aria-activedescendant={activeDescendantId}\n aria-label={`Language: ${currentLocale.label}. Change language.`}\n >\n <span className=\"ds-locale-dropdown__trigger-icon\">\n <GlobeIcon />\n </span>\n {currentLocale.flag && (\n <span className=\"ds-locale-dropdown__trigger-flag\" aria-hidden=\"true\">\n {currentLocale.flag}\n </span>\n )}\n <span\n className=\"ds-locale-dropdown__trigger-chevron\"\n data-state={isOpen ? 'open' : 'closed'}\n >\n <ChevronDownIcon />\n </span>\n </button>\n\n {/* Dropdown Panel — always mounted, CSS transitions handle show/hide */}\n <div\n ref={listRef}\n id={listboxId}\n className=\"ds-locale-dropdown__panel\"\n role=\"listbox\"\n aria-label=\"Select language\"\n data-state={isOpen ? 'open' : 'closed'}\n onKeyDown={handleKeyDown}\n >\n {locales.map((locale, index) => {\n const isActive = locale.code === activeLocale;\n const isFocused = index === focusIndex;\n const optionId = `${listboxId}-option-${index}`;\n\n const optionProps = {\n id: optionId,\n role: 'option' as const,\n 'aria-selected': isActive,\n className: clsx(\n 'ds-locale-dropdown__option',\n isActive && 'ds-locale-dropdown__option--active',\n isFocused && 'ds-locale-dropdown__option--focused',\n ),\n onClick: () => handleSelect(locale.code),\n ...(OptionComponent !== 'button' && getHref\n ? { href: getHref(locale.code) }\n : { type: 'button' as const }),\n };\n\n return (\n <OptionComponent key={locale.code} {...optionProps}>\n <span className=\"ds-locale-dropdown__option-content\">\n {locale.flag && (\n <span className=\"ds-locale-dropdown__option-flag\" aria-hidden=\"true\">\n {locale.flag}\n </span>\n )}\n <span className=\"ds-locale-dropdown__option-label\">\n {locale.label}\n </span>\n </span>\n {isActive && (\n <span className=\"ds-locale-dropdown__option-check\">\n <CheckIcon />\n </span>\n )}\n </OptionComponent>\n );\n })}\n </div>\n </div>\n </div>\n );\n },\n);\n\nLocaleDropdown.displayName = 'LocaleDropdown';\n","import React from 'react';\nimport { OutboundLink } from './OutboundLink';\n\n/**\n * A wrapper specifically designed to be passed into MDX component mappings.\n * It provides defaults suitable for markdown content.\n * \n * Usage:\n * <MDXRemote components={{ a: MDXOutboundLink }} />\n */\nexport const MDXOutboundLink = ({ \n href, \n children, \n ...props \n}: React.AnchorHTMLAttributes<HTMLAnchorElement> & { href?: string }) => {\n if (!href) {\n // eslint-disable-next-line no-restricted-syntax\n return <a {...props}>{children}</a>;\n }\n\n return (\n <OutboundLink \n href={href} \n context=\"cms_markdown\" \n preserveExistingUTM={true}\n openInNewTab={true}\n {...props}\n >\n {children}\n </OutboundLink>\n );\n};\n\nexport default MDXOutboundLink;"]}
|