mirror of
https://github.com/olehomelchenko/chart-sins.git
synced 2026-08-08 02:22:43 +00:00
Reframe the reference list; cite far more widely
"Canon" was leaking onto the public site — a nav item, a footer block, a page title, a set of CSS class names. It was also driving content decisions it had no business driving: the backlog was ordered around which references were still unused, which is curation dressed up as planning. The page is now /references/, the list is documented as a bibliography to grow rather than a canon to curate, and the backlog says plainly that a sin earns a slot by being worth a page — sources are found to support it, never the reverse. Adds six sources (Cairo's Truthful Art, Few's Show Me the Numbers, the Economist's audit of its own charts, Kosara's eagereyes, WTF Visualizations, Datawrapper's dual-axis piece) and roughly doubles the citations on the five published sins, to 5-7 each. Two of the new notes point at sources that complicate our own position rather than back it. The Economist essay ships without a URL rather than a guessed one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ULE5RRxdQE1ebwefEd2eCM
This commit is contained in:
@@ -31,14 +31,25 @@ Each sin page follows one shape: **poke → proof → why → the fix → receip
|
||||
(e.g. the dual-axis "sin" deliberately breaks the one-axis rule; its fix uses
|
||||
separate honest panels.) When picking chart colors or building a new chart,
|
||||
run the `dataviz` skill and validate the palette with its validator.
|
||||
- **Citations are core.** Every sin cites the canon (`src/lib/references.ts`)
|
||||
under "Don't take our word for it." Don't invent authority — point at it.
|
||||
- **Citations are core, and generous.** Every sin cites sources
|
||||
(`src/lib/references.ts`) under "Don't take our word for it." Don't invent
|
||||
authority — point at it, and point at as much of it as you honestly can.
|
||||
Five-ish sources per sin is normal; a reader who distrusts one author should
|
||||
find another in the list they don't. Adding a new reference is routine, not an
|
||||
editorial event — the file is a bibliography to grow, **not a canon to
|
||||
curate**, and coverage of it is not a goal in itself.
|
||||
Never stretch a source to fit: if it doesn't actually make the claim, cite one
|
||||
that does or leave it out. Getting an attribution wrong costs more than a
|
||||
thinner page. A source that *complicates* our position (Kosara on pie charts,
|
||||
Datawrapper's second thoughts on dual axes) is worth citing too — say so in
|
||||
the note.
|
||||
- **Internal build decisions stay out of visitor-facing content and the DOM.**
|
||||
The design system (Carbon), the typeface (IBM Plex), and the inspiration
|
||||
(nohello.net) are engineering choices — they must not appear in page copy,
|
||||
the footer, meta tags, or CSS class names on the public site. (They were
|
||||
scrubbed once already; keep them out.) Naming them *here*, in repo docs, is
|
||||
fine.
|
||||
fine. **"Canon" is on that list too** — it's our internal shorthand for the
|
||||
reference list; the site says "References" and links to `/references/`.
|
||||
|
||||
## Adding a sin
|
||||
|
||||
|
||||
+41
-30
@@ -1,9 +1,12 @@
|
||||
# Content backlog — what to write next
|
||||
|
||||
Working document. The rule that generated this list: **every sin must be
|
||||
condemned by something already in the canon** (`src/lib/references.ts`). We
|
||||
don't invent authority, so the backlog is mined *from* the sources rather than
|
||||
brainstormed and back-filled with citations.
|
||||
Working document. Ranked by what is worth writing — the sins people actually
|
||||
commit, and the pages most worth sending someone.
|
||||
|
||||
Sourcing is a constraint on that list, not the thing that generates it: a sin
|
||||
earns a slot because it's worth a page, and then we go find the sources that
|
||||
make the case. Never the reverse. What we don't do is invent authority, or
|
||||
stretch a source into saying something it doesn't.
|
||||
|
||||
The list deliberately mixes registers. Some sins are subtle enough that a
|
||||
competent analyst commits them by accident; others are arithmetically void and
|
||||
@@ -12,33 +15,43 @@ pages we can write, because there's nothing to argue about, and the subtle ones
|
||||
are what keep the site useful to people who already know the basics. Severity
|
||||
runs 2–5 on purpose.
|
||||
|
||||
## Canon coverage
|
||||
## Sources in play
|
||||
|
||||
Which references are doing work, after the first five sins:
|
||||
`src/lib/references.ts` currently holds 22 entries, 18 of them cited by the five
|
||||
published sins. This table is a **convenience, not a scoreboard** — it's here so
|
||||
you can spot a source that fits a sin you're drafting, not so we can drive the
|
||||
right-hand column to zero blanks. An uncited reference is not a debt.
|
||||
|
||||
Adding new references is the normal way to strengthen a page. If a sin deserves
|
||||
seven sources, give it seven and add whatever's missing to the file.
|
||||
|
||||
| Reference | Cited by |
|
||||
| --- | --- |
|
||||
| `callingbullshit` | truncated-y-axis, inverted-y-axis |
|
||||
| `clevelandmcgill` | truncated-y-axis, too-many-pie-slices, aspect-ratio |
|
||||
| `munzner` | — |
|
||||
| `healy` | — |
|
||||
| `schwabish` | — |
|
||||
| `ftvisvocab` | — |
|
||||
| `tufte` | truncated-y-axis |
|
||||
| `howchartslie` | truncated-y-axis, two-y-axes, inverted-y-axis, aspect-ratio |
|
||||
| `datatoviz` | two-y-axes, too-many-pie-slices |
|
||||
| `spurious` | two-y-axes |
|
||||
| `huff` | truncated-y-axis |
|
||||
| `swd` | two-y-axes |
|
||||
| `spurious` | two-y-axes |
|
||||
| `datawrapper` | two-y-axes |
|
||||
| `fewpies` | too-many-pie-slices |
|
||||
| `junkcharts` | too-many-pie-slices, inverted-y-axis |
|
||||
| `showmenumbers` | too-many-pie-slices |
|
||||
| `shapeparameter` | aspect-ratio |
|
||||
| **`munzner`** | — |
|
||||
| **`wilke`** | — |
|
||||
| **`healy`** | — |
|
||||
| **`huff`** | — |
|
||||
| **`schwabish`** | — |
|
||||
| **`ftvisvocab`** | — |
|
||||
| **`datawrapper`** | — |
|
||||
| `vizwtf` | inverted-y-axis |
|
||||
| `wilke` | too-many-pie-slices, truncated-y-axis |
|
||||
| `truthfulart` | aspect-ratio, two-y-axes |
|
||||
| `callingbullshit` | inverted-y-axis, truncated-y-axis |
|
||||
| `economistmistakes` | inverted-y-axis, truncated-y-axis |
|
||||
| `datatoviz` | too-many-pie-slices, two-y-axes |
|
||||
| `junkcharts` | inverted-y-axis, too-many-pie-slices |
|
||||
| `eagereyes` | aspect-ratio, too-many-pie-slices |
|
||||
| `clevelandmcgill` | aspect-ratio, too-many-pie-slices, truncated-y-axis |
|
||||
| `howchartslie` | aspect-ratio, inverted-y-axis, truncated-y-axis, two-y-axes |
|
||||
|
||||
Seven idle references. Each is an authority we've already endorsed on the canon
|
||||
page, so a sin that leans on one is cheap to justify and strengthens the page it
|
||||
sits on. The backlog is ordered to bring them all in.
|
||||
The citation lists in each entry below are **starting points, not budgets** —
|
||||
add to them while drafting.
|
||||
|
||||
## Ranked backlog
|
||||
|
||||
@@ -108,8 +121,7 @@ or it is nothing), `schwabish`, `ftvisvocab`.
|
||||
|
||||
The bar-of-means: every group collapsed to one number, so wildly different
|
||||
distributions draw identical bars. Wilke devotes a section to exactly this and
|
||||
Healy makes the perceptual case; it's the natural home for three idle references
|
||||
at once.
|
||||
Healy makes the perceptual case.
|
||||
|
||||
**Charts:** bad = grouped bar of means. Fixed = strip/box plot over the same
|
||||
observations, means still marked.
|
||||
@@ -122,9 +134,8 @@ observations, means still marked.
|
||||
|
||||
Scaling a circle's *radius* by the value instead of its *area* squares the
|
||||
apparent difference. This is Tufte's Lie Factor with an actual number attached,
|
||||
and it's the cleanest possible excuse to bring Munzner's channel ranking onto a
|
||||
page — the same ranking that already underwrites the pie and truncated-axis
|
||||
sins.
|
||||
and Munzner's channel ranking — already underwriting the pie and truncated-axis
|
||||
sins — applies directly.
|
||||
|
||||
**Charts:** bad = radius ∝ value (a `calculate` transform squaring the size
|
||||
encoding). Fixed = area ∝ value, or better, the same values as a dot plot where
|
||||
@@ -160,7 +171,7 @@ region starts with A."
|
||||
|
||||
Venial, universal, and the single most useful page to fire at a colleague —
|
||||
which is the whole product thesis. Low severity is a feature: the gallery needs
|
||||
a range, and this one brings in the FT Visual Vocabulary.
|
||||
a range.
|
||||
|
||||
**Charts:** bad = categorical bars in alphabetical order. Fixed = same bars
|
||||
sorted by value.
|
||||
@@ -179,8 +190,8 @@ rediscovering them:
|
||||
TopoJSON geometry and a build-time data dependency we don't have yet. Strong
|
||||
candidate the moment we take that on.
|
||||
- **Rainbow color scales for continuous data** (Wilke, Munzner, and Datawrapper's
|
||||
four-part color-scale series — the best free treatment of this anywhere) — the
|
||||
canon backing is no longer the constraint. What still blocks it is ours: the
|
||||
four-part color-scale series — the best free treatment of this anywhere) —
|
||||
sourcing is not the constraint. What still blocks it is ours: the
|
||||
fixed chart needs a sequential ramp validated on `--chart-canvas` in both
|
||||
themes. Do the palette work first (`dataviz` skill + its validator), then this
|
||||
is ready to write.
|
||||
|
||||
@@ -12,7 +12,7 @@ const resolved = citations.map((c) => ({ ...c, ref: getReference(c.key) }));
|
||||
resolved.length > 0 && (
|
||||
<section class="receipts" aria-labelledby="receipts-h">
|
||||
<h2 id="receipts-h" class="receipts__title">Don’t take our word for it</h2>
|
||||
<p class="receipts__lede">The giants who say the same thing, so you don’t have to argue:</p>
|
||||
<p class="receipts__lede">Other people already made this case, in print, so you don’t have to:</p>
|
||||
<ol class="receipts__list">
|
||||
{resolved.map(({ ref, note }) => (
|
||||
<li class="receipt">
|
||||
|
||||
@@ -13,8 +13,9 @@ const sins = defineCollection({
|
||||
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 into the reference list (src/lib/references.ts) with a per-sin
|
||||
// note on why that source is relevant. Cite generously — this is the
|
||||
// "don't take our word for it", and more sources is a stronger page.
|
||||
citations: z
|
||||
.array(z.object({ key: z.string(), note: z.string().optional() }))
|
||||
.default([]),
|
||||
|
||||
@@ -15,6 +15,10 @@ citations:
|
||||
note: "Slope is one of the elementary perceptual tasks they ranked — and it's the one the shape of the box distorts."
|
||||
- key: howchartslie
|
||||
note: "Cairo on proportions as a storytelling lever, not a neutral container."
|
||||
- key: eagereyes
|
||||
note: "Kosara’s write-up of banking to 45° — including the caveat that the rule was derived for comparing slopes, not as a universal law."
|
||||
- key: truthfulart
|
||||
note: "The positive version of the argument: choosing a shape deliberately is part of drawing an honest chart."
|
||||
---
|
||||
|
||||
## The sin
|
||||
|
||||
@@ -15,6 +15,10 @@ citations:
|
||||
note: "Cairo's case that readers absorb a chart's shape long before they audit its axis."
|
||||
- key: junkcharts
|
||||
note: "Fung has redrawn this exact trick more than once — the fix is always just turning the axis back over."
|
||||
- key: economistmistakes
|
||||
note: "A newsroom reopening its own misleading charts, which is the rarest and most useful kind of correction."
|
||||
- key: vizwtf
|
||||
note: "Where the wild-caught specimens live, if you want proof this ships to real readers."
|
||||
---
|
||||
|
||||
## The sin
|
||||
|
||||
@@ -17,6 +17,12 @@ citations:
|
||||
note: "Kaiser Fung’s running #onelesspie campaign exists for precisely this chart."
|
||||
- key: datatoviz
|
||||
note: "Pie charts are the first entry in its catalogue of caveats."
|
||||
- key: wilke
|
||||
note: "His chapter on proportions puts the same data in a pie, a stacked bar and side-by-side bars, so you can see what each one costs you."
|
||||
- key: eagereyes
|
||||
note: "Kosara has actually run the experiments, and complicates the blanket condemnation — read him before swearing off pies entirely."
|
||||
- key: showmenumbers
|
||||
note: "Few’s full design manual, for when the short broadside isn’t enough to win the argument."
|
||||
---
|
||||
|
||||
## The sin
|
||||
|
||||
@@ -10,7 +10,13 @@ fixedChart: "truncated-axis-fixed"
|
||||
date: 2026-08-05
|
||||
citations:
|
||||
- key: callingbullshit
|
||||
note: "Their “Misleading Axes” module is the canonical explainer for exactly this move."
|
||||
note: "Their “Misleading Axes” module is the standard explainer for exactly this move."
|
||||
- key: huff
|
||||
note: "Huff named it the “gee-whiz graph” in 1954. Seventy years on, nothing about it is new."
|
||||
- key: wilke
|
||||
note: "His chapter on visualizing amounts is blunt: a bar's length is the value, so the scale must begin at zero."
|
||||
- key: economistmistakes
|
||||
note: "The Economist reopening its own charts — several of the mistakes it owns up to are this one."
|
||||
- key: clevelandmcgill
|
||||
note: "The perception research: readers compare bar length, so length must map to value from zero."
|
||||
- key: tufte
|
||||
|
||||
@@ -17,6 +17,10 @@ citations:
|
||||
note: "Cairo on how aligned axes manufacture relationships that aren’t there."
|
||||
- key: swd
|
||||
note: "Knaflic’s standing advice: avoid the second axis; separate or index instead."
|
||||
- key: datawrapper
|
||||
note: "“Why not to use two axes, and what to use instead” walks through why the two scales' proportions are arbitrary — and they've since published second thoughts, which is worth reading too."
|
||||
- key: truthfulart
|
||||
note: "Cairo on what a chart owes its reader, which is the standard this one fails."
|
||||
---
|
||||
|
||||
## The sin
|
||||
|
||||
@@ -55,7 +55,7 @@ const image = Astro.props.image ?? new URL(href('og/default.png'), Astro.site).t
|
||||
</a>
|
||||
<nav class="site-header__nav" aria-label="Primary">
|
||||
<a href={href()}>Sins</a>
|
||||
<a href={href('canon/')}>Canon</a>
|
||||
<a href={href('references/')}>References</a>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
@@ -75,8 +75,8 @@ const image = Astro.props.image ?? new URL(href('og/default.png'), Astro.site).t
|
||||
<p>Every sin has a permanent link and cites its sources — made to share, not to re-explain.</p>
|
||||
</div>
|
||||
<div class="site-footer__col">
|
||||
<strong>The canon</strong>
|
||||
<p>Each entry stands on the shoulders of the field's giants. <a href={href('canon/')}>See the sources →</a></p>
|
||||
<strong>References</strong>
|
||||
<p>Nothing here is our own opinion dressed up as fact. <a href={href('references/')}>See every source →</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
+57
-6
@@ -1,8 +1,14 @@
|
||||
// The Canon — the shoulders of giants Chart Sins stands on.
|
||||
// References — every source cited anywhere on the site.
|
||||
//
|
||||
// Each sin cites into this list by key, so a page can say "don't take our word
|
||||
// for it" and point at the authority that actually condemns the practice.
|
||||
// Add a reference once here; cite it from any number of sins.
|
||||
// for it" and point at someone who already made the argument. Add a reference
|
||||
// once here; cite it from any number of sins.
|
||||
//
|
||||
// This is a bibliography, not a curated canon. There is no cap and no bar to
|
||||
// clear beyond being real, relevant, and described accurately — so when a sin
|
||||
// could cite five sources, cite five. Breadth is the point: a reader who
|
||||
// bounces off one author should find another in the same list they already
|
||||
// trust. Adding an entry is routine, not an editorial event.
|
||||
|
||||
export type RefKind = 'book' | 'site' | 'paper';
|
||||
|
||||
@@ -14,7 +20,7 @@ export interface Reference {
|
||||
year?: number;
|
||||
url?: string;
|
||||
kind: RefKind;
|
||||
/** One line on why it belongs in the canon. */
|
||||
/** One line on what this source is good for. */
|
||||
blurb: string;
|
||||
/** True for the free-to-read-online works, surfaced as a hint. */
|
||||
free?: boolean;
|
||||
@@ -49,6 +55,24 @@ export const REFERENCES = {
|
||||
kind: 'book',
|
||||
blurb: 'Origin of the “Lie Factor,” chartjunk, and the data-ink ratio.',
|
||||
},
|
||||
truthfulart: {
|
||||
authors: 'Alberto Cairo',
|
||||
title: 'The Truthful Art',
|
||||
work: 'New Riders',
|
||||
year: 2016,
|
||||
url: 'http://www.thefunctionalart.com/',
|
||||
kind: 'book',
|
||||
blurb: 'The companion argument to How Charts Lie: what a chart owes the reader, rather than only how charts betray them.',
|
||||
},
|
||||
showmenumbers: {
|
||||
authors: 'Stephen Few',
|
||||
title: 'Show Me the Numbers',
|
||||
work: 'Analytics Press (2nd ed.)',
|
||||
year: 2012,
|
||||
url: 'https://www.perceptualedge.com/',
|
||||
kind: 'book',
|
||||
blurb: 'The full table-and-graph design manual behind Few’s shorter broadsides.',
|
||||
},
|
||||
howchartslie: {
|
||||
authors: 'Alberto Cairo',
|
||||
title: 'How Charts Lie',
|
||||
@@ -133,6 +157,15 @@ export const REFERENCES = {
|
||||
blurb: 'A modern, chart-by-chart guide to which form fits which job.',
|
||||
},
|
||||
|
||||
economistmistakes: {
|
||||
authors: 'Sarah Leo',
|
||||
title: 'Mistakes, we’ve drawn a few',
|
||||
work: 'The Economist',
|
||||
year: 2019,
|
||||
kind: 'paper',
|
||||
blurb: 'A newsroom publicly reopening its own misleading charts and redrawing them — the rare correction written by the people who made the error.',
|
||||
},
|
||||
|
||||
// --- sites ---
|
||||
datatoviz: {
|
||||
authors: 'Yan Holtz & Conor Healy',
|
||||
@@ -170,6 +203,24 @@ export const REFERENCES = {
|
||||
blurb: 'Thousands of nonsense correlations — the canonical proof that “they move together” proves nothing.',
|
||||
free: true,
|
||||
},
|
||||
eagereyes: {
|
||||
authors: 'Robert Kosara',
|
||||
title: 'eagereyes',
|
||||
work: 'eagereyes.org',
|
||||
url: 'https://eagereyes.org/',
|
||||
kind: 'site',
|
||||
blurb: 'A researcher translating visualization studies into plain English — and often complicating the received wisdom rather than repeating it.',
|
||||
free: true,
|
||||
},
|
||||
vizwtf: {
|
||||
authors: 'WTF Visualizations',
|
||||
title: 'WTF Visualizations',
|
||||
work: 'viz.wtf',
|
||||
url: 'https://viz.wtf/',
|
||||
kind: 'site',
|
||||
blurb: 'A running gallery of real charts that went wrong in the wild — proof these mistakes ship.',
|
||||
free: true,
|
||||
},
|
||||
ftvisvocab: {
|
||||
authors: 'Financial Times Visual Journalism',
|
||||
title: 'Visual Vocabulary',
|
||||
@@ -183,12 +234,12 @@ export const REFERENCES = {
|
||||
|
||||
export type ReferenceKey = keyof typeof REFERENCES;
|
||||
|
||||
/** Resolve a citation key; throws at build time if it isn't in the canon. */
|
||||
/** Resolve a citation key; throws at build time if it isn't in the list. */
|
||||
export function getReference(key: string): Reference {
|
||||
const ref = (REFERENCES as Record<string, Reference>)[key];
|
||||
if (!ref) {
|
||||
throw new Error(
|
||||
`Reference "${key}" is not in the canon (src/lib/references.ts). Known: ${Object.keys(REFERENCES).join(', ')}`,
|
||||
`Reference "${key}" is not in src/lib/references.ts. Known: ${Object.keys(REFERENCES).join(', ')}`,
|
||||
);
|
||||
}
|
||||
return ref;
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
import { REFERENCES, citeLabel, type RefKind } from '../lib/references';
|
||||
|
||||
const groups: { kind: RefKind; heading: string; blurb: string }[] = [
|
||||
{ kind: 'book', heading: 'The books', blurb: 'The shelf every chart argument can lean on.' },
|
||||
{ kind: 'paper', heading: 'The papers & essays', blurb: 'The primary sources — where the evidence actually lives.' },
|
||||
{ kind: 'site', heading: 'The sites', blurb: 'Living references you can link straight into a thread.' },
|
||||
];
|
||||
|
||||
const byKind = (kind: RefKind) => Object.values(REFERENCES).filter((r) => r.kind === kind);
|
||||
---
|
||||
|
||||
<BaseLayout title="The Canon — Chart Sins" description="The books, papers, and sites Chart Sins stands on.">
|
||||
<section class="wrap hero">
|
||||
<p class="hero__eyebrow">// the shoulders we stand on</p>
|
||||
<h1 class="expressive-display">The Canon</h1>
|
||||
<p class="hero__lede">
|
||||
Every sin here cites its sources. This is the whole shelf in one place —
|
||||
the giants of data visualization who already made the case, so you can
|
||||
link the receipt instead of relitigating it.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div class="wrap canon">
|
||||
{
|
||||
groups.map((g) => (
|
||||
<section class="canon__group">
|
||||
<h2 class="canon__heading productive-heading-03">{g.heading}</h2>
|
||||
<p class="helper">{g.blurb}</p>
|
||||
<ul class="canon__list">
|
||||
{byKind(g.kind).map((ref) => (
|
||||
<li class="canon__item">
|
||||
<div class="canon__cite">
|
||||
{ref.url ? (
|
||||
<a href={ref.url} rel="noopener" class="canon__work">{citeLabel(ref)}</a>
|
||||
) : (
|
||||
<span class="canon__work">{citeLabel(ref)}</span>
|
||||
)}
|
||||
{ref.work && <span class="canon__pub">{ref.work}</span>}
|
||||
{ref.free && <span class="receipt__free">free online</span>}
|
||||
</div>
|
||||
<p class="canon__blurb">{ref.blurb}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
import { REFERENCES, citeLabel, type RefKind } from '../lib/references';
|
||||
|
||||
const groups: { kind: RefKind; heading: string; blurb: string }[] = [
|
||||
{ kind: 'book', heading: 'Books', blurb: 'Book-length treatments, for when you need the whole argument.' },
|
||||
{ kind: 'paper', heading: 'Papers & essays', blurb: 'Where the evidence actually lives — experiments, and practitioners marking their own homework.' },
|
||||
{ kind: 'site', heading: 'Sites', blurb: 'Living references you can link straight into a thread.' },
|
||||
];
|
||||
|
||||
const byKind = (kind: RefKind) => Object.values(REFERENCES).filter((r) => r.kind === kind);
|
||||
---
|
||||
|
||||
<BaseLayout title="References — Chart Sins" description="The books, papers, and sites cited across Chart Sins.">
|
||||
<section class="wrap hero">
|
||||
<p class="hero__eyebrow">// everything we cite</p>
|
||||
<h1 class="expressive-display">References</h1>
|
||||
<p class="hero__lede">
|
||||
Every sin here cites its sources, and this is all of them in one place.
|
||||
None of these arguments are ours — they were made, tested and written up
|
||||
by other people, so you can link the evidence instead of relitigating it.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div class="wrap refs">
|
||||
{
|
||||
groups.map((g) => (
|
||||
<section class="refs__group">
|
||||
<h2 class="refs__heading productive-heading-03">{g.heading}</h2>
|
||||
<p class="helper">{g.blurb}</p>
|
||||
<ul class="refs__list">
|
||||
{byKind(g.kind).map((ref) => (
|
||||
<li class="refs__item">
|
||||
<div class="refs__cite">
|
||||
{ref.url ? (
|
||||
<a href={ref.url} rel="noopener" class="refs__work">{citeLabel(ref)}</a>
|
||||
) : (
|
||||
<span class="refs__work">{citeLabel(ref)}</span>
|
||||
)}
|
||||
{ref.work && <span class="refs__pub">{ref.work}</span>}
|
||||
{ref.free && <span class="receipt__free">free online</span>}
|
||||
</div>
|
||||
<p class="refs__blurb">{ref.blurb}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -69,8 +69,8 @@ const ogImage = new URL(href(`og/${sin.id}.png`), Astro.site).toString();
|
||||
|
||||
<ShareLink url={pageUrl} />
|
||||
|
||||
<p class="more-canon">
|
||||
Building a case? See the <a href={href('canon/')}>full canon →</a>
|
||||
<p class="more-refs">
|
||||
Building a case? See <a href={href('references/')}>every source we cite →</a>
|
||||
</p>
|
||||
</article>
|
||||
</BaseLayout>
|
||||
|
||||
+12
-12
@@ -669,23 +669,23 @@ a.receipt__work {
|
||||
border-color: var(--support-success);
|
||||
}
|
||||
|
||||
.more-canon {
|
||||
.more-refs {
|
||||
margin-top: var(--spacing-07);
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
/* canon page */
|
||||
.canon {
|
||||
/* references page */
|
||||
.refs {
|
||||
padding-block: var(--spacing-08) var(--spacing-10);
|
||||
}
|
||||
.canon__group {
|
||||
.refs__group {
|
||||
margin-bottom: var(--spacing-09);
|
||||
}
|
||||
.canon__heading {
|
||||
.refs__heading {
|
||||
margin: 0;
|
||||
}
|
||||
.canon__list {
|
||||
.refs__list {
|
||||
list-style: none;
|
||||
margin: var(--spacing-05) 0 0;
|
||||
padding: 0;
|
||||
@@ -694,29 +694,29 @@ a.receipt__work {
|
||||
background: var(--border-subtle);
|
||||
border: 1px solid var(--border-subtle);
|
||||
}
|
||||
.canon__item {
|
||||
.refs__item {
|
||||
background: var(--layer-01);
|
||||
padding: var(--spacing-05) var(--spacing-06);
|
||||
}
|
||||
.canon__cite {
|
||||
.refs__cite {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--spacing-03);
|
||||
}
|
||||
.canon__work {
|
||||
.refs__work {
|
||||
font-weight: 600;
|
||||
font-size: 1.0625rem;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
a.canon__work {
|
||||
a.refs__work {
|
||||
color: var(--link-primary);
|
||||
}
|
||||
.canon__pub {
|
||||
.refs__pub {
|
||||
font-size: 0.8125rem;
|
||||
color: var(--text-helper);
|
||||
}
|
||||
.canon__blurb {
|
||||
.refs__blurb {
|
||||
margin: var(--spacing-03) 0 0;
|
||||
color: var(--text-secondary);
|
||||
max-width: 44rem;
|
||||
|
||||
Reference in New Issue
Block a user