<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="color-scheme" content="light dark" />
<title>Unread โ FeatherReader</title>
<link rel="stylesheet" href="feather.css" />
<script>
(function () {
var q = new URLSearchParams(location.search);
["theme", "state", "overlay"].forEach(function (k) {
var v = q.get(k);
if (v) document.documentElement.dataset[k] = v;
});
})();
</script>
</head>
<body>
<a class="skip-link" href="#content">Skip to content</a>
<div class="shell" id="shell">
<header class="topbar">
<button class="icon-btn" id="rail-toggle" aria-label="Open navigation"
aria-expanded="false" aria-controls="rail">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"
stroke-linecap="round" aria-hidden="true">
<path d="M4 7h16M4 12h16M4 17h16"/>
</svg>
</button>
<h1 class="topbar-title">Unread <span class="topbar-count">24</span></h1>
<button class="icon-btn" aria-label="Mark all read"
hx-post="/entries/mark-all-read" hx-target="#content" hx-swap="innerHTML">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M3 13l4 4L15 9"/><path d="M9 13l4 4 8-8"/>
</svg>
</button>
</header>
<button class="scrim" id="scrim" tabindex="-1" aria-hidden="true"></button>
<nav class="rail" id="rail" aria-label="Feeds">
<div class="rail-head">
<a class="brand" href="list.html">
<svg class="brand-mark" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M20.2 4.6c-2.3-2.3-7.2-1.4-10 1.4C7.4 8.8 4 17 4 20c3 0 11.2-3.4 14-6.2 2.8-2.8 4.5-6.9 2.2-9.2z"/>
<path d="M16 8 5 19"/>
</svg>
<span>FeatherReader</span>
</a>
<button class="icon-btn rail-close" id="rail-close" aria-label="Close navigation">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"
stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg>
</button>
</div>
<div class="rail-scroll">
<div class="filter" role="group" aria-label="Filter entries">
<a class="filter-opt" href="#">All</a>
<a class="filter-opt" href="#" aria-current="page">Unread</a>
<a class="filter-opt" href="#">Starred</a>
</div>
<div class="folder">
<h2 class="folder-name">Tech</h2>
<ul class="feed-list">
<li>
<a class="feed-link has-unread" href="#">
<span class="feed-name">Julia Evans</span>
<span class="feed-count">3</span>
</a>
</li>
<li>
<a class="feed-link has-unread" href="#" aria-current="page">
<span class="feed-name">Simon Willison</span>
<span class="feed-count">7</span>
</a>
</li>
<li>
<a class="feed-link" href="#">
<span class="feed-name">Dan Luu</span>
</a>
</li>
<li>
<a class="feed-link has-unread" href="#">
<span class="feed-name">The Pragmatic Engineer</span>
<span class="feed-count">2</span>
</a>
</li>
</ul>
</div>
<div class="folder">
<h2 class="folder-name">Essays</h2>
<ul class="feed-list">
<li>
<a class="feed-link has-unread" href="#">
<span class="feed-name">Craig Mod</span>
<span class="feed-count">1</span>
</a>
</li>
<li>
<a class="feed-link" href="#">
<span class="feed-name">Robin Rendle</span>
</a>
</li>
<li>
<a class="feed-link has-unread" href="#">
<span class="feed-name">The Marginalian</span>
<span class="feed-count">11</span>
</a>
</li>
</ul>
</div>
<div class="folder">
<h2 class="folder-name">Feeds</h2>
<ul class="feed-list">
<li>
<a class="feed-link" href="#">
<span class="feed-name">Low-tech Magazine</span>
</a>
</li>
</ul>
</div>
<div class="rail-tools">
<a class="rail-tool" href="add-feed.html">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"
stroke-linecap="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
Manage feeds
</a>
</div>
</div>
<p class="kbd-hint">Press <kbd>?</kbd> for keyboard shortcuts</p>
<div class="identity">
<span class="avatar" aria-hidden="true">js</span>
<span class="identity-meta">
<span class="identity-handle">@justin-stanley.com</span>
<span class="identity-note">your feeds live in your PDS</span>
</span>
<button class="btn-quiet" type="submit" form="signout">Sign out</button>
<form id="signout" method="post" action="/logout" hidden></form>
</div>
</nav>
<main class="content" id="content">
<div class="content-head">
<h1 class="content-title">Unread</h1>
<span class="content-count">24 entries</span>
<span class="content-spacer"></span>
<button class="btn-quiet"
hx-post="/entries/mark-all-read" hx-target="#content" hx-swap="innerHTML">
Mark all read
</button>
</div>
<ul class="entry-list" id="entry-list">
<li class="entry is-cursor" id="entry-1">
<a class="entry-main" href="reader.html">
<span class="entry-title">Notes on running a small, calm web service for a decade</span>
<span class="entry-snippet">What actually breaks over ten years isn't the code โ it's certificates, disks, and your own enthusiasm. Some notes on building for the long quiet haul.</span>
<span class="entry-meta">
<span class="entry-feed">Simon Willison</span>
<span class="sep" aria-hidden="true">ยท</span>
<time class="entry-time" datetime="2026-07-12T08:20:00Z">2h</time>
</span>
</a>
<button class="star-btn" aria-pressed="false" aria-label="Star entry"
hx-post="/entries/1/star" hx-swap="outerHTML">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"
stroke-linejoin="round" aria-hidden="true">
<path d="M12 3.5l2.6 5.3 5.9.9-4.2 4.1 1 5.8-5.3-2.8-5.3 2.8 1-5.8L3.5 9.7l5.9-.9z"/>
</svg>
</button>
</li>
<li class="entry" id="entry-2">
<a class="entry-main" href="reader.html">
<span class="entry-title">The disappearing art of the personal blogroll</span>
<span class="entry-snippet">Before algorithms decided what you read next, people did. A look at how blogrolls worked as a web of trust, and why the RSS revival is quietly bringing them back.</span>
<span class="entry-meta">
<span class="entry-feed">Robin Rendle</span>
<span class="sep" aria-hidden="true">ยท</span>
<time class="entry-time" datetime="2026-07-12T05:41:00Z">5h</time>
</span>
</a>
<button class="star-btn" aria-pressed="true" aria-label="Unstar entry"
hx-post="/entries/2/star" hx-swap="outerHTML">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"
stroke-linejoin="round" aria-hidden="true">
<path d="M12 3.5l2.6 5.3 5.9.9-4.2 4.1 1 5.8-5.3-2.8-5.3 2.8 1-5.8L3.5 9.7l5.9-.9z"/>
</svg>
</button>
</li>
<li class="entry" id="entry-3">
<a class="entry-main" href="reader.html">
<span class="entry-title">Walking Tokyo's Nakasendล, one photograph at a time</span>
<span class="entry-snippet">Day four: rain on cedar, a kissaten with exactly three seats, and the particular silence of a post town at 6 a.m.</span>
<span class="entry-meta">
<span class="entry-feed">Craig Mod</span>
<span class="sep" aria-hidden="true">ยท</span>
<time class="entry-time" datetime="2026-07-11T22:10:00Z">12h</time>
</span>
</a>
<button class="star-btn" aria-pressed="false" aria-label="Star entry"
hx-post="/entries/3/star" hx-swap="outerHTML">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"
stroke-linejoin="round" aria-hidden="true">
<path d="M12 3.5l2.6 5.3 5.9.9-4.2 4.1 1 5.8-5.3-2.8-5.3 2.8 1-5.8L3.5 9.7l5.9-.9z"/>
</svg>
</button>
</li>
<li class="entry is-read" id="entry-4">
<a class="entry-main" href="reader.html">
<span class="entry-title">How SQLite runs the world's quietest databases</span>
<span class="entry-snippet">A single file, no server, and more deployments than every other database combined. On the engineering culture behind the most boring software alive.</span>
<span class="entry-meta">
<span class="entry-feed">Julia Evans</span>
<span class="sep" aria-hidden="true">ยท</span>
<time class="entry-time" datetime="2026-07-11T15:02:00Z">19h</time>
</span>
</a>
<button class="star-btn" aria-pressed="false" aria-label="Star entry"
hx-post="/entries/4/star" hx-swap="outerHTML">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"
stroke-linejoin="round" aria-hidden="true">
<path d="M12 3.5l2.6 5.3 5.9.9-4.2 4.1 1 5.8-5.3-2.8-5.3 2.8 1-5.8L3.5 9.7l5.9-.9z"/>
</svg>
</button>
</li>
<li class="entry" id="entry-5">
<a class="entry-main" href="reader.html">
<span class="entry-title">A solar-powered website, three years on</span>
<span class="entry-snippet">Our server has been offline for a cumulative nineteen days since 2023 โ and that's fine. What a weather-dependent website taught us about acceptable downtime.</span>
<span class="entry-meta">
<span class="entry-feed">Low-tech Magazine</span>
<span class="sep" aria-hidden="true">ยท</span>
<time class="entry-time" datetime="2026-07-11T09:30:00Z">1d</time>
</span>
</a>
<button class="star-btn" aria-pressed="false" aria-label="Star entry"
hx-post="/entries/5/star" hx-swap="outerHTML">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"
stroke-linejoin="round" aria-hidden="true">
<path d="M12 3.5l2.6 5.3 5.9.9-4.2 4.1 1 5.8-5.3-2.8-5.3 2.8 1-5.8L3.5 9.7l5.9-.9z"/>
</svg>
</button>
</li>
<li class="entry is-read" id="entry-6">
<a class="entry-main" href="reader.html">
<span class="entry-title">Emily Dickinson's herbarium and the taxonomy of attention</span>
<span class="entry-snippet">Decades before the poems, a teenage Dickinson pressed 424 flowers into a leather album โ a masterclass in the art of noticing.</span>
<span class="entry-meta">
<span class="entry-feed">The Marginalian</span>
<span class="sep" aria-hidden="true">ยท</span>
<time class="entry-time" datetime="2026-07-10T20:15:00Z">2d</time>
</span>
</a>
<button class="star-btn" aria-pressed="true" aria-label="Unstar entry"
hx-post="/entries/6/star" hx-swap="outerHTML">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"
stroke-linejoin="round" aria-hidden="true">
<path d="M12 3.5l2.6 5.3 5.9.9-4.2 4.1 1 5.8-5.3-2.8-5.3 2.8 1-5.8L3.5 9.7l5.9-.9z"/>
</svg>
</button>
</li>
<li class="entry" id="entry-7">
<a class="entry-main" href="reader.html">
<span class="entry-title">Why your feed reader should do less</span>
<span class="entry-snippet">Every feature is a small tax on calm. An argument for readers that subtract: no recommendations, no rules engines, no unread-count anxiety mechanics.</span>
<span class="entry-meta">
<span class="entry-feed">The Pragmatic Engineer</span>
<span class="sep" aria-hidden="true">ยท</span>
<time class="entry-time" datetime="2026-07-10T11:00:00Z">2d</time>
</span>
</a>
<button class="star-btn" aria-pressed="false" aria-label="Star entry"
hx-post="/entries/7/star" hx-swap="outerHTML">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"
stroke-linejoin="round" aria-hidden="true">
<path d="M12 3.5l2.6 5.3 5.9.9-4.2 4.1 1 5.8-5.3-2.8-5.3 2.8 1-5.8L3.5 9.7l5.9-.9z"/>
</svg>
</button>
</li>
</ul>
<div class="empty">
<svg class="empty-mark" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M20.2 4.6c-2.3-2.3-7.2-1.4-10 1.4C7.4 8.8 4 17 4 20c3 0 11.2-3.4 14-6.2 2.8-2.8 4.5-6.9 2.2-9.2z"/>
<path d="M16 8 5 19"/>
</svg>
<h2 class="empty-title">All caught up</h2>
<p class="empty-note">Nothing unread. The quiet is the point.</p>
</div>
<div class="list-actions">
<button class="btn"
hx-post="/entries/mark-all-read" hx-target="#content" hx-swap="innerHTML">
Mark all read
<span class="htmx-indicator spinner" aria-hidden="true"></span>
</button>
</div>
</main>
</div>
<div class="kbd-overlay" id="kbd-overlay" role="dialog" aria-modal="true"
aria-labelledby="kbd-title">
<div class="kbd-card">
<h2 id="kbd-title">Keyboard shortcuts</h2>
<dl>
<dt><kbd>j</kbd> / <kbd>k</kbd></dt><dd>Next / previous entry</dd>
<dt><kbd>o</kbd></dt><dd>Open entry</dd>
<dt><kbd>m</kbd></dt><dd>Toggle read</dd>
<dt><kbd>s</kbd></dt><dd>Star / unstar</dd>
<dt><kbd>A</kbd></dt><dd>Mark all read</dd>
<dt><kbd>?</kbd></dt><dd>This overlay</dd>
<dt><kbd>Esc</kbd></dt><dd>Close</dd>
</dl>
<button class="btn kbd-close" id="kbd-close">Close</button>
</div>
</div>
<script src="keyboard.js" defer></script>
</body>
</html>