A map of the site. Click a line to read what that part is about.
The whole site: a few static files and two tiny PHP endpoints, rsynced to shared hosting. No build step.
Larry’s photo (one of three, random), a random quote with an “another quote” button, recommended pages, and the contact box.
Shared by every page: the wordmark, which shrinks on interior pages.
Three external sites worth reading: Reasonable Deviations, sneed.ing, streams.place. They open in a new tab.
Castlefall, its rules, Set with Friends, and NFL Pick’em.
An expandable mail form. It posts to contact.php, which validates, spam-checks, and sends to [email protected].
An expandable list of every quote in the pool. The pool itself lives in quotes.js.
Tweets about websites, rendered as black cards: avatar, username, date, native text, rehosted images, quoted tweets, replies. Data lives in thoughts.js.
Rehosted tweet images and avatars, so nothing depends on the originals staying up.
Six to ten people, two hidden teams, one word each. Everyone sees the same word list in a different order. A port of betaveros’s game — same rules, same protocol, rewritten to fit a site with no build step. Room name rides in the URL hash.
The game page: join a room, start a round, declare victory, and watch the leaderboard.
The whole client in one hand-written file: no React, no bundler. Talks JSON over a WebSocket, reconnects on its own with backoff, and comes straight back when you unlock your phone.
Styles for the game page: board, cards, chat, leaderboard.
How to play, adapted from the original README: the two ways to declare victory, suggested team sizes, and what makes a good clue.
The one piece of this site that isn’t a file on the host. Rooms need something to hold state and push it to everyone at once, so the server is a Cloudflare Worker with one Durable Object per room, answering at /castlefall/ws. Its source lives in the repo but never ships here.
Two people join the same lobby by code and pick every game of the week. Neither one sees the other’s picks until both have submitted, and the results arrive on their own after that.
Lobbies, picks and submissions need somewhere to live, so this is a Cloudflare Worker with a D1 database and a cron trigger, answering at /picks/api/. The cron fetches results from ESPN on a schedule, so nobody has to score a week by hand. Its source lives in the repo but never ships here.
The four PHP includes that make up the chrome every page shares: head, masthead, crumb, footer.
Opens the document: the doctype, the head, the inline theme script that runs before first paint, and the stylesheet link.
The wordmark — identical on every page, shrunk on interior pages.
The breadcrumb trail, driven by each page’s $crumb.
Closes the document: the visitor counter, the deploy stamp, and the site.js script tag.
The token contract and every component class. Themes express themselves entirely through tokens — same markup, different skin.
The theme switcher and the hit counter. Shows the counter only if counter.php answers.
The Larry David quote pool, one { q, cite } entry per line. Edit it, commit, push.
The thoughts data: a flat store of tweets keyed by id, plus the ordered list of which ones appear on thoughts.php.
Three photos of Larry David; the homepage rotates them along with the quotes.
The tiny backend behind the contact form. Validates the post, honeypot + rate limit, mails [email protected].
The visitor counter, polled by site.js and shown in the footer only if it answers.
Apache config: caching headers, the extensionless rewrites, and a deny on _private/.
You are here. A map of everything above.