cosmos-docusaurus-theme 2.0.3 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,71 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
7
7
 
8
8
  ---
9
9
 
10
+ ## [2.1.1] — 2026-03-11
11
+
12
+ ### Fixed
13
+
14
+ - **Breadcrumb**: `ul.breadcrumbs { display: flex }` + `::after { content: none }` — kills Infima's
15
+ whitespace injection between items; ChevronRight separator correctly aligned as flex child
16
+ - **Sidebar sub-menu**: corrected CSS selector from `.theme-doc-sidebar-menu .menu__list .menu__list`
17
+ to `.menu__list > .menu__list-item > .menu__list` (direct child `>`) — matches actual DOM depth;
18
+ `margin-left: 35px !important` aligns `|` line under category title text (measured 51.3px)
19
+ - **Sidebar sub-menu color**: `var(--ifm-menu-color)` instead of muted secondary
20
+ - **Banners (admonitions)**: reverted unsolicited CSS overrides; kept only the two requested rules:
21
+ `[class*='admonitionHeading']:not(:last-child) { margin-bottom: 1rem }` and
22
+ `[class*='admonitionIcon'] { display: inline-block; vertical-align: middle; margin-right: 0.4em }`
23
+ - **Demo MDX**: `class=` → `className=` in 7 files (fixes React DOM property warning)
24
+
25
+ ### Added
26
+
27
+ - **`lint-mdx`** Makefile target — scans `demo/docs/**/*.md` for `class=` outside code blocks,
28
+ preventing React prop warnings from slipping through the lint pipeline
29
+ - **`demo-check`** Makefile target — verifies 12 key pages exist in the static build output
30
+ after `make demo-build`; more reliable than HTTP checks against the SPA dev server
31
+ - **`demo/scripts/check-pages.js`** — static build file checker used by `demo-check`
32
+ - `lint` target now includes `lint-mdx` as 5th step
33
+
34
+ ## [2.1.0] — 2026-03-11
35
+
36
+ ### Added
37
+
38
+ - **Banners (admonitions) — complete redesign**: Dismissible Alert style from Rackscope
39
+ `ui-library/alerts` — uniform full border (not left-only), semantic icon colors, flex
40
+ heading layout, `overflow: hidden` clips child shadows at rounded corners
41
+ - **Navbar COSMOS wordmark**: Outfit 700 uppercase, brand indigo `#465fff` / `#7592ff` dark;
42
+ `|` vertical separator; active nav tab underline indicator matching Tabs style
43
+ - **Tabs**: flat underline (no border-radius), brand active state, proper dark mode vars
44
+ - **Pagination**: `rounded-lg`, monospace uppercase sublabel, brand hover ring
45
+ - **Breadcrumb**: ChevronRight SVG separator (disables Infima default), brand hover
46
+ - **Details accordion**: ChevronRight SVG arrow replacing `›` character
47
+ - **Blockquote**: brand left border + subtle tint
48
+ - **`<kbd>`**: chip style with 3D bottom border
49
+ - **Markdown images**: `border-radius: 12px` + shadow
50
+ - **`<abbr title>`**: styled tooltip on hover
51
+ - **Buttons**: `.btn` `.btn-primary` `.btn-secondary` `.btn-danger` `.btn-sm` `.btn-lg`
52
+ - **Release badges**: `.badge-new` `.badge-beta` `.badge-deprecated` `.badge-experimental`
53
+ - **Steps**: `ol.steps` — numbered procedure with circle indicators
54
+ - **Timeline**: `ul.timeline` — versioned event list with vertical line
55
+ - **Check list**: `ul.list-check` — feature list with checkmarks
56
+ - **Footer CSS**: 4-column grid, responsive (4→2→1), monospace section titles, brand colors
57
+ - **Announcement bar**: gradient indigo, improved link style
58
+ - **Favicon**: cosmos atom SVG injected via `injectHtmlTags()` with opt-out option
59
+ `injectFavicon: false`; SVG properly `encodeURIComponent()`-encoded for `data:` URI
60
+ - **`validateOptions()`** exported — Docusaurus options validation for the theme plugin
61
+ - **Demo site restructure**: `showcase/` → `components/` (10 pages); dual navbar
62
+ Documentation | Components; Components sidebar dedicated; `class=` → `className=` in MDX
63
+
64
+ ### Changed
65
+
66
+ - **Font**: JetBrains Mono → **IBM Plex Mono** (code blocks, kbd, monospace elements)
67
+ - **Sidebar sub-menu**: `var(--ifm-menu-color)` color; `|` line aligned under title text
68
+ - **GitHub Actions**: all SHA-pinned (supply chain hardening); Node 20.19 pinned
69
+ - **CI**: Trivy vulnerability scan before Docker push; `npm ci` in all demo jobs;
70
+ `publish.yml` runs full `npm run lint` before publish; `workflow_dispatch` default removed
71
+ - **Dockerfile**: `node:20.19-alpine3.21` (was floating `node:20-alpine`)
72
+ - **`demo/package.json`**: `@easyops-cn ^0.55` (was `latest`); `file:..` dependency
73
+ - **package.json**: description updated, removes stale "TailAdmin" reference
74
+
10
75
  ## [2.0.3] — 2026-03-11
