hive-c0re: swagger theme follows stylix via colors.css, not a hardcoded copy

Loads the dashboard's own themed /static/colors.css directly (same
origin, see vhosts.nix dashboardProxyLocation) instead of redeclaring
the Catppuccin Mocha hex values locally. The theme now re-themes live
with the rest of the dashboard instead of drifting out of sync.

Addresses review feedback on PR.
This commit is contained in:
iris 2026-08-02 19:55:10 +02:00 committed by mara
commit 062a84378d
2 changed files with 68 additions and 71 deletions

View file

@ -1,60 +1,50 @@
/* Partial hyperhive (Catppuccin Mocha) reskin for the vendored Swagger UI /* Partial hyperhive reskin for the vendored Swagger UI at /api/docs
at /api/docs the operator asked for this as a follow-up to the the operator asked for this as a follow-up to the OpenAPI/Swagger-UI
OpenAPI/Swagger-UI docs work. Scope is deliberately bounded per her docs work. Scope is deliberately bounded per her steer ("its not
steer ("its not about making it completely vibec0re, apply theme about making it completely vibec0re, apply theme colors only"):
colors only"): recolor the page chrome (background, topbar, recolor the page chrome (background, topbar, borders, links,
borders, links, headings, inputs) to match the rest of the dashboard; headings, inputs) to match the rest of the dashboard; leave Swagger's
leave Swagger's own semantic HTTP-method colours (GET/POST/PUT/DELETE own semantic HTTP-method colours (GET/POST/PUT/DELETE badges) and the
badges) and the execute/cancel action-button colours alone those execute/cancel action-button colours alone those carry real meaning
carry real meaning to anyone who already knows Swagger UI, not just to anyone who already knows Swagger UI, not just hyperhive branding.
hyperhive branding.
Loaded after swagger-ui.css (see index.html) so these rules win the Loaded after swagger-ui.css (see index.html) so these rules win the
cascade on shared selectors without `!important`; only reaching for cascade on shared selectors without `!important`; only reaching for
`!important` where Swagger's own CSS is more specific than a same- `!important` where Swagger's own CSS is more specific than a same-
specificity override can beat (documented per-rule below). specificity override can beat (documented per-rule below).
Same base16 contract as frontend/packages/shared/src/colors.css Follows stylix live, same as every other dashboard page: index.html
(Catppuccin Mocha) this file can't @import that one (separate build links the dashboard's own themed `colors.css` (served from
pipeline, plain static asset, no preprocessing), so the slots are `/static/`, same origin) directly ahead of this file, so the
redeclared here. Keep the two in sync if the palette ever changes; `--baseNN` custom properties below resolve to whatever the operator's
see docs/web-ui/css-vars.md for the base16 contract this mirrors. */ current stylix scheme actually is no hardcoded hex, nothing to
drift out of sync when the theme changes. See
:root { frontend/packages/shared/src/colors.css for the base16 contract. */
--hh-base00: #1e1e2e; /* default bg */
--hh-base01: #181825; /* lighter bg (elevated surfaces / topbar) */
--hh-base02: #313244; /* selection / surface — borders */
--hh-base03: #45475a; /* comments / dim surface */
--hh-base05: #cdd6f4; /* default foreground */
--hh-base0c: #89dceb; /* cyan — info accents */
--hh-base0d: #89b4fa; /* blue — links, interactive accent */
--hh-base0e: #cba6f7; /* mauve — primary accent (active tabs, highlights) */
}
/* Page chrome */ /* Page chrome */
html, html,
body { body {
background: var(--hh-base00); background: var(--base00);
} }
.swagger-ui { .swagger-ui {
color: var(--hh-base05); color: var(--base05);
font-family: "JetBrains Mono", "Fira Code", "Cascadia Code", font-family: "JetBrains Mono", "Fira Code", "Cascadia Code",
"Source Code Pro", monospace; "Source Code Pro", monospace;
} }
/* Topbar — replaces Swagger's default green bar. */ /* Topbar — replaces Swagger's default green bar. */
.swagger-ui .topbar { .swagger-ui .topbar {
background: var(--hh-base01); background: var(--base01);
border-bottom: 1px solid var(--hh-base02); border-bottom: 1px solid var(--base02);
} }
.swagger-ui .topbar .download-url-wrapper input[type="text"] { .swagger-ui .topbar .download-url-wrapper input[type="text"] {
border-color: var(--hh-base02); border-color: var(--base02);
background: var(--hh-base00); background: var(--base00);
color: var(--hh-base05); color: var(--base05);
} }
.swagger-ui .topbar .download-url-wrapper .download-url-button { .swagger-ui .topbar .download-url-wrapper .download-url-button {
background: var(--hh-base0e); background: var(--base0E);
color: var(--hh-base01); color: var(--base01);
} }
/* Info block (spec title/description) + links throughout. */ /* Info block (spec title/description) + links throughout. */
@ -62,42 +52,42 @@ body {
.swagger-ui .info li, .swagger-ui .info li,
.swagger-ui .info p, .swagger-ui .info p,
.swagger-ui .info table { .swagger-ui .info table {
color: var(--hh-base05); color: var(--base05);
} }
.swagger-ui a.nostyle, .swagger-ui a.nostyle,
.swagger-ui a.nostyle:visited, .swagger-ui a.nostyle:visited,
.swagger-ui .info a { .swagger-ui .info a {
color: var(--hh-base0d); color: var(--base0D);
} }
.swagger-ui .opblock-tag { .swagger-ui .opblock-tag {
color: var(--hh-base05); color: var(--base05);
border-bottom-color: var(--hh-base02); border-bottom-color: var(--base02);
} }
.swagger-ui .opblock-tag:hover { .swagger-ui .opblock-tag:hover {
background: color-mix(in srgb, var(--hh-base0e) 8%, transparent); background: color-mix(in srgb, var(--base0E) 8%, transparent);
} }
/* Scheme/server selector bar. */ /* Scheme/server selector bar. */
.swagger-ui .scheme-container { .swagger-ui .scheme-container {
background: var(--hh-base01); background: var(--base01);
box-shadow: none; box-shadow: none;
border-bottom: 1px solid var(--hh-base02); border-bottom: 1px solid var(--base02);
} }
/* Endpoint rows keep the method-colour left border (GET/POST/etc, it's /* Endpoint rows keep the method-colour left border (GET/POST/etc, it's
Swagger's own semantic language) but recolour the card body so it Swagger's own semantic language) but recolour the card body so it
doesn't sit on stock white. */ doesn't sit on stock white. */
.swagger-ui .opblock { .swagger-ui .opblock {
background: var(--hh-base01); background: var(--base01);
border-color: var(--hh-base02); border-color: var(--base02);
} }
.swagger-ui .opblock .opblock-summary-description, .swagger-ui .opblock .opblock-summary-description,
.swagger-ui .opblock .opblock-summary-path, .swagger-ui .opblock .opblock-summary-path,
.swagger-ui .opblock .opblock-summary-path__deprecated { .swagger-ui .opblock .opblock-summary-path__deprecated {
color: var(--hh-base05); color: var(--base05);
} }
.swagger-ui .opblock .opblock-section-header { .swagger-ui .opblock .opblock-section-header {
background: var(--hh-base00); background: var(--base00);
} }
.swagger-ui .opblock-description-wrapper p, .swagger-ui .opblock-description-wrapper p,
.swagger-ui .opblock-external-docs-wrapper p, .swagger-ui .opblock-external-docs-wrapper p,
@ -107,39 +97,39 @@ body {
.swagger-ui .parameter__deprecated, .swagger-ui .parameter__deprecated,
.swagger-ui .parameter__in, .swagger-ui .parameter__in,
.swagger-ui table.model tr.property-row td { .swagger-ui table.model tr.property-row td {
color: var(--hh-base05); color: var(--base05);
} }
.swagger-ui .tab li, .swagger-ui .tab li,
.swagger-ui .opblock .opblock-section-header h4, .swagger-ui .opblock .opblock-section-header h4,
.swagger-ui .opblock .opblock-section-header label { .swagger-ui .opblock .opblock-section-header label {
color: var(--hh-base05); color: var(--base05);
} }
/* Response / model tables. */ /* Response / model tables. */
.swagger-ui table thead tr td, .swagger-ui table thead tr td,
.swagger-ui table thead tr th { .swagger-ui table thead tr th {
color: var(--hh-base05); color: var(--base05);
border-bottom-color: var(--hh-base02); border-bottom-color: var(--base02);
} }
.swagger-ui .responses-inner h4, .swagger-ui .responses-inner h4,
.swagger-ui .responses-inner h5 { .swagger-ui .responses-inner h5 {
color: var(--hh-base05); color: var(--base05);
} }
.swagger-ui .response-col_status { .swagger-ui .response-col_status {
color: var(--hh-base05); color: var(--base05);
} }
.swagger-ui .model-box, .swagger-ui .model-box,
.swagger-ui section.models { .swagger-ui section.models {
background: var(--hh-base01); background: var(--base01);
} }
.swagger-ui section.models { .swagger-ui section.models {
border-color: var(--hh-base02); border-color: var(--base02);
} }
.swagger-ui section.models h4 { .swagger-ui section.models h4 {
color: var(--hh-base05); color: var(--base05);
} }
.swagger-ui .model { .swagger-ui .model {
color: var(--hh-base05); color: var(--base05);
} }
/* Form controls inputs/selects/textareas default to Swagger's stock /* Form controls inputs/selects/textareas default to Swagger's stock
@ -152,25 +142,25 @@ body {
.swagger-ui input[type="email"], .swagger-ui input[type="email"],
.swagger-ui input[type="file"], .swagger-ui input[type="file"],
.swagger-ui textarea { .swagger-ui textarea {
background: var(--hh-base00); background: var(--base00);
color: var(--hh-base05); color: var(--base05);
border-color: var(--hh-base02); border-color: var(--base02);
} }
/* Generic (non-semantic) buttons "Try it out" / "Reset" / "Clear" / /* Generic (non-semantic) buttons "Try it out" / "Reset" / "Clear" /
"Authorize" close etc. Execute (green) and Cancel (red) keep Swagger's "Authorize" close etc. Execute (green) and Cancel (red) keep Swagger's
own colours; only the ones that were plain-white-on-white before. */ own colours; only the ones that were plain-white-on-white before. */
.swagger-ui .btn { .swagger-ui .btn {
color: var(--hh-base05); color: var(--base05);
border-color: var(--hh-base02); border-color: var(--base02);
background: var(--hh-base00); background: var(--base00);
} }
.swagger-ui .btn.authorize { .swagger-ui .btn.authorize {
color: var(--hh-base0e); color: var(--base0E);
border-color: var(--hh-base0e); border-color: var(--base0E);
} }
.swagger-ui .btn.authorize svg { .swagger-ui .btn.authorize svg {
fill: var(--hh-base0e); fill: var(--base0E);
} }
/* `!important` needed here: Swagger's own `.swagger-ui .highlight-code` /* `!important` needed here: Swagger's own `.swagger-ui .highlight-code`
@ -181,8 +171,8 @@ body {
request code-sample background only token colours stay as request code-sample background only token colours stay as
highlight.js's own theme provides, this is just the block bg. */ highlight.js's own theme provides, this is just the block bg. */
.swagger-ui .highlight-code { .swagger-ui .highlight-code {
background: var(--hh-base00) !important; background: var(--base00) !important;
} }
.swagger-ui .microlight { .swagger-ui .microlight {
color: var(--hh-base05); color: var(--base05);
} }

View file

@ -2,10 +2,16 @@
<!-- Overrides the vendored Swagger UI's own `dist/index.html` (byte-for- <!-- Overrides the vendored Swagger UI's own `dist/index.html` (byte-for-
byte identical otherwise — copied from utoipa-swagger-ui-vendored byte identical otherwise — copied from utoipa-swagger-ui-vendored
0.1.2's swagger-ui-5.17.14/dist/index.html) via the crate's 0.1.2's swagger-ui-5.17.14/dist/index.html) via the crate's
`SWAGGER_UI_OVERWRITE_FOLDER` build-time hook, adding exactly one `SWAGGER_UI_OVERWRITE_FOLDER` build-time hook, adding two lines: the
line: the hyperhive-theme.css stylesheet link, loaded after dashboard's own themed `colors.css` (same absolute `/static/`
swagger-ui.css so its rules win the cascade without needing origin the dashboard dist serves it from — see
`!important`. See docs/web-ui/dashboard.md::Dashboard endpoints. --> nix/host-modules/hive-gateway/vhosts.nix's dashboardProxyLocation,
`/` and `/api/` share one vhost so this resolves whatever the
operator's stylix theme currently renders, not a frozen copy) and
hyperhive-theme.css, which consumes those `--baseNN` vars. Loaded
after swagger-ui.css so hyperhive-theme.css's rules win the cascade
without needing `!important`. See
docs/web-ui/dashboard.md::Dashboard endpoints. -->
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
@ -13,6 +19,7 @@
<title>Swagger UI</title> <title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" /> <link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
<link rel="stylesheet" type="text/css" href="index.css" /> <link rel="stylesheet" type="text/css" href="index.css" />
<link rel="stylesheet" type="text/css" href="/static/colors.css" />
<link rel="stylesheet" type="text/css" href="hyperhive-theme.css" /> <link rel="stylesheet" type="text/css" href="hyperhive-theme.css" />
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" /> <link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" /> <link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />