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
@@ -0,0 +1,209 @@
---
/**
* The one gilt panel on Work: the featured case study with its role, summary,
* tech, key facts and a link to the full study.
*/
import Button from "@gk/ui/components/Button.astro";
import Chip from "@gk/ui/components/Chip.astro";
import GiltCorners from "@gk/ui/components/GiltCorners.astro";
import Seal from "@gk/ui/components/Seal.astro";
import Star from "@gk/ui/components/Star.astro";
import TickScale from "@gk/ui/components/TickScale.astro";
import type { Note } from "../../lib/content.ts";
import { workGroup, workKicker } from "../../lib/work.ts";
interface Props {
study: Note<"post">;
href: string | null;
core: Set<string>;
}
const { study, href, core } = Astro.props;
const d = study.data;
const facts = d.facts ?? [];
---
<section aria-labelledby="work-featured" class="featured-wrap" data-group={workGroup(study)}>
<article class="panel">
<GiltCorners inset={4} />
<div class="inner">
<Seal name="transmutation" size={340} class="ghost" />
<div class="main">
<span class="kicker"><Star size={14} />Featured · {workKicker(study)}</span>
<div class="heading">
<h2 id="work-featured">{d.title}</h2>
<span class="underline" aria-hidden="true"></span>
</div>
{d.role && <span class="role">{d.role}</span>}
{d.period && <span class="period">{d.period}</span>}
{d.summary && <p class="summary">{d.summary}</p>}
{
d.tech?.length ? (
<div class="chips">
{d.tech.map((t) => (
<Chip core={core.has(t.toLowerCase())}>{t}</Chip>
))}
</div>
) : null
}
{href && <Button href={href} arrow class="cta">Read the case study</Button>}
</div>
{
facts.length > 0 && (
<div class="side">
<dl class="facts">
{facts.map((f) => (
<div class="fact">
<dt>{f.label}</dt>
<dd>
<span class="value">{f.value}</span>
<TickScale width={110} height={10} count={22} class="ticks" />
</dd>
</div>
))}
</dl>
</div>
)
}
</div>
</article>
</section>
<style>
.featured-wrap {
padding: 24px 0 8px;
}
.panel {
position: relative;
overflow: hidden;
background: var(--gk-midnight);
border: 1px solid var(--gk-gold);
border-radius: var(--gk-radius);
padding: 8px;
}
.inner {
position: relative;
border: 1px solid rgba(138, 101, 22, 0.35);
border-radius: 6px;
padding: 36px;
display: flex;
flex-wrap: wrap;
gap: 36px;
}
.inner :global(.ghost) {
position: absolute;
right: -60px;
bottom: -80px;
opacity: 0.12;
pointer-events: none;
}
.main {
flex: 1 1 420px;
min-width: 0;
display: flex;
flex-direction: column;
gap: 14px;
position: relative;
}
.kicker {
display: flex;
align-items: center;
gap: 10px;
font-size: 11px;
letter-spacing: 0.3em;
font-weight: 600;
color: var(--gk-gold-bright);
text-transform: uppercase;
}
.heading {
display: flex;
flex-direction: column;
gap: 8px;
}
h2 {
margin: 0;
font-size: clamp(30px, 5vw, 40px);
letter-spacing: 0.06em;
line-height: 1.1;
}
.underline {
display: block;
width: 180px;
height: 2px;
border-radius: 2px;
background:
linear-gradient(90deg, var(--gk-gold), rgba(201, 162, 74, 0.15) 70%, transparent),
radial-gradient(circle at 18% 50%, var(--gk-teal-bright) 0 2px, transparent 3px);
box-shadow: 0 0 8px rgba(201, 162, 74, 0.35);
}
.role {
font-size: 15px;
font-weight: 600;
color: var(--gk-teal-bright);
}
.period {
margin-top: -8px;
font-size: 13px;
color: var(--gk-muted);
}
.summary {
margin: 0;
font-size: 16px;
line-height: 1.65;
color: var(--gk-muted);
padding-left: 14px;
border-left: 2px solid var(--gk-gold);
}
.chips {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.main :global(.cta) {
align-self: flex-start;
margin-top: 6px;
}
.side {
flex: 1 1 360px;
min-width: 0;
position: relative;
}
.facts {
margin: 0;
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.fact {
flex: 1 1 140px;
display: flex;
flex-direction: column;
padding: 20px;
border: 1px solid var(--gk-lines);
border-radius: var(--gk-radius);
background: var(--gk-sky);
}
.fact dd {
margin: 0;
}
.value {
display: block;
font-family: var(--gk-font-display);
font-weight: 700;
font-size: 36px;
color: var(--gk-gold-bright);
line-height: 1;
}
.fact :global(.ticks) {
margin: 6px 0 2px;
}
.fact dt {
order: 1;
margin-top: 6px;
font-size: 14px;
color: var(--gk-muted);
}
@media (max-width: 640px) {
.inner {
padding: 24px 20px;
}
}
</style>