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:

  1. BreadcrumbAlex Priest -> [Section] in the site header. Provides context and a path home.
  2. Page titleh1 at the page level, outside any <article>. Signifier at the default heading scale.
  3. Section label.section-label marks each content group. Pure typographic markers with no decorative affordance.
  4. Content list — The list pattern appropriate to the content type: post list, media list, archive, or feed.
  5. 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.title in Signifier with font-variation-settings: 'wght' 400. On hover, shifts to weight 500 and --accent color. The weight-shift transition uses the signature easing: 0.4s cubic-bezier(0.22, 1, 0.36, 1).
  • Date.date in 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 with margin-right: auto.
  • Dividers1px solid var(--ui) bottom border on each <li> except the last.
  • Spacingpadding: var(--space-sm) 0 per 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-title in Signifier, font-variation-settings: 'wght' 400. Same weight-shift hover as post list titles (to 500, accent color).
    • .media-year in Montreuil, 0.85rem, --text-2.
    • .type-badge colored from the pill companion triple (--pill-1 for Film, --pill-2 for TV, --pill-3 for Game). Montreuil, 0.6rem, uppercase, with color-mix(in srgb, var(--pill-n) 8%, transparent) background.
    • .season-pill for TV season indicators. Montreuil, 0.6rem, --text-2 on a --ui tinted background.
  • Right group (.media-meta-right) — Rating and date. display: flex; align-items: baseline; gap: var(--space-sm); flex-shrink: 0.
    • .rating in --accent at 0.85rem (star characters).
    • .date in Montreuil, 0.8rem, --text-2.
  • Mobile — At <=600px, each <li> stacks to flex-direction: column; align-items: flex-start. The right group spans full width with justify-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 with line-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/archive for 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, &#10022;) 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 to pointer.
  • .section-label-link — Same visual treatment but rendered as an <a> element with text-decoration: none; background-image: none. Transitions to --accent on 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>