/* Stylized SVG visuals of a Milky Way enterprise map. Three flavors: - HeroMap: medium-density, animated, with customer-journey arm - CompactMap: tighter, for the "what is the map" section - PerspectiveMap: switches highlight set based on selected lens */ const cap = (x, y, w, h, label, tools, opts = {}) => ({ x, y, w, h, label, tools, ...opts }); // Hero map nodes — abstracted, cleaner than the original but recognizable const HERO_NODES = [ cap(70, 150, 130, 56, "Marketing", ["EXCEL", "FILE-SYS"]), cap(230, 110, 150, 56, "Campaign & Sales", ["EMAIL", "QLIK"]), cap(410, 130, 130, 56, "Search & Find", ["GOOGLE"]), cap(570, 110, 130, 56, "Digital Booking", ["ADMINWEB"]), cap(720, 130, 130, 56, "Payments", ["VISMA"]), cap(870, 100, 150, 56, "Customer Support", ["CRM", "COURSEWEB"]), cap(50, 280, 140, 56, "Cost calc.", ["FINANCE"]), cap(210, 300, 140, 56, "Price calc.", ["EXCEL"]), cap(380, 280, 160, 56, "Content prod.", ["COURSEWEB"]), cap(70, 430, 150, 56, "Staff selection", ["E-LEARN"]), cap(240, 450, 150, 56, "Contract mgmt.", ["FILE-SYS"]), cap(420, 430, 150, 56, "Course design", ["POWERPT"], { partner: true }), cap(720, 280, 160, 56, "Course delivery", ["COURSEWEB"], { partner: true }), cap(900, 310, 140, 56, "Evaluation", ["WEBEVAL"]), cap(720, 430, 160, 56, "Sales analysis", ["QLIK"]), cap(900, 450, 140, 56, "Invoicing", ["DIGI-INV"]), ]; const HUB = { cx: 555, cy: 295, r: 64 }; const STICKIES = [ { x: HUB.cx - 30, y: HUB.cy - 130, label: "Marketing", color: "#f4a261" }, { x: HUB.cx + 80, y: HUB.cy - 60, label: "Deliver", color: "#7ee787" }, { x: HUB.cx + 50, y: HUB.cy + 80, label: "Follow up", color: "#a78bfa" }, { x: HUB.cx - 110, y: HUB.cy + 60, label: "Plan", color: "#f472b6" }, { x: HUB.cx - 130, y: HUB.cy - 40, label: "Productify", color: "#facc15" }, ]; function CapBox({ node, dim, highlight }) { const cls = highlight ? "cap-box hl" : dim ? "cap-box dim" : "cap-box"; return ( {node.label} {node.tools && ( {node.tools.map((t, i) => ( {t} ))} )} ); } function CustomerJourney({ animated = true }) { // Curving "galaxy arm" that wraps the top of the map const path = "M 20 60 C 200 -40, 500 30, 760 40 S 1050 60, 1100 180 L 1100 360 C 1080 480, 980 540, 800 540 S 240 520, 100 540"; return ( {/* Touch points */} {[0.05, 0.18, 0.32, 0.48, 0.62, 0.78, 0.92].map((t, i) => { // Approximate positions along the path const positions = [ [30, 50], [200, 8], [400, 22], [620, 42], [900, 70], [1095, 280], [950, 535] ]; const [x, y] = positions[i] || [0, 0]; return ( ); })} ); } function Hub({ stickies = STICKIES, label = "UniBiz" }) { return ( {/* outer ring */} {/* hub disc */} {label} {/* stickies */} {stickies.map((s, i) => ( {s.label} ))} ); } // Connections from hub to selected capabilities function HubLinks({ targets, color = "#7ee787", dashed = false }) { return ( {targets.map((t, i) => { const tx = t.x + t.w / 2; const ty = t.y + t.h / 2; return ( ); })} ); } // Inter-capability connection arrows function Flows({ pairs, color = "#3a3a52" }) { return ( {pairs.map(([a, b], i) => { const x1 = a.x + a.w; const y1 = a.y + a.h / 2; const x2 = b.x; const y2 = b.y + b.h / 2; const mx = (x1 + x2) / 2; return ( ); })} ); } function MapDefs() { return ( ); } function HeroMap({ animated = true }) { const flows = [ [HERO_NODES[0], HERO_NODES[1]], [HERO_NODES[1], HERO_NODES[2]], [HERO_NODES[2], HERO_NODES[3]], [HERO_NODES[3], HERO_NODES[4]], [HERO_NODES[4], HERO_NODES[5]], [HERO_NODES[6], HERO_NODES[7]], [HERO_NODES[7], HERO_NODES[8]], [HERO_NODES[9], HERO_NODES[10]], [HERO_NODES[10], HERO_NODES[11]], [HERO_NODES[12], HERO_NODES[13]], [HERO_NODES[14], HERO_NODES[15]], ]; return ( {HERO_NODES.map((n, i) => )} {/* Title corner */} MILKY WAY v1.2 · UniBiz · 2026 {/* Legend */} OWN PARTNER JOURNEY ); } // --- Compact map (used in "what is" section) --- const COMPACT_NODES = [ cap(60, 60, 120, 50, "Acquire", ["CRM"]), cap(210, 80, 120, 50, "Onboard", ["FORM"]), cap(360, 60, 120, 50, "Activate", ["APP"]), cap(510, 80, 120, 50, "Bill", ["STRIPE"]), cap(60, 220, 120, 50, "Support", ["DESK"]), cap(210, 240, 120, 50, "Retain", ["EMAIL"]), cap(510, 240, 120, 50, "Expand", ["DATA"]), ]; function CompactMap() { const hubCx = 410, hubCy = 165, hubR = 40; return ( {/* journey */} {/* connections from hub */} {COMPACT_NODES.map((n, i) => ( ))} {COMPACT_NODES.map((n, i) => )} Your co. ); } // --- Perspective map: same map, different lens --- const PERSP_HIGHLIGHTS = { operations: [1, 2, 3, 4, 5, 12, 13], // customer-facing flow tactics: [0, 6, 7, 8, 9, 10, 14], // capabilities + planning strategy: [11, 12, 13, 14, 15], // delivery + analysis }; function PerspectiveMap({ lens = "operations" }) { const highlights = new Set(PERSP_HIGHLIGHTS[lens] || []); const color = lens === "operations" ? "#7ee787" : lens === "tactics" ? "#a78bfa" : "#facc15"; return ( {/* lens-specific journey only for operations */} {lens === "operations" && ( )} {HERO_NODES.map((n, i) => ( ))} UniBiz ); } Object.assign(window, { HeroMap, CompactMap, PerspectiveMap });