From 8aeec312b52df3b965d26c038c6f18bdeb7bbda3 Mon Sep 17 00:00:00 2001 From: Lukas Bresser Date: Mon, 29 Jun 2026 15:51:06 +0200 Subject: [PATCH 01/10] Add cross-focus-area impact dashboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds /impact — a public, filterable dashboard that tracks PL R&D's impact via the twelve pre-registered inflection points, one set per focus area. What it does: - Filterable by focus area (vertical tab rail); a user always lands in one area rather than seeing all twelve at once. - Each inflection point is a card with a Defined -> Emerging -> Reached -> Scaling field-progress meter and a PL-role tag (Substrate / Originator / Funder & convener). Clicking opens a detail modal. - The modal traces Q1 (did it happen — the pre-registered threshold), Q2 (did it matter — the cascade), and Q3 (did our work make it happen) as Inputs -> Activities -> Outputs. - Field progress and PL contribution are kept on separate axes and never collapsed into one score: a point can be reached with little PL involvement and that is still a win for the field. - For the two Economies & Governance points with live data, the modal pulls live OUTPUTS from the same sources as the FA2 live dashboard (GainForest, Glow, Simocracy) — labelled strictly as Q3 contribution evidence, never as Q1 progress. Fetched server-side with 60s ISR and graceful fallback. - A "Measuring impact" explainer covers the logic model and the three questions. - Adds an "Impact" item to the main nav. Co-Authored-By: Claude Opus 4.8 --- src/app/impact/page.tsx | 150 +++++++++ src/components/ImpactDashboard.tsx | 445 ++++++++++++++++++++++++++ src/components/MeasuringQuestions.tsx | 107 +++++++ src/lib/inflection-points.ts | 350 ++++++++++++++++++++ src/lib/site-config.ts | 1 + 5 files changed, 1053 insertions(+) create mode 100644 src/app/impact/page.tsx create mode 100644 src/components/ImpactDashboard.tsx create mode 100644 src/components/MeasuringQuestions.tsx create mode 100644 src/lib/inflection-points.ts diff --git a/src/app/impact/page.tsx b/src/app/impact/page.tsx new file mode 100644 index 00000000..b62a73be --- /dev/null +++ b/src/app/impact/page.tsx @@ -0,0 +1,150 @@ +import type { Metadata } from 'next' +import Breadcrumb from '@/components/Breadcrumb' +import ImpactDashboard, { type LiveMetric, type LiveOutputs } from '@/components/ImpactDashboard' +import MeasuringQuestions from '@/components/MeasuringQuestions' +import { fetchSimocracyStats } from '@/lib/simocracy' +import { fetchGainforestStats } from '@/lib/gainforest' +import { fetchGlowStats } from '@/lib/glow' + +// Pull live output metrics for the Economies & Governance inflection points from +// the same sources as the FA2 live dashboard. These are Q3 OUTPUTS (the work +// PL-backed teams have produced) — never Q1 progress toward a threshold. +export const revalidate = 60 + +async function fetchLiveOutputs(): Promise { + const compact = (n: number) => + new Intl.NumberFormat('en-US', { notation: 'compact', maximumFractionDigits: 1 }).format(n) + const out: LiveOutputs = {} + + const [sim, gf, glow] = await Promise.allSettled([ + fetchSimocracyStats(), + fetchGainforestStats(), + fetchGlowStats(), + ]) + + // A binding decision at scale — Simocracy (a PL-supported deliberation mechanism). + if (sim.status === 'fulfilled' && !sim.value.degraded) { + const t = sim.value.totals + const metrics: LiveMetric[] = [ + { n: t.uniqueHumans, label: 'participants' }, + { n: t.totalSims, label: 'simulations' }, + { n: t.totalGatherings, label: 'gatherings' }, + ] + .filter((m) => m.n > 0) + .map((m) => ({ value: compact(m.n), label: m.label })) + if (metrics.length) out['A binding decision at scale'] = metrics + } + + // Capital that pays on verified outcomes — GainForest + Glow (PL-backed MRV teams). + const verified: LiveMetric[] = [] + if (gf.status === 'fulfilled' && !gf.value.degraded) { + const g = gf.value + if (g.observations > 0) verified.push({ value: compact(g.observations), label: 'species observations' }) + if (g.certifiedOrgs > 0) verified.push({ value: compact(g.certifiedOrgs), label: 'certified orgs' }) + } + if (glow.status === 'fulfilled' && !glow.value.degraded) { + const gl = glow.value + if (gl.activeFarms > 0) verified.push({ value: compact(gl.activeFarms), label: 'active solar farms' }) + if (gl.carbon > 0) verified.push({ value: compact(gl.carbon), label: 'tCO₂ / wk' }) + } + if (verified.length) out['Capital that pays on verified outcomes'] = verified + + return out +} + +export const metadata: Metadata = { + title: 'Impact', + description: + 'How we measure whether PL R&D’s work matters: the inflection points we have pre-registered across every focus area, and how we will know if they happen.', +} + +// The logic-model chain: planned work on the left, intended results on the right. +const LOGIC_MODEL = [ + { label: 'Inputs', body: 'The resources we commit — funding, teams, convenings, standards.' }, + { label: 'Activities', body: 'What we do with them — seeding teams, building primitives, setting standards.' }, + { label: 'Outputs', body: 'The volume of work produced — teams funded, deployments, papers, ventures.' }, + { label: 'Outcomes', body: 'The changes that follow — adoption, capital inflows, new entrants.' }, + { label: 'Impact', body: 'The lasting shift in the system — an inflection point that holds.' }, +] + +export default async function ImpactPage() { + const liveOutputs = await fetchLiveOutputs() + return ( +
+ {/* Hero */} +
+ +
+

+ Our impact +

+

+ Across our four focus areas we have named a small set of{' '} + inflection points — specific, + observable, falsifiable shifts we believe would be catalytic, and that have not yet + happened. +

+
+
+ + {/* Inflection points — grey full-bleed section to set it apart from the rest of the site */} +
+
+

+ Inflection points we are tracking +

+

+ Select a focus area. Each card shows the pre-registered threshold (did it happen), the + cascade we expect if it matters, and the PL contribution we would trace. Pre-registering + the threshold now is what keeps us honest later — the answer in two years should be a + reading, not an argument. +

+ +
+
+ + {/* Measuring impact */} +
+

Measuring impact

+

+ Impact is the last link in a chain that runs from the work we plan to the results we + intend. Inputs and activities are our planned work; outcomes and impact are the change in + the world that follows. We only count something as impact when it is a durable shift in the + system — not just activity or output. +

+ + {/* Logic-model chain */} +
+ {LOGIC_MODEL.map((stage, i) => ( +
+
+ + {i + 1} + + {stage.label} +
+

{stage.body}

+
+ ))} +
+
+ ← Our planned work + Our intended results → +
+

+ Each inflection point instantiates this chain. On its card, the Q3 detail tracks our + inputs, activities, and outputs; the field meter tracks the outcomes and impact they aim + at. +

+ + {/* The three questions — pick one to read its detail */} +

+ For frontier research, the hard part is the right edge of that chain. So for every + inflection point we ask three questions — different jobs that should not be collapsed into + one metric. Select one to read how we measure it. +

+ +
+
+ ) +} diff --git a/src/components/ImpactDashboard.tsx b/src/components/ImpactDashboard.tsx new file mode 100644 index 00000000..0d7ed7e4 --- /dev/null +++ b/src/components/ImpactDashboard.tsx @@ -0,0 +1,445 @@ +'use client' + +import { useEffect, useMemo, useState } from 'react' +import { + CONTRIBUTION_META, + FIELD_STAGES, + FOCUS_AREAS, + INFLECTION_POINTS, + STATUS_META, + stageIndexForStatus, + type FocusAreaKey, + type InflectionPoint, +} from '@/lib/inflection-points' +import { AreaIcon, type AreaIconType } from '@/components/AreaIcons' + +type Filter = FocusAreaKey + +/** Live output metrics for a point, keyed by the point's title. Fetched server-side. */ +export type LiveMetric = { value: string; label: string } +export type LiveOutputs = Record + +const FA_ICON: Record = { + 'digital-human-rights': 'shield', + 'economies-governance': 'hexagon', + 'ai-robotics': 'neural', + neurotech: 'brain', +} + +export default function ImpactDashboard({ liveOutputs = {} }: { liveOutputs?: LiveOutputs }) { + const [filter, setFilter] = useState('digital-human-rights') + const [active, setActive] = useState(null) + + const visible = useMemo( + () => INFLECTION_POINTS.filter((p) => p.area === filter), + [filter], + ) + + return ( +
+ {/* Vertical tabs */} +
+ {FOCUS_AREAS.map((fa) => ( + p.area === fa.key).length} + icon={FA_ICON[fa.key]} + accent={fa.accent} + active={filter === fa.key} + onClick={() => setFilter(fa.key)} + /> + ))} +
+ + {/* Content */} +
+ {visible.length > 0 ? ( +
+ {visible.map((p) => ( + setActive(p)} + /> + ))} +
+ ) : ( + + )} +
+ + {active && ( + setActive(null)} + /> + )} +
+ ) +} + +function Tab({ + label, + count, + active, + icon, + accent, + onClick, +}: { + label: string + count: number + active: boolean + icon?: AreaIconType + accent?: string + onClick: () => void +}) { + return ( + + ) +} + +/** Field-progress lifecycle meter (Q1 -> Q2). Colored in the focus-area accent. */ +function FieldMeter({ + status, + accent, + compact = false, +}: { + status: InflectionPoint['status'] + accent: string + compact?: boolean +}) { + const reached = stageIndexForStatus(status) + return ( +
+
+ {FIELD_STAGES.map((_, i) => ( + + ))} +
+ {!compact && ( +
+ {FIELD_STAGES.map((s, i) => ( + + {s} + + ))} +
+ )} +
+ ) +} + +function ContributionChip({ level }: { level: InflectionPoint['contributionLevel'] }) { + const meta = CONTRIBUTION_META[level] + return ( + + PL role + {meta.label} + + ) +} + +function InflectionCard({ + point, + onOpen, +}: { + point: InflectionPoint + onOpen: () => void +}) { + const fa = FOCUS_AREAS.find((f) => f.key === point.area)! + const status = STATUS_META[point.status] + + return ( + + ) +} + +function InflectionModal({ + point, + metrics, + onClose, +}: { + point: InflectionPoint + metrics?: LiveMetric[] + onClose: () => void +}) { + const fa = FOCUS_AREAS.find((f) => f.key === point.area)! + const status = STATUS_META[point.status] + const role = CONTRIBUTION_META[point.contributionLevel] + + // Close on Escape, and lock body scroll while open. + useEffect(() => { + const onKey = (e: KeyboardEvent) => { + if (e.key === 'Escape') onClose() + } + document.addEventListener('keydown', onKey) + const prev = document.body.style.overflow + document.body.style.overflow = 'hidden' + return () => { + document.removeEventListener('keydown', onKey) + document.body.style.overflow = prev + } + }, [onClose]) + + return ( +
+
e.stopPropagation()} + > + {/* Close */} + + +
+ {/* Header */} +
+ + + + {fa.label} + · + {point.opportunitySpace} +
+

