# TT Festival timetable visualiser

A standalone, static HTML page that renders the TT Festival programme **by day, stage
and time** (clash-finder style grid + a per-stage list view).

Open [`index.html`](index.html) in any browser — no server, build step or network
access required. All data is embedded in the page.

> **Looking for the live programme?** This page is a **frozen 2026-06-08
> snapshot**. A live, **hourly-refreshed** version (opens on today, jumps to the
> current hour) is published from a separate repo at
> <https://graafg.github.io/tt-timetable/>. For how the live API is accessed, see
> [`docs/timetable-api-access.md`](../../docs/timetable-api-access.md).

## Where the data comes from

The festival app does **not** render the timetable from data baked into the APK — it
downloads it at runtime from the white-label **Appmiral** backend and caches it locally:

- **API base:** `https://app.appmiral.com/api/v7/`
- **Route shape:** `events/ttfestival/editions/ttfestival2026/{stages,performances,artists}`
- The read API is gated: with **no** auth it returns `403 Missing authentication`,
  and it recognises an `X-Api-Key` header (rejecting unknown keys with `401`).
  It was later found that the app's static **`x-protect`** header (hardcoded in
  the APK) unlocks the API with `200 OK` — that is how the *live* version above is
  built. See [`docs/timetable-api-access.md`](../../docs/timetable-api-access.md).

When this page was first built that live access had not yet been achieved, so it
was built from the app's on-device SQLite cache instead (tables `Performance`,
`Stage`, `Artist`):

- **Source:** `db_ttfestival2026_nl.sqlite` (captured 2026-06-08)
- **Contents:** 87 performances · 17 stages · 56 artists, 20–28 June 2026
- Times are stored in UTC and rendered in **Europe/Amsterdam (CEST)**.

`timetable.json` is the extracted dataset (also embedded inside `index.html`).

## Features

- Day tabs (late-night sets group with the day they belong to).
- **Grid** view: stage columns coloured with each stage's own colour, time axis,
  blocks positioned by start/end time.
- **List** view: performances grouped per stage, ordered by time.
- Free-text filter (artist / stage).
- Click any performance for details (stage, time, sold-out flag, artist bio/image
  when present in the dataset).

## Notes

- This is a **snapshot**, not a live feed. The live, hourly-refreshed version is
  at <https://graafg.github.io/tt-timetable/> (built straight from the Appmiral
  API via the `x-protect` header — see
  [`docs/timetable-api-access.md`](../../docs/timetable-api-access.md)). To refresh
  *this* embedded copy you would re-extract the three tables from a current app
  cache, or pull them live from the API.
- A few biographies contain mojibake (e.g. `fresia�s`) — that encoding artefact is
  present in the source data and is left unmodified.
