Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/docs/web-ui/css-vars.md
atlas 884fb3e08b dashboard: remove the L0GS page and its journal backend
Logs live at swarm level now (VictoriaLogs, read through Grafana
Explore). The hive dashboard's own journal viewer goes, with
everything that existed only to serve it:

- frontend: /logs.html, logs.js, logs.css, the H0M3 "Logs" tile and
  the per-agent menu's "journal logs ->" link. The build-log list
  rules BU1LDS used from logs.css move into builds.css.
- hive-c0re: GET /api/journal/{name} and GET /api/journal-host, and
  priv_client::read_container_journal.
- hive-priv / hive-priv-sock: the ReadContainerJournal request, its
  JournalQuery/JournalOutput wire types and the journalctl -M executor.
- nix: hive-c0re's systemd-journal supplementary group, whose only
  reader was the journal-host handler.
- docs: the L0GS section, the API entry and the security table row.

Closes #5113
Closes #3819
2026-10-12 01:26:33 +02:00

10 KiB
Raw Blame History

CSS custom properties (theme variables)

Colour variables live in two standalone stylesheets, split so a theme swap touches only the first:

  1. colors.css — the 16 --base00…--base0F base16 slots. This is the entire theme swap contract. A generator (for example one fed a stylix base16 scheme, which is natively base00–base0F) replaces only this file.
  2. theme.css — the semantic layer: --bg, --fg, --purple, … derived from the base16 slots (--bg: var(--base00) etc.). This is what the app references and it never changes on a swap.

Both files live in frontend/packages/shared/src/. Per-page stylesheets (common.css, dashboard.css, flow.css, agent.css) reference the semantic names and must not redeclare them or reach for the raw --baseNN slots directly. (base.css holds only the shared body typography — it references the palette but no longer defines it.)

colors.css declares each palette's 16 hex values exactly once — --mocha-baseNN (dark, Catppuccin Mocha) and --latte-baseNN (light, Catppuccin-Latte-derived; base08-base0F run darker than stock Latte to actually clear WCAG AA against how this app uses them — real contrast failures found in review, see the comment above those declarations in colors.css for the numbers and why). Everything else in the file just points the active --baseNN slot at one of those two raw palettes via var(), never a second copy of a hex value: an unconditional default (Mocha), a row gated behind @media (prefers-color-scheme: light) (Latte, the OS/browser-level default), and two :root[data-theme='light'|'dark'] blocks a per-user override sets (swarm-ui's SettingsMenu) — an attribute selector always outranks the plain :root inside the media query, so the override wins regardless of the actual OS preference. Absent an override, the media query decides; that's what a client with no more specific theme decision gets (see "Theme swapping" below for how a stylix deployment supersedes all of this at once).

Both are deliberately standalone, not @imported into the page bundles: each package re-exports them (src/{colors,theme}.css → @import "@hive/shared/…") so esbuild emits its own dist/static/colors.css + dist/static/theme.css, and every page links them first (colors.css then theme.css) ahead of the page CSS. Note theme.css does not @import colors.css — that would bake the slots back into it; they're two separate output files so a swap replaces just colors.css. (Load order doesn't actually affect resolution — custom properties resolve at computed-value time — but each page still links colors.css first for clarity.)

Semantic palette (theme.css)

Each semantic var derives from a base16 slot (or, for the three that have no clean slot, a color-mix() over base16 — pixel-identical under the default palette). Default hexes shown are Catppuccin Mocha.