+ {point.title} +

+ + {/* Field axis */} +
+
+ + Field progress + + + + {status.label} + +
+ +

+ The field axis (Q1 → Q2) is tracked independently of PL’s contribution. It can + advance with little or no PL involvement. +

+
+ + {/* Three questions */} +
+ {point.signal} +
+
+ {point.cascade} +
+
+
+ + {role.description} +
+
+ {point.contribution.inputs} + {point.contribution.activities} + {point.contribution.outputs} +
+

+ Inputs → activities → outputs are PL’s planned work. The outcomes and impact they + aim at are tracked on the field axis above (Q2, then Q1). +

+
+ + {/* Live evidence (Q3 only — never a Q1 reading) */} + {point.liveEvidence && ( + +
+ Live outputs +
+
+ + + + + {point.liveEvidence.label} + + + +
+ {metrics && metrics.length > 0 && ( +
+ {metrics.map((m) => ( + + {m.value} + {m.label} + + ))} +
+ )} +

+ {point.liveEvidence.note} +

+
+ )} +
+
+
+ ) +} + +function LogicRow({ label, children }: { label: string; children: React.ReactNode }) { + return ( +
+ + {label} + + {children} +
+ ) +} + +function Section({ + q, + label, + accent, + children, +}: { + q: string + label: string + accent: string + children: React.ReactNode +}) { + return ( +
+
+ + {q} + + {label} +
+
{children}
+
+ ) +} + +function EmptyState({ filter }: { filter: Filter }) { + const fa = FOCUS_AREAS.find((f) => f.key === filter) + return ( +
+

+ Inflection points for {fa?.label ?? 'this focus area'} are being defined. +

+

+ This focus area is still finalizing its plan of attack. Its pre-registered bets will appear + here once they are set. +

+
+ ) +} diff --git a/src/components/MeasuringQuestions.tsx b/src/components/MeasuringQuestions.tsx new file mode 100644 index 00000000..84e27da8 --- /dev/null +++ b/src/components/MeasuringQuestions.tsx @@ -0,0 +1,107 @@ +'use client' + +import { useState } from 'react' +import { CONTRIBUTION_META } from '@/lib/inflection-points' + +const QUESTIONS = [ + { + q: 'Q1', + title: 'Did it happen?', + maps: 'Impact', + body: 'We pre-register one observable threshold and report a simple yes/no plus a date when it is reached. It is externally observable — measured the same way whether or not PL is involved.', + }, + { + q: 'Q2', + title: 'Did it matter?', + maps: 'Outcomes', + body: 'A signal is only worth naming if it unlocks something. We name the second-order effects in advance and watch whether they follow. A threshold that is reached but unlocks nothing is itself a finding.', + }, + { + q: 'Q3', + title: 'Did our work make it happen?', + maps: 'Inputs · Activities · Outputs', + body: 'We trace contribution rather than claim credit: which PL-funded teams, convenings, standards, or ventures were on the critical path — and reason honestly about the counterfactual: would this have happened as fast, or at all, without us?', + }, +] + +export default function MeasuringQuestions() { + const [active, setActive] = useState(0) + const item = QUESTIONS[active] + + return ( +
+ {/* Vertical tabs */} +
+ {QUESTIONS.map((qq, i) => { + const isActive = active === i + return ( + + ) + })} +
+ + {/* Detail panel */} +
+
+ Maps to logic model: {item.maps} +
+

{item.title}

+

{item.body}

+ + {active === 2 && ( +
+
+ PL’s role on the critical path +
+

+ Contribution sits on its own axis, separate from how far the field has moved — we never + collapse the two into a single score. A point can be reached with little or no PL + involvement; that is still a win for the field, and we record our role honestly. Each + card tags PL’s role as one of three: +

+
+ {Object.values(CONTRIBUTION_META).map((c) => ( +
+ + {c.label} + +

{c.description}

+
+ ))} +
+
+ )} +
+
+ ) +} diff --git a/src/lib/inflection-points.ts b/src/lib/inflection-points.ts new file mode 100644 index 00000000..d47a46e9 --- /dev/null +++ b/src/lib/inflection-points.ts @@ -0,0 +1,350 @@ +// Cross-focus-area inflection points and how we measure them. +// +// Each focus area names a small set of inflection points: specific, observable, +// falsifiable shifts we believe would be catalytic and that have NOT yet happened +// as of 2026. They are hypotheses, not descriptions of the present. We judge our +// work against three questions, mapped to the fields on every point: +// +// Q1 (signal) Did it happen? A pre-registered threshold — yes/no + date. +// Q2 (cascade) Did it matter? The second-order effects it should unlock. +// Q3 (contribution) Did our work make it happen? PL's inputs -> activities -> outputs on the +// critical path (the planned-work side of the +// logic model), traced honestly. +// +// IMPORTANT — these are distinct jobs and are NOT collapsed into one score. A point +// can be reached (Q1) and matter (Q2) with low PL contribution (Q3); that is still a +// win for the field. So we track field progress (Q1 -> Q2) on one axis and PL's +// contribution (Q3) on a separate, independent axis. +// +// Source: "Inflection points across PL R&D, and how we will measure them." + +export type InflectionStatus = 'watching' | 'early-signal' | 'tripped' + +/** PL's pre-registered role on the critical path — a claim to be evidenced, not a credit score. */ +export type ContributionLevel = 'substrate' | 'originator' | 'funder-convener' + +/** + * Q3 contribution, structured along the planned-work side of the logic model. + * Inputs (resources committed) -> Activities (what we do) -> Outputs (what gets produced). + * The outcomes and impact these aim at are tracked on the field axis (Q2, Q1). + */ +export type Contribution = { + inputs: string + activities: string + outputs: string +} + +/** A pointer to live activity that is contribution evidence (Q3) — NOT a Q1 threshold reading. */ +export type LiveEvidence = { + label: string + href: string + note: string +} + +export type InflectionPoint = { + /** Focus-area slug, matches /areas/. */ + area: FocusAreaKey + /** The opportunity space this bet lives in. */ + opportunitySpace: string + /** The inflection point, stated as a hypothesis. */ + title: string + /** Q1 — observable threshold that says it happened (not yet true). */ + signal: string + /** Q2 — why it matters / the cascade to watch. */ + cascade: string + /** Q3 — PL contribution to trace, as inputs -> activities -> outputs. */ + contribution: Contribution + /** Q3, summarized as PL's role on the critical path. */ + contributionLevel: ContributionLevel + /** Field-progress lifecycle state. All start 'watching' — none reached as of 2026. */ + status: InflectionStatus + /** Optional live activity from PL-backed teams — strictly Q3 evidence, never Q1 progress. */ + liveEvidence?: LiveEvidence +} + +export type FocusAreaKey = + | 'digital-human-rights' + | 'economies-governance' + | 'ai-robotics' + | 'neurotech' + +export type FocusAreaMeta = { + key: FocusAreaKey + label: string + /** Short legacy code used in the strategy docs. */ + code: string + href: string + /** Accent color (hex from the theme) for badges and the field-progress meter. */ + accent: string +} + +export const FOCUS_AREAS: FocusAreaMeta[] = [ + { key: 'digital-human-rights', label: 'Digital Human Rights', code: 'FA1', href: '/areas/digital-human-rights/', accent: '#1982F4' }, + { key: 'economies-governance', label: 'Economies & Governance', code: 'FA2', href: '/areas/economies-governance/', accent: '#12bfdf' }, + { key: 'ai-robotics', label: 'AI & Robotics', code: 'FA3', href: '/areas/ai-robotics/', accent: '#3966FE' }, + { key: 'neurotech', label: 'Neurotech', code: 'FA4', href: '/areas/neurotech/', accent: '#E51A66' }, +] + +// ── Field-progress lifecycle (Q1 -> Q2). Deliberately separate from PL contribution. ── +export const FIELD_STAGES = ['Defined', 'Emerging', 'Reached', 'Scaling'] as const +export type FieldStage = (typeof FIELD_STAGES)[number] + +/** How far along the field axis a point sits, given its status. */ +export function stageIndexForStatus(status: InflectionStatus): number { + switch (status) { + case 'watching': + return 0 // threshold defined, waiting at it + case 'early-signal': + return 1 + case 'tripped': + return 2 + } +} + +export const STATUS_META: Record = { + watching: { + label: 'Defined', + description: 'The threshold is defined and pre-registered. No movement toward it yet.', + color: '#6b6d79', + }, + 'early-signal': { + label: 'Emerging', + description: 'Leading indicators are moving toward the threshold.', + color: '#1982F4', + }, + tripped: { + label: 'Reached', + description: 'The defined threshold has been crossed.', + color: '#12bfdf', + }, +} + +export const CONTRIBUTION_META: Record = { + substrate: { + label: 'Substrate', + description: 'PL-built technology is the underlying rail this would run on.', + }, + originator: { + label: 'Originator', + description: 'PL originated the mechanism, standard, or benchmark in play.', + }, + 'funder-convener': { + label: 'Funder & convener', + description: 'PL funds the teams on the critical path and convenes the field.', + }, +} + +export const INFLECTION_POINTS: InflectionPoint[] = [ + // ── FA1 · Digital Human Rights ─────────────────────────────────────────── + { + area: 'digital-human-rights', + opportunitySpace: 'Censorship-Resistant Communication', + title: 'Communication that cannot be switched off', + signal: + 'A consumer-scale connectivity provider operates without state licensing or identity gating, and a metadata-resistant messenger crosses tens of millions of users; a population stays connected through a deliberate shutdown.', + cascade: + 'Censoring speech and assembly becomes impractical, not just illegal; organizing survives adversarial conditions.', + contribution: { + inputs: 'The libp2p / IPFS open-source networking stack; funding for resilient-comms and private-messaging teams.', + activities: 'Maintaining the substrate, funding teams, and contributing to interoperability standards.', + outputs: 'libp2p / IPFS deployments and the funded comms and messaging teams building on them.', + }, + contributionLevel: 'substrate', + status: 'watching', + }, + { + area: 'digital-human-rights', + opportunitySpace: 'Portable Identity, Credentials & Trust', + title: 'Personhood without the state in the loop', + signal: + 'A service at >100M people verifies unique humans for everyday use without a nation-state ID or KYC.', + cascade: + 'Recognition stops being rented from platforms and states; privacy-preserving personhood becomes safe to build on.', + contribution: { + inputs: 'Convening capacity across identity protocols; seed funding for portable-credential initiatives.', + activities: 'Convening identity-protocol teams and seeding / funding portable-credential work.', + outputs: 'The identity and credential initiatives PL has seeded or funded.', + }, + contributionLevel: 'funder-convener', + status: 'watching', + }, + { + area: 'digital-human-rights', + opportunitySpace: 'Verifiable Public Knowledge & Provenance', + title: 'Provenance becomes the default for truth', + signal: + 'Two consecutive frontier-model generations ship attested provenance by default, and a major platform or archive adopts content-addressed provenance as default.', + cascade: + 'A public record that can prove its own integrity becomes the precondition for trustworthy information in the AI era.', + contribution: { + inputs: 'Content addressing (IPFS) as the provenance substrate; funding for provenance and verifiable-compute teams.', + activities: 'Providing the content-addressing substrate and backing provenance / verifiable-compute teams.', + outputs: 'Content-addressed provenance tooling and the PL-backed teams building it.', + }, + contributionLevel: 'substrate', + status: 'watching', + }, + { + area: 'digital-human-rights', + opportunitySpace: 'Sovereign Infrastructure for AI & Agents', + title: 'Agents run on open rails', + signal: + 'A frontier-scale model is trained across independent decentralized hardware, or a meaningful share of agent-to-agent economic activity settles on open permissionless compute / storage / identity.', + cascade: + 'The rights architecture of the agent economy is set in the open rather than by whoever owns the cluster.', + contribution: { + inputs: 'The Filecoin / open-compute portfolio; PL capital and coordination across storage, compute, and identity.', + activities: 'Building open compute and storage rails and bridging them with identity for agents.', + outputs: 'Filecoin and the open-compute portfolio; integrations across storage, compute, and identity.', + }, + contributionLevel: 'substrate', + status: 'watching', + }, + + // ── FA2 · Economies & Governance ───────────────────────────────────────── + { + area: 'economies-governance', + opportunitySpace: 'Sovereign Digital Public Infrastructure', + title: 'Programmable government in production', + signal: + 'At least one sovereign moves >$1B/yr of real public funds through programmable, real-time-auditable rails; 3+ jurisdictions use selective-disclosure credentials for a high-stakes function (election, passport, census).', + cascade: + 'Digital government crosses from digitization to transformation; a reference deployment others can copy.', + contribution: { + inputs: 'Standards and procurement playbooks; convening capacity with sovereigns and builders; funding for DPI primitives.', + activities: 'Writing standards and playbooks, convening sovereigns with builders, and funding DPI primitives.', + outputs: 'Published playbooks, convened sovereign–builder cohorts, and funded DPI primitives.', + }, + contributionLevel: 'funder-convener', + status: 'watching', + }, + { + area: 'economies-governance', + opportunitySpace: 'Computational Coordination & Governance', + title: 'A binding decision at scale', + signal: + 'A city or government makes a consequential, binding decision through a computational mechanism with tens of thousands participating, beating the legacy process on cost, turnout, or trust.', + cascade: + 'Deliberation tools move from advisory to part of real decision-making infrastructure.', + contribution: { + inputs: 'Support for computational-deliberation mechanisms (e.g. Simocracy, broad-listening tools); convening capacity.', + activities: 'Supporting mechanism teams and convening government teams with tool teams.', + outputs: 'Simocracy and broad-listening tools, and the government–tool convenings around them.', + }, + contributionLevel: 'funder-convener', + status: 'watching', + liveEvidence: { + label: 'Simocracy governance simulation — live participation', + href: '/areas/economies-governance/impact/live-dashboard/', + note: 'Live activity from a PL-supported mechanism. This is contribution evidence (Q3) from a simulation — not the binding-decision-in-government threshold (Q1).', + }, + }, + { + area: 'economies-governance', + opportunitySpace: 'Programmable Capital Allocation', + title: 'Public goods become a financeable category', + signal: + '>$1B/yr flows through programmable allocation, a mainstream allocator (DFI, pension, sovereign fund) treats it as infrastructure, and a material real-world outcome is documented.', + cascade: + 'Funding public goods becomes a durable capital market rather than a niche.', + contribution: { + inputs: 'Hypercerts (PL origin) and the Gitcoin / Funding-the-Commons lineage; PL evidence and standards work.', + activities: 'Originating allocation mechanisms, building evidence and standards, and converting work into ventures.', + outputs: 'Hypercerts, Funding the Commons, and the ventures spun out of this lineage.', + }, + contributionLevel: 'originator', + status: 'watching', + }, + { + area: 'economies-governance', + opportunitySpace: 'Verifiable Real-World Infrastructure & Systems', + title: 'Capital that pays on verified outcomes', + signal: + 'A $1B+ climate or public-goods fund disburses against independently verified real-world outcomes, faster and cheaper than a legacy audit.', + cascade: + 'Verification becomes the rail capital runs on; the loop back to better decisions closes.', + contribution: { + inputs: 'Funding for MRV / outcome-verification teams (e.g. GainForest, Glow); benchmark and standards convening.', + activities: 'Backing MRV teams and convening benchmark and standards work for outcome verification.', + outputs: 'GainForest, Glow, and the verification benchmarks and standards they inform.', + }, + contributionLevel: 'funder-convener', + status: 'watching', + liveEvidence: { + label: 'GainForest & Glow — live verification activity', + href: '/areas/economies-governance/impact/live-dashboard/', + note: 'Live output from PL-backed MRV teams on this critical path. Contribution evidence (Q3) — not the $1B-disbursed-against-verified-outcomes threshold (Q1).', + }, + }, + + // ── FA4 · Neurotech ────────────────────────────────────────────────────── + { + area: 'neurotech', + opportunitySpace: 'Neural Augmentation (BCI)', + title: 'The BCI app store', + signal: + 'A regulator clears a standardized software / API layer for a commercial BCI (with medical guardrails), and the first third-party app launches and is adopted.', + cascade: + 'BCI value compounds after surgery; a developer ecosystem forms; demand shifts toward elective use.', + contribution: { + inputs: 'PL Neuro standards work for a BCI component ecosystem; convening capacity across regulators, device makers, and developers.', + activities: 'Defining the BCI component-ecosystem standard and convening regulators, makers, and developers.', + outputs: 'A draft BCI component / API standard and the regulator–maker–developer convenings around it.', + }, + contributionLevel: 'originator', + status: 'watching', + }, + { + area: 'neurotech', + opportunitySpace: 'Biologically Inspired Intelligence (NeuroAI)', + title: 'Neural distillation', + signal: + 'A major lab matches frontier reasoning by training on human neural data at a fraction of the parameters / energy, or venture funding surges into consumer EEG to harvest cognitive data for AI.', + cascade: + 'High-fidelity neural data becomes as valuable to AI as text; comp-neuro talent flow reverses.', + contribution: { + inputs: 'The PL Neuro talent network bridging AI labs and comp neuro; investment in neural-data infrastructure and norms.', + activities: 'Bridging AI-lab and comp-neuro talent and building neural-data infrastructure and norms.', + outputs: 'The PL Neuro talent network and the neural-data infrastructure and norms it seeds.', + }, + contributionLevel: 'funder-convener', + status: 'watching', + }, + { + area: 'neurotech', + opportunitySpace: 'Biologically Inspired Intelligence (NeuroAI)', + title: 'The neuromorphic energy pivot', + signal: + 'A brain-inspired model matches state-of-the-art performance at 3+ orders of magnitude better energy efficiency, and frontier labs begin acquiring neuromorphic startups.', + cascade: + 'Neurally derived design becomes foundational to commercial AI; AI is tethered to neuroscience.', + contribution: { + inputs: 'Funding for NeuroAI / neuromorphic research and demos; benchmark design defining the efficiency target.', + activities: 'Funding neuromorphic research and demos and defining the efficiency benchmark.', + outputs: 'PL-funded NeuroAI demos and the energy-efficiency benchmarks that frame the target.', + }, + contributionLevel: 'funder-convener', + status: 'watching', + }, + { + area: 'neurotech', + opportunitySpace: 'Whole Organism Emulation (WBE)', + title: 'Memory retrieval in simulation', + signal: + 'A reconstructed mouse connectome simulated in silico reproduces a specific behavior the biological mouse learned before its connectome was harvested.', + cascade: + 'WBE turns from speculation into a benchmarked engineering discipline; serious policy engagement begins.', + contribution: { + inputs: 'PL Neuro benchmark definition; connectomics workshops and throughput targets; engineering capacity for a demo.', + activities: 'Defining the WBE benchmark, running connectomics workshops, and engineering a reference demo.', + outputs: 'The WBE benchmark, connectomics throughput targets, and a PL-engineered demo.', + }, + contributionLevel: 'originator', + status: 'watching', + }, +] + +export function pointsForArea(area: FocusAreaKey | 'all'): InflectionPoint[] { + if (area === 'all') return INFLECTION_POINTS + return INFLECTION_POINTS.filter((p) => p.area === area) +} diff --git a/src/lib/site-config.ts b/src/lib/site-config.ts index 72a2bd97..a56a4a8c 100644 --- a/src/lib/site-config.ts +++ b/src/lib/site-config.ts @@ -35,6 +35,7 @@ export const mainNav: NavItem[] = [ { name: 'Neurotech', url: '/areas/neurotech/' }, ], }, + { name: 'Impact', url: '/impact/' }, { name: 'Insights', url: '/insights/' }, { name: 'Team', url: '/authors/' }, ] From fa6f6c27a0d130f0a4e94e52219c922b0bdfc8a9 Mon Sep 17 00:00:00 2001 From: Lukas Bresser Date: Mon, 29 Jun 2026 16:08:00 +0200 Subject: [PATCH 02/10] Refine impact dashboard copy and logic-model alignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Inflection section intro: drop the "pre-registering keeps us honest / reading not an argument" tail; "pre-registered" -> "defined" threshold. - Cards: remove the redundant "Defined" status pill (the field meter already shows stage); rename the teaser label "Signal it happened" -> "Inflection point". - Detail modal: tag Q1 with "Impact" and Q2 with "Outcome" so all three questions share the logic-model row layout used by Q3's Inputs / Activities / Outputs. - Measuring impact: move the "each inflection point instantiates this chain" note above the logic-model strip; style the strip labels as grey uppercase to match the detail cards. - Three-questions explainer: surface each question's logic-model stage(s) — Impact, Outcomes, and Inputs/Activities/Outputs — to tie the section back to the cards. - Hoist LOGIC_MODEL into lib/inflection-points so the strip, the explainer, and the modal share one vocabulary. Co-Authored-By: Claude Opus 4.8 --- src/app/impact/page.tsx | 37 +++++++++++---------------- src/components/ImpactDashboard.tsx | 36 ++++++++------------------ src/components/MeasuringQuestions.tsx | 32 ++++++++++++++++++----- src/lib/inflection-points.ts | 13 ++++++++++ 4 files changed, 64 insertions(+), 54 deletions(-) diff --git a/src/app/impact/page.tsx b/src/app/impact/page.tsx index b62a73be..30fae988 100644 --- a/src/app/impact/page.tsx +++ b/src/app/impact/page.tsx @@ -5,6 +5,7 @@ import MeasuringQuestions from '@/components/MeasuringQuestions' import { fetchSimocracyStats } from '@/lib/simocracy' import { fetchGainforestStats } from '@/lib/gainforest' import { fetchGlowStats } from '@/lib/glow' +import { LOGIC_MODEL } from '@/lib/inflection-points' // Pull live output metrics for the Economies & Governance inflection points from // the same sources as the FA2 live dashboard. These are Q3 OUTPUTS (the work @@ -58,15 +59,6 @@ export const metadata: Metadata = { 'How we measure whether PL R&D’s work matters: the inflection points we have pre-registered across every focus area, and how we will know if they happen.', } -// The logic-model chain: planned work on the left, intended results on the right. -const LOGIC_MODEL = [ - { label: 'Inputs', body: 'The resources we commit — funding, teams, convenings, standards.' }, - { label: 'Activities', body: 'What we do with them — seeding teams, building primitives, setting standards.' }, - { label: 'Outputs', body: 'The volume of work produced — teams funded, deployments, papers, ventures.' }, - { label: 'Outcomes', body: 'The changes that follow — adoption, capital inflows, new entrants.' }, - { label: 'Impact', body: 'The lasting shift in the system — an inflection point that holds.' }, -] - export default async function ImpactPage() { const liveOutputs = await fetchLiveOutputs() return ( @@ -94,10 +86,8 @@ export default async function ImpactPage() { Inflection points we are tracking

