diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index 6141c4e..ef1975b 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -1,9 +1,9 @@ --- name: Deploy to GitHub Pages -# Builds the static site and publishes ./dist to GitHub Pages on every push to -# master. One-time setup: repo Settings → Pages → Build and deployment → Source -# = "GitHub Actions". +# Builds the static site and publishes ./dist to GitHub Pages when a CalVer tag +# (e.g. 2026.8.0) is pushed; a push to master alone does not deploy. One-time +# setup: repo Settings → Pages → Build and deployment → Source = "GitHub Actions". on: push: @@ -32,7 +32,7 @@ jobs: with: bun-version: 1.3.14 - run: bun install --frozen-lockfile - # Gate the deploy on the same checks CI runs, so master never ships red. + # Gate the deploy on the same checks CI runs, so a tag never ships red. - run: bun run lint - run: bun run typecheck - run: bun test diff --git a/CLAUDE.md b/CLAUDE.md index 90221fb..b255a2a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,11 +6,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co A **fully static** world clock for digital signage: a board of cities, each showing its own local time, date, GMT offset and a day/night accent. Everything -on screen is driven by **URL query parameters** — there is no server and no +on screen is driven by **URL query parameters**: there is no server and no backend. The site builds to `./dist` and is published to **GitHub Pages**. It is modelled loosely on the sibling [`../clock-app`](../clock-app) (the -"Observatory" aesthetic — Fraunces serif over a night sky), but where clock-app +"Observatory" aesthetic: Fraunces serif over a night sky), but where clock-app is a single edge-rendered Cloudflare Worker clock, this is a self-contained, multi-zone, client-only static site. All client code is **TypeScript**. @@ -32,21 +32,22 @@ bun run sync-fonts # vendor webfonts from @fontsource only ``` CI (`.github/workflows/ci.yml`) runs lint → typecheck → test → build on every PR. -Pushing to `master` runs `deploy-pages.yml`, which re-runs those checks and -publishes `./dist` to GitHub Pages. +Deploys are tag-driven: pushing a CalVer tag (e.g. `2026.8.0`) runs +`deploy-pages.yml`, which re-runs those checks and publishes `./dist` to GitHub +Pages. Pushing to `master` on its own does not deploy. ## Architecture ### Pure logic vs. DOM (the split to preserve) -- **`src/clocks.ts`** — pure, side-effect-free helpers: URL parsing +- **`src/clocks.ts`** holds the pure, side-effect-free helpers: URL parsing (`parseClocks`), `Intl` formatter construction (`buildFormatters`), and the formatting/banding helpers. Every function takes an explicit `Date`, so tests are independent of the machine clock and timezone. This is the **only** file with unit tests (`src/clocks.test.ts`). Keep testable logic here. -- **`src/main.ts`** — the DOM driver: reads `location.search`, builds one card +- **`src/main.ts`** is the DOM driver: reads `location.search`, builds one card per clock, and repaints them on a shared timer. No `Intl`/parsing logic of its - own — it imports it from `clocks.ts`. Loaded as a `type="module"` script. + own; it imports it from `clocks.ts`. Loaded as a `type="module"` script. This mirrors clock-app's `locale.js` / `main.js` split, but here `main.ts` is a normal ES module (the static page uses `