Variable Derives from Default hex Use
--bg base00 #1e1e2e page background
--bg-elev base01 #181825 elevated surfaces: floating dropdowns, popovers
--border base02 #313244 general borders, hover/active backgrounds
--purple-dim base03 #45475a subtle borders, terminal chrome, badge backgrounds
--fg base05 #cdd6f4 primary text colour
--red base08 #f38ba8 errors, fail state
--amber base09 #fab387 warnings, pending / running state
--yellow base0A #f9e2af flash messages, mild warnings
--green base0B #a6e3a1 success, ok state
--cyan base0C #89dceb tool-use events, info accents
--blue base0D #89b4fa links, interactive accent (distinct from cyan)
--purple base0E #cba6f7 accent — active tabs, links, highlights
--pink base0F #f5c2e7 thinking events
--crust mix(base00 58%, #000000) #11111b terminal / code block background (below --bg)
--muted mix(base05 55.5%, base00) #7f849c secondary / dimmed text
--subtext0 mix(base05 77.7%, base00) #a6adc8 toolbar/status text; dimmer than --fg, lighter than --muted

Common mistakes

The Catppuccin colour names don't map 1:1 to the variable names. Variables to avoid (undefined — they will silently resolve to transparent / inherited):

Wrong Correct
--text --fg
--mauve --purple
--surface0 --bg-elev (float bg) or --border (border/hover)
--surface1 --border
--surface2 --purple-dim
--overlay0, --overlay1 --muted
--base, --mantle --bg, --bg-elev

Usage guide

Floating menus and dropdowns (for example agent context menu, tabbar overflow):

background: var(--bg-elev);
border: 1px solid var(--purple-dim);

Hover / active state backgrounds:

background: var(--border);

Active tab text / accent elements:

color: var(--purple);

Muted / meta text:

color: var(--muted);

Error / warning / success badges:

color: var(--red); /* error */
color: var(--amber); /* warning / running */
color: var(--green); /* ok */

Theme swapping — the base16 contract

The swap interface is colors.css — the 16 base16 slots, not the semantic names. A theme generator (for example one reading a stylix base16 scheme) overrides only colors.css; the semantic layer in theme.css derives everything else, so the whole UI re-themes with nothing else to template or regenerate. The base16 slot → semantic mapping is internal to theme.css (the "Derives from" column above) — a generator never needs to know the semantic var names, and theme.css + the page bundles stay untouched.

Two palettes, one contract. colors.css ships both a dark default (Catppuccin Mocha, unconditional) and a light default (Catppuccin Latte, behind @media (prefers-color-scheme: light)), plus a per-user override path (:root[data-theme]) — a theme generator that overrides the file wholesale (for example the stylix path, which writes a single unconditional :root block with no media query, no --mocha-*/--latte-* vars, no [data-theme] blocks) supersedes all of it at once, same as today.

colors.css base16 slot defaults (Catppuccin Mocha, dark default):

Slot Default Standard base16 role Mapped to
base00 #1e1e2e default bg --bg, (darkened) --crust
base01 #181825 lighter bg --bg-elev
base02 #313244 selection/surface --border
base03 #45475a comments/dim surface --purple-dim
base04 #585b70 dark foreground (unused; kept for completeness)
base05 #cdd6f4 default foreground --fg, (blended) --muted/--subtext0
base06 #f5e0dc light foreground (unused)
base07 #b4befe lightest (unused)
base08 #f38ba8 red --red
base09 #fab387 orange --amber
base0A #f9e2af yellow --yellow
base0B #a6e3a1 green --green
base0C #89dceb cyan --cyan (named sky here; Catppuccin's base0C is teal)
base0D #89b4fa blue --blue
base0E #cba6f7 magenta --purple
base0F #f5c2e7 extra accent --pink

Notes for theme authors:

  • --crust, --muted, --subtext0 have no own slot — they're derived via color-mix() over base16 (--crust = a darkened base00; --muted/--subtext0 = base05↔base00 blends). They still track a swap automatically; no generator action needed.
  • A standard Catppuccin base16 scheme uses teal for base0C; colors.css defaults it to sky (#89dceb) to preserve the historical accent. A stylix Catppuccin scheme will shift --cyan to teal — that's the operator's chosen scheme, working as intended.
  • base04/base06/base07 aren't consumed by a semantic var today; they're kept at their standard values so the 16-slot contract is complete (a partial scheme override still works).