From 4c63e57ac6b03c864d472c6b5b14b314235bac1b Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 5 Aug 2026 14:10:55 +0000 Subject: [PATCH] Generalize pokes; drop citations from OG card MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rewrite pokes to name the sin itself, not our sample's exact numbers (a visitor didn't "start at 90" — they mis-set the baseline) - Remove the "cited:" line from the OG card; citations stay on the page Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01XPEvmMbac2fCvKXpQcovj8 --- src/content/sins/dual-axis-deception.md | 2 +- src/content/sins/pie-chart-overload.md | 2 +- src/content/sins/truncated-y-axis.md | 2 +- src/lib/og.ts | 15 +-------------- src/pages/og/[slug].png.ts | 1 - 5 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/content/sins/dual-axis-deception.md b/src/content/sins/dual-axis-deception.md index 95cb157..faa7e9c 100644 --- a/src/content/sins/dual-axis-deception.md +++ b/src/content/sins/dual-axis-deception.md @@ -1,7 +1,7 @@ --- title: "The Dual-Axis Deception" summary: "Two unrelated series on two independent axes, engineered to look correlated." -poke: "Two y-axes, tuned until the lines kiss. Congratulations — you can now make anything 'cause' anything." +poke: "Two y-axes, scaled until the lines overlap — and suddenly anything 'causes' anything." category: "False Relationships" severity: 5 tags: ["dual axis", "correlation", "line chart"] diff --git a/src/content/sins/pie-chart-overload.md b/src/content/sins/pie-chart-overload.md index 1378385..971c79e 100644 --- a/src/content/sins/pie-chart-overload.md +++ b/src/content/sins/pie-chart-overload.md @@ -1,7 +1,7 @@ --- title: "Pie Chart Overload" summary: "Eight near-identical slices no human eye can rank. A bar chart was right there." -poke: "Eight slices, three of them the same size. Nobody can read this. A bar chart could." +poke: "More slices than anyone can rank by eye. A bar chart was right there." category: "Chart-Type Abuse" severity: 3 tags: ["pie chart", "part-to-whole", "comparison"] diff --git a/src/content/sins/truncated-y-axis.md b/src/content/sins/truncated-y-axis.md index 7911e98..271610f 100644 --- a/src/content/sins/truncated-y-axis.md +++ b/src/content/sins/truncated-y-axis.md @@ -1,7 +1,7 @@ --- title: "The Truncated Y-Axis" summary: "Chopping the baseline off a bar chart to make small differences look enormous." -poke: "You started the y-axis at 90. That's not a bar chart — it's a magic trick." +poke: "Your bars don't start at zero. That's not a bar chart — it's a magic trick." category: "Misleading Scales" severity: 4 tags: ["bar chart", "axis", "exaggeration"] diff --git a/src/lib/og.ts b/src/lib/og.ts index 11381d5..0e26df0 100644 --- a/src/lib/og.ts +++ b/src/lib/og.ts @@ -5,7 +5,6 @@ import { html } from 'satori-html'; import { Resvg } from '@resvg/resvg-js'; import type { TopLevelSpec } from 'vega-lite'; import { renderChartSvg } from './renderChart'; -import { getReference } from './references'; // OpenGraph card generator. Runs only at build time. Composes a 1200×630 card // with satori (text → vector paths, so the raster step needs no fonts) and @@ -34,13 +33,6 @@ const fonts = [ const esc = (s: string) => s.replace(/&/g, '&').replace(//g, '>'); -/** Surname of the first author, for a compact "cited: Tufte, Cairo" line. */ -function shortAuthor(key: string): string { - const first = getReference(key).authors.split(/ & |,|;/)[0].trim(); - const parts = first.split(' '); - return parts[parts.length - 1]; -} - /** Render a chart spec to a PNG data URI at a fixed display height (2× for crispness). * Fixing height (not width) keeps tall vconcat charts from overflowing the card. */ async function chartImage(spec: TopLevelSpec, displayHeight: number) { @@ -79,13 +71,11 @@ export interface SinCard { severity: number; badSpec: TopLevelSpec; fixedSpec: TopLevelSpec; - citationKeys: string[]; } export async function renderSinCard(d: SinCard): Promise { const bad = await chartImage(d.badSpec, 250); const fixed = await chartImage(d.fixedSpec, 250); - const cited = d.citationKeys.slice(0, 3).map(shortAuthor).join(', '); const panel = (label: string, color: string, img: { uri: string; width: number; height: number }) => `
@@ -104,10 +94,7 @@ export async function renderSinCard(d: SinCard): Promise { ${panel('THE SIN', '#fa4d56', bad)} ${panel('THE FIX', '#42be65', fixed)}
-
-
${esc(d.category)}
-
${cited ? 'cited: ' + esc(cited) : ''}
-
+
${esc(d.category)}
`); } diff --git a/src/pages/og/[slug].png.ts b/src/pages/og/[slug].png.ts index 359fe8f..8ca543a 100644 --- a/src/pages/og/[slug].png.ts +++ b/src/pages/og/[slug].png.ts @@ -16,7 +16,6 @@ export const GET: APIRoute = async ({ props }) => { severity: sin.data.severity, badSpec: getChartSpec(sin.data.badChart), fixedSpec: getChartSpec(sin.data.fixedChart), - citationKeys: sin.data.citations.map((c) => c.key), }); return new Response(new Uint8Array(png), { headers: { 'Content-Type': 'image/png', 'Cache-Control': 'public, max-age=31536000, immutable' },