sky: Midnight Sky and Noonday Sky baked from sun.js; bubbles and buttons as albedo x irradiance (do not merge) #22

Closed
void wants to merge 3 commits from void/sky-tokens into void/sky-sun
Member

Stacked on #20 (void/sky-sun, head 7c89bd02); do not merge. Supersedes #18's Dawn/Day/Dusk themes with the two names Meta ruled: Midnight Sky (dark) and Noonday Sky (light). No terrain anywhere in this PR.

What it does

  1. Baked fallback sky. scripts/bake-sky.mjs (npm run bake:sky) lights a fixed moment with sun.js (equinox, 45N on the prime meridian; clear weather because a bake has no feed) and writes src/sky/baked.ts: a 7-stop vertical sky gradient per theme. src/sky.css.ts paints it as the fixed body background (body.midnight-sky, body.noonday-sky). Sun elevation at the two moments: -44.6 and +45.2 degrees.
  2. Bubbles and buttons are albedo x irradiance. src/sky/skyTokens.js holds the albedos (bark, pale bark, leaf, new leaf, soil, clay, ochre, eight pigments for names) and multiplies each by the irradiance colour sun.js returns (diffuse + direct * sin(elevation), rescaled to a per-role brightness key, since the eye adapts to the scene and only the light's colour survives). Output: folds tokens for Background/Surface/SurfaceVariant and Primary/Secondary/Success/Warning/Critical (leaf for Primary, bark for Secondary), link colour, --mx-uc-1..8, and bubble vars --sky-bubble, --sky-bubble-own and their text colours. Keys, albedos and the horizon mix are tuned by eye and marked EYEBALLED. colors.css.ts replaces the navy gamecultTheme with midnightSkyTheme / noondaySkyTheme built from the bake; index.css keeps only the GameCult type rules; default themeId is midnight-sky.
  3. Chat bubbles. There is no bubble component on this line (it is in #2 / #16). This PR publishes the bubble colours as CSS variables on the theme classes for those PRs to consume; it does not restyle message layout.

Contrast (WCAG AA, 4.5:1) — src/sky/skyTokens.test.ts

Computed from the baked hex values with the WCAG relative-luminance formula.

Midnight Sky Noonday Sky
Message text on Background / Surface / SurfaceVariant (rest, hover, active), lowest 10.23 6.06
Text in other people's bubble 12.17 6.70
Text in own bubble 9.82 6.56
Button labels, lowest over 5 roles x rest/hover/active 4.52 (Critical) 4.61 (Warning)
Primary button label (rest) 6.09 6.19
Link colour, lowest over panels and bubbles 4.58 4.52
Names (--mx-uc-*), lowest over panels and bubbles 4.50 4.54
Body text straight on the sky gradient, lowest 5.05 7.62

Mechanism, so the numbers are not luck: button, link and name colours are pushed brighter (dark) or darker (light) until they clear 4.5 on every ground they can sit on, and the test fails if any pair drops below 4.5 or if baked.ts differs from a fresh bake. It caught one real miss while writing (Noonday link on Background was 4.45). Contrast is checked on the solid token colours; nothing is translucent here.

Verified / not

vitest run in a TMPDIR copy: 157 pass (13 files, includes 12 new). vite build ok (CINNY_BASE=/void/sky-tokens/). eslint clean on the new and edited files except one no-explicit-any warning in the test; sun.js itself (from #20) has eslint style errors (Math.pow, nested ternary, cloud_cover camelCase) that I left alone. Nothing has been seen rendered (no browser here): the gradient, panel depth and the Midnight Critical button (clay under blue light reads violet) want a Redmi/desktop look. Existing users with themeId: gamecult-theme fall back to Midnight Sky. The opt-in WebGL scene palette still has its own navy sky. Not merged, no deploy; no preview needs a login.

Note for the stewards: the workspace-level /var/lib/mind-void-self/package.json is a 0-byte file, which makes vitest fail from inside this checkout (Unexpected end of file in JSON); tests were run from a copy.

Who shaped this

From Void's recorded notes, not verbatim transcripts, except the two quoted lines (already quoted in #20):

  • Meta (2026-11-06): themes named Midnight Sky and Noonday Sky; the palette derived from a simplified physically based shading of bark/leaf/soil albedos lit by the sky; UI elements as parts of Yggdrasil, with the fallback being a baked sky plus PBR-coloured bubbles and buttons.

"Ratatoskr themes are named Midnight Sky (dark mode) and Noonday Sky (light mode)."

  • Nibu: sun.js and its weather-shaped inputs, which this PR consumes unchanged.

🤖 Generated with Claude Code

Stacked on #20 (`void/sky-sun`, head 7c89bd02); do not merge. Supersedes #18's Dawn/Day/Dusk themes with the two names Meta ruled: Midnight Sky (dark) and Noonday Sky (light). No terrain anywhere in this PR. ## What it does 1. **Baked fallback sky.** `scripts/bake-sky.mjs` (`npm run bake:sky`) lights a fixed moment with `sun.js` (equinox, 45N on the prime meridian; clear weather because a bake has no feed) and writes `src/sky/baked.ts`: a 7-stop vertical sky gradient per theme. `src/sky.css.ts` paints it as the fixed body background (`body.midnight-sky`, `body.noonday-sky`). Sun elevation at the two moments: -44.6 and +45.2 degrees. 2. **Bubbles and buttons are albedo x irradiance.** `src/sky/skyTokens.js` holds the albedos (bark, pale bark, leaf, new leaf, soil, clay, ochre, eight pigments for names) and multiplies each by the irradiance colour `sun.js` returns (`diffuse + direct * sin(elevation)`, rescaled to a per-role brightness key, since the eye adapts to the scene and only the light's colour survives). Output: folds tokens for Background/Surface/SurfaceVariant and Primary/Secondary/Success/Warning/Critical (leaf for Primary, bark for Secondary), link colour, `--mx-uc-1..8`, and bubble vars `--sky-bubble`, `--sky-bubble-own` and their text colours. Keys, albedos and the horizon mix are tuned by eye and marked EYEBALLED. `colors.css.ts` replaces the navy `gamecultTheme` with `midnightSkyTheme` / `noondaySkyTheme` built from the bake; `index.css` keeps only the GameCult type rules; default `themeId` is `midnight-sky`. 3. **Chat bubbles.** There is no bubble component on this line (it is in #2 / #16). This PR publishes the bubble colours as CSS variables on the theme classes for those PRs to consume; it does not restyle message layout. ## Contrast (WCAG AA, 4.5:1) — `src/sky/skyTokens.test.ts` Computed from the baked hex values with the WCAG relative-luminance formula. | | Midnight Sky | Noonday Sky | |---|---|---| | Message text on Background / Surface / SurfaceVariant (rest, hover, active), lowest | 10.23 | 6.06 | | Text in other people's bubble | 12.17 | 6.70 | | Text in own bubble | 9.82 | 6.56 | | Button labels, lowest over 5 roles x rest/hover/active | 4.52 (Critical) | 4.61 (Warning) | | Primary button label (rest) | 6.09 | 6.19 | | Link colour, lowest over panels and bubbles | 4.58 | 4.52 | | Names (`--mx-uc-*`), lowest over panels and bubbles | 4.50 | 4.54 | | Body text straight on the sky gradient, lowest | 5.05 | 7.62 | Mechanism, so the numbers are not luck: button, link and name colours are pushed brighter (dark) or darker (light) until they clear 4.5 on every ground they can sit on, and the test fails if any pair drops below 4.5 or if `baked.ts` differs from a fresh bake. It caught one real miss while writing (Noonday link on Background was 4.45). Contrast is checked on the solid token colours; nothing is translucent here. ## Verified / not `vitest run` in a TMPDIR copy: 157 pass (13 files, includes 12 new). `vite build` ok (`CINNY_BASE=/void/sky-tokens/`). eslint clean on the new and edited files except one `no-explicit-any` warning in the test; `sun.js` itself (from #20) has eslint style errors (`Math.pow`, nested ternary, `cloud_cover` camelCase) that I left alone. **Nothing has been seen rendered** (no browser here): the gradient, panel depth and the Midnight Critical button (clay under blue light reads violet) want a Redmi/desktop look. Existing users with `themeId: gamecult-theme` fall back to Midnight Sky. The opt-in WebGL scene palette still has its own navy sky. Not merged, no deploy; no preview needs a login. Note for the stewards: the workspace-level `/var/lib/mind-void-self/package.json` is a 0-byte file, which makes `vitest` fail from inside this checkout (`Unexpected end of file in JSON`); tests were run from a copy. ## Who shaped this From Void's recorded notes, not verbatim transcripts, except the two quoted lines (already quoted in #20): - **Meta** (2026-11-06): themes named Midnight Sky and Noonday Sky; the palette derived from a simplified physically based shading of bark/leaf/soil albedos lit by the sky; UI elements as parts of Yggdrasil, with the fallback being a baked sky plus PBR-coloured bubbles and buttons. > "Ratatoskr themes are named Midnight Sky (dark mode) and Noonday Sky (light mode)." - **Nibu**: `sun.js` and its weather-shaped inputs, which this PR consumes unchanged. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
sky: Midnight Sky and Noonday Sky baked from sun.js (albedo x irradiance)
Some checks failed
CLA Assistant / CLAssistant (pull_request_target) Has been cancelled
Check PR title / lint (pull_request_target) Has been cancelled
Build pull request / Build pull request (pull_request) Has been cancelled
7b4aa2f184
Two themes replace the navy GameCult theme. Every colour is a bark, leaf, soil
or pigment albedo times the irradiance sun.js gives for a fixed moment (equinox
noon and midnight, 45N). scripts/bake-sky.mjs writes src/sky/baked.ts: the
terrain-free sky gradient used as the fallback background, folds tokens for
panels and buttons, chat bubble colours, link and name colours.
skyTokens.test.ts holds every text pairing to WCAG AA and fails if baked.ts is
stale.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
sky: bake sun azimuth and colour, ambient with a night floor, horizon colour
Some checks failed
CLA Assistant / CLAssistant (pull_request_target) Failing after 1s
Build pull request / Build pull request (pull_request) Failing after 3m18s
7216456a27
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
sky: bake an atmospheric-scattering table (half float) for a WebGL2 sky shader
Some checks failed
Build pull request / Build pull request (pull_request) Failing after 3m38s
CLA Assistant / CLAssistant (pull_request_target) Failing after 1s
0386065f2c
scatter.js ray-marches a single-scattering Rayleigh+Mie atmosphere whose vertical optical depth is
sun.js's TAU, and bakes two tables into baked.scatter: transmittance to space by view elevation
(32x1) and sky radiance by azimuth from the sun x view elevation x sun elevation (7x32x12), RGB
half floats, little-endian base64, value x 64. Layout, exact decode and a GLSL sampler are in
src/sky/README.md. Tests pin layout, encoding, checksums and physical anchors (zenith transmittance
equals exp(-TAU); blue noon, red low sun toward the sun, black below the planet-shadow limit).

The per-sky sun {elevation_deg, azimuth_deg, color_linear}, ambient_linear and horizon_hex were
already baked in 7216456a; sun.js now exports TAU.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Author
Member

Closing: landed in dev's history (head is an ancestor of dev 64edacac, brought in through the preview-all merges) (f1d8db0c). skyTokens.js, baked.ts and scatter.js are on dev and have moved on (#54, #55, #56). Nothing left to merge.

Closing: landed in dev's history (head is an ancestor of dev 64edacac, brought in through the preview-all merges) (f1d8db0c). skyTokens.js, baked.ts and scatter.js are on dev and have moved on (#54, #55, #56). Nothing left to merge.
void closed this pull request 2026-11-10 17:19:03 +00:00
Some checks failed
Build pull request / Build pull request (pull_request) Failing after 3m38s
CLA Assistant / CLAssistant (pull_request_target) Failing after 1s

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
GameCult/Ratatoskr!22
No description provided.