diff --git a/assets/accents.json b/assets/accents.json
new file mode 100644
index 00000000..601d2ee5
--- /dev/null
+++ b/assets/accents.json
@@ -0,0 +1,25 @@
+{
+ "anndata": [["orange", [0.711, 0.138, 51]]],
+ "scanpy": [
+ ["cerise", [0.608, 0.209, 1]],
+ ["mandy", [0.634, 0.1737, 22]]
+ ],
+ "mudata": [["green", [0.686, 0.134, 154.4]]],
+ "muon": [["aquamarine", [0.863, 0.163, 154.5]]],
+ "spatialdata": [["blue", [0.714, 0.2, 247.3]]],
+ "squidpy": [["violet", [0.72, 0.112, 279]]],
+ "scirpy": [
+ ["purple", [0.601, 0.209, 358.5]],
+ ["orange", [0.7824, 0.156, 69]]
+ ],
+ "pertpy": [
+ ["blue", [0.5, 0.1, 249]],
+ ["red", [0.595, 0.177, 14]]
+ ],
+ "scvi": [["yellow", [0.824, 0.1634, 81]]],
+ "scverse": [
+ ["deep-blue", [0.405, 0.205, 270]],
+ ["sky-blue", [0.799, 0.108, 236]],
+ ["gold", [0.758, 0.2, 92]]
+ ]
+}
diff --git a/assets/main.scss b/assets/main.scss
index 41554d2c..bd57f5f7 100644
--- a/assets/main.scss
+++ b/assets/main.scss
@@ -1,28 +1,21 @@
// Neutral colors come straight from Bootstrap’s tokens (--bs-bg-*, --bs-fg-*, --bs-border-*),
// which carry their own dark values. Only the brand hues and a few measures live here.
+// The scverse and package accents come from accents.json, passed in by layouts/partials/head.html.
+@import "hugo:vars";
:root {
- /* stylelint-disable color-no-hex -- the one place the brand hues are spelled out */
- --anndata-orange: #e5864b;
- --scanpy-cerise: #de367b;
- --scanpy-mandy: #e05559;
- --mudata-green: #4ab274;
- --muon-aquamarine: #6cf1a1;
- --spatialdata-blue: #40a9ff;
- --squidpy-violet: #969dea;
- --scirpy-purple: #da347f;
- --pertpy-blue: #30679a;
- --pertpy-red: #d2455e;
- --scvi-yellow: #fbb822;
- --scverse-deep-blue: #262fb5; // the darker end of the Join button gradient
- --scverse-sky-blue: #74c8fa; // the lighter end
- --scverse-gold: #d4ac00;
- --github-black: #171b21;
- --discourse-yellow: #f7f0b1;
- --youtube-red: #e03021;
- --zulip-blue: #62a3f0;
- --bluesky-blue: #0a7aff;
- --linkedin-blue: #0a66c2;
- /* stylelint-enable color-no-hex */
+ @each $pkg, $colors in $accents {
+ @each $name, $color in $colors {
+ --#{$pkg}-#{$name}: #{$color};
+ }
+ }
+ /* stylelint-disable function-disallowed-list -- the one place the third-party brand hues are spelled out */
+ --github-black: oklch(0.22 0.013 258);
+ --discourse-yellow: oklch(0.9458 0.08 102);
+ --youtube-red: oklch(0.59 0.213 29.7);
+ --zulip-blue: oklch(0.705 0.132 254);
+ --bluesky-blue: oklch(0.6035 0.22 257.8);
+ --linkedin-blue: oklch(0.516 0.163 254.7);
+ /* stylelint-enable function-disallowed-list */
// Call-to-action buttons: white on the blue gradient (its light end darkened to keep 4.5:1),
// black on the bright hover gradient
diff --git a/layouts/partials/head.html b/layouts/partials/head.html
index 65b03fc3..6c66b6db 100644
--- a/layouts/partials/head.html
+++ b/layouts/partials/head.html
@@ -7,7 +7,18 @@
{{ end }}
-{{ $styles := resources.Get "main.scss" | toCSS | minify }}
+{{/* accents.json → Sass map (pkg: (name: oklch(…), …), …); JSON objects are unordered, so each package lists [name, [L, C, H]] pairs, primary first */}}
+{{ $accentsJSON := resources.Get "accents.json" }}
+{{ $accentsJSON.Publish }}{{/* served at /accents.json for other sites to reuse */}}
+{{ $accents := slice }}
+{{ range $pkg, $colors := $accentsJSON | transform.Unmarshal }}
+ {{ $pairs := slice }}
+ {{ range $colors }}
+ {{ $pairs = $pairs | append (printf "%s: oklch(%s)" (index . 0) (delimit (index . 1) " ")) }}
+ {{ end }}
+ {{ $accents = $accents | append (printf "%s: (%s)" $pkg (delimit $pairs ", ")) }}
+{{ end }}
+{{ $styles := resources.Get "main.scss" | toCSS (dict "vars" (dict "accents" (css.Unquoted (printf "(%s)" (delimit $accents ", "))))) | minify }}
{{ $script := resources.Get "main.ts" | js.Build (dict "format" "esm" "minify" true "sourceMap" "linked" "externals" (slice "bootstrap" "pagefind")) }}