Establish the publication foundation
validate / validate (push) Failing after 7s

This commit is contained in:
Compleet
2026-07-14 11:54:31 +01:00
commit 006955bfc8
46 changed files with 7704 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
---
import { getCollection, render, type CollectionEntry } from 'astro:content';
import ArticleLayout from '../../layouts/ArticleLayout.astro';
export async function getStaticPaths() {
const entries = await getCollection('episodes', ({ data }) => !data.draft);
return entries.map((entry) => ({ params: { id: entry.id }, props: { entry } }));
}
interface Props { entry: CollectionEntry<'episodes'> }
const { entry } = Astro.props;
const { Content } = await render(entry);
---
<ArticleLayout
title={entry.data.title}
description={entry.data.description}
kind={`Podcast · Episode ${entry.data.episode}`}
author={entry.data.author}
maintainers={entry.data.maintainers}
published={entry.data.published}
reviewed={entry.data.reviewed}
status={entry.data.status}
sourcePath={`src/content/episodes/${entry.id}.md`}
>
{entry.data.audioUrl && <audio controls preload="metadata" src={entry.data.audioUrl}>Your browser does not support embedded audio.</audio>}
<Content />
</ArticleLayout>
<style>
audio { width: 100%; margin-bottom: 2.5rem; }
</style>
+54
View File
@@ -0,0 +1,54 @@
---
import { getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
import { formatDate, newestFirst } from '../../lib/content';
const entries = newestFirst(await getCollection('episodes', ({ data }) => !data.draft));
---
<BaseLayout title="Podcast" description="Conversations about authority, delegation, recovery, and responsibility.">
<section class="podcast-hero">
<div class="shell podcast-grid">
<div>
<p class="eyebrow">The podcast</p>
<h1 class="display">Who gets to act in our name?</h1>
</div>
<p>Conversations pairing people who rarely share a microphone: system designers and the people who meet those systems at their most consequential edges. Full transcripts live beside every episode.</p>
</div>
<div class="wave shell" aria-hidden="true">
{Array.from({ length: 21 }).map((_, index) => <i style={`--n:${(index * 37) % 100}`} />)}
</div>
</section>
<section class="shell episode-list">
<div class="section-rule">
<h2 class="section-title">Episodes</h2>
<a href="/rss.xml">RSS →</a>
</div>
{entries.length > 0 ? entries.map((entry) => (
<article>
<span>{String(entry.data.episode).padStart(2, '0')}</span>
<div>
<h3><a href={`/podcast/${entry.id}`}>{entry.data.title}</a></h3>
<p>{entry.data.description}</p>
</div>
<time datetime={entry.data.published.toISOString()}>{formatDate(entry.data.published)}</time>
</article>
)) : <p class="empty-state">The archive is ready for real episodes and transcripts. No synthetic placeholder episode has been published.</p>}
</section>
</BaseLayout>
<style>
.podcast-hero { padding: clamp(4rem, 9vw, 8rem) 0 0; background: var(--ink); color: var(--paper); }
.podcast-grid { display: grid; grid-template-columns: 1.5fr .7fr; gap: clamp(2rem, 7vw, 7rem); align-items: end; }
.podcast-grid .eyebrow { color: #9fb8d4; }
.podcast-grid > p { color: #bcb8af; }
.wave { display: flex; height: 210px; align-items: center; justify-content: space-between; margin-top: 4rem; overflow: hidden; }
.wave i { display: block; width: 2px; height: calc(20% + var(--n) * .75%); background: color-mix(in srgb, var(--paper) calc(25% + var(--n) * .5%), var(--amend)); }
.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 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; } }
</style>