A clean, full-screen quotation for digital signage. On each load it shows one work-friendly quote, chosen at random, set in the "Reading room" style — a large Fraunces serif over a warm ink ground with a gilt byline.
Live: https://quotes.srly.io
Part of the Screenly signage family alongside the weather and clock apps. Unlike those (Cloudflare Workers), this one is a fully static site hosted on GitHub Pages — random selection happens in the browser, so there's no server.
- Bun — package manager, bundler, and test runner (no npm/npx)
- TypeScript — all app JS, strict mode
- Tailwind CSS v4 — CSS-first config (
@theme), compiled by the Tailwind CLI - Biome — lint + format
- Self-hosted variable fonts (Fraunces, Hanken Grotesk), vendored from
@fontsource
bun install # install deps (fonts get vendored during build)
bun run dev # build, then serve dist/ locally
bun run build # build the static site into dist/
bun test # run unit + dataset tests
bun run typecheck # tsc --noEmit
bun run lint # Biome (lint:fix / format to auto-fix)bun run build is non-destructive: it assembles everything into dist/
(gitignored) — copies index.html + static assets, compiles Tailwind, bundles
the TypeScript, stamps a content-hash ?v= onto asset URLs for cache-busting,
and writes the CNAME.
assets/static/data/quotes.json holds 487 verified { text, author }
quotes. Candidates are generated by a one-off script (not part of the build):
bun run curate-quotesThat fetches the open, MIT-licensed Quotable
dataset, drops sensitive themes, keeps short punchy lines, dedupes, caps per
author, and samples an even spread of lengths. See scripts/curate-quotes.ts.
The shipped quotes go beyond curation: every one was adversarially
fact-checked for correct wording and attribution, and only verified quotes
were kept (1,430 audited → 487 kept; ~34% pass rate). Misquotes and
misattributions — e.g. "Do one thing every day that scares you" is Mary Schmich,
not Eleanor Roosevelt — were removed. See docs/AUDIT.md.
The layout is fluid (one clamp()-driven root size, orientation-neutral). Verified
landscape and portrait across:
| Resolution | Notes |
|---|---|
| 4096×2160 · 3840×2160 (+ portrait) | 4K |
| 1920×1080 (+ portrait) | 1080p |
| 1280×720 (+ portrait) | 720p |
| 800×480 (+ portrait) | Raspberry Pi Touch Display |
Push to master runs .github/workflows/deploy-pages.yml, which builds and
publishes dist/ to GitHub Pages. CI (ci.yml) typechecks, lints, tests, and
builds on every PR.
One-time setup (outside this repo):
- DNS:
CNAMErecordquotes.srly.io → screenly-labs.github.io. - Repo → Settings → Pages: Source = "GitHub Actions"; set the custom domain
to
quotes.srly.ioand enable "Enforce HTTPS" once the certificate provisions.
AGPL-3.0-only (see LICENSE). Quote text is from the MIT-licensed Quotable dataset.
