Ryn

2026

Sine — a cinema programme for the services you already pay for

I rebuilt a streaming catalogue as a programme for tonight. It filters the home screen to films available on the services you already have.

Role
Product, interface and development; I set the direction for both rounds and made the scope decisions
Tools
Next.js · React · TypeScript · CSS Modules · Vitest · TMDB API · YouTube IFrame API · Vercel

The first version looked finished and answered the wrong question

I started Sine as a streaming browse app. It had a large feature at the top, rows of posters, title details, search, a saved list and YouTube trailers. It worked, but the shape was already familiar.

That was the problem. The first version proved I could finish a catalogue interface. It did not explain why this catalogue needed to exist or what decision I had made beyond building it.

I came to development from design, so I know a screen can look complete while avoiding the harder question. For Sine, that question was simple: what is this for?

The answer was not another place to browse every film. It was a programme for one evening, limited to the streaming services someone already pays for. That gave the second round a reason to exist and a rule for deciding what stayed.

I made tonight and your services the whole product

The new promise became: show me what I can watch tonight.

A visitor picks a country and ticks their services. Sine saves those choices on the device and uses them to decide every row on Home. The feature, the programme rows and the service marks all come from the same choice. Until a visitor chooses, the page says there are no showings yet instead of pretending it knows what is available to them.

I used one test for the redesign. If an element could be pasted back into a generic streaming clone without changing its meaning, I cut it. The general trending section and the old ranking badge went. The replacement is a ticket-like programme with a feature, a reason for the choice and a showtime.

The strict filter has a cost. A service with a small catalogue can produce fewer rows. I accepted that because a shorter programme that keeps its promise is better than a full page padded with films the visitor cannot stream.

Rent and buy offers do not count as showing tonight either. They still appear in the availability details, but they do not enter the home programme. The phrase “services you already pay for” stops being useful if the primary screen quietly asks for another payment.

Every screen now tells the truth about availability

The home screen is strict, but search, the saved list and similar titles are not. Those surfaces can show a film outside the programme because hiding it would make discovery worse. Each result therefore carries its availability state: on one of your services, available elsewhere, rent or buy, or not showing in the selected country.

That distinction shaped the data layer. Sine reads film metadata and regional watch-provider data from TMDB. The trailer player uses YouTube’s privacy-enhanced embed and falls back to a direct YouTube link when a video cannot play inside the page. The availability panel groups streaming offers before rent and buy, then links out to TMDB’s watch page for the selected country. Sine does not guess prices or scrape provider pages.

There is no account, server or database behind the product. The selected country, services and saved film ids live in local storage. That means no cross-device sync, and clearing browser storage clears the choices. In return, the deployed app is a static export and keeps no visitor profile on a server.

The rules are covered by automated checks because availability can fail quietly. The current suite has 332 passing tests across the programme, storage, trailer, search and interface behaviour, followed by a production build.

The programme is live and playback remains outside it

Sine is live at https://sine-iota.vercel.app. The deployed home page asks visitors to set up their programme, and the services page explains that suggestions come only from the services they tick. With live data, the app can fill a programme from a selected service while checking each title against that film’s own regional availability response.

The limit is deliberate and visible. Sine tells someone where a film is available and sends them to the provider path through TMDB. It does not play the film itself. I explored making playback part of the project and parked it because the public options either crossed a legal line or introduced a paid dependency that weakened the point of a small portfolio app.

A legitimate playback version would use a private media server for films I own, with Sine as the front door. That is a separate product decision, not a missing button. For this version, the outcome is the programme: one evening, one country and the services already on the bill.

Outcome

Sine is live at https://sine-iota.vercel.app with real film data, service-based availability and YouTube trailers.