mirror of
https://github.com/Patiun/com.gregkilmer.www.git
synced 2026-11-07 19:58:24 +00:00
7aa2910b12
Dark stays the default. A device set to light gets the picks from the light motif board: the Dawn chart sky (dawn wash over faint star chart lines, atlas marks in the hero), deep gold line seals, Midnight, violet and gold dust, the deep gold to teal filament and the morning sky placeholder. Large standalone seals (404, Inquiries, Inquiry sent, the blog's lead) are gold foil in both modes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
210 lines
5.0 KiB
Plaintext
210 lines
5.0 KiB
Plaintext
---
|
|
/**
|
|
* The landing's "From the blog": one featured post (pinned, else newest) with
|
|
* its image and topic, and the two most recent beside it. Renders nothing when
|
|
* there are no posts.
|
|
*/
|
|
import StarChartArt from "@gk/ui/components/StarChartArt.astro";
|
|
import { slugify } from "@gk/schema";
|
|
import { blogStrip, readMinutes } from "../../lib/home.ts";
|
|
import { formatDate, mediaSrc, type SiteIndex } from "../../lib/site.ts";
|
|
|
|
interface Props {
|
|
site: SiteIndex;
|
|
}
|
|
const { site: s } = Astro.props;
|
|
const { featured, recent } = blogStrip(s);
|
|
const topicHref = (topic: string) => `/blog/topic/${slugify(topic)}`;
|
|
---
|
|
{
|
|
featured && (
|
|
<div class="strip">
|
|
<div class="head">
|
|
<div class="gk-heading-sm">
|
|
<h3 id="from-blog">From the blog</h3>
|
|
<span class="underline" aria-hidden="true" />
|
|
</div>
|
|
<a href="/blog" class="gk-text all">All articles</a>
|
|
</div>
|
|
<div class="posts">
|
|
<article class="featured gk-card gk-linked">
|
|
<StarChartArt
|
|
seal="seven-metals"
|
|
ratio="auto"
|
|
src={mediaSrc(featured.data.cover)}
|
|
alt={featured.data.cover ? featured.title : ""}
|
|
class="art"
|
|
/>
|
|
<div class="body">
|
|
<div class="tags">
|
|
<span class="label">{featured.data.pinned ? "Featured" : "Latest"}</span>
|
|
<a class="gk-chip" href={topicHref(featured.data.topic)}>{featured.data.topic}</a>
|
|
</div>
|
|
<h4 class="ftitle">
|
|
<a href={s.href(featured) ?? "/blog"}>{featured.title}</a>
|
|
</h4>
|
|
<p class="summary">{featured.data.summary}</p>
|
|
<span class="date">
|
|
<time datetime={featured.data.date}>{formatDate(featured.data.date)}</time> · {readMinutes(featured.body)} min read
|
|
</span>
|
|
</div>
|
|
</article>
|
|
{
|
|
recent.length > 0 && (
|
|
<div class="recent">
|
|
{recent.map((p) => (
|
|
<article class="gk-card gk-linked small">
|
|
<span class="tags">
|
|
<span class="label">New</span>
|
|
<a class="gk-chip" href={topicHref(p.data.topic)}>{p.data.topic}</a>
|
|
</span>
|
|
<h4 class="rtitle">
|
|
<a href={s.href(p) ?? "/blog"}>{p.title}</a>
|
|
</h4>
|
|
<span class="date">
|
|
<time datetime={p.data.date}>{formatDate(p.data.date)}</time> · {readMinutes(p.body)} min read
|
|
</span>
|
|
</article>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
<style>
|
|
.strip {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 22px;
|
|
margin-top: 16px;
|
|
}
|
|
.head {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: baseline;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
}
|
|
.gk-heading-sm {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
.gk-heading-sm h3 {
|
|
margin: 0;
|
|
font-size: 22px;
|
|
letter-spacing: 0.08em;
|
|
}
|
|
.underline {
|
|
display: block;
|
|
width: 180px;
|
|
height: 2px;
|
|
border-radius: 2px;
|
|
background: linear-gradient(90deg, var(--gk-gold), rgba(var(--gk-gold-rgb), 0.15) 70%, transparent);
|
|
box-shadow: 0 0 8px rgba(var(--gk-gold-rgb), 0.35);
|
|
}
|
|
.all {
|
|
font-size: 14px;
|
|
}
|
|
.posts {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 20px;
|
|
}
|
|
.featured {
|
|
flex: 2 1 560px;
|
|
min-width: 0;
|
|
padding: 0;
|
|
overflow: hidden;
|
|
flex-direction: row;
|
|
flex-wrap: wrap;
|
|
gap: 0;
|
|
}
|
|
.featured :global(.art) {
|
|
flex: 1 1 240px;
|
|
min-width: 0;
|
|
height: 260px;
|
|
border-radius: 0;
|
|
border-right: 2px solid var(--gk-gold);
|
|
}
|
|
.body {
|
|
flex: 2 1 300px;
|
|
min-width: 0;
|
|
padding: 26px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
.tags {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
align-items: center;
|
|
}
|
|
.label {
|
|
font-size: 11px;
|
|
letter-spacing: 0.3em;
|
|
font-weight: 600;
|
|
color: var(--gk-gold-bright);
|
|
text-transform: uppercase;
|
|
}
|
|
h4 {
|
|
margin: 0;
|
|
font-family: var(--gk-font-display);
|
|
font-weight: 700;
|
|
letter-spacing: 0.04em;
|
|
line-height: 1.2;
|
|
}
|
|
h4 a {
|
|
color: var(--gk-text);
|
|
text-decoration: none;
|
|
}
|
|
h4 a::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
}
|
|
.tags a {
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
.ftitle {
|
|
font-size: 24px;
|
|
}
|
|
.rtitle {
|
|
font-size: 17px;
|
|
}
|
|
.summary {
|
|
margin: 0;
|
|
font-size: 15px;
|
|
line-height: 1.6;
|
|
color: var(--gk-muted);
|
|
}
|
|
.date {
|
|
margin-top: auto;
|
|
font-size: 12px;
|
|
color: var(--gk-muted);
|
|
}
|
|
.recent {
|
|
flex: 1 1 280px;
|
|
min-width: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 14px;
|
|
}
|
|
.small {
|
|
padding: 18px 20px;
|
|
}
|
|
@media (max-width: 640px) {
|
|
.featured :global(.art) {
|
|
border-right: 0;
|
|
border-bottom: 2px solid var(--gk-gold);
|
|
height: 200px;
|
|
flex-basis: 100%;
|
|
}
|
|
}
|
|
</style>
|