Listing
Index pages. The browsing experience. Where the article pattern prioritizes immersive reading, listings prioritize scanability — the reader should be able to find what they want in a glance.
Composition
Every listing page follows the same skeleton:
- Breadcrumb —
Alex Priest -> [Section]in the site header. Provides context and a path home. - Page title —
h1at the page level, outside any<article>. Signifier at the default heading scale. - Section label —
.section-labelmarks each content group. Pure typographic markers with no decorative affordance. - Content list — The list pattern appropriate to the content type: post list, media list, archive, or feed.
- Footer — Site colophon with navigation, settings, copyright.
Patterns
Post list
The workhorse listing component. Used on /writing, /shortlist, /links, /now.
A <ul class="post-list"> with each <li> containing a flex row linking to the post. The link spans the full row with display: flex; justify-content: space-between; align-items: baseline.
- Title —
.titlein Signifier withfont-variation-settings: 'wght' 400. On hover, shifts to weight 500 and--accentcolor. The weight-shift transition uses the signature easing:0.4s cubic-bezier(0.22, 1, 0.36, 1). - Date —
.datein Montreuil at 0.85rem,--text-2,font-variant-numeric: tabular-nums,white-space: nowrap. Dates align to a consistent right edge. - Latest mark — Optional
.latest-mark(Montreuil, 0.6rem, uppercase,--accent,font-weight: 600). Positioned between title and date withmargin-right: auto. - Dividers —
1px solid var(--ui)bottom border on each<li>except the last. - Spacing —
padding: var(--space-sm) 0per row. No list-style, no padding on the<ul>.
On the writing index, posts are grouped by year. Each year gets a <section class="year-group"> with a <h2 class="year-heading"> (Signifier, 1.2rem, weight 400, --text-2). Year groups after the first receive a --ui top border with var(--space-xl) padding.
See Content components for detailed specs on prose links, hover behavior, and typographic details.
Media list
Used on /media and its subpages (/media/films, /media/tv, /media/games).
A <ul class="media-list"> with each <li> as a flex row: justify-content: space-between; align-items: baseline.
- Left group (
.media-main) — Title, year, and optional badge/pill.display: flex; align-items: baseline; gap: var(--space-xs)..media-titlein Signifier,font-variation-settings: 'wght' 400. Same weight-shift hover as post list titles (to 500, accent color)..media-yearin Montreuil, 0.85rem,--text-2..type-badgecolored from the pill companion triple (--pill-1for Film,--pill-2for TV,--pill-3for Game). Montreuil, 0.6rem, uppercase, withcolor-mix(in srgb, var(--pill-n) 8%, transparent)background..season-pillfor TV season indicators. Montreuil, 0.6rem,--text-2on a--uitinted background.
- Right group (
.media-meta-right) — Rating and date.display: flex; align-items: baseline; gap: var(--space-sm); flex-shrink: 0..ratingin--accentat 0.85rem (star characters)..datein Montreuil, 0.8rem,--text-2.
- Mobile — At <=600px, each
<li>stacks toflex-direction: column; align-items: flex-start. The right group spans full width withjustify-content: space-between.
Media sections use collapsible <details> elements with <summary> headers. The section label inside a summary gets a rotatable chevron (::after content '>') that transitions to 90deg when open. Each section header includes a “See all” link with an arrow that translates 3px right on hover.
See Media components for pill color system details, poster cards, and category conventions.
Archive
Class: .archive-list
A year-grouped serif list without bullets or borders. Minimal and scannable.
list-style: none; padding: 0; margin-top: var(--space-sm).- Each
<li>in Signifier at 1rem withline-height: 1.8. The generous line-height creates vertical breathing room without explicit spacing tokens. - Links use the standard prose sweep hover (accent color, underline sweep).
- Used on the now page for “Previously” archives, and on
/writing/archivefor older writing.
Feed
A unified cross-content stream showing writing, shortlist, and links together. Used on /feed.
Each .feed-item is an <article> containing:
- Meta row (
.feed-meta) — Date link (Montreuil, 0.8rem,tabular-nums,--text-2) and a type pill (.feed-type) colored from the pill triple. Writing uses--pill-1, Links use--pill-2, Shortlist uses--pill-3. - Title (
.feed-title) — Signifier at 1.5rem, weight 400,letter-spacing: -0.01em,text-wrap: pretty. Same weight-shift hover. Link posts have their title linking to the external URL with a permalink glyph (.feed-permalink,✦) and optional “Must read” marginalia. - Description (
.feed-desc) — Signifier at 1rem,--text-2,line-height: 1.55. Auto-generated from the post’s description field or first paragraph.
Feed items are separated by 1px solid var(--ui) bottom borders with var(--space-xl) padding.
Filter tabs (.feed-filters) sit above the feed. Montreuil, 0.75rem, uppercase, weight 500. The active filter gets --text color, weight 600, and a 1.5px --text bottom border. Filters toggle .is-hidden on feed items via JavaScript. The current filter is reflected in the URL hash.
Font-pending state — The feed starts with opacity: 0 (.is-fonts-pending) and reveals after fonts load or a 1200ms timeout, whichever comes first. This prevents a flash of unstyled weight-shift text.
Section labels
Pure typographic markers. No background, no border, no box. The typeface shift from Signifier (reading) to Montreuil (functional) creates the distinction.
.section-label— Montreuil, 0.7rem, weight 600,text-transform: uppercase,letter-spacing: 0.05em,--text-2.margin-bottom: var(--space-sm).cursor: default(not interactive by default). Inside a<summary>, cursor switches topointer..section-label-link— Same visual treatment but rendered as an<a>element withtext-decoration: none; background-image: none. Transitions to--accenton hover.
Code example
HTML structure of a post list page (writing index):
<body>
<div class="scroll-progress" aria-hidden="true"></div>
<div class="site-wrapper">
<header class="site-header">
<nav class="breadcrumb" aria-label="Breadcrumb">
<a href="/" class="name" style="view-transition-name: nameplate;">Alex Priest</a>
<span class="separator" aria-hidden="true">-></span>
<span class="current">Writing</span>
</nav>
</header>
<main id="main">
<h1>Writing</h1>
<section class="year-group">
<h2 class="year-heading">2026</h2>
<ul class="post-list">
<li>
<a href="/writing/post-slug">
<span class="title">Post title</span>
<span class="latest-mark">Latest</span>
<span class="date">Feb 15, 2026</span>
</a>
</li>
<li>
<a href="/writing/another-post">
<span class="title">Another post</span>
<span class="date">Jan 28, 2026</span>
</a>
</li>
</ul>
</section>
<section class="year-group">
<h2 class="year-heading">2025</h2>
<ul class="post-list">
<li>
<a href="/writing/older-post">
<span class="title">Older post</span>
<span class="date">Dec 3, 2025</span>
</a>
</li>
</ul>
</section>
<p class="archive-link"><a href="/writing/archive">Older writing -></a></p>
</main>
<footer class="site-footer">
<!-- Colophon -->
</footer>
</div>
<aside class="side-rail" aria-label="Navigation">
<!-- Book-spine nav links -->
</aside>
</body>