// Mock data representing a single scored participant, modelled on the v2.5 scored card schema. const MOCK_PARTICIPANT = { respondentId: 'p-001', name: 'Arjun Mehta', role: 'Co-founder & CEO', org: 'Meridian Labs', completedAt: '2026-04-18T14:23:00Z', scoringPath: 'native', responseQuality: { flag: 'CLEAN', reliability: 'HIGH', pctMidpoint: 12, pctAgreement: 48, completionMinutes: 27.4 }, dimensions: { philosophyCohesion: 78, driveAlignment: 86, bondingIndex: 42, adaptiveIntelligence: 81, volatilityVector: 71, ambiguityTolerance: 74, influenceStyle: 82, feedbackOrientation: 38, temporalOrientation: 64, energyResilience: 77, }, scaleMeans: { perceptualDepth: 4.21, generativeRange: 4.05, aestheticSensitivity: 3.33, socialPresence: 4.11, prosocialDrive: 2.94, relationalTrust: 2.76, goalPersistence: 4.60, executionStriving: 4.67, structuralOrder: 4.12, impulseGovernance: 3.21, reactiveImpulse: 4.15, hostileReactivity: 3.05, threatSensitivity: 2.32, affectiveVolatility: 2.80, moodDepression: 1.95, forwardDeliberation: 3.05, directiveForce: 4.42, }, supplementary: { gritTotal: 4.12, gritPerseverance: 4.50, gritConsistency: 3.75, brcsScore: 17, workEthicTotal: 44 }, aiPreferences: { informationProcessing: 'A', challengeTolerance: 'A', decisionSupport: 'A', communicationTempo: 'A', cognitiveBlindSpot: 'A' }, signature: 'Decisive Strategist with Low-Warmth Tilt', }; const MOCK_PARTNER = { respondentId: 'p-002', name: 'Lena Sørensen', role: 'Co-founder & COO', org: 'Meridian Labs', dimensions: { philosophyCohesion: 72, driveAlignment: 81, bondingIndex: 78, adaptiveIntelligence: 64, volatilityVector: 32, ambiguityTolerance: 41, influenceStyle: 44, feedbackOrientation: 72, temporalOrientation: 79, energyResilience: 58, }, signature: 'Relational Operator, Deliberative Anchor', }; // Dimension display metadata (IP-protected participant labels) const DIMS = [ { id: 'philosophyCohesion', label: 'Philosophy Cohesion', blurb: 'Alignment with mission and long-term direction.' }, { id: 'driveAlignment', label: 'Drive Alignment', blurb: 'Work ethic, standards, self-direction.' }, { id: 'bondingIndex', label: 'Bonding Index', blurb: 'Prosocial orientation and relational investment.' }, { id: 'adaptiveIntelligence', label: 'Adaptive Intelligence', blurb: 'Learning agility and fluid thinking.' }, { id: 'volatilityVector', label: 'Volatility Vector', blurb: 'Risk tolerance and impulse profile.' }, { id: 'ambiguityTolerance', label: 'Ambiguity Tolerance', blurb: 'Functioning in open-ended environments.' }, { id: 'influenceStyle', label: 'Influence Style', blurb: 'Collaborative vs. directive leadership.' }, { id: 'feedbackOrientation', label: 'Feedback Orientation', blurb: 'Receptivity to direct challenge.' }, { id: 'temporalOrientation', label: 'Temporal Orientation', blurb: 'Near-term vs. long-horizon bias.' }, { id: 'energyResilience', label: 'Energy & Resilience', blurb: 'Sustained output, recovery speed.' }, ]; const band = (score) => { if (score <= 25) return 'Low'; if (score <= 50) return 'Mid-Low'; if (score <= 75) return 'Mid-High'; return 'High'; }; // Pairwise deltas + a single Kalibr cohesion score. function computePair(a, b) { const weights = { philosophyCohesion: { w: 1.5, type: 'similarity' }, driveAlignment: { w: 1.3, type: 'similarity' }, bondingIndex: { w: 1.2, type: 'similarity' }, adaptiveIntelligence: { w: 0.8, type: 'complementary' }, volatilityVector: { w: 0.9, type: 'complementary' }, ambiguityTolerance: { w: 1.0, type: 'similarity' }, influenceStyle: { w: 0.7, type: 'complementary' }, feedbackOrientation: { w: 1.1, type: 'similarity' }, temporalOrientation: { w: 1.4, type: 'similarity' }, energyResilience: { w: 0.8, type: 'similarity' }, }; const rows = DIMS.map(d => { const av = a.dimensions[d.id], bv = b.dimensions[d.id]; const diff = Math.abs(av - bv); const cfg = weights[d.id]; let score; if (cfg.type === 'similarity') score = 100 - diff * 1.2; else { const ideal = 25; score = 100 - Math.abs(diff - ideal) * 1.4; } score = Math.max(0, Math.min(100, score)); return { id: d.id, label: d.label, av, bv, diff, type: cfg.type, weight: cfg.w, score }; }); const total = rows.reduce((s, r) => s + r.score * r.weight, 0) / rows.reduce((s, r) => s + r.weight, 0); return { rows, cohesion: Math.round(total) }; } // ─── Live score reader ──────────────────────────────────────────────────────── // Reads from window.__kalibr_python_scores (set by bridge) or localStorage fallback. // Returns the full /score response object, or null if not yet available. function getKalibrScores() { // Priority 1: window.__kalibr_python_scores set by the bridge const py = window.__kalibr_python_scores; if (py) { // Full response object: { dimensions, scaleMeans, supplementary, aiPreferences, quality } if (py.dimensions && typeof py.dimensions === 'object') return py; // Bridge may have set it directly to the dimensions object if (typeof py.philosophyCohesion === 'number') { return { dimensions: py, supplementary: {}, aiPreferences: {}, scaleMeans: {}, quality: {} }; } } // Priority 2: localStorage — bridge writes dimensions there too try { const raw = localStorage.getItem('kalibr.be.cards'); if (raw) { const cards = JSON.parse(raw); const keys = Object.keys(cards); if (keys.length) { const entry = cards[keys[keys.length - 1]]; const card = entry && entry.card; if (card && card.dimensions && typeof card.dimensions === 'object') { return { dimensions: card.dimensions, supplementary: card.supplementary || {}, aiPreferences: card.aiPreferences || {}, scaleMeans: card.scaleMeans || {}, quality: card.quality || {}, }; } } } } catch (e) { /* silent fail */ } return null; } // React hook: returns live scores and re-renders when bridge writes new data. Object.assign(window, { MOCK_PARTICIPANT, MOCK_PARTNER, DIMS, band, computePair, getKalibrScores });