diff --git a/scripts/sql/007_add_manifold_url.sql b/scripts/sql/007_add_manifold_url.sql
new file mode 100644
index 0000000..0b10fee
--- /dev/null
+++ b/scripts/sql/007_add_manifold_url.sql
@@ -0,0 +1,4 @@
+-- Add manifold_url column to research table for prediction market links
+ALTER TABLE research ADD COLUMN IF NOT EXISTS manifold_url TEXT;
+
+COMMENT ON COLUMN research.manifold_url IS 'Manifold Markets prediction market URL for this bill';
diff --git a/src/components/ManifoldBadge.jsx b/src/components/ManifoldBadge.jsx
new file mode 100644
index 0000000..6be2b65
--- /dev/null
+++ b/src/components/ManifoldBadge.jsx
@@ -0,0 +1,79 @@
+import { useState, useEffect } from "react";
+import { colors, typography, spacing } from "../designTokens";
+
+/**
+ * Displays a live prediction market probability badge from Manifold Markets.
+ * Fetches the current probability on mount and links to the market.
+ */
+export default function ManifoldBadge({ marketUrl }) {
+ const [prob, setProb] = useState(null);
+
+ useEffect(() => {
+ if (!marketUrl) return;
+
+ // Extract slug from URL: https://manifold.markets/User/slug -> slug
+ const slug = marketUrl.split("/").pop();
+ if (!slug) return;
+
+ fetch(`https://api.manifold.markets/v0/slug/${slug}`)
+ .then((r) => r.json())
+ .then((data) => {
+ if (data.probability != null) {
+ setProb(data.probability);
+ }
+ })
+ .catch(() => {});
+ }, [marketUrl]);
+
+ if (prob == null) return null;
+
+ const pct = Math.round(prob * 100);
+
+ return (
+ e.stopPropagation()}
+ title="Prediction market probability (Manifold Markets)"
+ style={{
+ display: "inline-flex",
+ alignItems: "center",
+ gap: spacing.xs,
+ padding: `2px ${spacing.sm}`,
+ borderRadius: spacing.radius.md,
+ backgroundColor: `${colors.primary[600]}12`,
+ border: `1px solid ${colors.primary[600]}30`,
+ color: colors.primary[700],
+ fontSize: typography.fontSize.xs,
+ fontWeight: typography.fontWeight.semibold,
+ fontFamily: typography.fontFamily.body,
+ textDecoration: "none",
+ flexShrink: 0,
+ transition: "background-color 0.15s ease",
+ }}
+ onMouseEnter={(e) =>
+ (e.currentTarget.style.backgroundColor = `${colors.primary[600]}25`)
+ }
+ onMouseLeave={(e) =>
+ (e.currentTarget.style.backgroundColor = `${colors.primary[600]}12`)
+ }
+ >
+
+ {pct}%
+
+ );
+}
diff --git a/src/components/StatePanel.jsx b/src/components/StatePanel.jsx
index 35ae81e..da0878c 100644
--- a/src/components/StatePanel.jsx
+++ b/src/components/StatePanel.jsx
@@ -3,6 +3,7 @@ import { stateData } from "../data/states";
import { useData } from "../context/DataContext";
import ResearchCard from "./ResearchCard";
import ReformAnalyzer from "./reform/ReformAnalyzer";
+import ManifoldBadge from "./ManifoldBadge";
import { colors, typography, spacing } from "../designTokens";
import { track } from "../lib/analytics";
import { BASE_PATH } from "../lib/basePath";
@@ -279,13 +280,18 @@ const StatePanel = memo(({ stateAbbr, onClose, initialBillId }) => {
{bill.bill}
+{bill.bill}
+ {bill.manifoldUrl && ( +