Phase 5: every page of the site, the resume PDF and RSS

Landing, About, Now, Resume (with a generated PDF), Work and case studies,
Inquiries and the sent page, Library and the Shelf, Workshop and craft pages,
Tabletop, Blog with topics and posts, RSS, the Store, product lines, the
order form and the 404, all rendered from the content service's notes.

Schema: experience previousRoles, skills stack core items, page stats,
make tags and deck favorite. Icon names from notes map to brand icons in one
place, and HTML comments are dropped when Markdown renders.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
This commit is contained in:
Claude
2026-10-11 21:33:49 +00:00
parent 7025e95f89
commit 99ecdc2113
83 changed files with 11681 additions and 14 deletions
+27 -2
View File
@@ -193,6 +193,10 @@ export const make = def({
date: isoDate({ title: "Finished" }).optional(),
photos: z.array(image({ title: "Photo" })).meta({ title: "Photos" }).optional(),
blurb: line({ title: "Blurb" }).optional(),
tags: z
.array(line({ title: "Tag" }))
.meta({ title: "Tags", description: "Like sword rack, which puts the make on the Workshop's sword rack." })
.optional(),
}),
});
@@ -251,6 +255,7 @@ export const deck = def({
archidektId: z.number().int().meta({ title: "Archidekt deck id" }).optional(),
listUrl: z.url().meta({ title: "Deck list link", description: "For games not on Archidekt." }).optional(),
take: line({ title: "Your take", description: "One line on the deck." }).optional(),
favorite: z.boolean().meta({ title: "Favorite", description: "Shows first among the decks." }).optional(),
}),
});
@@ -265,7 +270,11 @@ export const experience = def({
body: "Optional longer notes; the resume uses the bullets.",
schema: note("experience", {
company: line({ title: "Company" }),
role: line({ title: "Role" }),
role: line({ title: "Role", description: "The current or last title at this company." }),
previousRoles: strings({
title: "Earlier titles",
description: "Earlier titles at the same company, newest first, shown as Previously.",
}).optional(),
start: isoMonth({ title: "Start" }),
end: isoMonth({ title: "End", description: "Leave out while it is your current role." }).optional(),
location: line({ title: "Location" }).optional(),
@@ -286,7 +295,13 @@ export const skills = def({
core: strings({ title: "Core strengths" }),
learning: strings({ title: "Learning now" }).optional(),
stack: z
.array(z.object({ label: line({ title: "Group" }), items: strings({ title: "Items" }) }))
.array(
z.object({
label: line({ title: "Group" }),
items: strings({ title: "Items" }),
core: strings({ title: "Core items", description: "Items from this group outlined as the core stack." }).optional(),
}),
)
.meta({ title: "Technical stack" }),
}),
});
@@ -476,6 +491,16 @@ export const page = def({
.array(z.object({ icon: line({ title: "Icon" }), text: line({ title: "Text" }) }))
.meta({ title: "Quick facts" })
.optional(),
stats: z
.array(
z.object({
value: line({ title: "Value", description: "Like 1,000+." }),
label: line({ title: "Label", description: "Like Active users." }),
detail: line({ title: "Detail" }).optional(),
}),
)
.meta({ title: "Highlights", description: "Big numbers on the page, like the resume highlights. Only real, checkable numbers." })
.optional(),
}),
});