diff --git a/package-lock.json b/package-lock.json
index c6a4f7e..a9d8a2b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,9 @@
"version": "0.1.0",
"dependencies": {
"@astrojs/rss": "4.0.19",
+ "@fontsource-variable/inter": "^5.2.8",
+ "@fontsource-variable/newsreader": "^5.2.10",
+ "@fontsource/ibm-plex-mono": "^5.2.7",
"astro": "7.0.9"
},
"devDependencies": {
@@ -629,28 +632,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@emnapi/core": {
- "version": "1.11.2",
- "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz",
- "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "@emnapi/wasi-threads": "1.2.2",
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@emnapi/runtime": {
- "version": "1.11.2",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz",
- "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
"node_modules/@emnapi/wasi-threads": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz",
@@ -1077,6 +1058,33 @@
"node": ">=18"
}
},
+ "node_modules/@fontsource-variable/inter": {
+ "version": "5.2.8",
+ "resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.2.8.tgz",
+ "integrity": "sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
+ "node_modules/@fontsource-variable/newsreader": {
+ "version": "5.2.10",
+ "resolved": "https://registry.npmjs.org/@fontsource-variable/newsreader/-/newsreader-5.2.10.tgz",
+ "integrity": "sha512-MdI2iRwrqWpMOU/2aV2BgfZ4dJNlj/XlYaY8Zb7t87mWqHskYW0XiUANkt1cyOCiEfW2VQ0bQ5vZgGPp6B2B4w==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
+ "node_modules/@fontsource/ibm-plex-mono": {
+ "version": "5.2.7",
+ "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.2.7.tgz",
+ "integrity": "sha512-MKAb8qV+CaiMQn2B0dIi1OV3565NYzp3WN5b4oT6LTkk+F0jR6j0ZN+5BKJiIhffDC3rtBULsYZE65+0018z9w==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
"node_modules/@img/colour": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
@@ -2078,6 +2086,7 @@
"integrity": "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==",
"devOptional": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"undici-types": "~8.3.0"
}
@@ -2205,6 +2214,7 @@
"integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@@ -2857,6 +2867,7 @@
"integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
"hasInstallScript": true,
"license": "MIT",
+ "peer": true,
"bin": {
"esbuild": "bin/esbuild"
},
@@ -4016,6 +4027,7 @@
"integrity": "sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -4494,6 +4506,7 @@
"integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
"dev": true,
"license": "Apache-2.0",
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -4806,6 +4819,7 @@
"resolved": "https://registry.npmjs.org/vite/-/vite-8.1.4.tgz",
"integrity": "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"lightningcss": "^1.32.0",
"picomatch": "^4.0.5",
@@ -5245,6 +5259,7 @@
"integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
"devOptional": true,
"license": "ISC",
+ "peer": true,
"bin": {
"yaml": "bin.mjs"
},
diff --git a/package.json b/package.json
index 60883fe..fe596ea 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,9 @@
},
"dependencies": {
"@astrojs/rss": "4.0.19",
+ "@fontsource-variable/inter": "^5.2.8",
+ "@fontsource-variable/newsreader": "^5.2.10",
+ "@fontsource/ibm-plex-mono": "^5.2.7",
"astro": "7.0.9"
},
"devDependencies": {
diff --git a/src/components/Footer.astro b/src/components/Footer.astro
index c907aca..ee6a242 100644
--- a/src/components/Footer.astro
+++ b/src/components/Footer.astro
@@ -48,7 +48,7 @@ import { site } from '../site.config';
.footer-title {
color: var(--paper);
- font-family: 'Newsreader', Georgia, serif;
+ font-family: 'Newsreader Variable', Georgia, serif;
font-size: 2rem;
line-height: 1;
}
diff --git a/src/components/Header.astro b/src/components/Header.astro
index 0f7c430..485fb4f 100644
--- a/src/components/Header.astro
+++ b/src/components/Header.astro
@@ -86,7 +86,7 @@ import { navigation, site } from '../site.config';
}
.masthead strong {
- font-family: 'Newsreader', Georgia, serif;
+ font-family: 'Newsreader Variable', Georgia, serif;
font-size: 1.55rem;
letter-spacing: -0.03em;
}
diff --git a/src/components/MaintenanceMeta.astro b/src/components/MaintenanceMeta.astro
index 5dbeff9..c5864fc 100644
--- a/src/components/MaintenanceMeta.astro
+++ b/src/components/MaintenanceMeta.astro
@@ -12,6 +12,10 @@ interface Props {
}
const { author, maintainers, published, reviewed, status, sourcePath } = Astro.props;
+
+const REVIEW_DUE_DAYS = 180;
+const reviewAgeDays = Math.floor((Date.now() - reviewed.getTime()) / 86_400_000);
+const reviewDue = reviewAgeDays > REVIEW_DUE_DAYS;
---
@@ -19,22 +23,25 @@ const { author, maintainers, published, reviewed, status, sourcePath } = Astro.p
By
{author}
-
-
Published
- {formatDate(published)}
-
Last reviewed
- {formatDate(reviewed)}
-
-
-
Maintained by
- {maintainers.join(', ')}
+
+ {formatDate(reviewed)}
+ {reviewDue && review due }
+
Status
{status}
+
+
Published
+ {formatDate(published)}
+
+
+
Maintained by
+ {maintainers.join(', ')}
+
Record
Source file ↗
@@ -66,6 +73,16 @@ const { author, maintainers, published, reviewed, status, sourcePath } = Astro.p
font-weight: 600;
}
+ .review-due {
+ margin-left: 0.5rem;
+ color: var(--amend);
+ font-family: 'IBM Plex Mono', monospace;
+ font-size: 0.62rem;
+ font-weight: 500;
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+ }
+
.status {
display: inline-flex;
align-items: center;
diff --git a/src/components/StoryCard.astro b/src/components/StoryCard.astro
index 4163035..2c0ad43 100644
--- a/src/components/StoryCard.astro
+++ b/src/components/StoryCard.astro
@@ -8,15 +8,23 @@ interface Props {
}
const { entry, featured = false } = Astro.props;
+const pattern = entry.data.trustPattern;
+const status = entry.data.status;
+const nodes = pattern
+ ? ['CLAIM', 'TRUSTED', 'FAILURE']
+ : ['PERSON', 'SYSTEM', 'CONSEQUENCE'];
---
-
-
PERSON
-
-
SYSTEM
-
-
CONSEQUENCE
+
+
+ {nodes[0]}
+
+ {nodes[1]}
+
+ {nodes[2]}
+
+ {pattern &&
“{pattern.claim}”
}
Story · {formatDate(entry.data.published)}
@@ -43,6 +51,7 @@ const { entry, featured = false } = Astro.props;
align-items: center;
justify-content: center;
flex-direction: column;
+ gap: 1.4rem;
padding: 2rem;
background: var(--blue);
color: var(--paper);
@@ -51,7 +60,13 @@ const { entry, featured = false } = Astro.props;
letter-spacing: 0.1em;
}
- .visual i {
+ .chain {
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ }
+
+ .chain i {
display: block;
width: 1px;
height: 2.8rem;
@@ -59,13 +74,25 @@ const { entry, featured = false } = Astro.props;
background: #8ea7c1;
}
- .visual .broken {
- position: relative;
+ /* The failure link encodes the story's status. */
+
+ /* developing — the claim is still being tested: a dashed, uncertain link */
+ .chain .fail-link {
height: 3.4rem;
+ background: repeating-linear-gradient(
+ to bottom,
+ #8ea7c1 0 0.45rem,
+ transparent 0.45rem 0.9rem
+ );
+ }
+
+ /* disputed — the link is broken */
+ [data-status='disputed'] .chain .fail-link {
+ position: relative;
background: linear-gradient(to bottom, #8ea7c1 0 38%, transparent 38% 62%, #8ea7c1 62%);
}
- .visual .broken::after {
+ [data-status='disputed'] .chain .fail-link::after {
position: absolute;
width: 0.8rem;
height: 2px;
@@ -76,6 +103,31 @@ const { entry, featured = false } = Astro.props;
transform: rotate(-45deg);
}
+ /* resolved — the link holds */
+ [data-status='resolved'] .chain .fail-link {
+ background: #8ea7c1;
+ }
+
+ /* historical — the record stands, the heat is gone */
+ .visual[data-status='historical'] {
+ background: color-mix(in srgb, var(--blue) 55%, var(--ink));
+ }
+
+ [data-status='historical'] .chain .fail-link {
+ background: #8ea7c1;
+ }
+
+ .visual-claim {
+ max-width: 24ch;
+ margin: 0;
+ color: #c5d1df;
+ font-size: 0.68rem;
+ letter-spacing: 0.02em;
+ line-height: 1.55;
+ text-align: center;
+ text-transform: none;
+ }
+
.story-copy {
display: flex;
flex-direction: column;
@@ -86,7 +138,7 @@ const { entry, featured = false } = Astro.props;
h3 {
max-width: 17ch;
margin: 0;
- font-family: 'Newsreader', Georgia, serif;
+ font-family: 'Newsreader Variable', Georgia, serif;
font-size: clamp(1.8rem, 4vw, 3rem);
font-weight: 600;
letter-spacing: -0.03em;
@@ -122,19 +174,36 @@ const { entry, featured = false } = Astro.props;
.visual {
min-height: 190px;
+ gap: 1rem;
+ }
+
+ .chain {
flex-direction: row;
}
- .visual i {
+ .chain i {
width: 2.5rem;
height: 1px;
margin: 0 0.65rem;
}
- .visual .broken {
+ .chain .fail-link {
width: 3rem;
height: 1px;
+ background: repeating-linear-gradient(
+ to right,
+ #8ea7c1 0 0.45rem,
+ transparent 0.45rem 0.9rem
+ );
+ }
+
+ [data-status='disputed'] .chain .fail-link {
background: linear-gradient(to right, #8ea7c1 0 38%, transparent 38% 62%, #8ea7c1 62%);
}
+
+ [data-status='resolved'] .chain .fail-link,
+ [data-status='historical'] .chain .fail-link {
+ background: #8ea7c1;
+ }
}
diff --git a/src/components/TrustPattern.astro b/src/components/TrustPattern.astro
index c6e5153..1c52e56 100644
--- a/src/components/TrustPattern.astro
+++ b/src/components/TrustPattern.astro
@@ -11,7 +11,7 @@ const { pattern } = Astro.props;
---
{pattern && (
-
+
The trust pattern
Claim {pattern.claim}
@@ -24,7 +24,7 @@ const { pattern } = Astro.props;
diff --git a/src/pages/book.astro b/src/pages/book.astro
index f31f3ed..005a12a 100644
--- a/src/pages/book.astro
+++ b/src/pages/book.astro
@@ -29,7 +29,7 @@ import { site } from '../site.config';
diff --git a/src/pages/briefing/index.astro b/src/pages/briefing/index.astro
index ee89053..cb37eb4 100644
--- a/src/pages/briefing/index.astro
+++ b/src/pages/briefing/index.astro
@@ -29,7 +29,7 @@ const entries = newestFirst(await getCollection('briefings', ({ data }) => !data
.archive-head > p:last-child { max-width: 58ch; color: var(--muted); }
.issue-list article { display: grid; grid-template-columns: 8rem 1fr 1fr 8rem; gap: 1.5rem; align-items: baseline; padding: 1.5rem 0; border-top: 1px solid var(--rule); }
.issue-list span, .issue-list time { color: var(--muted); font-family: 'IBM Plex Mono', monospace; font-size: .68rem; }
- h2 { margin: 0; font-family: 'Newsreader', Georgia, serif; font-size: 2rem; line-height: 1; }
+ h2 { margin: 0; font-family: 'Newsreader Variable', Georgia, serif; font-size: 2rem; line-height: 1; }
h2 a { text-decoration: none; }
.issue-list p { margin: 0; color: var(--muted); font-size: .9rem; }
@media (max-width: 760px) { .issue-list article { grid-template-columns: 1fr auto; } h2, .issue-list p { grid-column: 1 / -1; } }
diff --git a/src/pages/guides/index.astro b/src/pages/guides/index.astro
index 186b8cd..82b65ed 100644
--- a/src/pages/guides/index.astro
+++ b/src/pages/guides/index.astro
@@ -31,7 +31,7 @@ const entries = guidesByReview(await getCollection('guides', ({ data }) => !data
.archive-head > p:last-child { max-width: 62ch; color: var(--muted); }
.guide-list article { display: grid; grid-template-columns: 5rem 1fr 10rem; gap: 2rem; padding: 2rem 0; border-top: 1px solid var(--rule); }
.guide-list > article > span { color: var(--amend); font-family: 'IBM Plex Mono', monospace; font-size: .72rem; }
- h2 { margin: 0; font-family: 'Newsreader', Georgia, serif; font-size: clamp(2rem, 5vw, 3.5rem); line-height: 1; }
+ h2 { margin: 0; font-family: 'Newsreader Variable', Georgia, serif; font-size: clamp(2rem, 5vw, 3.5rem); line-height: 1; }
h2 a { text-decoration: none; }
p, small { color: var(--muted); }
small { font-family: 'IBM Plex Mono', monospace; font-size: .66rem; text-transform: uppercase; }
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 063bf48..11eb38e 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -29,7 +29,11 @@ const latestEpisode = episodes[0];
@@ -63,74 +67,61 @@ const latestEpisode = episodes[0];
-
-
-
-
-
+ {latestEpisode && (
+
+
-
- {latestEpisode ? (
- <>
-
Episode {latestEpisode.data.episode}
-
-
{latestEpisode.data.description}
- >
- ) : (
- <>
-
Podcast
-
Who gets to act in our name?
-
Conversations about authority, recovery, delegation, and the human lives hidden inside technical systems. Episodes and full transcripts will live here.
- >
- )}
+
+
+
+
+
+
Episode {latestEpisode.data.episode}
+
+
{latestEpisode.data.description}
+
-
-
+
+ )}
-
-
- {guides.length > 0 ? (
+ {guides.length > 0 && (
+
+
- {guides.slice(0, 3).map((guide, index) => (
+ {guides.slice(0, 3).map((guide) => (
- 0{index + 1}
+ Reviewed {formatDate(guide.data.reviewed)}
{guide.data.description}
- Reviewed {formatDate(guide.data.reviewed)}
))}
- ) : (
-
- {['Passkeys', 'Government wallets', 'Agent authority'].map((title, index) => (
-
- 0{index + 1}
- {title}
- In preparation. Published only when the review date means something.
-
- ))}
-
- )}
-
+
+ )}
-
- THE BOOK
-
-
The book
-
A permanent home, not a checkout widget.
-
The book page is ready for its real title, cover, sample chapter, argument, and purchase route—without inventing details before they are supplied.
-
Visit the book page
-
-
+ {site.book.enabled && (
+
+ )}
+
+ Planned but not yet real: the podcast{site.book.enabled ? '' : ', the book'}, and more guides.
+ Nothing ships here before it exists — see the roadmap ↗
+
@@ -153,7 +144,7 @@ const latestEpisode = episodes[0];
}
.hero-note p:first-child {
- font-family: 'Newsreader', Georgia, serif;
+ font-family: 'Newsreader Variable', Georgia, serif;
font-size: 1.45rem;
line-height: 1.2;
}
@@ -197,7 +188,7 @@ const latestEpisode = episodes[0];
.guide-grid h3,
.book-strip h2 {
margin: 0.35rem 0;
- font-family: 'Newsreader', Georgia, serif;
+ font-family: 'Newsreader Variable', Georgia, serif;
font-weight: 600;
letter-spacing: -0.025em;
line-height: 1;
@@ -292,10 +283,13 @@ const latestEpisode = episodes[0];
border-right: 0;
}
- .guide-number {
- color: var(--amend);
+ .guide-reviewed {
+ display: block;
+ color: var(--muted);
font-family: 'IBM Plex Mono', monospace;
- font-size: 0.72rem;
+ font-size: 0.65rem;
+ letter-spacing: 0.05em;
+ text-transform: uppercase;
}
.guide-grid h3 {
@@ -303,18 +297,14 @@ const latestEpisode = episodes[0];
font-size: 2rem;
}
- .guide-grid p,
- .guide-grid small {
+ .guide-grid p {
color: var(--muted);
}
- .guide-grid small {
- font-family: 'IBM Plex Mono', monospace;
- font-size: 0.65rem;
- }
-
- .planned article {
- opacity: 0.75;
+ .planned-note {
+ margin: 2rem 0 0;
+ color: var(--muted);
+ font-size: 0.85rem;
}
.book-strip {
@@ -335,7 +325,7 @@ const latestEpisode = episodes[0];
border: 1px solid #7690ad;
box-shadow: 18px 18px 0 #0e2c51;
background: #102f55;
- font-family: 'Newsreader', Georgia, serif;
+ font-family: 'Newsreader Variable', Georgia, serif;
font-size: 2.5rem;
line-height: 0.9;
text-align: center;
diff --git a/src/pages/podcast/index.astro b/src/pages/podcast/index.astro
index 7a98b1c..741b4a2 100644
--- a/src/pages/podcast/index.astro
+++ b/src/pages/podcast/index.astro
@@ -47,7 +47,7 @@ const entries = newestFirst(await getCollection('episodes', ({ data }) => !data.
.episode-list { margin-top: 6rem; }
.episode-list article { display: grid; grid-template-columns: 4rem 1fr 8rem; gap: 2rem; padding: 2rem 0; border-bottom: 1px solid var(--rule); }
.episode-list article > span, time { color: var(--muted); font-family: 'IBM Plex Mono', monospace; font-size: .7rem; }
- h3 { margin: 0; font-family: 'Newsreader', Georgia, serif; font-size: 2.3rem; line-height: 1; }
+ h3 { margin: 0; font-family: 'Newsreader Variable', Georgia, serif; font-size: 2.3rem; line-height: 1; }
h3 a { text-decoration: none; }
.episode-list p { color: var(--muted); }
@media (max-width: 700px) { .podcast-grid { grid-template-columns: 1fr; } .episode-list article { grid-template-columns: 2rem 1fr; } time { grid-column: 2; } }
diff --git a/src/styles/global.css b/src/styles/global.css
index e4ce166..749717d 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -10,7 +10,7 @@
--max: 1180px;
--reading: 720px;
color-scheme: light;
- font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
+ font-family: 'Inter Variable', Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
font-synthesis: none;
background: var(--paper);
color: var(--ink);
@@ -73,7 +73,7 @@ select {
.display {
margin: 0;
- font-family: 'Newsreader', Georgia, serif;
+ font-family: 'Newsreader Variable', Georgia, serif;
font-size: clamp(2.8rem, 7vw, 6.5rem);
font-weight: 500;
letter-spacing: -0.045em;
@@ -82,7 +82,7 @@ select {
.section-title {
margin: 0;
- font-family: 'Newsreader', Georgia, serif;
+ font-family: 'Newsreader Variable', Georgia, serif;
font-size: clamp(2rem, 4vw, 3.25rem);
font-weight: 600;
letter-spacing: -0.025em;
@@ -136,7 +136,7 @@ select {
.prose {
width: min(100%, var(--reading));
- font-family: 'Newsreader', Georgia, serif;
+ font-family: 'Newsreader Variable', Georgia, serif;
font-size: clamp(1.15rem, 2.2vw, 1.35rem);
line-height: 1.7;
}