- Select a focus area. Each card shows the pre-registered threshold (did it happen), the - cascade we expect if it matters, and the PL contribution we would trace. Pre-registering - the threshold now is what keeps us honest later — the answer in two years should be a - reading, not an argument. + Select a focus area. Each card shows the defined threshold (did it happen), the cascade we + expect if it matters, and the PL contribution we would trace.

@@ -113,15 +103,23 @@ export default async function ImpactPage() { system — not just activity or output.

- {/* Logic-model chain */} +

+ Each inflection point instantiates this chain. On its card, the Q3 detail tracks our + inputs, activities, and outputs; the field meter tracks the outcomes and impact they aim + at. +

+ + {/* Logic-model chain — labels styled like the detail cards */}
{LOGIC_MODEL.map((stage, i) => ( -
+
- + {i + 1} - {stage.label} + + {stage.label} +

{stage.body}

@@ -131,11 +129,6 @@ export default async function ImpactPage() { ← Our planned work Our intended results →
-

- Each inflection point instantiates this chain. On its card, the Q3 detail tracks our - inputs, activities, and outputs; the field meter tracks the outcomes and impact they aim - at. -

{/* The three questions — pick one to read its detail */}

diff --git a/src/components/ImpactDashboard.tsx b/src/components/ImpactDashboard.tsx index 0d7ed7e4..f23fa6d8 100644 --- a/src/components/ImpactDashboard.tsx +++ b/src/components/ImpactDashboard.tsx @@ -180,7 +180,6 @@ function InflectionCard({ onOpen: () => void }) { const fa = FOCUS_AREAS.find((f) => f.key === point.area)! - const status = STATUS_META[point.status] return ( ) @@ -238,7 +253,6 @@ function InflectionModal({ }) { const fa = FOCUS_AREAS.find((f) => f.key === point.area)! const status = STATUS_META[point.status] - const role = CONTRIBUTION_META[point.contributionLevel] // Close on Escape, and lock body scroll while open. useEffect(() => { @@ -322,9 +336,15 @@ function InflectionModal({ {point.cascade}

-
- - {role.description} +
+ +
    + {PL_ROLE_ORDER.filter((r) => point.roles.includes(r)).map((r) => ( +
  • + {ROLE_META[r].label}: {ROLE_META[r].description} +
  • + ))} +
{point.contribution.inputs} diff --git a/src/components/MeasuringQuestions.tsx b/src/components/MeasuringQuestions.tsx index 741df8d7..b28b05eb 100644 --- a/src/components/MeasuringQuestions.tsx +++ b/src/components/MeasuringQuestions.tsx @@ -1,7 +1,7 @@ 'use client' import { useState } from 'react' -import { CONTRIBUTION_META, LOGIC_MODEL, type LogicStageKey } from '@/lib/inflection-points' +import { ROLE_META, PL_ROLE_ORDER, LOGIC_MODEL, type LogicStageKey } from '@/lib/inflection-points' const QUESTIONS: { q: string @@ -25,7 +25,7 @@ const QUESTIONS: { q: 'Q3', title: 'Did our work make it happen?', stages: ['inputs', 'activities', 'outputs'], - body: 'We trace contribution rather than claim credit: which PL-funded teams, convenings, standards, or ventures were on the critical path — and reason honestly about the counterfactual: would this have happened as fast, or at all, without us?', + body: 'We trace contribution rather than claim credit: which PL instruments — open infrastructure, field-mapping, convenings, grants, ventures, or policy work — were on the critical path, and reason honestly about the counterfactual: would this have happened as fast, or at all, without us?', }, ] @@ -104,11 +104,12 @@ export default function MeasuringQuestions() {

Contribution sits on its own axis, separate from how far the field has moved — we never collapse the two into a single score. A point can be reached with little or no PL - involvement; that is still a win for the field, and we record our role honestly. Each - card tags PL’s role as one of three: + involvement; that is still a win for the field, and we record our role honestly. The + toolkit is plural by design, so each card tags one or more of these roles — the + instrument matched to the bottleneck it releases:

-
- {Object.values(CONTRIBUTION_META).map((c) => ( +
+ {PL_ROLE_ORDER.map((r) => ROLE_META[r]).map((c) => (
{c.label} diff --git a/src/lib/inflection-points.ts b/src/lib/inflection-points.ts index 15cb96a7..53759333 100644 --- a/src/lib/inflection-points.ts +++ b/src/lib/inflection-points.ts @@ -20,8 +20,11 @@ export type InflectionStatus = 'watching' | 'early-signal' | 'tripped' -/** PL's pre-registered role on the critical path — a claim to be evidenced, not a credit score. */ -export type ContributionLevel = 'substrate' | 'originator' | 'funder-convener' +/** PL's pre-registered role(s) on the critical path — claims to be evidenced, not a credit score. */ +export type PLRole = 'infrastructure' | 'legibility' | 'connection' | 'capital' | 'translation' | 'permission' + +/** Canonical display order for role pills, so cards read consistently. */ +export const PL_ROLE_ORDER: PLRole[] = ['infrastructure', 'legibility', 'connection', 'capital', 'translation', 'permission'] /** * Q3 contribution, structured along the planned-work side of the logic model. @@ -54,8 +57,8 @@ export type InflectionPoint = { cascade: string /** Q3 — PL contribution to trace, as inputs -> activities -> outputs. */ contribution: Contribution - /** Q3, summarized as PL's role on the critical path. */ - contributionLevel: ContributionLevel + /** Q3, summarized as the PL role(s) on the critical path — the instruments we bring. */ + roles: PLRole[] /** Field-progress lifecycle state. All start 'watching' — none reached as of 2026. */ status: InflectionStatus /** Optional live activity from PL-backed teams — strictly Q3 evidence, never Q1 progress. */ @@ -132,18 +135,30 @@ export const STATUS_META: Record = { - substrate: { - label: 'Substrate', - description: 'PL-built technology is the underlying rail this would run on.', +export const ROLE_META: Record = { + infrastructure: { + label: 'Infrastructure', + description: 'The open, neutral rail this runs on did not exist — PL builds and maintains it (e.g. libp2p / IPFS / Filecoin).', + }, + legibility: { + label: 'Legibility', + description: 'The field lacked a shared map — PL increases visibility and navigability through roadmaps, taxonomies, benchmarks, and written artifacts.', + }, + connection: { + label: 'Connection', + description: 'Progress was blocked by too few connections — PL convenes the right people (dinners, retreats, residencies, hackathons).', + }, + capital: { + label: 'Capital', + description: 'Pre-commercial work needed patient funding — PL runs grants and prizes and helps peer funders deploy theirs.', }, - originator: { - label: 'Originator', - description: 'PL originated the mechanism, standard, or benchmark in play.', + translation: { + label: 'Translation', + description: 'The work was ready to leave the lab — PL helps convert it into ventures, pilots, and deployments.', }, - 'funder-convener': { - label: 'Funder & convener', - description: 'PL funds the teams on the critical path and convenes the field.', + permission: { + label: 'Permission', + description: 'The rules did not yet permit or recognize the technology — PL engages standards, policy, and regulatory pathways.', }, } @@ -162,7 +177,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ activities: 'Maintaining the substrate, funding teams, and contributing to interoperability standards.', outputs: 'libp2p / IPFS deployments and the funded comms and messaging teams building on them.', }, - contributionLevel: 'substrate', + roles: ['infrastructure', 'capital'], status: 'watching', }, { @@ -178,7 +193,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ activities: 'Convening identity-protocol teams and seeding / funding portable-credential work.', outputs: 'The identity and credential initiatives PL has seeded or funded.', }, - contributionLevel: 'funder-convener', + roles: ['connection', 'capital'], status: 'watching', }, { @@ -194,7 +209,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ activities: 'Providing the content-addressing substrate and backing provenance / verifiable-compute teams.', outputs: 'Content-addressed provenance tooling and the PL-backed teams building it.', }, - contributionLevel: 'substrate', + roles: ['infrastructure', 'capital'], status: 'watching', }, { @@ -210,7 +225,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ activities: 'Building open compute and storage rails and bridging them with identity for agents.', outputs: 'Filecoin and the open-compute portfolio; integrations across storage, compute, and identity.', }, - contributionLevel: 'substrate', + roles: ['infrastructure', 'connection', 'capital'], status: 'watching', }, @@ -228,7 +243,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ activities: 'Writing standards and playbooks, convening sovereigns with builders, and funding DPI primitives.', outputs: 'Published playbooks, convened sovereign–builder cohorts, and funded DPI primitives.', }, - contributionLevel: 'funder-convener', + roles: ['connection', 'capital', 'permission'], status: 'watching', }, { @@ -244,7 +259,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ activities: 'Supporting mechanism teams and convening government teams with tool teams.', outputs: 'Simocracy and broad-listening tools, and the government–tool convenings around them.', }, - contributionLevel: 'funder-convener', + roles: ['connection', 'capital'], status: 'watching', liveEvidence: { label: 'Simocracy governance simulation — live participation', @@ -265,7 +280,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ activities: 'Originating allocation mechanisms, building evidence and standards, and converting work into ventures.', outputs: 'Hypercerts, Funding the Commons, and the ventures spun out of this lineage.', }, - contributionLevel: 'originator', + roles: ['infrastructure', 'capital', 'translation'], status: 'watching', }, { @@ -281,7 +296,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ activities: 'Backing MRV teams and convening benchmark and standards work for outcome verification.', outputs: 'GainForest, Glow, and the verification benchmarks and standards they inform.', }, - contributionLevel: 'funder-convener', + roles: ['legibility', 'connection', 'capital'], status: 'watching', liveEvidence: { label: 'GainForest & Glow — live verification activity', @@ -304,7 +319,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ activities: 'Defining the BCI component-ecosystem standard and convening regulators, makers, and developers.', outputs: 'A draft BCI component / API standard and the regulator–maker–developer convenings around it.', }, - contributionLevel: 'originator', + roles: ['connection', 'permission'], status: 'watching', }, { @@ -320,7 +335,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ activities: 'Bridging AI-lab and comp-neuro talent and building neural-data infrastructure and norms.', outputs: 'The PL Neuro talent network and the neural-data infrastructure and norms it seeds.', }, - contributionLevel: 'funder-convener', + roles: ['infrastructure', 'connection', 'capital'], status: 'watching', }, { @@ -336,7 +351,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ activities: 'Funding neuromorphic research and demos and defining the efficiency benchmark.', outputs: 'PL-funded NeuroAI demos and the energy-efficiency benchmarks that frame the target.', }, - contributionLevel: 'funder-convener', + roles: ['legibility', 'capital'], status: 'watching', }, { @@ -352,7 +367,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ activities: 'Defining the WBE benchmark, running connectomics workshops, and engineering a reference demo.', outputs: 'The WBE benchmark, connectomics throughput targets, and a PL-engineered demo.', }, - contributionLevel: 'originator', + roles: ['legibility', 'connection'], status: 'watching', }, ] From d6e20aed249dc0bab986c702a79eebb95fa725ab Mon Sep 17 00:00:00 2001 From: Lukas Bresser Date: Tue, 30 Jun 2026 19:17:43 +0200 Subject: [PATCH 04/10] fix(impact): drop per-role descriptions from detail modal The role pill descriptions in the inflection-point modal duplicated the 'Measuring impact' Q3 explainer. Keep the role pills (with hover titles) but remove the description list so the explanation lives in one place. --- src/components/ImpactDashboard.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/components/ImpactDashboard.tsx b/src/components/ImpactDashboard.tsx index 71906b6d..e80c323e 100644 --- a/src/components/ImpactDashboard.tsx +++ b/src/components/ImpactDashboard.tsx @@ -338,13 +338,6 @@ function InflectionModal({
-
    - {PL_ROLE_ORDER.filter((r) => point.roles.includes(r)).map((r) => ( -
  • - {ROLE_META[r].label}: {ROLE_META[r].description} -
  • - ))} -
{point.contribution.inputs} From 61daa6f797366cf73cd65da43d028162f86d3f87 Mon Sep 17 00:00:00 2001 From: Lukas Bresser Date: Tue, 30 Jun 2026 20:21:20 +0200 Subject: [PATCH 05/10] fix(impact): swap Q1/Q2 (Q1=did it matter/impact, Q2=did it happen/outcome) + self-contained role tooltips - Q1 is now 'Did it matter?' (impact) and Q2 'Did it happen?' (outcome), consistent across the inflection-point detail modal and the Measuring- impact tabs (and doc comments / live-evidence notes). - Role pills now carry a label + description tooltip matching the Measuring-impact Q3 role explainer. --- src/app/impact/page.tsx | 2 +- src/components/ImpactDashboard.tsx | 16 ++++++++-------- src/components/MeasuringQuestions.tsx | 8 ++++---- src/lib/inflection-points.ts | 22 +++++++++++----------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/app/impact/page.tsx b/src/app/impact/page.tsx index 30fae988..ca1db74d 100644 --- a/src/app/impact/page.tsx +++ b/src/app/impact/page.tsx @@ -9,7 +9,7 @@ import { LOGIC_MODEL } from '@/lib/inflection-points' // Pull live output metrics for the Economies & Governance inflection points from // the same sources as the FA2 live dashboard. These are Q3 OUTPUTS (the work -// PL-backed teams have produced) — never Q1 progress toward a threshold. +// PL-backed teams have produced) — never Q2 progress toward a threshold. export const revalidate = 60 async function fetchLiveOutputs(): Promise { diff --git a/src/components/ImpactDashboard.tsx b/src/components/ImpactDashboard.tsx index e80c323e..347fc423 100644 --- a/src/components/ImpactDashboard.tsx +++ b/src/components/ImpactDashboard.tsx @@ -126,7 +126,7 @@ function Tab({ ) } -/** Field-progress lifecycle meter (Q1 -> Q2). Colored in the focus-area accent. */ +/** Field-progress lifecycle meter (Q1 & Q2). Colored in the focus-area accent. */ function FieldMeter({ status, accent, @@ -173,7 +173,7 @@ function RoleChips({ roles, eyebrow = true }: { roles: PLRole[]; eyebrow?: boole {ROLE_META[r].label} @@ -323,17 +323,17 @@ function InflectionModal({

- The field axis (Q1 → Q2) is tracked independently of PL’s contribution. It can + The field axis (Q1 & Q2) is tracked independently of PL’s contribution. It can advance with little or no PL involvement.

{/* Three questions — each tagged with the logic-model stage it maps to */} -
- {point.signal} +
+ {point.cascade}
-
- {point.cascade} +
+ {point.signal}
@@ -350,7 +350,7 @@ function InflectionModal({

- {/* Live evidence (Q3 only — never a Q1 reading) */} + {/* Live evidence (Q3 only — never a Q2 reading) */} {point.liveEvidence && ( activities -> outputs on the // critical path (the planned-work side of the // logic model), traced honestly. // // IMPORTANT — these are distinct jobs and are NOT collapsed into one score. A point -// can be reached (Q1) and matter (Q2) with low PL contribution (Q3); that is still a -// win for the field. So we track field progress (Q1 -> Q2) on one axis and PL's +// can be reached (Q2) and matter (Q1) with low PL contribution (Q3); that is still a +// win for the field. So we track field progress (Q1 & Q2) on one axis and PL's // contribution (Q3) on a separate, independent axis. // // Source: "Inflection points across PL R&D, and how we will measure them." @@ -37,7 +37,7 @@ export type Contribution = { outputs: string } -/** A pointer to live activity that is contribution evidence (Q3) — NOT a Q1 threshold reading. */ +/** A pointer to live activity that is contribution evidence (Q3) — NOT a Q2 threshold reading. */ export type LiveEvidence = { label: string href: string @@ -51,9 +51,9 @@ export type InflectionPoint = { opportunitySpace: string /** The inflection point, stated as a hypothesis. */ title: string - /** Q1 — observable threshold that says it happened (not yet true). */ + /** Q2 — observable threshold that says it happened (not yet true). */ signal: string - /** Q2 — why it matters / the cascade to watch. */ + /** Q1 — why it matters / the cascade to watch. */ cascade: string /** Q3 — PL contribution to trace, as inputs -> activities -> outputs. */ contribution: Contribution @@ -61,7 +61,7 @@ export type InflectionPoint = { roles: PLRole[] /** Field-progress lifecycle state. All start 'watching' — none reached as of 2026. */ status: InflectionStatus - /** Optional live activity from PL-backed teams — strictly Q3 evidence, never Q1 progress. */ + /** Optional live activity from PL-backed teams — strictly Q3 evidence, never Q2 progress. */ liveEvidence?: LiveEvidence } @@ -101,7 +101,7 @@ export const LOGIC_MODEL = [ ] as const export type LogicStageKey = (typeof LOGIC_MODEL)[number]['key'] -// ── Field-progress lifecycle (Q1 -> Q2). Deliberately separate from PL contribution. ── +// ── Field-progress lifecycle (Q1 & Q2). Deliberately separate from PL contribution. ── export const FIELD_STAGES = ['Defined', 'Emerging', 'Reached', 'Scaling'] as const export type FieldStage = (typeof FIELD_STAGES)[number] @@ -264,7 +264,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ liveEvidence: { label: 'Simocracy governance simulation — live participation', href: '/areas/economies-governance/impact/live-dashboard/', - note: 'Live activity from a PL-supported mechanism. This is contribution evidence (Q3) from a simulation — not the binding-decision-in-government threshold (Q1).', + note: 'Live activity from a PL-supported mechanism. This is contribution evidence (Q3) from a simulation — not the binding-decision-in-government threshold (Q2).', }, }, { @@ -301,7 +301,7 @@ export const INFLECTION_POINTS: InflectionPoint[] = [ liveEvidence: { label: 'GainForest & Glow — live verification activity', href: '/areas/economies-governance/impact/live-dashboard/', - note: 'Live output from PL-backed MRV teams on this critical path. Contribution evidence (Q3) — not the $1B-disbursed-against-verified-outcomes threshold (Q1).', + note: 'Live output from PL-backed MRV teams on this critical path. Contribution evidence (Q3) — not the $1B-disbursed-against-verified-outcomes threshold (Q2).', }, }, From f6802f02e7be5b1c9c948cdb5af0df821d36294e Mon Sep 17 00:00:00 2001 From: Lukas Bresser Date: Tue, 30 Jun 2026 20:34:03 +0200 Subject: [PATCH 06/10] fix(impact): real hover tooltip on PL role pills Native title was unreliable; replace with a scoped CSS tooltip (group/role) that shows the role's label + description on hover, pulled from the same ROLE_META used by the Measuring-impact Q3 section. --- src/components/ImpactDashboard.tsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/components/ImpactDashboard.tsx b/src/components/ImpactDashboard.tsx index 347fc423..965a20cf 100644 --- a/src/components/ImpactDashboard.tsx +++ b/src/components/ImpactDashboard.tsx @@ -170,12 +170,16 @@ function RoleChips({ roles, eyebrow = true }: { roles: PLRole[]; eyebrow?: boole PL role )} {ordered.map((r) => ( - - {ROLE_META[r].label} + + + {ROLE_META[r].label} + + + {ROLE_META[r].label} — {ROLE_META[r].description} + ))} From 43464ff878fbfd69ff656a7334264c1e59ed6d9a Mon Sep 17 00:00:00 2001 From: Lukas Bresser Date: Wed, 1 Jul 2026 08:50:36 +0200 Subject: [PATCH 07/10] impact(redesign): two-axis color tokens + role/logic-model copy Add FIELD_COLOR (teal) / HAND_COLOR (violet) tokens; update ROLE_META and LOGIC_MODEL copy to the mockup wording. --- src/lib/inflection-points.ts | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/lib/inflection-points.ts b/src/lib/inflection-points.ts index 893a6b70..ff29fb60 100644 --- a/src/lib/inflection-points.ts +++ b/src/lib/inflection-points.ts @@ -26,6 +26,12 @@ export type PLRole = 'infrastructure' | 'legibility' | 'connection' | 'capital' /** Canonical display order for role pills, so cards read consistently. */ export const PL_ROLE_ORDER: PLRole[] = ['infrastructure', 'legibility', 'connection', 'capital', 'translation', 'permission'] +// Two-axis color system used across the impact dashboard: +// FIELD = the change in the world (outcomes + impact) — moves with or without us +// HAND = our planned work / the PL toolkit — the only axis we control +export const FIELD_COLOR = '#12bfdf' +export const HAND_COLOR = '#7c5cf5' + /** * Q3 contribution, structured along the planned-work side of the logic model. * Inputs (resources committed) -> Activities (what we do) -> Outputs (what gets produced). @@ -93,11 +99,11 @@ export const FOCUS_AREAS: FocusAreaMeta[] = [ // questions explainer, and the per-point detail modal so the vocabulary lives // in one place. export const LOGIC_MODEL = [ - { key: 'inputs', label: 'Inputs', body: 'The resources we commit — funding, teams, convenings, standards.' }, - { key: 'activities', label: 'Activities', body: 'What we do with them — seeding teams, building primitives, setting standards.' }, - { key: 'outputs', label: 'Outputs', body: 'The volume of work produced — teams funded, deployments, papers, ventures.' }, - { key: 'outcomes', label: 'Outcomes', body: 'The changes that follow — adoption, capital inflows, new entrants.' }, - { key: 'impact', label: 'Impact', body: 'The lasting shift in the system — an inflection point that holds.' }, + { key: 'inputs', label: 'Inputs', body: 'Funding, teams, convenings, standards we commit.' }, + { key: 'activities', label: 'Activities', body: 'Seeding teams, building primitives, setting standards.' }, + { key: 'outputs', label: 'Outputs', body: 'Teams funded, deployments, papers, ventures.' }, + { key: 'outcomes', label: 'Outcomes', body: 'Adoption, capital inflows, new entrants.' }, + { key: 'impact', label: 'Impact', body: 'The lasting shift: an inflection point that holds.' }, ] as const export type LogicStageKey = (typeof LOGIC_MODEL)[number]['key'] @@ -138,27 +144,27 @@ export const STATUS_META: Record = { infrastructure: { label: 'Infrastructure', - description: 'The open, neutral rail this runs on did not exist — PL builds and maintains it (e.g. libp2p / IPFS / Filecoin).', + description: 'The open, neutral rail this runs on did not exist. PL builds and maintains it (libp2p / IPFS / Filecoin lineage).', }, legibility: { label: 'Legibility', - description: 'The field lacked a shared map — PL increases visibility and navigability through roadmaps, taxonomies, benchmarks, and written artifacts.', + description: 'The field lacked a shared map. PL adds roadmaps, taxonomies, benchmarks, and written artifacts.', }, connection: { label: 'Connection', - description: 'Progress was blocked by too few connections — PL convenes the right people (dinners, retreats, residencies, hackathons).', + description: 'Too few connections blocked progress. PL convenes the people who need to collide: dinners, retreats, residencies, hackathons.', }, capital: { label: 'Capital', - description: 'Pre-commercial work needed patient funding — PL runs grants and prizes and helps peer funders deploy theirs.', + description: 'Pre-commercial work needed patient funding. PL runs grants and prizes and helps peer funders deploy theirs.', }, translation: { label: 'Translation', - description: 'The work was ready to leave the lab — PL helps convert it into ventures, pilots, and deployments.', + description: 'The work was ready to leave the lab. PL helps convert it into ventures, pilots, and deployments.', }, permission: { label: 'Permission', - description: 'The rules did not yet permit or recognize the technology — PL engages standards, policy, and regulatory pathways.', + description: 'The rules did not yet recognize the technology. PL engages standards, policy, and regulatory pathways.', }, } From c9e819f1310019594bd6e87f8f1425c08ac5a944 Mon Sep 17 00:00:00 2001 From: Lukas Bresser Date: Wed, 1 Jul 2026 08:50:36 +0200 Subject: [PATCH 08/10] impact(redesign): cards use THE FIELD / OUR HAND split + live signal Drop focus-area color coding (neutral icons). Card now shows a teal 'field' axis (meter + did it happen & matter) and a violet 'our hand' axis (role pills + did our work help), plus a LIVE SIGNAL block for points with live outputs. Modal recolored/reordered to A (our hand) / B, C (the field). --- src/components/ImpactDashboard.tsx | 132 ++++++++++++++++++----------- 1 file changed, 81 insertions(+), 51 deletions(-) diff --git a/src/components/ImpactDashboard.tsx b/src/components/ImpactDashboard.tsx index 965a20cf..9bf235d2 100644 --- a/src/components/ImpactDashboard.tsx +++ b/src/components/ImpactDashboard.tsx @@ -4,6 +4,8 @@ import { useEffect, useMemo, useState } from 'react' import { ROLE_META, PL_ROLE_ORDER, + FIELD_COLOR, + HAND_COLOR, FIELD_STAGES, FOCUS_AREAS, INFLECTION_POINTS, @@ -52,7 +54,6 @@ export default function ImpactDashboard({ liveOutputs = {} }: { liveOutputs?: Li label={fa.label} count={INFLECTION_POINTS.filter((p) => p.area === fa.key).length} icon={FA_ICON[fa.key]} - accent={fa.accent} active={filter === fa.key} onClick={() => setFilter(fa.key)} /> @@ -67,6 +68,7 @@ export default function ImpactDashboard({ liveOutputs = {} }: { liveOutputs?: Li setActive(p)} /> ))} @@ -92,14 +94,12 @@ function Tab({ count, active, icon, - accent, onClick, }: { label: string count: number active: boolean icon?: AreaIconType - accent?: string onClick: () => void }) { return ( @@ -116,7 +116,7 @@ function Tab({ > {icon && } @@ -126,14 +126,12 @@ function Tab({ ) } -/** Field-progress lifecycle meter (Q1 & Q2). Colored in the focus-area accent. */ +/** Field-progress lifecycle meter — the “field” axis (teal). */ function FieldMeter({ status, - accent, compact = false, }: { status: InflectionPoint['status'] - accent: string compact?: boolean }) { const reached = stageIndexForStatus(status) @@ -144,7 +142,7 @@ function FieldMeter({ ))}
@@ -167,11 +165,14 @@ function RoleChips({ roles, eyebrow = true }: { roles: PLRole[]; eyebrow?: boole return ( {eyebrow && ( - PL role + PL role )} {ordered.map((r) => ( - + {ROLE_META[r].label} void }) { const fa = FOCUS_AREAS.find((f) => f.key === point.area)! + const stageLabel = FIELD_STAGES[stageIndexForStatus(point.status)] return ( ) @@ -281,8 +312,7 @@ function InflectionModal({ onClick={onClose} >
e.stopPropagation()} > {/* Close */} @@ -300,7 +330,7 @@ function InflectionModal({
{/* Header */}
- + {fa.label} @@ -314,8 +344,8 @@ function InflectionModal({ {/* Field axis */}
- - Field progress + + The field
- +

- The field axis (Q1 & Q2) is tracked independently of PL’s contribution. It can - advance with little or no PL involvement. + The field (did it happen & matter) moves with or without us — it can advance with + little or no PL involvement. Our hand is the separate axis below.

- {/* Three questions — each tagged with the logic-model stage it maps to */} -
- {point.cascade} -
-
- {point.signal} -
-
+ {/* Our hand (A) + the field (B, C) */} +
@@ -349,10 +373,16 @@ function InflectionModal({ {point.contribution.outputs}

- Inputs → activities → outputs are PL’s planned work. The outcomes and impact they - aim at are tracked on the field axis above (Q2, then Q1). + Inputs → activities → outputs are the only axis we control. Whether they move the + field (above) is what we watch — and reason about honestly against the counterfactual.

+
+ {point.signal} +
+
+ {point.cascade} +
{/* Live evidence (Q3 only — never a Q2 reading) */} {point.liveEvidence && ( From 6baad8d9a9e7ff3bdf75ec77eaa84aa40f4ce086 Mon Sep 17 00:00:00 2001 From: Lukas Bresser Date: Wed, 1 Jul 2026 08:50:36 +0200 Subject: [PATCH 09/10] impact(redesign): measuring A/B/C cards + color-coded chain + toolkit section Measuring-impact section: color-code the logic-model chain by axis, dot legend (not tick-boxes), and three always-visible A/B/C question cards. Extract the six PL roles into a separate 'toolkit' section. --- src/app/impact/page.tsx | 96 +++++++++++----- src/components/MeasuringQuestions.tsx | 154 ++++++++------------------ 2 files changed, 117 insertions(+), 133 deletions(-) diff --git a/src/app/impact/page.tsx b/src/app/impact/page.tsx index ca1db74d..79c01143 100644 --- a/src/app/impact/page.tsx +++ b/src/app/impact/page.tsx @@ -5,7 +5,7 @@ import MeasuringQuestions from '@/components/MeasuringQuestions' import { fetchSimocracyStats } from '@/lib/simocracy' import { fetchGainforestStats } from '@/lib/gainforest' import { fetchGlowStats } from '@/lib/glow' -import { LOGIC_MODEL } from '@/lib/inflection-points' +import { LOGIC_MODEL, ROLE_META, PL_ROLE_ORDER, FIELD_COLOR, HAND_COLOR } from '@/lib/inflection-points' // Pull live output metrics for the Economies & Governance inflection points from // the same sources as the FA2 live dashboard. These are Q3 OUTPUTS (the work @@ -97,47 +97,89 @@ export default async function ImpactPage() {

Measuring impact

- Impact is the last link in a chain that runs from the work we plan to the results we - intend. Inputs and activities are our planned work; outcomes and impact are the change in - the world that follows. We only count something as impact when it is a durable shift in the - system — not just activity or output. + Every inflection point runs along one chain — from the work we plan to the change in the + world it aims at. We hold two axes apart and never collapse them into a single score:{' '} + our hand (the work + we control) and{' '} + the field (the + change that follows, with or without us).

-

- Each inflection point instantiates this chain. On its card, the Q3 detail tracks our - inputs, activities, and outputs; the field meter tracks the outcomes and impact they aim - at. -

- - {/* Logic-model chain — labels styled like the detail cards */} + {/* Logic-model chain — color-coded by axis */}
- {LOGIC_MODEL.map((stage, i) => ( -
-
- - {i + 1} - - - {stage.label} - + {LOGIC_MODEL.map((stage, i) => { + const color = i >= 3 ? FIELD_COLOR : HAND_COLOR + return ( +
+
+ + {i + 1} + + + {stage.label} + +
+

{stage.body}

-

{stage.body}

-
- ))} + ) + })}
← Our planned work - Our intended results → + The change in the world →
- {/* The three questions — pick one to read its detail */} + {/* Legend — dots, not tick-boxes */} +
+ + + Our planned work — within our control + + + + The field — moves with or without us + +
+ + {/* The three questions — always visible */}

For frontier research, the hard part is the right edge of that chain. So for every inflection point we ask three questions — different jobs that should not be collapsed into - one metric. Select one to read how we measure it. + one metric.

+ + {/* The toolkit — deep dive on the "our hand" roles */} +
+
+

+ Six roles, matched to the bottleneck each one releases +

+

+ Every card tags the roles PL played — this is the legend those tags point to, and it is + our account of how we create value: match the instrument to the bottleneck. A bet can be + reached with little or no PL involvement, which is still a win for the field, and we + record our role honestly. +

+
+ {PL_ROLE_ORDER.map((r) => ( +
+ + {ROLE_META[r].label} + +

{ROLE_META[r].description}

+
+ ))} +
+
+
) } diff --git a/src/components/MeasuringQuestions.tsx b/src/components/MeasuringQuestions.tsx index 9473babe..69e1899f 100644 --- a/src/components/MeasuringQuestions.tsx +++ b/src/components/MeasuringQuestions.tsx @@ -1,126 +1,68 @@ -'use client' +import { FIELD_COLOR, HAND_COLOR } from '@/lib/inflection-points' -import { useState } from 'react' -import { ROLE_META, PL_ROLE_ORDER, LOGIC_MODEL, type LogicStageKey } from '@/lib/inflection-points' - -const QUESTIONS: { - q: string +// Three questions, always visible. One is "our hand" (the only axis we control); +// two are "the field" (the change in the world, which moves with or without us). +const CARDS: { + key: string + color: string + eyebrow: string title: string - stages: LogicStageKey[] body: string + footLead: string + footRest: string }[] = [ { - q: 'Q1', - title: 'Did it matter?', - stages: ['impact'], - body: 'A signal is only worth naming if it unlocks something. We name the second-order effects in advance and watch whether they follow. A threshold that is reached but unlocks nothing is itself a finding.', + key: 'A', + color: HAND_COLOR, + eyebrow: 'Inputs · Activities · Outputs', + title: 'Did our work help?', + body: 'Which PL instruments were on the critical path, and would this have happened as fast, or at all, without us.', + footLead: 'Ours.', + footRest: 'The only axis we control.', }, { - q: 'Q2', + key: 'B', + color: FIELD_COLOR, + eyebrow: 'Outcomes', title: 'Did it happen?', - stages: ['outcomes'], - body: 'We pre-register one observable threshold and report a simple yes/no plus a date when it is reached. It is externally observable — measured the same way whether or not PL is involved.', + body: 'One pre-registered, externally observable threshold. A yes/no plus a date, measured the same way with or without PL.', + footLead: 'The field.', + footRest: 'Advances with or without us.', }, { - q: 'Q3', - title: 'Did our work make it happen?', - stages: ['inputs', 'activities', 'outputs'], - body: 'We trace contribution rather than claim credit: which PL instruments — open infrastructure, field-mapping, convenings, grants, ventures, or policy work — were on the critical path, and reason honestly about the counterfactual: would this have happened as fast, or at all, without us?', + key: 'C', + color: FIELD_COLOR, + eyebrow: 'Impact', + title: 'Did it matter?', + body: 'A threshold that unlocks nothing is itself a finding. We name the second-order effects in advance and watch.', + footLead: 'The field.', + footRest: 'The cascade the signal should trigger.', }, ] export default function MeasuringQuestions() { - const [active, setActive] = useState(0) - const item = QUESTIONS[active] - const stages = item.stages.map((k) => LOGIC_MODEL.find((s) => s.key === k)!) - return ( -
- {/* Vertical tabs */} -
- {QUESTIONS.map((qq, i) => { - const isActive = active === i - return ( - - ) - })} -
- - {/* Detail panel */} -
-
- Maps to logic model: {stages.map((s) => s.label).join(' · ')} -
-

{item.title}

-

{item.body}

- - {/* Logic-model stage(s) this question covers — same row style as the cards */} -
- {stages.map((s) => ( -
- - {s.label} - - {s.body} -
- ))} -
- - {active === 2 && ( -
-
- PL’s role on the critical path -
-

- Contribution sits on its own axis, separate from how far the field has moved — we never - collapse the two into a single score. A point can be reached with little or no PL - involvement; that is still a win for the field, and we record our role honestly. The - toolkit is plural by design, so each card tags one or more of these roles — the - instrument matched to the bottleneck it releases: -

-
- {PL_ROLE_ORDER.map((r) => ROLE_META[r]).map((c) => ( -
- - {c.label} - -

{c.description}

-
- ))} -
+ {c.key} + +

{c.title}

- )} -
+
+ {c.eyebrow} +
+

{c.body}

+

+ {c.footLead} {c.footRest} +

+
+ ))}
) } From 5f504f0ce9088d0d3ffcc3b2c828a46516f66986 Mon Sep 17 00:00:00 2001 From: Lukas Bresser Date: Wed, 1 Jul 2026 09:46:29 +0200 Subject: [PATCH 10/10] impact(redesign): review pass - Swap axis colors: field = purple, our hand = PL blue (#1982F4); teal removed - Live signal now a pulsing green dot; 'Live outputs' -> 'Live signal' - Cards: 'Detail' affordance (subtle top-right, not a full row); 'Methodology' removed - Detail modal: wider + two-column (our hand | the field) with full-width live signal; remove repeated status badge and the field explainer; 'the signal' -> 'the inflection point'; 'Did our work help?' -> 'Is our work making a difference?' - AI & Robotics empty state: 'inflection points' instead of 'pre-registered bets' --- src/components/ImpactDashboard.tsx | 140 ++++++++++++-------------- src/components/MeasuringQuestions.tsx | 2 +- src/lib/inflection-points.ts | 10 +- 3 files changed, 69 insertions(+), 83 deletions(-) diff --git a/src/components/ImpactDashboard.tsx b/src/components/ImpactDashboard.tsx index 9bf235d2..7b870b3b 100644 --- a/src/components/ImpactDashboard.tsx +++ b/src/components/ImpactDashboard.tsx @@ -6,10 +6,10 @@ import { PL_ROLE_ORDER, FIELD_COLOR, HAND_COLOR, + LIVE_COLOR, FIELD_STAGES, FOCUS_AREAS, INFLECTION_POINTS, - STATUS_META, stageIndexForStatus, type FocusAreaKey, type InflectionPoint, @@ -204,8 +204,16 @@ function InflectionCard({ type="button" onClick={onOpen} aria-haspopup="dialog" - className="group flex flex-col rounded-xl border border-gray-200 bg-white p-6 text-left transition-all hover:border-gray-300 hover:shadow-md" + className="group relative flex flex-col rounded-xl border border-gray-200 bg-white p-6 text-left transition-all hover:border-gray-300 hover:shadow-md" > + {/* Subtle detail affordance */} + + Detail + + + + + {/* Header: focus area (neutral — no per-area color) */}
@@ -238,7 +246,7 @@ function InflectionCard({ Our hand - · did our work help + · is our work making a difference
@@ -248,8 +256,8 @@ function InflectionCard({
- - + + Live signal
@@ -264,15 +272,6 @@ function InflectionCard({
)} - {/* Detail affordance — opens the per-point methodology modal */} -
- - Methodology - - - - -
) } @@ -287,7 +286,6 @@ function InflectionModal({ onClose: () => void }) { const fa = FOCUS_AREAS.find((f) => f.key === point.area)! - const status = STATUS_META[point.status] // Close on Escape, and lock body scroll while open. useEffect(() => { @@ -312,7 +310,7 @@ function InflectionModal({ onClick={onClose} >
e.stopPropagation()} > {/* Close */} @@ -341,48 +339,50 @@ function InflectionModal({ {point.title} - {/* Field axis */} + {/* Field progress — full width */}
-
- - The field - - - - {status.label} - +
+ Field progress
-

- The field (did it happen & matter) moves with or without us — it can advance with - little or no PL involvement. Our hand is the separate axis below. -

- {/* Our hand (A) + the field (B, C) */} -
-
- + {/* Two axes: our hand | the field */} +
+ {/* OUR HAND */} +
+
Our hand
+

Is our work making a difference? The only axis we control.

+
+ + Is our work making a difference? +
+
+
+ {point.contribution.inputs} + {point.contribution.activities} + {point.contribution.outputs} +
-
- {point.contribution.inputs} - {point.contribution.activities} - {point.contribution.outputs} + + {/* THE FIELD */} +
+
The field
+

Did it happen, did it matter. Moves with or without us.

+
+ + Did it happen? +
+
Outcome — the inflection point
+

{point.signal}

+
+ + Did it matter? +
+
Impact — the cascade
+

{point.cascade}

-

- Inputs → activities → outputs are the only axis we control. Whether they move the - field (above) is what we watch — and reason about honestly against the counterfactual. -

-
-
- {point.signal} -
-
- {point.cascade} -
+
{/* Live evidence (Q3 only — never a Q2 reading) */} {point.liveEvidence && ( @@ -391,12 +391,12 @@ function InflectionModal({ className="mt-5 block rounded-xl border border-gray-200 bg-white p-4 transition-colors hover:border-blue/40 no-underline" >
- Live outputs + Live signal
- - + + {point.liveEvidence.label} @@ -435,30 +435,14 @@ function LogicRow({ label, children }: { label: string; children: React.ReactNod ) } -function Section({ - q, - label, - accent, - children, -}: { - q: string - label: string - accent: string - children: React.ReactNode -}) { +function QBadge({ letter, color }: { letter: string; color: string }) { return ( -
-
- - {q} - - {label} -
-
{children}
-
+ + {letter} + ) } @@ -470,7 +454,7 @@ function EmptyState({ filter }: { filter: Filter }) { Inflection points for {fa?.label ?? 'this focus area'} are being defined.

- This focus area is still finalizing its plan of attack. Its pre-registered bets will appear + This focus area is still finalizing its plan of attack. Its inflection points will appear here once they are set.

diff --git a/src/components/MeasuringQuestions.tsx b/src/components/MeasuringQuestions.tsx index 69e1899f..e30126d3 100644 --- a/src/components/MeasuringQuestions.tsx +++ b/src/components/MeasuringQuestions.tsx @@ -15,7 +15,7 @@ const CARDS: { key: 'A', color: HAND_COLOR, eyebrow: 'Inputs · Activities · Outputs', - title: 'Did our work help?', + title: 'Is our work making a difference?', body: 'Which PL instruments were on the critical path, and would this have happened as fast, or at all, without us.', footLead: 'Ours.', footRest: 'The only axis we control.', diff --git a/src/lib/inflection-points.ts b/src/lib/inflection-points.ts index ff29fb60..9fe1c268 100644 --- a/src/lib/inflection-points.ts +++ b/src/lib/inflection-points.ts @@ -27,10 +27,12 @@ export type PLRole = 'infrastructure' | 'legibility' | 'connection' | 'capital' export const PL_ROLE_ORDER: PLRole[] = ['infrastructure', 'legibility', 'connection', 'capital', 'translation', 'permission'] // Two-axis color system used across the impact dashboard: -// FIELD = the change in the world (outcomes + impact) — moves with or without us -// HAND = our planned work / the PL toolkit — the only axis we control -export const FIELD_COLOR = '#12bfdf' -export const HAND_COLOR = '#7c5cf5' +// FIELD = the change in the world (outcomes + impact) — moves with or without us (purple) +// HAND = our planned work / the PL toolkit — the only axis we control (PL blue) +export const FIELD_COLOR = '#7c5cf5' +export const HAND_COLOR = '#1982F4' +/** Live-signal accent — the pulsing dot on points with live outputs (green). */ +export const LIVE_COLOR = '#22c55e' /** * Q3 contribution, structured along the planned-work side of the logic model.