feat(homepage): rebuild on Australis Skyfall — dual theme, light mode shipped
The board was on the Australis TERMINAL palette, which is dark-only by design
("Always dark first. No light mode in this system"). Skyfall is the dual-theme
web derivative of the same science, and its bundle turned out to be sitting in
this repo's own git history: a predecessor vendored it on 2026-08-19 and a
later commit deleted it. `git show 45c1995:...` returns colors.css with both
`:root` (dark) and `[data-theme="light"]` (Skyfall Day) intact, plus the
calm-depth layout tokens, the typography scale and Supreme 400/500/700. So the
light ramp is canonical rather than derived, which was the entire objection to
building one.
The visual language moves with the palette. Depth is now the recipe and not a
choice — every elevated surface carries a 1px hairline AND a two-layer shadow,
never one without the other. Radii move to Skyfall's scale, cards at
--radius-lg. Widget stat values move from the display face to mono, because
Skyfall is explicit that numbers and telemetry are always --font-mono. The
full-width aurora ribbon under the tab bar is gone: Skyfall sanctions exactly
two accent expressions, the active rail and hero-only glows, and a decorative
gradient across the chrome is neither — so the colour it carried now lands on
the active tab as a 2px accent bar plus an --accent-soft fill, which is the
rail. Every binding is written against the semantic layer; there are no raw
family tokens and no colour literals left in our own file.
build.py now guards the vendoring instead of advising it. The three token files
are hashed and a mismatch FAILS the build — a vendored file is either
byte-identical to the bundle or it is a fork wearing the bundle's name, and the
theme this one replaces had to be torn out twice for exactly that.
⚠ Homepage's own theme toggle is unreachable, and reaching for it breaks the
dashboard. It renders only when settings.yaml leaves `theme:` unpinned, and
with the key absent the page's data loader throws and its catch branch serves
`initialSettings: {}` — no tab bar, no layout, no i18n. Six force-recreates
over seven minutes all came up empty; restoring `theme: dark` rendered
correctly on the next recreate in 12 seconds, while /api/services returned 200
with fully correct content the whole time. That is the first confirmed cause of
the long-running "tab bar goes missing after a recreate" symptom, and it also
retires the homepage.log-size lead recorded earlier today: rolling the log
aside did nothing during this episode, so that coincidence was intermittency.
So the toggle is ours. conf/custom.js renders it and stores the choice;
build.py re-emits each vendored light block twice, once for an explicit
`data-theme` and once inside a prefers-color-scheme media query scoped to
`html:not([data-theme="dark"]):not([data-theme="light"])` — that :not() pair is
what lets a stored dark choice survive a light-mode OS. Verified against both
OS preferences: load, click, click back, reload, all four correct. `data-theme`
is the control surface; Homepage's own `dark` class stays on <html> and does
not fight, because our rules carry !important on the surfaces Tailwind's
`dark:` variants would otherwise claim.
Two font substitutions, both documented rather than silent: Space Grotesk for
Bespoke Sans and JetBrains Mono for Victor Mono. Only Supreme was ever vendored
here and Skyfall's own notes call Victor Mono user-supplied, so this is a
two-line swap when the real faces arrive.
Dark and light, all four tabs: http://10.100.10.50:8090/b/homepage-skyfall/
This commit is contained in:
@@ -210,3 +210,99 @@ rolling the 8.6 MB `conf/homepage/logs/homepage.log` aside and recreating healed
|
||||
it within 15 seconds. That is one observation, not proof — but it is a coherent
|
||||
mechanism (oversized log → logger init throws → silent catch) and it is the
|
||||
cheapest thing to try first next time.
|
||||
|
||||
---
|
||||
|
||||
# `[2026-08-24, pass 3]` Rebuilt on Australis Skyfall — dual theme, light shipped
|
||||
|
||||
Operator supplied the Skyfall design-system README and said "Go full with
|
||||
skyfall."
|
||||
|
||||
## The bundle was already in this repo's git history
|
||||
|
||||
**The Skyfall tokens did not need to be hunted down.** A predecessor vendored
|
||||
them on 2026-08-19 and a later commit deleted them; git kept everything:
|
||||
|
||||
```bash
|
||||
git show 45c1995:stacks/homepage/theme/colors.css # 208 lines, BOTH themes
|
||||
git show 45c1995:stacks/homepage/theme/layout.css # calm-depth tokens
|
||||
git show 45c1995:stacks/homepage/theme/typography.css
|
||||
git show 45c1995:stacks/homepage/theme/fonts/Supreme-{400,500,700}.woff2
|
||||
```
|
||||
|
||||
`colors.css` carries `:root` (dark) **and** `[data-theme="light"]` (Skyfall
|
||||
Day) — so the light ramp is canonical, not derived. That killed the entire
|
||||
objection from the previous answer, which was correct only about the
|
||||
`australis-design` skill ("Always dark first. No light mode in this system").
|
||||
**Skyfall is the dual-theme derivative; australis-design is the terminal
|
||||
theme. They are different systems and only one of them has a light mode.**
|
||||
|
||||
## ⚠⚠ REMOVING `theme:` FROM settings.yaml BREAKS THE DASHBOARD
|
||||
|
||||
The documented way to get Homepage's own light/dark toggle is to leave `theme:`
|
||||
unpinned. **Do not.** With the key absent, the page's data loader throws and its
|
||||
catch branch serves `initialSettings: {}` — no tab bar, no layout, no i18n.
|
||||
|
||||
Measured, not inferred: six force-recreates over seven minutes all came up
|
||||
empty with the key removed; restoring `theme: dark` rendered correctly on the
|
||||
next recreate in **12 seconds**. `/api/services` stays 200 and fully correct
|
||||
throughout, which is exactly why this reads as a caching or warm-up problem and
|
||||
is not one.
|
||||
|
||||
This is the first *confirmed* trigger for the long-running "tab bar goes
|
||||
missing" mystery. It does not explain every occurrence (the symptom has
|
||||
appeared with `theme:` present), but it means **the first diagnostic step is
|
||||
now `git log -p -- stacks/homepage/conf/settings.yaml`**, not container
|
||||
archaeology. Also retires an earlier lead from this same session: rolling the
|
||||
8.6 MB `homepage.log` aside once coincided with a recovery, but did nothing
|
||||
during the `theme:`-key episode — coincidence, not cause.
|
||||
|
||||
## So the toggle is ours
|
||||
|
||||
`conf/custom.js` renders it (was an empty placeholder). Precedence:
|
||||
|
||||
1. explicit choice — `localStorage['skyfall-theme']`, written by the toggle;
|
||||
2. OS preference — `@media (prefers-color-scheme: light)`;
|
||||
3. dark — Skyfall's default.
|
||||
|
||||
`theme/build.py` re-emits each vendored `[data-theme="light"]` block twice: as
|
||||
`[data-theme="light"], html.light`, and inside the media query scoped to
|
||||
`html:not([data-theme="dark"]):not([data-theme="light"])`. **That `:not()` pair
|
||||
is what lets a stored *dark* choice survive a light-mode OS.** Verified across
|
||||
both OS preferences: load, click, click again, reload — all four correct.
|
||||
|
||||
⚠ Homepage keeps its own `class="dark scheme-dark theme-slate"` on `<html>`
|
||||
regardless, because `theme:` is pinned. That is fine and was checked
|
||||
explicitly: with the dark class present AND `data-theme="light"`, every themed
|
||||
surface resolves to Skyfall Day, because our rules carry `!important` on the
|
||||
surfaces Tailwind's `dark:` variants would otherwise claim. **`data-theme` is
|
||||
the control surface; the class is not.**
|
||||
|
||||
## The anti-fork guard is now mechanical
|
||||
|
||||
`build.py` records the SHA-256 of each vendored file and **fails the build** on
|
||||
a mismatch, rather than warning. A vendored file is either byte-identical to
|
||||
the bundle or it is a fork wearing the bundle's name. Overrides go in
|
||||
`skyfall.css.in`, which is written entirely against the semantic layer
|
||||
(`--surface-*`, `--text-*`, `--border-*`, `--success/--danger/--warning`) — no
|
||||
raw family tokens, no colour literals.
|
||||
|
||||
The one place a literal is unavoidable: Homepage consumes
|
||||
`--color-logo-start/stop` as `rgb(var(--x))`, which cannot take an `oklch()`.
|
||||
Those four values are exact sRGB conversions of real tokens (`--sea-80`,
|
||||
`--blue-base` for dark; `--sea-40`, `--blue-deep` for light), computed rather
|
||||
than eyeballed, with the conversion recorded in the file.
|
||||
|
||||
## Deviations, all deliberate and all written down
|
||||
|
||||
- **The aurora ribbon under the tab bar is gone.** Skyfall sanctions exactly two
|
||||
accent expressions — the active rail and hero-only glows — and a decorative
|
||||
gradient across the chrome is neither. The colour moved to a 2px accent bar
|
||||
plus `--accent-soft` fill on the active tab, which *is* the rail.
|
||||
- **Widget stat values moved from the display face to mono**, per Skyfall's
|
||||
"numbers and telemetry are always `--font-mono`".
|
||||
- **Two font substitutions**: Space Grotesk for Bespoke Sans, JetBrains Mono
|
||||
for Victor Mono. Only Supreme was ever vendored, and Skyfall's own notes call
|
||||
Victor Mono "user-supplied". Two-line swap when the real faces arrive.
|
||||
|
||||
Dark + light, all four tabs: `http://10.100.10.50:8090/b/homepage-skyfall/`
|
||||
|
||||
Reference in New Issue
Block a user