mirror of
https://github.com/olehomelchenko/chart-sins.git
synced 2026-08-08 02:22:43 +00:00
e0d3f9f773
Make each sin a self-contained page you send instead of re-explaining: - Per-sin "poke" one-liner (the shareable callout) - Citations system: a canonical bibliography (src/lib/references.ts) of the field's giants — Munzner, Knaflic, Tufte, Cairo, Few, Cleveland & McGill, Wilke, Healy, Calling Bullshit, data-to-viz, Junk Charts, Spurious Correlations, FT Visual Vocabulary — cited per sin with a relevance note - "Don't take our word for it" receipts block on each sin - /canon page: the full annotated bibliography - Share control: copy-link "send them the receipt" (progressive enhancement) - Restructured sin page: poke -> proof -> why -> receipts -> share - Header nav (Sins / Canon); homepage reframed to the "send the link" mission Also fix the truncated-axis bad chart: clamp the [90,100] domain so the bar baseline doesn't overflow thousands of pixels off-canvas. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XPEvmMbac2fCvKXpQcovj8
36 lines
1.5 KiB
TypeScript
36 lines
1.5 KiB
TypeScript
import { defineCollection, z } from 'astro:content';
|
|
import { glob } from 'astro/loaders';
|
|
|
|
// Each "sin" is one Markdown/MDX file in src/content/sins/.
|
|
// Charts are authored as Vega-Lite JSON specs in src/charts/ and referenced
|
|
// here by their basename (without the .json extension). The page template
|
|
// renders `badChart` and `fixedChart` side by side automatically.
|
|
const sins = defineCollection({
|
|
loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/sins' }),
|
|
schema: z.object({
|
|
title: z.string(),
|
|
// Short one-line summary shown on the index gallery.
|
|
summary: z.string(),
|
|
// The cheeky one-line callout — the thing you send the sinner.
|
|
poke: z.string(),
|
|
// Citations into the canon (src/lib/references.ts) with a per-sin note on
|
|
// why that source is relevant. This is the "don't take our word for it".
|
|
citations: z
|
|
.array(z.object({ key: z.string(), note: z.string().optional() }))
|
|
.default([]),
|
|
// Grouping, e.g. "Misleading Scales", "Chart-Type Abuse".
|
|
category: z.string(),
|
|
// 1 (venial) … 5 (mortal). Drives the flame rating in the UI.
|
|
severity: z.number().int().min(1).max(5),
|
|
tags: z.array(z.string()).default([]),
|
|
// Basenames of Vega-Lite specs in src/charts/ (without .json).
|
|
badChart: z.string(),
|
|
fixedChart: z.string(),
|
|
// Optional publish date; unset entries sort last.
|
|
date: z.coerce.date().optional(),
|
|
draft: z.boolean().default(false),
|
|
}),
|
|
});
|
|
|
|
export const collections = { sins };
|