diff --git a/CLAUDE.md b/CLAUDE.md index 829ca4511..58bd620e2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,6 +23,7 @@ decides which one a given file belongs in: |---|---| | **`www/`** | **everything the site serves.** Pages, client scripts, CSS, photos, dictionaries. If a browser can fetch it, it is in here. | | **`src/worker/`** | **the site Worker**, which was `www/_worker.js/` until 2026-08-16. It moved for the reason the row below already gave for cal and serendipity: it is a program with its own tests, not a document. It was never served either way (`.assetsignore` has always listed `_worker.js`), so the move changed no served byte. It STAGES to `.build/src/worker/`, mirroring its source path, and that mirroring is load-bearing rather than tidy: cal and serendipity import the Worker across the project boundary and are bundled from `.build/`, so a relative specifier has to resolve in BOTH trees, which is only possible when the two have the same shape. | +| **`src/client/`**, **`src/styles/`** | the client islands (`nav.js`, `tooltip.js`, `lens*.js`, `quiz.js`, …) and the stylesheets (`luna.css`, `lwe-base.css`, …), moved out of `www/` on 2026-08-16. They STAGE back to the root of the served tree, so their public URLs are still `/nav.js` and `/luna.css`: source layout and URL layout are different questions, and only the first one moved. Every served byte and every `/a/` content hash is unchanged. | | `cal/`, `serendipity/` | the two application modules the site Worker bundles and serves at `/coffee` and `/serendipity`. They sit outside `www/` because they are programs with their own tests, not documents. | | `cf-garage/`, `lwe-ask/`, `lens-reader/` | the three SEPARATELY deployed auxiliary Workers, each with its own `wrangler.toml` and its own deploy. Nothing here reaches production through the site Worker. | | **`scripts/`** | **every developer tool.** The build (`build.mjs`), the test suite (`contract-tests.mjs`), the route oracle, the perf budget, and the `check-*` / `gen-*` family. Nothing in here ships. | @@ -33,6 +34,12 @@ decides which one a given file belongs in: | `design/` | the Luna design system. `tokens/` and `DESIGN.md` are canonical; the rest is history, and `design/README.md` draws that line. | | `migrations/`, `talks/` | D1 SQL for the site Worker, and talk material. | +Three directories now compose the served URL root: `www/` plus `src/client/` +plus `src/styles/`, merged by `build.mjs` into `.build/www`. That is why +`config/tsconfig.browser.json` maps `/*` across all three rather than at `www/` +alone. An absolute specifier like `import "/hoist.js"` is checkable only if the +mapping names the directory the file actually authors in. + Four things stay at the repository root because their tooling demands it, and moving any of them costs more than it buys: @@ -804,17 +811,17 @@ Single-page personal site at `aadhar.sh`. A Cloudflare Worker with static assets |---|---| | `www/index.html` | The whole page in one file. Inline CSS + JS. ~58KB uncompressed, ~15.4KB zstd (measured 2026-07-21 via live nav-timing; CF serves zstd, not brotli). Served on the shared `PAGE_CACHE_CONTROL` (`lib/const.js`) like every other document, + ETag, and still never `no-store` (the one directive that would cost the page bfcache). It held `private, no-cache, must-revalidate` through its SSR era and kept it after the SSR left; that cost two things at once, since no shared cache could store it (every front-door hit ran the worker) and Chromium refuses to keep a dictionary offered under `no-cache` (so `/` was the ONE page outside the per-page dcz tier). Changed 2026-07-31. Comments deliberately kept readable for View Source. | | `www/writing/` | Written content as plain `.txt` files + `posts.json` registry `[{slug,title,date}]`. The worker renders each as an XP **Notepad** window at `/writing/` (a server-rendered `