/** * Demo presets — BCRG Community Flow. * * 2 sources → BCRG central funnel → 5 person funnels (Alice–Eve) → 11 outcomes. */ import type { FlowNode, FunnelNodeData, OutcomeNodeData, SourceNodeData } from "./types"; export const SPENDING_COLORS = ["#3b82f6", "#8b5cf6", "#ec4899", "#06b6d4", "#10b981", "#6366f1"]; export const OVERFLOW_COLORS = ["#f59e0b", "#ef4444", "#f97316", "#eab308", "#dc2626", "#ea580c"]; export const demoNodes: FlowNode[] = [ // ── Sources (Y=-300) ── { id: "source-a", type: "source", position: { x: 480, y: -300 }, data: { label: "Grants & Donations", flowRate: 7500, sourceType: "card", targetAllocations: [{ targetId: "bcrg", percentage: 100, color: "#10b981" }], } as SourceNodeData, }, { id: "source-b", type: "source", position: { x: 900, y: -300 }, data: { label: "Membership Fees", flowRate: 7500, sourceType: "card", targetAllocations: [{ targetId: "bcrg", percentage: 100, color: "#10b981" }], } as SourceNodeData, }, // ── BCRG central funnel (Y=0) ── { id: "bcrg", type: "funnel", position: { x: 660, y: 0 }, data: { label: "BCRG", currentValue: 0, desiredOutflow: 5000, minThreshold: 5000, sufficientThreshold: 20000, maxThreshold: 30000, maxCapacity: 45000, inflowRate: 15000, dynamicOverflow: true, overflowAllocations: [], spendingAllocations: [ { targetId: "alice", percentage: 20, color: SPENDING_COLORS[0] }, { targetId: "bob", percentage: 20, color: SPENDING_COLORS[1] }, { targetId: "carol", percentage: 20, color: SPENDING_COLORS[2] }, { targetId: "dave", percentage: 20, color: SPENDING_COLORS[3] }, { targetId: "eve", percentage: 20, color: SPENDING_COLORS[4] }, ], } as FunnelNodeData, }, // ── Person funnels (Y=400) ── { id: "alice", type: "funnel", position: { x: 80, y: 400 }, data: { label: "Alice", currentValue: 0, desiredOutflow: 1000, minThreshold: 1000, sufficientThreshold: 4000, maxThreshold: 6000, maxCapacity: 9000, inflowRate: 3000, overflowAllocations: [], spendingAllocations: [ { targetId: "alice-comms", percentage: 50, color: SPENDING_COLORS[0] }, { targetId: "alice-events", percentage: 50, color: SPENDING_COLORS[1] }, ], } as FunnelNodeData, }, { id: "bob", type: "funnel", position: { x: 380, y: 400 }, data: { label: "Bob", currentValue: 0, desiredOutflow: 800, minThreshold: 800, sufficientThreshold: 3200, maxThreshold: 4800, maxCapacity: 7200, inflowRate: 3000, overflowAllocations: [], spendingAllocations: [ { targetId: "bob-research", percentage: 60, color: SPENDING_COLORS[0] }, { targetId: "bob-writing", percentage: 40, color: SPENDING_COLORS[1] }, ], } as FunnelNodeData, }, { id: "carol", type: "funnel", position: { x: 680, y: 400 }, data: { label: "Carol", currentValue: 0, desiredOutflow: 1200, minThreshold: 1200, sufficientThreshold: 4800, maxThreshold: 7200, maxCapacity: 10800, inflowRate: 3000, overflowAllocations: [], spendingAllocations: [ { targetId: "carol-ops", percentage: 50, color: SPENDING_COLORS[0] }, { targetId: "carol-infra", percentage: 50, color: SPENDING_COLORS[1] }, ], } as FunnelNodeData, }, { id: "dave", type: "funnel", position: { x: 980, y: 400 }, data: { label: "Dave", currentValue: 0, desiredOutflow: 1000, minThreshold: 1000, sufficientThreshold: 4000, maxThreshold: 6000, maxCapacity: 9000, inflowRate: 3000, overflowAllocations: [], spendingAllocations: [ { targetId: "dave-design", percentage: 45, color: SPENDING_COLORS[0] }, { targetId: "dave-prototypes", percentage: 55, color: SPENDING_COLORS[1] }, ], } as FunnelNodeData, }, { id: "eve", type: "funnel", position: { x: 1280, y: 400 }, data: { label: "Eve", currentValue: 0, desiredOutflow: 1000, minThreshold: 1000, sufficientThreshold: 4000, maxThreshold: 6000, maxCapacity: 9000, inflowRate: 3000, overflowAllocations: [], spendingAllocations: [ { targetId: "eve-legal", percentage: 40, color: SPENDING_COLORS[0] }, { targetId: "eve-compliance", percentage: 30, color: SPENDING_COLORS[1] }, { targetId: "eve-governance", percentage: 30, color: SPENDING_COLORS[2] }, ], } as FunnelNodeData, }, // ── Outcome nodes (Y=850) — 11 total ── // Alice's outcomes { id: "alice-comms", type: "outcome", position: { x: -20, y: 850 }, data: { label: "Comms Strategy", description: "Community communications and outreach", fundingReceived: 0, fundingTarget: 12000, status: "not-started", phases: [ { name: "Planning", fundingThreshold: 4000, tasks: [ { label: "Stakeholder mapping", completed: true }, { label: "Channel audit", completed: true }, ] }, { name: "Execution", fundingThreshold: 8000, tasks: [ { label: "Newsletter launch", completed: true }, { label: "Social media calendar", completed: true }, ] }, { name: "Review", fundingThreshold: 12000, tasks: [ { label: "Impact metrics report", completed: true }, ] }, ], } as OutcomeNodeData }, { id: "alice-events", type: "outcome", position: { x: 260, y: 850 }, data: { label: "Event Series", description: "Quarterly community gatherings", fundingReceived: 0, fundingTarget: 15000, status: "not-started", phases: [ { name: "Venue & Logistics", fundingThreshold: 5000, tasks: [ { label: "Venue scouting", completed: true }, { label: "Catering contracts", completed: true }, ] }, { name: "Programming", fundingThreshold: 10000, tasks: [ { label: "Speaker invitations", completed: false }, { label: "Workshop facilitation", completed: false }, ] }, ], } as OutcomeNodeData }, // Bob's outcomes { id: "bob-research", type: "outcome", position: { x: 400, y: 850 }, data: { label: "Field Research", description: "Participatory action research in partner communities", fundingReceived: 0, fundingTarget: 20000, status: "not-started", phases: [ { name: "Literature Review", fundingThreshold: 5000, tasks: [ { label: "Systematic review", completed: true }, { label: "Gap analysis", completed: true }, ] }, { name: "Field Work", fundingThreshold: 15000, tasks: [ { label: "Site visits", completed: false }, { label: "Interviews & surveys", completed: false }, ] }, ], } as OutcomeNodeData }, { id: "bob-writing", type: "outcome", position: { x: 680, y: 850 }, data: { label: "Publications", description: "Research papers and policy briefs", fundingReceived: 0, fundingTarget: 10000, status: "not-started", phases: [ { name: "Drafting", fundingThreshold: 5000, tasks: [ { label: "Working paper draft", completed: false }, ] }, { name: "Peer Review", fundingThreshold: 10000, tasks: [ { label: "Submit to journal", completed: false }, ] }, ], } as OutcomeNodeData }, // Carol's outcomes { id: "carol-ops", type: "outcome", position: { x: 820, y: 850 }, data: { label: "Operations", description: "Day-to-day operational management", fundingReceived: 0, fundingTarget: 18000, status: "not-started", phases: [ { name: "Setup", fundingThreshold: 6000, tasks: [ { label: "Process documentation", completed: true }, { label: "Tool selection", completed: true }, ] }, { name: "Execution", fundingThreshold: 12000, tasks: [ { label: "Monthly reporting", completed: true }, { label: "Budget tracking", completed: true }, ] }, { name: "Optimization", fundingThreshold: 18000, tasks: [ { label: "Workflow automation", completed: true }, ] }, ], } as OutcomeNodeData }, { id: "carol-infra", type: "outcome", position: { x: 1100, y: 850 }, data: { label: "Infrastructure", description: "Shared infrastructure and hosting", fundingReceived: 0, fundingTarget: 20000, status: "not-started", phases: [ { name: "Provisioning", fundingThreshold: 8000, tasks: [ { label: "Server setup", completed: true }, { label: "CI/CD pipeline", completed: true }, ] }, { name: "Hardening", fundingThreshold: 20000, tasks: [ { label: "Security audit", completed: false }, { label: "Disaster recovery plan", completed: false }, ] }, ], } as OutcomeNodeData }, // Dave's outcomes { id: "dave-design", type: "outcome", position: { x: 1240, y: 850 }, data: { label: "Design System", description: "Shared UI/UX design system", fundingReceived: 0, fundingTarget: 15000, status: "not-started", phases: [ { name: "Foundations", fundingThreshold: 5000, tasks: [ { label: "Color & type system", completed: true }, { label: "Component library", completed: true }, ] }, { name: "Documentation", fundingThreshold: 10000, tasks: [ { label: "Storybook setup", completed: true }, { label: "Usage guidelines", completed: true }, ] }, { name: "Rollout", fundingThreshold: 15000, tasks: [ { label: "Team training", completed: true }, ] }, ], } as OutcomeNodeData }, { id: "dave-prototypes", type: "outcome", position: { x: 1520, y: 850 }, data: { label: "Prototypes", description: "Rapid prototyping of new tools", fundingReceived: 0, fundingTarget: 12000, status: "not-started", phases: [ { name: "Discovery", fundingThreshold: 4000, tasks: [ { label: "User interviews", completed: true }, ] }, { name: "Build", fundingThreshold: 8000, tasks: [ { label: "MVP development", completed: false }, ] }, { name: "Test", fundingThreshold: 12000, tasks: [ { label: "User testing rounds", completed: false }, ] }, ], } as OutcomeNodeData }, // Eve's outcomes { id: "eve-legal", type: "outcome", position: { x: 1660, y: 850 }, data: { label: "Legal Framework", description: "Legal structure and agreements", fundingReceived: 0, fundingTarget: 10000, status: "not-started", phases: [ { name: "Research", fundingThreshold: 4000, tasks: [ { label: "Jurisdiction analysis", completed: true }, { label: "Entity comparison", completed: true }, ] }, { name: "Formation", fundingThreshold: 10000, tasks: [ { label: "Articles of incorporation", completed: true }, { label: "Operating agreement", completed: true }, ] }, ], } as OutcomeNodeData }, { id: "eve-compliance", type: "outcome", position: { x: 1940, y: 850 }, data: { label: "Compliance", description: "Regulatory compliance and reporting", fundingReceived: 0, fundingTarget: 12000, status: "not-started", phases: [ { name: "Assessment", fundingThreshold: 4000, tasks: [ { label: "Compliance gap analysis", completed: true }, ] }, { name: "Implementation", fundingThreshold: 8000, tasks: [ { label: "KYC/AML procedures", completed: false }, ] }, { name: "Audit", fundingThreshold: 12000, tasks: [ { label: "External audit", completed: false }, ] }, ], } as OutcomeNodeData }, { id: "eve-governance", type: "outcome", position: { x: 2220, y: 850 }, data: { label: "Governance Model", description: "Governance framework and voting mechanisms", fundingReceived: 0, fundingTarget: 8000, status: "not-started", phases: [ { name: "Design", fundingThreshold: 3000, tasks: [ { label: "Governance charter draft", completed: false }, ] }, { name: "Implementation", fundingThreshold: 8000, tasks: [ { label: "Voting mechanism setup", completed: false }, { label: "Dispute resolution process", completed: false }, ] }, ], } as OutcomeNodeData }, ]; /** * Simulation Demo — starts empty so you can watch flow propagate. * * 1 source → central funnel → 3 domain funnels → 6 outcomes. * All currentValue and fundingReceived start at 0. * Press Play to watch resources flow from source through the entire system. */ export const simDemoNodes: FlowNode[] = [ // ── Source ── { id: "src-grants", type: "source", position: { x: 600, y: -300 }, data: { label: "Funding Source", flowRate: 12000, sourceType: "card", targetAllocations: [{ targetId: "treasury", percentage: 100, color: "#10b981" }], } as SourceNodeData, }, // ── Central Treasury ── { id: "treasury", type: "funnel", position: { x: 560, y: 0 }, data: { label: "Treasury", currentValue: 0, desiredOutflow: 2000, minThreshold: 2000, sufficientThreshold: 8000, maxThreshold: 12000, maxCapacity: 18000, inflowRate: 12000, dynamicOverflow: true, overflowAllocations: [], spendingAllocations: [ { targetId: "ops", percentage: 40, color: SPENDING_COLORS[0] }, { targetId: "research", percentage: 35, color: SPENDING_COLORS[1] }, { targetId: "community", percentage: 25, color: SPENDING_COLORS[2] }, ], } as FunnelNodeData, }, // ── Domain Funnels ── { id: "ops", type: "funnel", position: { x: 200, y: 400 }, data: { label: "Operations", currentValue: 0, desiredOutflow: 800, minThreshold: 800, sufficientThreshold: 3200, maxThreshold: 4800, maxCapacity: 7200, inflowRate: 0, overflowAllocations: [ { targetId: "community", percentage: 100, color: OVERFLOW_COLORS[0] }, ], spendingAllocations: [ { targetId: "infra", percentage: 50, color: SPENDING_COLORS[0] }, { targetId: "admin", percentage: 50, color: SPENDING_COLORS[1] }, ], } as FunnelNodeData, }, { id: "research", type: "funnel", position: { x: 560, y: 400 }, data: { label: "Research", currentValue: 0, desiredOutflow: 700, minThreshold: 700, sufficientThreshold: 2800, maxThreshold: 4200, maxCapacity: 6300, inflowRate: 0, overflowAllocations: [ { targetId: "community", percentage: 100, color: OVERFLOW_COLORS[1] }, ], spendingAllocations: [ { targetId: "papers", percentage: 60, color: SPENDING_COLORS[2] }, { targetId: "tools", percentage: 40, color: SPENDING_COLORS[3] }, ], } as FunnelNodeData, }, { id: "community", type: "funnel", position: { x: 920, y: 400 }, data: { label: "Community", currentValue: 0, desiredOutflow: 500, minThreshold: 500, sufficientThreshold: 2000, maxThreshold: 3000, maxCapacity: 4500, inflowRate: 0, overflowAllocations: [], spendingAllocations: [ { targetId: "events", percentage: 50, color: SPENDING_COLORS[4] }, { targetId: "outreach", percentage: 50, color: SPENDING_COLORS[5] }, ], } as FunnelNodeData, }, // ── Outcomes ── { id: "infra", type: "outcome", position: { x: 60, y: 850 }, data: { label: "Infrastructure", description: "Servers, hosting, CI/CD", fundingReceived: 0, fundingTarget: 15000, status: "not-started" } as OutcomeNodeData }, { id: "admin", type: "outcome", position: { x: 320, y: 850 }, data: { label: "Admin & Legal", description: "Legal, compliance, accounting", fundingReceived: 0, fundingTarget: 12000, status: "not-started" } as OutcomeNodeData }, { id: "papers", type: "outcome", position: { x: 520, y: 850 }, data: { label: "Publications", description: "Research papers and reports", fundingReceived: 0, fundingTarget: 18000, status: "not-started" } as OutcomeNodeData }, { id: "tools", type: "outcome", position: { x: 720, y: 850 }, data: { label: "R&D Tools", description: "Prototyping and tooling", fundingReceived: 0, fundingTarget: 10000, status: "not-started" } as OutcomeNodeData }, { id: "events", type: "outcome", position: { x: 920, y: 850 }, data: { label: "Events", description: "Meetups and conferences", fundingReceived: 0, fundingTarget: 8000, status: "not-started" } as OutcomeNodeData }, { id: "outreach", type: "outcome", position: { x: 1120, y: 850 }, data: { label: "Outreach", description: "Marketing and comms", fundingReceived: 0, fundingTarget: 6000, status: "not-started" } as OutcomeNodeData }, ];