diff --git a/lib/slideshows.ts b/lib/slideshows.ts
index 9aa3968..dfea92a 100644
--- a/lib/slideshows.ts
+++ b/lib/slideshows.ts
@@ -29,8 +29,10 @@ import { overhang2026LightningConfig } from "@/slideshows/overhang-2026-lightnin
import { blsTaxsim2026Config } from "@/slideshows/bls-taxsim-2026/config";
import { scottishGovernment2026Config } from "@/slideshows/scottish-government-2026/config";
import { goodGrowthFoundation2026Config } from "@/slideshows/good-growth-foundation-2026/config";
+import { autumnBudget2026Config } from "@/slideshows/autumn-budget-2026/config";
export const slideshows: SlideshowConfig[] = [
+ autumnBudget2026Config,
goodGrowthFoundation2026Config,
scottishGovernment2026Config,
blsTaxsim2026Config,
diff --git a/next.config.ts b/next.config.ts
index c66c230..71f0735 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -8,6 +8,16 @@ const nextConfig: NextConfig = {
env: {
NEXT_PUBLIC_BASE_PATH: '/slides',
},
+ // The Autumn Budget 2026 webinar deck was introduction-2026 until 28 October.
+ async redirects() {
+ return [
+ {
+ source: '/introduction-2026/:path*',
+ destination: '/autumn-budget-2026/:path*',
+ permanent: true,
+ },
+ ];
+ },
// Pin the workspace root so Turbopack does not silently pick up a stray
// lockfile from a parent directory during local development or CI.
turbopack: {
diff --git a/public/images/autumn-budget-2026/dashboard-qr.svg b/public/images/autumn-budget-2026/dashboard-qr.svg
new file mode 100644
index 0000000..7874146
--- /dev/null
+++ b/public/images/autumn-budget-2026/dashboard-qr.svg
@@ -0,0 +1 @@
+
diff --git a/public/logos/funders/nuffield-foundation-white.svg b/public/logos/funders/nuffield-foundation-white.svg
new file mode 100644
index 0000000..a53f698
--- /dev/null
+++ b/public/logos/funders/nuffield-foundation-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/logos/orgs/good-growth-foundation.png b/public/logos/orgs/good-growth-foundation.png
new file mode 100644
index 0000000..fdfec09
Binary files /dev/null and b/public/logos/orgs/good-growth-foundation.png differ
diff --git a/slideshows/autumn-budget-2026/README.md b/slideshows/autumn-budget-2026/README.md
new file mode 100644
index 0000000..d016199
--- /dev/null
+++ b/slideshows/autumn-budget-2026/README.md
@@ -0,0 +1,33 @@
+# Analysing the Autumn Budget 2026 with PolicyEngine
+
+5 slides at `/slides/autumn-budget-2026`, for the 28 October 2026 webinar
+(`/slides/introduction-2026` redirects here):
+what PolicyEngine is, how we prepared for Budget day, and a slide with the live
+[Autumn Budget 2026 dashboard](https://ab2026-local-preview.vercel.app/uk/autumn-budget-2026)
+embedded in it, where the analysis is presented. The closing slide links the
+same address, with its QR code, and credits the Nuffield Foundation, which
+funds our UK Budget analysis.
+
+- `config.ts` controls the slide order and metadata.
+- `content.ts` holds the sources, the three pillars of What PolicyEngine is,
+ the dates of the Budget-day rehearsals (the mock Budgets) and the
+ preparation items, written for a general audience.
+- `slides/index.tsx` contains the slides. The analysis slide embeds the
+ dashboard itself (`slides/DashboardEmbed.tsx`): Expand stretches the same
+ frame over the whole screen, so whatever is open in it is kept, and New tab
+ opens it in the browser. Buttons in its bar load the Public finances,
+ Pensioners (By age) and Living standards sub-tabs and the Household
+ calculator tab into the frame. The deck draws no charts of its own, so nothing
+ here goes stale when the dashboard's data change.
+- `SPEAKER-NOTES.md` gives the presenter track.
+
+`public/images/autumn-budget-2026/dashboard-qr.svg` encodes
+the dashboard's address.
+
+`public/logos/funders/nuffield-foundation-white.svg` is the Nuffield
+Foundation's white logo, downloaded from nuffieldfoundation.org on 22 October
+2026 (3,432 bytes, SHA-256
+`b3727385be9295f8daa3938c745f87b2e00e5675130354f6394ae6b3fec5654c`). That day
+its communications team asked for "funded" rather than "supported", and for
+its logo, the white version on a dark background. Keep the file as
+downloaded; don't recolour or redraw it.
diff --git a/slideshows/autumn-budget-2026/SPEAKER-NOTES.md b/slideshows/autumn-budget-2026/SPEAKER-NOTES.md
new file mode 100644
index 0000000..db82a2e
--- /dev/null
+++ b/slideshows/autumn-budget-2026/SPEAKER-NOTES.md
@@ -0,0 +1,70 @@
+# Speaker notes: Analysing the UK Autumn Budget 2026 with PolicyEngine
+
+## 1. Title
+
+Webinar, Wednesday 28 October 2026, 4:30pm UK time. Presenters: Vahid
+Ahmadi, Max Ghenis, María Juaristi.
+
+## 2. What PolicyEngine is
+
+A brief view: PolicyEngine in one line (a nonprofit building free,
+open-source tools, in policyengine.org's own words), then the rules, the
+households and the results, and that all the code is public.
+
+## 3. How we prepared
+
+The slide is for a general audience: the rehearsals and what they gave us.
+The detail below is background, if asked.
+
+- Last year's Budget (26 November 2025): the dashboard went live on Budget
+ day, and the other measures and the household calculator followed by 28
+ November (the 2025 dashboard repo's commit history).
+- Five Budget-day rehearsals, the mock Budgets (28 September; 5, 12, 19 and
+ 26 October): drill issues #6 (with the drill 1 retrospective), #8, #10, #53
+ and #144 in the dashboard repo.
+- The model and data: the policyengine package 6.11.1, with policyengine-uk
+ 2.151.0 and the Microcosm UK 2024-25 households. The live dashboard's
+ publication manifest records it for every measure and the package, and
+ main's uv.lock pins it (28 October).
+- National results run on Modal, one machine per measure: all ten units (nine
+ measures and the package) took 8.1 minutes on 26 October (dashboard PR
+ #178). The household calculator also runs on Modal and is kept warm.
+- Mark anything still in review as such on the slide before presenting.
+
+## 4. The analysis: live dashboard
+
+The dashboard itself is on the slide; it loads while slide 3 is showing.
+Press **Expand** to fill the screen with it and present from there. **Back to
+the slide** returns to the deck with the same tab, measures and household
+still open. **New tab** opens it in a browser tab, if the embedded copy ever
+misbehaves.
+
+While you are using the dashboard, the arrow keys, Space and a clicker go to
+it, not to the deck (the arrows switch its tabs). Press **Back to the slide**,
+or click the bar above the dashboard, before moving on.
+
+The buttons in the bar (Public finances, Pensioners, Living standards,
+Household calculator) load that view into the frame; each click reloads it,
+so measures or a household chosen in the frame are not kept. Its tabs:
+
+- **Population impact**, with five sub-tabs: **Public finances** (the
+ default: revenue by year and the OBR comparison), **All households** (the
+ constituency map and households by income), **By age** (the Pensioners
+ button opens it at pensioners), **Living standards** (income by decile and
+ inequality) and **Poverty**.
+- **Household calculator**: run one household live with Calculate, or pick
+ an example card.
+- **Pre-measures forecast**: the outlook before the Budget's measures, with
+ the OBR forecast named on the tab.
+- **Policies**: what each measure does.
+- **Methodology**.
+
+These are the tabs at ab2026-local-preview.vercel.app/uk/autumn-budget-2026
+on 28 October. The frame and the closing slide's link and QR code all open
+that address.
+
+## 5. Close
+
+The dashboard link, with a QR code for phones, and how to reach us. Thank
+the Nuffield Foundation, which funds our UK Budget analysis ("funded by",
+not "supported by").
diff --git a/slideshows/autumn-budget-2026/config.ts b/slideshows/autumn-budget-2026/config.ts
new file mode 100644
index 0000000..d0f3e01
--- /dev/null
+++ b/slideshows/autumn-budget-2026/config.ts
@@ -0,0 +1,26 @@
+import type { SlideshowConfig } from "@/lib/types";
+import {
+ ClosingSlide,
+ DashboardSlide,
+ PreparationSlide,
+ TitleSlide,
+ WhatSlide,
+} from "./slides";
+
+export const autumnBudget2026Config: SlideshowConfig = {
+ id: "autumn-budget-2026",
+ title: "Analysing the Autumn Budget 2026 with PolicyEngine",
+ description:
+ "What PolicyEngine is, how we prepared for Budget day, and the analysis, presented live on the dashboard.",
+ date: "2026-10-28",
+ location: "PolicyEngine",
+ // The slides keep this clear of the viewer's slide counter (deck.module.css).
+ footerText: "Autumn Budget 2026 webinar · 28 October 2026",
+ slides: [
+ TitleSlide,
+ WhatSlide,
+ PreparationSlide,
+ DashboardSlide,
+ ClosingSlide,
+ ],
+};
diff --git a/slideshows/autumn-budget-2026/content.ts b/slideshows/autumn-budget-2026/content.ts
new file mode 100644
index 0000000..de14782
--- /dev/null
+++ b/slideshows/autumn-budget-2026/content.ts
@@ -0,0 +1,144 @@
+// Content for the PolicyEngine and Autumn Budget 2026 deck.
+
+export type Source = { label: string; href: string };
+
+export const sources = {
+ home: { label: "policyengine.org", href: "https://www.policyengine.org/uk" },
+ model: {
+ label: "PolicyEngine UK code",
+ href: "https://github.com/PolicyEngine/policyengine-uk",
+ },
+ data: {
+ label: "Microcosm data pipeline",
+ href: "https://github.com/PolicyEngine/microcosm",
+ },
+ hansard: {
+ label: "Hansard, 24 February 2026",
+ href: "https://hansard.parliament.uk/Lords/2026-02-24/debates/A381F7D6-0A3C-48FD-8D9E-67751E25877A/NationalInsuranceContributions(EmployerPensionsContributions)Bill",
+ },
+ tpa: {
+ label: "Tax Policy Associates, September 2026",
+ href: "https://taxpolicy.org.uk/2026/09/10/universities-uk-national-insurance-proposal/",
+ },
+ cps: {
+ label: "Centre for Policy Studies, July 2023",
+ href: "https://cps.org.uk/research/family-friendly-taxation/",
+ },
+ nuffield: {
+ label: "Nuffield Foundation project",
+ href: "https://www.nuffieldfoundation.org/project/enhancing-localising-and-democratising-tax-benefit-policy-analysis",
+ },
+ nef: {
+ label: "New Economics Foundation, July 2026",
+ href: "https://neweconomics.org/2026/07/insecure-low-quality-work-a-major-driver-of-uks-neets-and-inactivity-crisis",
+ },
+ no10Post: {
+ label: "PolicyEngine at No 10",
+ href: "https://www.policyengine.org/uk/research/policyengine-10-downing-street",
+ },
+ // The dashboard the webinar presents, on the analysis slide and in the
+ // closing slide's link and QR code. The host alone returns 404.
+ dashboard: {
+ label: "Autumn Budget 2026 dashboard",
+ href: "https://ab2026-local-preview.vercel.app/uk/autumn-budget-2026",
+ },
+ dashboardCode: {
+ label: "Dashboard code",
+ href: "https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026",
+ },
+ dashboard2025Code: {
+ label: "2025 dashboard code",
+ href: "https://github.com/PolicyEngine/uk-autumn-budget-dashboard",
+ },
+};
+
+// How policyengine.org/uk/donate describes PolicyEngine.
+export const about =
+ "PolicyEngine is a nonprofit building free, open-source tools that help people understand tax and benefit policies.";
+
+// The Nuffield Foundation's credit. On 22 October its communications team
+// asked for "funded" rather than "supported", and for its logo, the white
+// version on a dark background. The logo is the white one from
+// nuffieldfoundation.org, kept as downloaded (3,432 bytes, SHA-256
+// b3727385…); its own size is 117.862 by 70.
+export const funder = {
+ label: "Funded by",
+ name: "Nuffield Foundation",
+ logo: "/logos/funders/nuffield-foundation-white.svg",
+ width: 118,
+ height: 70,
+};
+
+// What PolicyEngine is: the rules, the households and the results. The rules
+// are the main ones in the Good Growth Foundation deck's checked list.
+export const pillars = [
+ {
+ title: "Rules",
+ items: [
+ "Income tax and National Insurance",
+ "Universal Credit and other benefits",
+ "State Pension and Pension Credit",
+ "VAT, fuel duty and capital gains tax",
+ ],
+ },
+ {
+ title: "Households",
+ items: [
+ "Built from the Family Resources Survey",
+ "With HMRC tax records and other surveys",
+ "Weighted to match official statistics",
+ "Or enter any household yourself",
+ ],
+ },
+ {
+ title: "Results",
+ items: [
+ "Cost or saving to the Treasury",
+ "Who gains and loses, by income decile",
+ "Poverty and inequality",
+ "By region and constituency",
+ ],
+ },
+];
+
+// Last year's Budget, from the 2025 dashboard's commit history: the dashboard
+// went live on the day, and the other measures and the household calculator
+// followed by 28 November.
+export const lastBudget = {
+ title: "Autumn Budget 2025",
+ text: "Analysed on the day, 26 Nov",
+};
+
+// The five Budget-day rehearsals (the mock Budgets): full runs of the day on
+// invented measures.
+export const mockBudgets = ["28 Sep", "5 Oct", "12 Oct", "19 Oct", "26 Oct"];
+
+export type PrepItem = { title: string; text: string; status: "Done" | "In review" };
+
+// Written for a general audience: the technical detail is in the speaker
+// notes. Each line is checked against PolicyEngine/uk-autumn-budget-dashboard-2026;
+// the version is the one in the live dashboard's publication manifest and in
+// main's uv.lock on 28 October.
+export const preparation: PrepItem[] = [
+ {
+ title: "Fixed model and data",
+ text: "Every figure comes from PolicyEngine 6.11.1 and the same set of households, so anyone can reproduce it.",
+ status: "Done",
+ },
+ {
+ title: "A household calculator",
+ text: "Enter any household to see how the measures change its income, live on the dashboard.",
+ status: "Done",
+ },
+ {
+ title: "Every measure in about 8 minutes",
+ text: "The cost of each measure, and who gains and loses, worked out all at once rather than one by one.",
+ status: "Done",
+ },
+ {
+ title: "Each measure published once reviewed",
+ text: "A measure goes on the dashboard as soon as its figures have been checked.",
+ status: "In review",
+ },
+];
+
diff --git a/slideshows/autumn-budget-2026/funder.test.ts b/slideshows/autumn-budget-2026/funder.test.ts
new file mode 100644
index 0000000..d927e27
--- /dev/null
+++ b/slideshows/autumn-budget-2026/funder.test.ts
@@ -0,0 +1,31 @@
+import { createHash } from "node:crypto";
+import { readFileSync } from "node:fs";
+import path from "node:path";
+import { describe, expect, it } from "vitest";
+import { funder } from "./content";
+
+// The white logo as downloaded from nuffieldfoundation.org on 22 October. Keep
+// it byte for byte: don't recolour or redraw it.
+const DOWNLOADED_SHA256 =
+ "b3727385be9295f8daa3938c745f87b2e00e5675130354f6394ae6b3fec5654c";
+
+describe("the Nuffield Foundation credit on the closing slide", () => {
+ const file = path.join(__dirname, "../../public", funder.logo);
+ const bytes = readFileSync(file);
+
+ it("uses the logo exactly as downloaded", () => {
+ expect(bytes.length).toBe(3432);
+ expect(createHash("sha256").update(bytes).digest("hex")).toBe(DOWNLOADED_SHA256);
+ });
+
+ it("matches the logo's own dimensions", () => {
+ const svg = bytes.toString("utf8");
+ const size = (name: string) => Number(svg.match(new RegExp(`${name}="([\\d.]+)"`))?.[1]);
+ expect(Math.round(size("width"))).toBe(funder.width);
+ expect(Math.round(size("height"))).toBe(funder.height);
+ });
+
+ it('reads "Funded by"', () => {
+ expect(funder.label).toBe("Funded by");
+ });
+});
diff --git a/slideshows/autumn-budget-2026/slides/ClosingSlide.test.tsx b/slideshows/autumn-budget-2026/slides/ClosingSlide.test.tsx
new file mode 100644
index 0000000..a089e51
--- /dev/null
+++ b/slideshows/autumn-budget-2026/slides/ClosingSlide.test.tsx
@@ -0,0 +1,35 @@
+import { act } from "react";
+import { createRoot, type Root } from "react-dom/client";
+import { afterEach, beforeEach, describe, expect, it } from "vitest";
+import { funder, sources } from "../content";
+import { ClosingSlide } from "./index";
+
+let container: HTMLDivElement;
+let root: Root;
+
+beforeEach(async () => {
+ (globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
+ container = document.createElement("div");
+ document.body.appendChild(container);
+ root = createRoot(container);
+ await act(async () => root.render());
+});
+
+afterEach(() => {
+ act(() => root.unmount());
+ container.remove();
+});
+
+describe("the closing slide's funder credit", () => {
+ it('reads "Funded by" beside the Nuffield Foundation logo', () => {
+ const logo = container.querySelector(`img[alt="${funder.name}"]`);
+ expect(logo).not.toBeNull();
+ expect(decodeURIComponent(logo!.getAttribute("src") ?? "")).toContain(funder.logo);
+ expect(logo!.closest("a")?.textContent).toContain("Funded by");
+ });
+
+ it("links to the Nuffield Foundation's page for the project", () => {
+ const logo = container.querySelector(`img[alt="${funder.name}"]`);
+ expect(logo?.closest("a")?.getAttribute("href")).toBe(sources.nuffield.href);
+ });
+});
diff --git a/slideshows/autumn-budget-2026/slides/DashboardEmbed.tsx b/slideshows/autumn-budget-2026/slides/DashboardEmbed.tsx
new file mode 100644
index 0000000..5250d32
--- /dev/null
+++ b/slideshows/autumn-budget-2026/slides/DashboardEmbed.tsx
@@ -0,0 +1,84 @@
+"use client";
+
+import { useState } from "react";
+import {
+ IconArrowsMaximize,
+ IconArrowsMinimize,
+ IconExternalLink,
+} from "@tabler/icons-react";
+import styles from "./deck.module.css";
+
+/**
+ * The dashboard, live on the slide. Expand stretches the same frame over the
+ * whole screen, so the tab, measures and household it shows are kept when it
+ * goes back to the slide. Clicks in the frame go to the dashboard, and so do
+ * the arrow keys until the slide is clicked outside it. The view buttons in
+ * the bar load one of the dashboard's tabs or sub-tabs into the same frame.
+ */
+export type DashboardView = {
+ label: string;
+ /** The deep link's query string, such as "?tab=household". */
+ query: string;
+};
+
+export default function DashboardEmbed({
+ href,
+ title,
+ views = [],
+}: {
+ href: string;
+ title: string;
+ /** Buttons that open a tab or sub-tab in the frame. */
+ views?: DashboardView[];
+}) {
+ const [expanded, setExpanded] = useState(false);
+ const [src, setSrc] = useState(href);
+ // Bumped on every view button, so a second click on the same view reloads it.
+ const [load, setLoad] = useState(0);
+ const ToggleIcon = expanded ? IconArrowsMinimize : IconArrowsMaximize;
+
+ return (
+
+ );
+}
+
+// A content slide as in the BLS and CPID decks: the title and accent bar, an
+// optional note at the right of the title, then the body and its sources.
+function Frame({
+ title,
+ aside,
+ children,
+ references = [],
+}: {
+ title: string;
+ /** Short text on the title's line, at the right, such as an address. */
+ aside?: ReactNode;
+ children: ReactNode;
+ references?: Source[];
+}) {
+ return (
+
+
+
+
+ {title}
+ {aside && {aside}}
+
+
+
+ {children}
+ {references.length > 0 && }
+
+
+
+ );
+}
+
+export function TitleSlide() {
+ return (
+
+ );
+}
+
+// Each pillar's icon and band colour, in the order of `pillars`.
+const pillarLooks: { icon: Icon; color: string }[] = [
+ { icon: IconScale, color: "var(--pe-teal)" },
+ { icon: IconUsers, color: "var(--pe-teal-dark)" },
+ { icon: IconChartBar, color: "var(--pe-dark)" },
+];
+
+// The BLS and CPID decks' three-pillar slide, with the UK model's lists.
+export function WhatSlide() {
+ return (
+
+
+
+
+ All the code is public, so anyone can check how each number is
+ calculated.
+
+
+ );
+}
+
+// Each preparation item's icon, in the order of `preparation`.
+const prepIcons: Icon[] = [IconLock, IconCalculator, IconBolt, IconShieldCheck];
+
+export function PreparationSlide() {
+ return (
+
+
+
+ Last year's Budget, then five Budget-day rehearsals
+ Each one a full run of the day, on invented measures
+
+
+ );
+}
+
+// The dashboard's tabs and Population impact sub-tabs that the bar's buttons
+// open in the frame. Public finances is Population impact's default sub-tab.
+const dashboardViews = [
+ { label: "Public finances", query: "?tab=dashboard" },
+ { label: "Pensioners", query: "?tab=dashboard&sub=age&age=pensioners" },
+ { label: "Living standards", query: "?tab=dashboard&sub=living" },
+ { label: "Household calculator", query: "?tab=household" },
+];
+
+// The analysis is presented live, on the dashboard embedded in the slide, with
+// its address beside the title as on the CPID deck's live demo.
+export function DashboardSlide() {
+ return (
+
+
+
+ );
+}
+
+const contacts = [
+ { label: "policyengine.org/uk", url: sources.home.href, Icon: IconWorld },
+ { label: "hello@policyengine.org", url: "mailto:hello@policyengine.org", Icon: IconMail },
+ { label: "github.com/PolicyEngine", url: "https://github.com/PolicyEngine", Icon: IconBrandGithub },
+ {
+ label: "linkedin.com/company/thepolicyengine",
+ url: "https://www.linkedin.com/company/thepolicyengine",
+ Icon: IconBrandLinkedin,
+ },
+];
+
+export function ClosingSlide() {
+ return (
+
+
+
Thank you
+
+
+
+ Explore the dashboard
+ {/* The full address: the host alone does not serve the dashboard. */}
+
+ {sources.dashboard.href.replace("https://", "")}
+
+ Scan the code to open it on your phone
+
+
+
+
+ );
+}
diff --git a/slideshows/good-growth-foundation-2026/README.md b/slideshows/good-growth-foundation-2026/README.md
index 2e3767e..2042f61 100644
--- a/slideshows/good-growth-foundation-2026/README.md
+++ b/slideshows/good-growth-foundation-2026/README.md
@@ -15,7 +15,7 @@ PolicyEngine UK for the Good Growth Foundation, for a 20 to 30 minute slot.
10. Thank you, with the Autumn Budget webinar invitation and its registration QR code
Slides 2 and 9 come from the 9 October introduction deck
-(`introduction-2026`, policyengine-slides #77); slide 2 merges its "What
+(`introduction-2026`, since renamed `autumn-budget-2026`, policyengine-slides #77); slide 2 merges its "What
PolicyEngine is" and "How it works" slides. Slides 5 and 7 come from the
Scottish Government deck of the same day (`scottish-government-2026`), told
for the whole UK: the pipeline drops the Scotland-only stage, and the decile