watchinorder

watchinorder.in

Curated watch orders for film and TV franchises. Release order or in-universe chronology, an essentials-only path, and local watch tracking — starting with the MCU and DC, built to take any franchise.

Next.js (App Router) · TypeScript · Tailwind v4 · Radix · Framer Motion.

No API, no database, no images. Every fact the site renders lives in a TypeScript file under content/. The build makes zero network calls, so it is reproducible offline and every data change shows up in a diff.

Getting started

npm install
npm run dev          # http://localhost:3000
script does
npm run dev dev server
npm run build production build (fully static)
npm run typecheck tsc --noEmit

How it fits together

content/franchises/*.ts   the data — one file per franchise, hand-curated
content/guides.ts         long-form SEO landing pages
lib/types.ts              the schema
lib/franchises.ts         registry + resolution   (server — pulls in all content)
lib/ordering.ts           sort/filter/group/format (pure — safe for the client)
app/[franchise]/          hub page and per-title pages

The split between lib/franchises.ts and lib/ordering.ts is deliberate. The hub UI is a client component; if it imported the registry it would drag every franchise’s dataset into the browser bundle. It receives resolved data as props and uses lib/ordering instead.

Adding a franchise

  1. Write content/franchises/<slug>.ts.
  2. Add it to FRANCHISES in lib/franchises.ts.

That’s it. Routing, the sitemap, the home page, nav and footer all read from that array.

Adding or editing a title

Open the franchise file and edit the array. Two fields are worth understanding:

runtime is optional and currently unset on every entry. Fill it in and it appears on the detail page, in the quick view, and as duration in the page’s JSON-LD. Leave it off and none of that renders — omit rather than guess.

Design without artwork

There is no poster art anywhere, by design. The position numeral carries the visual weight instead: set large in the display face, tinted with the group colour, and echoed as an oversized watermark behind the card and hero text. Franchise and group identity come from colour rails and accents, not imagery — which also means every page is text-only and renders instantly.

Franchise theming

Each franchise sets theme.accent / accent2 / glow. <FranchiseTheme> writes those to CSS custom properties on a wrapper; buttons, gradients, focus rings and the ambient page glow all read the same variables. One wrapper repaints the whole identity — there are no per-franchise conditionals in components.

SEO

Accessibility

prefers-reduced-motion is respected globally in CSS and per-component via Framer Motion’s useReducedMotion. Dialogs and toggles are Radix primitives. There’s a skip link, breadcrumbs, and keyboard nav in the quick view (← → to step, Esc to close).

Data accuracy

Read content/GAPS.md. Current as of 3 August 2026: 112 titles, including announced releases through December 2026. Release dates are sourced; needsCheck now flags only uncertain phase labels, and the chronological orderings are opinion in places. That file records all of it.

Titles with a future releaseDate are marked upcoming automatically at build time — they appear in the lists but are excluded from watch-progress totals. Rebuilding is what rolls them over as they release.

The previous version

legacy/ holds the original zero-build static MCU site this grew out of. Kept for reference — its interaction patterns (order toggle, sticky section headers with per-group progress, cursor tilt, scroll reveal) were ported rather than reinvented. Nothing in the app imports from it.