Inspiration

Before the internet was in every pocket, millions of people in the UK got their news, football scores and weather from teletext: blocky pages of coloured text on the TV, reached by typing a three-digit page number on the remote and waiting while the header counted through the pages. It was switched off years ago, but its design was brilliant: instant, scannable, no ads, no clutter. For Kiroween's Resurrection category I wanted to bring it back from the dead, faithfully, and make it run anywhere with a link.

What it does

Page 100 is a teletext service in your browser:

  • Type a page number (keyboard or on-screen remote). The header shows SEARCH.. and rolls through page numbers, just like the real thing, before the page appears.
  • Fastext: four coloured shortcuts on the bottom row (R / G / Y / C keys, the remote's coloured buttons, or a click).
  • Authentic rendering: a 40×25 character grid in the eight teletext colours, the public-domain Bedstead teletext font, 2×3 mosaic block graphics, double-height headlines, flashing text and a live clock in the header.
  • Multi-part pages rotate every 15 seconds (1/2, 2/2); press H to hold.
  • Concealed text: the quiz page hides its answers until you press V / Reveal.
  • "Page not found" for pages that aren't being broadcast.
  • Accessible: a plain-text screen-reader view of every page (Alt+T), and an on-screen remote that moves under the picture on phones.

Pages: 100 index with a block-graphics logo, 101 news, 150 quiz, 302 football scores, 401 a UK weather map drawn entirely in teletext mosaics. (Mock content is fictional.)

How I built it (with Kiro)

Steering first. I wrote three steering files (product.md, tech.md, structure.md) so every Kiro request knew the rules: authentic 40×25 teletext, TypeScript + Vite, tests for every module, pages as pure functions, no API keys in the repo.

Spec-driven development. I described the teletext engine and let Kiro generate the spec, then reviewed each stage before approving:

  • Requirements (14, EARS format). Reviewing them caught real bugs before any code existed: the header row placed the clock in columns 36–43 on a 40-column grid, and Reveal was described both as display-only and as changing cell data. I had Kiro fix both, make the on-screen remote available on every device, and tidy the screen-reader output.
  • Design. Kiro produced the architecture, interfaces, a navigation state machine and 9 correctness properties. I had it switch to TypeScript to match the steering, make the data provider async so live data can plug in later without rewriting navigation, add Fastext labels, bundle the Bedstead font, and render crisply on Retina screens.
  • Tasks. A 21-task, dependency-ordered plan. I made sure it set up Vite, made every test task required, and added the font, README and licence.

Implementation. Kiro implemented the project setup and the first engine modules (grid model, colours, mosaics, number entry, with property-based tests).

Hooks.

  • Run tests on save: runs the full Vitest suite whenever a source or test file is saved (a runCommand hook).
  • Page directory check: when the pages change, asks Kiro to verify the index, every Fastext link and the README page table still match.

Stack: TypeScript, Vite, Canvas 2D, Vitest + fast-check, GitHub Pages. No UI framework, about 20 KB of JavaScript.

Challenges I ran into

  • Pixel-perfect teletext on modern screens. Cells must be whole pixels or the block graphics blur, yet the grid must stay roughly 4:3 at any window size and look sharp on high-DPI displays. The layout is computed in device pixels and the canvas is scaled by devicePixelRatio.
  • Double-height text spans two rows, so the renderer has to know which cells are "covered" by the row above and never paint over them.
  • Mosaic graphics: teletext packs a 2×3 pixel block into one character code with a non-obvious bit layout. Property-based tests prove the encode/decode round-trip for every valid code.
  • Spec bugs: the header overflow and the Reveal contradiction were only caught because the spec was reviewed carefully. That was a good lesson in why spec-first matters.

Accomplishments that I'm proud of

  • It genuinely feels like teletext, down to the rolling page search.
  • 150 tests, including property-based tests, with 100% line coverage on the engine and data modules.
  • A UK weather map drawn entirely in 2×3 mosaic characters.
  • Accessible by design: a screen-reader text view and full keyboard control.

What I learned

  • Spec-first development catches design bugs while they're still cheap: a clock that doesn't fit is a one-line requirement fix, not a rendering bug hunt.
  • Steering files keep an AI agent consistent across dozens of requests.
  • Property-based testing is ideal for encodings like teletext mosaics.

What's next for Page 100

  • Live data: real headlines, weather and football scores through the async data provider (a second Kiro spec).
  • A spooky page 666 for Halloween, with static, ghosts and flickering text.
  • More pages (TV listings, a news ticker), and an installable app (PWA) for phones and TVs.

Built With

Share this project:

Updates

Submission history