import { DEMO_SCENARIOS, type DemoScenarioKey, useDemoMode } from '../../lib/operations/demo-mode'; import { ArrowRight, Clock, Play, Sparkles, X } from 'lucide-react'; import { useEffect, useState } from 'react'; import { useLocation } from 'wouter'; const BASE = import.meta.env.BASE_URL.replace(/\/$/, ''); const STORAGE_KEY = 'command_demo_launchpad_dismissed'; type RouteKey = 'exec5' | 'operator15'; interface RouteOption { key: RouteKey; label: string; minutes: number; audience: string; description: string; steps: { label: string; href: string }[]; } const ROUTES: RouteOption[] = [ { key: 'exec5', label: '5-Minute Executive', minutes: 5, audience: 'C-suite, investors, board', description: 'One full governed decision cycle — signal to outcome, with proof.', steps: [ { label: 'Governed Decision Loop', href: '/operations/governed-decision-loop' }, { label: 'Policy Gate', href: '/operations/governed-decision-loop?tab=policy' }, { label: 'Approval Chain', href: '/operations/governed-decision-loop?tab=approval' }, { label: 'Proof Chain', href: '/operations/governed-decision-loop?tab=proof' }, { label: 'Outcome', href: '/operations/governed-decision-loop?tab=outcome' }, ], }, { key: 'operator15', label: '15-Minute Operator', minutes: 15, audience: 'VP Ops, Chief of Staff, enterprise buyers', description: 'Signal triage, full nine-step loop, audit surface, cross-domain intelligence.', steps: [ { label: 'Signal Feed', href: '/operations/prism' }, { label: 'Governed Decision Loop', href: '/operations/governed-decision-loop' }, { label: 'Approvals', href: '/operations/policy-approvals' }, { label: 'Trust Console', href: '/operations/trust-audit' }, { label: 'Executive Briefing', href: '/strategy/executive-briefing' }, ], }, ]; function isLive(): boolean { const override = (import.meta.env.VITE_DEPLOY_ENV as string | undefined)?.toLowerCase(); if (override) return override === 'live'; return import.meta.env.PROD === true; } export function DemoLaunchpadPanel() { const [, navigate] = useLocation(); const { activate } = useDemoMode(); const [dismissed, setDismissed] = useState(true); const [selectedRoute, setSelectedRoute] = useState('exec5'); const [selectedScenario, setSelectedScenario] = useState('aegis'); useEffect(() => { if (isLive()) return; const stored = typeof window !== 'undefined' ? window.localStorage.getItem(STORAGE_KEY) : '1'; setDismissed(stored === '1'); }, []); if (isLive() || dismissed) return null; const route = ROUTES.find((r) => r.key === selectedRoute) ?? ROUTES[0]; const handleDismiss = () => { try { window.localStorage.setItem(STORAGE_KEY, '1'); } catch { /* ignore */ } setDismissed(true); }; const goTo = (href: string) => { if (href.startsWith('http')) { window.location.href = href; return; } const path = href.startsWith(BASE) ? href.slice(BASE.length) || '/' : href; navigate(path); }; const handleStart = () => { activate(selectedScenario); goTo('/operations/governed-decision-loop'); }; return (
Demo Launchpad

One-click start for presenters. Pick a route, pick a scenario, then launch the governed decision loop.

{ROUTES.map((r) => { const isActive = r.key === selectedRoute; return ( ); })}

Step Navigation — {route.label}

{route.steps.map((step, i) => ( ))}
Scenario: {DEMO_SCENARIOS.map((s) => { const isActive = s.key === selectedScenario; return ( ); })}
); } export default DemoLaunchpadPanel;