site: media + colocation — chunk 1/4 (code, configs, docs)

Code, configs, README, CHANGELOG, sources/log files, .claude.
Subsequent chunks land the renamed media files.
This commit is contained in:
2026-05-04 17:54:14 -04:00
parent e873460465
commit 5dcd99361f
25 changed files with 1138 additions and 243 deletions
+26 -21
View File
@@ -2,6 +2,7 @@
import { getCollection, render } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
import SourceBadge from '../../components/SourceBadge.astro';
import EditAction from '../../components/EditAction.astro';
import {
resolveExternalLink,
AFFILIATE_REL,
@@ -30,6 +31,7 @@ const fmt = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'UTC',
});
const linkLabel =
@@ -78,6 +80,10 @@ const breadcrumbs = buildBreadcrumbs([
<BaseLayout
title={review.data.name}
description={description}
subheader={review.data.name}
subheaderSubtitle={review.data.subtitle}
subheaderVariant="headline"
lastUpdated={review.data.date}
ogType="article"
ogImage={ogImage}
publishedTime={review.data.date}
@@ -85,18 +91,11 @@ const breadcrumbs = buildBreadcrumbs([
jsonLd={[reviewSchema, breadcrumbs]}
>
<article>
{review.data.source && (
<p class="source-line"><SourceBadge source={review.data.source} /></p>
)}
<header class="review-header">
<h1>{review.data.name}</h1>
<p class="subtitle">{review.data.subtitle}</p>
{review.data.source && (
<p class="source-line"><SourceBadge source={review.data.source} /></p>
)}
<p class="meta">
<time datetime={review.data.date.toISOString()}>
{fmt.format(review.data.date)}
</time>
<span class="dot">·</span>
<a href={`/categories/${review.data.category}/`} class="category">
{review.data.category}
</a>
@@ -135,6 +134,16 @@ const breadcrumbs = buildBreadcrumbs([
<Content />
</div>
{import.meta.env.DEV && (
<div class="edit-toolbar">
<EditAction
label="Make today's pick"
command={`/set-pick ${review.id}`}
confirm={`This will set ${review.data.name} as the homepage hero (updates HERO_SLUG in src/pages/index.astro).`}
/>
</div>
)}
{
review.data.tags.length > 0 && (
<footer class="tags">
@@ -160,19 +169,10 @@ const breadcrumbs = buildBreadcrumbs([
}
.from-find time { color: var(--muted); }
.review-header {
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 1px solid var(--rule);
}
h1 { margin: 0 0 0.35rem; }
.subtitle {
margin: 0 0 0.75rem;
color: var(--muted);
font-size: 1.1rem;
font-style: italic;
margin-bottom: 1.5rem;
}
.meta {
margin: 0;
margin: 0.5rem 0 0;
color: var(--muted);
font-size: 0.9rem;
}
@@ -309,5 +309,10 @@ const breadcrumbs = buildBreadcrumbs([
.tag { font-size: 0.85rem; color: var(--muted); }
.tag:hover { color: var(--accent); }
.back { margin-top: 2rem; font-size: 0.9rem; }
.edit-toolbar {
margin: 2rem 0 0;
padding-top: 1rem;
border-top: 1px dashed color-mix(in srgb, var(--accent) 30%, var(--rule));
}
</style>
</BaseLayout>