11
76
 
12
77
  ### Added
package/README.md CHANGED
@@ -16,32 +16,31 @@
16
16
 
17
17
  ---
18
18
 
19
- A **CSS-only** Docusaurus theme built from the same design system that powers
20
- [Rackscope](https://rackscope.dev) a production monitoring platform for datacenters and HPC clusters.
21
- Dark-first, opinionated, and refined.
19
+ A **CSS-only** Docusaurus theme built from the same design system that powers [Rackscope](https://rackscope.dev).
20
+ Dark-first, opinionated, pixel-perfect.
22
21
 
23
22
  - **Void** dark palette — deep neutral blacks (`#030712 / #111827`) with indigo accents
24
23
  - **Slate** light palette — warm white surfaces with brown text tones, not cold blue-gray
25
- - **Outfit** display typeface + **JetBrains Mono** for code
24
+ - **Outfit** display typeface + **IBM Plex Mono** for code
26
25
  - Zero JavaScript, no swizzled components — pure CSS override of Docusaurus Infima
27
- - Every element covered: admonitions, tabs, cards, tables, details, DocSearch, breadcrumbs…
28
- - Smooth dark/light transition, ghost-button navbar, TOC active state, 4px scrollbar
26
+ - Every native Docusaurus element styled out of the box
27
+ - Utility classes for MDX pages: buttons, badges, steps, timeline, check lists
29
28
 
30
29
  ---
31
30
 
32
31
  ## Screenshots
33
32
 
34
- > Dark mode — Void palette — with local search
33
+ > Dark mode — Void palette
35
34
 
36
35
  ![Dark mode](https://raw.githubusercontent.com/SckyzO/cosmos-docusaurus-theme/main/docs/screenshots/dark.png)
37
36
 
38
- > Searchdropdown styled to Void/Slate palette
37
+ > Light mode — Slate palette
39
38
 
40
- ![Search active](https://raw.githubusercontent.com/SckyzO/cosmos-docusaurus-theme/main/docs/screenshots/search.png)
39
+ ![Light mode](https://raw.githubusercontent.com/SckyzO/cosmos-docusaurus-theme/main/docs/screenshots/light.png)
41
40
 
42
- > Light mode Slate palette admonitions AlertBanner style
41
+ > BannersDismissible Alert style, semantic icons, full border
43
42
 
44
- ![Light mode](https://raw.githubusercontent.com/SckyzO/cosmos-docusaurus-theme/main/docs/screenshots/light.png)
43
+ ![Banners](https://raw.githubusercontent.com/SckyzO/cosmos-docusaurus-theme/main/docs/screenshots/banners.png)
45
44
 
46
45
  > See all components live → **[sckyzo.github.io/cosmos-docusaurus-theme](https://sckyzo.github.io/cosmos-docusaurus-theme/)**
47
46
 
@@ -65,9 +64,17 @@ export default {
65
64
  };
66
65
  ```
67
66
 
68
- ### Try it instantly with Docker
67
+ ### Options
69
68
 
70
- Zero npm install required — the full demo runs in a container:
69
+ ```js title="docusaurus.config.js"
70
+ themes: [
71
+ ['cosmos-docusaurus-theme', {
72
+ injectFavicon: false, // disable cosmos favicon injection (default: true)
73
+ }],
74
+ ],
75
+ ```
76
+
77
+ ### Try it instantly with Docker
71
78
 
72
79
  ```bash
73
80
  git clone https://github.com/SckyzO/cosmos-docusaurus-theme.git
@@ -76,43 +83,77 @@ docker compose up
76
83
  # → http://localhost:3000
77
84
  ```
78
85
 
79
- Or pull from GitHub Container Registry:
86
+ ---
80
87
 
81
- ```bash
82
- docker run -p 3000:3000 ghcr.io/sckyzo/cosmos-docusaurus-theme:latest
83
- ```
88
+ ## What's covered
89
+
90
+ ### Native Docusaurus elements
91
+
92
+ Styled automatically — no configuration needed:
93
+
94
+ | Element | Notes |
95
+ | ------------------------------------------------------- | --------------------------------------------- |
96
+ | Navbar — COSMOS wordmark, ghost buttons, `\|` separator | Brand indigo title |
97
+ | Sidebar — icons, sub-menu line, version badge | `className: 'sidebar-cat-*'` for icons |
98
+ | Breadcrumb — ChevronRight separator, brand hover | Automatic |
99
+ | Tabs — flat underline, brand active | `import Tabs from '@theme/Tabs'` |
100
+ | Pagination — monospace sublabel, brand hover | Automatic prev / next |
101
+ | Code blocks — all languages, titles | IBM Plex Mono |
102
+ | Banners — Dismissible Alert style, semantic icons | 5 types: note / tip / info / warning / danger |
103
+ | Tables — full-width desktop, scroll mobile | Automatic |
104
+ | Cards — rounded-2xl, dark shadow, hover | `<div class="card">` |
105
+ | Tags | `<span class="tag">` |
106
+ | Details / summary — accordion style | `<details><summary>` |
107
+ | TOC — H2/H3 hierarchy + active pill | Right panel |
108
+ | Blockquote — brand left border | `>` markdown syntax |
109
+ | `<kbd>` — chip style | `<kbd>Ctrl</kbd>` |
110
+ | Images — rounded-xl, shadow | `![alt](src)` |
111
+ | `<abbr title>` — tooltip on hover | `<abbr title="...">` |
112
+ | Back-to-top + progress bar | Automatic |
113
+ | Algolia DocSearch | `--docsearch-*` variables |
114
+ | Local search (easyops-cn) | `--search-local-*` variables |
115
+ | Announcement bar | `themeConfig.announcementBar` |
116
+ | Smooth dark/light transition | Automatic |
117
+
118
+ ### Utility classes
119
+
120
+ For use in MDX pages (`className=` in JSX context):
121
+
122
+ | Class | Purpose |
123
+ | -------------------------------------------------------------------- | --------------------------- |
124
+ | `.btn` `.btn-primary` `.btn-secondary` `.btn-danger` | CTA buttons |
125
+ | `.btn-sm` `.btn-lg` | Button sizes |
126
+ | `.badge-new` `.badge-beta` `.badge-deprecated` `.badge-experimental` | Release lifecycle labels |
127
+ | `.method-get/post/put/delete/patch` | HTTP method labels |
128
+ | `.status-ok/warn/crit/unknown` | Operational health labels |
129
+ | `ol.steps` | Numbered procedure guide |
130
+ | `ul.timeline` | Version history / changelog |
131
+ | `ul.list-check` | Feature checklist |
84
132
 
85
133
  ---
86
134
 
87
- ## What's covered
135
+ ## Sidebar icons
88
136
 
89
- | Element | Styled |
90
- | -------------------------------------------- | :----: |
91
- | Navbar + ghost buttons | ✅ |
92
- | Sidebar + section labels | ✅ |
93
- | Code blocks (all languages) | ✅ |
94
- | Admonitions — AlertBanner style, rounded-2xl | ✅ |
95
- | Tables | ✅ |
96
- | Tabs + synced tabs | ✅ |
97
- | Details/summary — SectionCard style | ✅ |
98
- | Cards — rounded-2xl + dark shadow | ✅ |
99
- | Tags + Badges | ✅ |
100
- | Breadcrumbs | ✅ |
101
- | TOC — H2/H3 hierarchy + active pill | ✅ |
102
- | Pagination | ✅ |
103
- | Announcement bar | ✅ |
104
- | Back-to-top + Progress bar | ✅ |
105
- | Algolia DocSearch | ✅ |
106
- | Smooth dark/light transition | ✅ |
137
+ Add `className: 'sidebar-cat-*'` to any category in `sidebars.js`:
138
+
139
+ ```js title="sidebars.js"
140
+ {
141
+ type: 'category',
142
+ label: 'Getting Started',
143
+ className: 'sidebar-cat-rocket',
144
+ items: ['getting-started'],
145
+ }
146
+ ```
147
+
148
+ Available icons: `rocket` `monitor` `pencil` `puzzle` `sliders` `folder` `server` `database` `layers` `grid` `code`
107
149
 
108
150
  ---
109
151
 
110
152
  ## Customization
111
153
 
112
- Override any CSS variable in your own `custom.css`:
154
+ Override any CSS variable in `custom.css`:
113
155
 
114
156
  ```css title="src/css/custom.css"
115
- /* Brand color */
116
157
  :root {
117
158
  --ifm-color-primary: #e11d48;
118
159
  --ifm-color-primary-dark: #be123c;
@@ -122,35 +163,18 @@ Override any CSS variable in your own `custom.css`:
122
163
  --ifm-color-primary-lighter: #fda4af;
123
164
  --ifm-color-primary-lightest: #ffe4e6;
124
165
  }
125
-
126
- /* Font */
127
- :root {
128
- --ifm-font-family-base: 'Inter', system-ui, sans-serif;
129
- }
130
166
  ```
131
167
 
132
- See the [Color Tokens](https://sckyzo.github.io/cosmos-docusaurus-theme/color-tokens) page
133
- for all available tokens (dark + light with visual swatches).
134
-
135
- ---
136
-
137
- ## Utility classes
138
-
139
- | Class | Usage |
140
- | ----------------------------------- | ---------------------------------------------- |
141
- | `.method-get/post/put/delete/patch` | HTTP method labels (monospace, semantic color) |
142
- | `.status-ok/warn/crit/unknown` | Health state labels |
143
- | `.state-ok/warn/crit/unknown` | Aliases for the above |
144
-
145
168
  ---
146
169
 
147
170
  ## Development
148
171
 
149
172
  ```bash
150
173
  make install # install devDependencies
151
- make lint # CSS + JS + Markdown + format check
152
- make security # npm audit + no-runtime-deps check
174
+ make lint # CSS + JS + Markdown + format + MDX class= check
175
+ make security # npm audit + no-runtime-deps
153
176
  make demo-build # build demo static site
177
+ make demo-check # verify 12 key pages exist in build output
154
178
  make demo-start # dev server at http://localhost:3000
155
179
  make docker-up # demo in Docker at http://localhost:3000
156
180
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cosmos-docusaurus-theme",
3
- "version": "2.0.3",
3
+ "version": "2.1.1",
4
4
  "description": "A clean, dark-first Docusaurus theme aligned with the Rackscope Void/Slate design system — CSS-only, IBM Plex Mono + Outfit typography, brand indigo",
5
5
  "keywords": [
6
6
  "docusaurus",
package/src/css/theme.css CHANGED
@@ -527,18 +527,6 @@ code {
527
527
  border-color: #1f2937;
528
528
  }
529
529
 
530
- /* ── Breadcrumbs — explicit active + separator colors ────────────────────── */
531
- .breadcrumbs__link--active,
532
- .breadcrumbs__item--active .breadcrumbs__link {
533
- color: var(--ifm-color-primary);
534
- /* No background on active breadcrumb — avoids computed #080d25 artifact */
535
- background: none;
536
- }
537
-
538
- [data-theme='dark'] .breadcrumbs__link:not(.breadcrumbs__link--active) {
539
- color: #9ca3af; /* gray-400 — readable on Void dark without being dominant */
540
- }
541
-
542
530
  /* ── Right navbar — unified ghost button style ───────────────────────────── */
543
531
  /* Both the external links (GitHub, npm…) and the color mode toggle get the */
544
532
  /* same bordered ghost button treatment for visual consistency. */
@@ -727,51 +715,19 @@ details > :not(summary) {
727
715
  border: 1px solid;
728
716
  border-radius: 12px;
729
717
  padding: 16px;
718
+ overflow: hidden;
730
719
  }
731
720
 
732
721
  /* Heading — flex row: icon as first item, title text as second.
733
722
  align-items: center = perfect icon ↔ title baseline alignment. */
734
- [class*='admonitionHeading'] {
735
- display: flex;
736
- align-items: center;
737
- gap: 12px;
738
- font-size: 1.25rem !important;
739
- font-weight: 600 !important;
740
- text-transform: none;
741
- letter-spacing: 0;
742
- line-height: 1.4;
743
- margin-bottom: 8px;
723
+ [class*='admonitionHeading']:not(:last-child) {
724
+ margin-bottom: 1rem;
744
725
  }
745
726
 
746
- /* Icon span — 20px, natural Docusaurus SVG size */
747
727
  [class*='admonitionIcon'] {
748
- flex-shrink: 0;
749
- display: flex;
750
- align-items: center;
751
- justify-content: center;
752
- width: 20px;
753
- height: 20px;
754
- }
755
-
756
- [class*='admonitionIcon'] svg {
757
- width: 20px !important;
758
- height: 20px !important;
759
- min-width: 20px;
760
- max-width: 20px;
761
- min-height: 20px;
762
- max-height: 20px;
763
- display: block;
764
- flex-shrink: 0;
765
- }
766
-
767
- /* Force SVG paths to inherit color from parent (overrides any hardcoded fill) */
768
- [class*='admonitionIcon'] svg path,
769
- [class*='admonitionIcon'] svg circle,
770
- [class*='admonitionIcon'] svg rect,
771
- [class*='admonitionIcon'] svg polyline,
772
- [class*='admonitionIcon'] svg line {
773
- fill: currentcolor;
774
- stroke: none;
728
+ display: inline-block;
729
+ vertical-align: middle;
730
+ margin-right: 0.4em;
775
731
  }
776
732
 
777
733
  /* Body — indented under title (20px icon + 12px gap = 32px) */
@@ -789,13 +745,6 @@ details > :not(summary) {
789
745
  margin-bottom: 0;
790
746
  }
791
747
 
792
- /* Code blocks inside banners — full width, cancel body indent */
793
- [class*='admonitionContent'] pre,
794
- [class*='admonitionContent'] [class*='codeBlockContainer'] {
795
- margin-left: -32px;
796
- margin-right: 0;
797
- }
798
-
799
748
  /* ── note (secondary) — gray ─────────────────── */
800
749
  .alert--secondary {
801
750
  border-color: rgb(107, 114, 128, 0.25);
@@ -1121,27 +1070,44 @@ details > :not(summary) {
1121
1070
  border-bottom-color: rgb(255, 255, 255, 0.08);
1122
1071
  }
1123
1072
 
1124
- /* ── Breadcrumbs ─────────────────────────────────────────────────────────── */
1125
- /* Matches Rackscope "With Icons" variant ChevronRight separator,
1126
- brand hover on inactive items, muted color for trail. */
1073
+ /* ── Breadcrumbs rewritten from scratch ────────────────────────────────── */
1074
+ /* ul flex container no HTML whitespace between items.
1075
+ Text separator always vertically aligned (no SVG alignment hell).
1076
+ Active item: brand color. Inactive: muted gray. Hover: brand. */
1127
1077
  :root {
1128
1078
  --ifm-breadcrumb-color-active: #465fff;
1129
1079
  --ifm-breadcrumb-item-background-active: transparent;
1130
1080
  --ifm-breadcrumb-border-radius: 4px;
1131
- --ifm-breadcrumb-padding-horizontal: 4px;
1081
+ --ifm-breadcrumb-padding-horizontal: 0;
1132
1082
  --ifm-breadcrumb-padding-vertical: 2px;
1133
- /* Disable Infima's built-in separator — we supply our own SVG via ::before */
1134
1083
  --ifm-breadcrumb-separator: none;
1135
1084
  --ifm-breadcrumb-separator-size-multiplier: 0;
1136
1085
  }
1137
1086
 
1087
+ ul.breadcrumbs {
1088
+ display: flex !important;
1089
+ align-items: center !important;
1090
+ flex-wrap: wrap;
1091
+ gap: 0;
1092
+ }
1093
+
1094
+ .breadcrumbs__item {
1095
+ display: flex !important;
1096
+ align-items: center !important;
1097
+ }
1098
+
1099
+ /* Infima injects ::after { content: ' ' } on breadcrumb items — kills it */
1100
+ .breadcrumbs__item::after {
1101
+ content: none !important;
1102
+ display: none !important;
1103
+ }
1104
+
1138
1105
  .breadcrumbs__link {
1139
- border-radius: 4px;
1140
1106
  font-size: 0.8125rem;
1141
- color: #6b7280; /* gray-500 — muted trail */
1142
- transition:
1143
- color 0.12s,
1144
- background 0.12s;
1107
+ color: #6b7280;
1108
+ padding: 2px 6px;
1109
+ border-radius: 4px;
1110
+ transition: color 0.12s;
1145
1111
  }
1146
1112
 
1147
1113
  .breadcrumbs__link:hover {
@@ -1149,33 +1115,25 @@ details > :not(summary) {
1149
1115
  color: var(--ifm-color-primary);
1150
1116
  }
1151
1117
 
1152
- /* ChevronRight separatorour SVG, Infima's built-in separator disabled via
1153
- --ifm-breadcrumb-separator: none above. background shorthand resets all
1154
- sub-properties to prevent Infima's background from bleeding through. */
1155
- /* Each breadcrumb item is a flex row — ::before becomes a flex item,
1156
- align-items: center provides true pixel-perfect vertical centering.
1157
- vertical-align has no effect in flex context and is intentionally omitted. */
1158
- .breadcrumbs__item {
1159
- display: flex;
1160
- align-items: center;
1118
+ /* Active breadcrumbbrand color, no background */
1119
+ .breadcrumbs__link--active,
1120
+ .breadcrumbs__item--active .breadcrumbs__link {
1121
+ color: var(--ifm-color-primary);
1122
+ background: none;
1161
1123
  }
1162
1124
 
1125
+ /* Separator — ChevronRight SVG, flex item inside flex li → perfectly centered */
1163
1126
  .breadcrumbs__item + .breadcrumbs__item::before {
1164
1127
  content: '';
1165
- display: block; /* flex item, not inline-block */
1128
+ display: block;
1166
1129
  flex-shrink: 0;
1167
1130
  width: 14px;
1168
1131
  height: 14px;
1169
- background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 18l6-6-6-6'/%3E%3C/svg%3E")
1170
- center / 14px no-repeat;
1171
- margin: 0 2px;
1172
- }
1173
-
1174
- [data-theme='dark'] .breadcrumbs__item + .breadcrumbs__item::before {
1175
- background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234b5563' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 18l6-6-6-6'/%3E%3C/svg%3E")
1132
+ background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 18l6-6-6-6'/%3E%3C/svg%3E")
1176
1133
  center / 14px no-repeat;
1177
1134
  }
1178
1135
 
1136
+ /* Dark mode */
1179
1137
  [data-theme='dark'] .breadcrumbs__link {
1180
1138
  color: #6b7280;
1181
1139
  }
@@ -1184,6 +1142,15 @@ details > :not(summary) {
1184
1142
  color: #7592ff;
1185
1143
  }
1186
1144
 
1145
+ [data-theme='dark'] .breadcrumbs__link--active,
1146
+ [data-theme='dark'] .breadcrumbs__item--active .breadcrumbs__link {
1147
+ color: #7592ff;
1148
+ }
1149
+
1150
+ [data-theme='dark'] .breadcrumbs__item + .breadcrumbs__item::before {
1151
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234b5563' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 18l6-6-6-6'/%3E%3C/svg%3E");
1152
+ }
1153
+
1187
1154
  /* ── Tabs ────────────────────────────────────────────────────────────────── */
1188
1155
  /* Matches Rackscope Tabs component — flat underline, brand active,
1189
1156
  no background fill on hover (clean underline-only style). */
@@ -1541,32 +1508,27 @@ details > :not(summary) {
1541
1508
  /* │ sub item */
1542
1509
  /* │ sub item */
1543
1510
 
1544
- .theme-doc-sidebar-menu .menu__list .menu__list {
1545
- margin-left: 8px;
1546
- padding-left: 12px;
1511
+ /* Nested list: border-left aligned under title text (after icon).
1512
+ Measured: title text at x=51.3, sub-list default at x=16.3 → need +35px.
1513
+ !important required to override Infima's margin reset. */
1514
+ /* Nested sub-menu: border-left aligned under title text (after icon 15px+8px gap).
1515
+ Selector uses direct child (>) to match the DOM: ul>li>ul structure.
1516
+ margin-left: 35px !important needed to override Infima's margin reset. */
1517
+ .menu__list > .menu__list-item > .menu__list {
1518
+ margin-left: 35px !important;
1519
+ padding-left: 8px;
1547
1520
  border-left: 1.5px solid var(--ifm-toc-border-color);
1548
1521
  }
1549
1522
 
1550
- [data-theme='dark'] .theme-doc-sidebar-menu .menu__list .menu__list {
1551
- border-left-color: #374151; /* Void gray-700 — slightly more visible */
1523
+ [data-theme='dark'] .menu__list > .menu__list-item > .menu__list {
1524
+ border-left-color: #374151;
1552
1525
  }
1553
1526
 
1554
- /* Sub-items: slightly smaller + muted when inactive */
1555
- .menu__list .menu__list > .menu__list-item > .menu__link {
1527
+ /* Sub-items normal menu color (not muted), slightly smaller font */
1528
+ .menu__list > .menu__list-item > .menu__list > .menu__list-item > .menu__link {
1556
1529
  font-size: 0.8375rem;
1557
- padding-left: 12px;
1558
- }
1559
-
1560
- .menu__list .menu__list > .menu__list-item > .menu__link:not(.menu__link--active) {
1561
- color: var(--ifm-font-color-secondary);
1562
- }
1563
-
1564
- [data-theme='dark']
1565
- .menu__list
1566
- .menu__list
1567
- > .menu__list-item
1568
- > .menu__link:not(.menu__link--active) {
1569
- color: #71717a;
1530
+ padding-left: 8px;
1531
+ color: var(--ifm-menu-color);
1570
1532
  }
1571
1533
 
1572
1534
  /* ── Category icons — via className in sidebars.js ───────────────────────── */
@@ -2305,7 +2267,7 @@ ul.timeline > li:last-child {
2305
2267
  ul.timeline > li::before {
2306
2268
  content: '';
2307
2269
  position: absolute;
2308
- left: -1.15rem;
2270
+ left: -1.37rem;
2309
2271
  top: 0.35rem;
2310
2272
  width: 0.65rem;
2311
2273
  height: 0.65rem;