Skip to content
This repository was archived by the owner on Jul 15, 2026. It is now read-only.

Commit d72dc30

Browse files
authored
Merge pull request #149 from stackabletech/feat/add-universal-header
feat: Add universal navigation bar
2 parents 4731d86 + 04880bf commit d72dc30

13 files changed

Lines changed: 447 additions & 7 deletions

src/css/header.css

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ html.is-clipped--navbar {
88
}
99

1010
body {
11-
padding-top: var(--navbar-height);
11+
padding-top: var(--body-top);
1212
}
1313

1414
.navbar {
@@ -17,7 +17,7 @@ body {
1717
font-size: calc(16 / var(--rem-base) * 1rem);
1818
height: var(--navbar-height);
1919
position: fixed;
20-
top: 0;
20+
top: var(--universal-nav-height);
2121
width: 100%;
2222
z-index: var(--z-index-navbar);
2323
display: flex;
@@ -233,7 +233,7 @@ body {
233233
position: fixed;
234234
display: none;
235235
z-index: 5;
236-
top: var(--navbar-height);
236+
top: var(--body-top);
237237
width: 100%;
238238
background: var(--navbar-menu-background);
239239
box-shadow: 0 8px 16px rgba(10, 10, 10, 0.1);

src/css/nav.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
.nav-container {
1212
position: fixed;
13-
top: var(--navbar-height);
13+
top: var(--body-top);
1414
left: 0;
1515
width: 100%;
1616
font-size: calc(17 / var(--rem-base) * 1rem);
@@ -54,7 +54,7 @@
5454

5555
@media screen and (min-width: 1024px) {
5656
.nav {
57-
top: calc(var(--navbar-height));
57+
top: var(--body-top);
5858
box-shadow: none;
5959
position: sticky;
6060
height: var(--nav-height--desktop);

src/css/site.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
@import "toc.css";
1111
@import "doc.css";
1212
@import "pagination.css";
13+
@import "universal-nav.css";
1314
@import "header.css";
1415
@import "footer.css";
1516
@import "highlight.css";

src/css/toolbar.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
@media screen and (min-width: 1024px) {
2020
.toolbar {
21-
top: calc(var(--navbar-height));
21+
top: var(--body-top);
2222
}
2323
}
2424

src/css/universal-nav.css

Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
/**
2+
* The Stackable universal navigation strip — links the three Stackable
3+
* properties (stackable.tech, docs, hub), mirroring the hub's meta strip.
4+
*/
5+
6+
.universal-nav {
7+
position: fixed;
8+
top: 0;
9+
left: 0;
10+
width: 100%;
11+
height: var(--universal-nav-height);
12+
z-index: var(--z-index-universal-nav);
13+
background: var(--universal-nav-background);
14+
color: var(--universal-nav-font-color);
15+
border-bottom: solid 1px transparent;
16+
}
17+
18+
.universal-nav__bar {
19+
display: flex;
20+
align-items: center;
21+
gap: 18px;
22+
height: 100%;
23+
padding: 0 28px;
24+
}
25+
26+
.universal-nav a {
27+
text-decoration: none;
28+
}
29+
30+
.universal-nav__brand {
31+
display: flex;
32+
align-items: center;
33+
border-radius: 6px;
34+
flex: none;
35+
}
36+
37+
.universal-nav__logo {
38+
display: block;
39+
height: 20px;
40+
width: auto;
41+
}
42+
43+
.universal-nav__sep {
44+
width: 1px;
45+
height: 18px;
46+
background: rgba(255, 255, 255, 0.16);
47+
flex: none;
48+
}
49+
50+
.universal-nav__tabs {
51+
display: flex;
52+
align-items: center;
53+
gap: 4px;
54+
flex: 1;
55+
}
56+
57+
.universal-nav__tab {
58+
display: inline-flex;
59+
align-items: center;
60+
gap: 7px;
61+
height: 30px;
62+
padding: 0 14px;
63+
border-radius: 7px;
64+
color: rgba(255, 255, 255, 0.62);
65+
font-size: 13.5px;
66+
font-weight: 500;
67+
line-height: 1;
68+
white-space: nowrap;
69+
transition:
70+
background var(--universal-nav-duration-fast) var(--universal-nav-ease),
71+
color var(--universal-nav-duration-fast) var(--universal-nav-ease);
72+
}
73+
74+
.universal-nav__tab:hover {
75+
background: var(--universal-nav-hover-background);
76+
color: rgba(255, 255, 255, 0.85);
77+
}
78+
79+
.universal-nav__tab.is-current {
80+
color: var(--universal-nav-font-color);
81+
font-weight: 700;
82+
background: rgba(255, 255, 255, 0.12);
83+
}
84+
85+
.universal-nav__dot {
86+
width: 6px;
87+
height: 6px;
88+
border-radius: 50%;
89+
flex: none;
90+
background: rgba(255, 255, 255, 0.3);
91+
}
92+
93+
.universal-nav__tab.is-current .universal-nav__dot {
94+
background: var(--universal-nav-accent-current);
95+
}
96+
97+
.universal-nav__dot--site {
98+
background: var(--universal-nav-accent-site);
99+
}
100+
101+
.universal-nav__dot--docs {
102+
background: var(--universal-nav-accent-docs);
103+
}
104+
105+
.universal-nav__dot--hub {
106+
background: var(--universal-nav-accent-hub);
107+
}
108+
109+
.universal-nav__icon {
110+
display: inline-flex;
111+
align-items: center;
112+
justify-content: center;
113+
border-radius: 6px;
114+
color: rgba(255, 255, 255, 0.7);
115+
transition: color var(--universal-nav-duration-fast) var(--universal-nav-ease);
116+
}
117+
118+
.universal-nav__icon:hover {
119+
color: var(--universal-nav-font-color);
120+
}
121+
122+
.universal-nav__cta {
123+
display: inline-flex;
124+
align-items: center;
125+
justify-content: center;
126+
height: 30px;
127+
padding: 0 16px;
128+
border-radius: 99px;
129+
background: var(--universal-nav-cta-background);
130+
color: var(--universal-nav-cta-font-color);
131+
font-size: 13px;
132+
font-weight: 500;
133+
line-height: 1;
134+
white-space: nowrap;
135+
flex: none;
136+
transition: background var(--universal-nav-duration-fast) var(--universal-nav-ease);
137+
}
138+
139+
.universal-nav__cta:hover {
140+
background: var(--universal-nav-cta-hover-background);
141+
}
142+
143+
.universal-nav__disclosure {
144+
display: none;
145+
align-items: center;
146+
gap: 7px;
147+
margin-left: auto;
148+
padding: 6px 8px;
149+
border: 0;
150+
background: none;
151+
color: var(--universal-nav-font-color);
152+
border-radius: 7px;
153+
font-size: 13.5px;
154+
font-weight: 600;
155+
line-height: 1;
156+
cursor: pointer;
157+
}
158+
159+
.universal-nav__disclosure:hover {
160+
background: var(--universal-nav-hover-background);
161+
}
162+
163+
.universal-nav__caret {
164+
display: inline-flex;
165+
color: rgba(255, 255, 255, 0.7);
166+
transition: transform var(--universal-nav-duration-med) var(--universal-nav-ease);
167+
}
168+
169+
.universal-nav__disclosure[aria-expanded="true"] .universal-nav__caret {
170+
transform: rotate(180deg);
171+
}
172+
173+
.universal-nav__sr {
174+
position: absolute;
175+
width: 1px;
176+
height: 1px;
177+
padding: 0;
178+
margin: -1px;
179+
overflow: hidden;
180+
clip: rect(0, 0, 0, 0);
181+
white-space: nowrap;
182+
border: 0;
183+
}
184+
185+
.universal-nav__sheet {
186+
position: absolute;
187+
top: var(--universal-nav-height);
188+
left: 0;
189+
width: 100%;
190+
background: var(--universal-nav-background);
191+
border-bottom: solid 1px rgba(255, 255, 255, 0.16);
192+
padding: 8px 12px 12px;
193+
line-height: 1.5;
194+
}
195+
196+
.universal-nav__sheet[hidden] {
197+
display: none;
198+
}
199+
200+
.universal-nav__sheet-row {
201+
display: flex;
202+
align-items: center;
203+
gap: 12px;
204+
padding: 12px;
205+
border-radius: 9px;
206+
margin-bottom: 4px;
207+
border: 1px solid transparent;
208+
}
209+
210+
.universal-nav__sheet-row:hover {
211+
background: var(--universal-nav-hover-background);
212+
}
213+
214+
.universal-nav__sheet-row.is-current {
215+
background: rgba(255, 255, 255, 0.06);
216+
border-color: rgba(255, 255, 255, 0.12);
217+
}
218+
219+
.universal-nav__sheet-dot {
220+
width: 9px;
221+
height: 9px;
222+
border-radius: 50%;
223+
flex: none;
224+
}
225+
226+
.universal-nav__sheet-text {
227+
flex: 1;
228+
min-width: 0;
229+
}
230+
231+
.universal-nav__sheet-name {
232+
display: block;
233+
font-size: 14.5px;
234+
font-weight: 700;
235+
color: var(--universal-nav-font-color);
236+
}
237+
238+
.universal-nav__sheet-host {
239+
display: block;
240+
color: rgba(255, 255, 255, 0.5);
241+
font-family: var(--monospace-font-family);
242+
font-size: 11px;
243+
margin-top: 1px;
244+
}
245+
246+
.universal-nav__here {
247+
color: var(--universal-nav-accent-current);
248+
font-size: 11px;
249+
font-weight: 600;
250+
white-space: nowrap;
251+
}
252+
253+
.universal-nav__ext {
254+
display: inline-flex;
255+
color: rgba(255, 255, 255, 0.5);
256+
}
257+
258+
.universal-nav__sheet-cta {
259+
width: 100%;
260+
height: 40px;
261+
margin-top: 6px;
262+
}
263+
264+
.universal-nav a:focus-visible,
265+
.universal-nav button:focus-visible {
266+
outline: 2px solid var(--universal-nav-font-color);
267+
outline-offset: 2px;
268+
}
269+
270+
@media (prefers-reduced-motion: reduce) {
271+
.universal-nav__tab,
272+
.universal-nav__icon,
273+
.universal-nav__caret,
274+
.universal-nav__disclosure,
275+
.universal-nav__cta {
276+
transition: none;
277+
}
278+
}
279+
280+
@media screen and (max-width: 720px) {
281+
.universal-nav__bar {
282+
padding: 0 14px;
283+
gap: 10px;
284+
}
285+
286+
.universal-nav__tabs,
287+
.universal-nav__icon,
288+
.universal-nav__bar > .universal-nav__cta,
289+
.universal-nav__sep {
290+
display: none;
291+
}
292+
293+
.universal-nav__disclosure {
294+
display: inline-flex;
295+
}
296+
}
297+
298+
@media screen and (min-width: 721px) {
299+
.universal-nav__sheet {
300+
display: none;
301+
}
302+
}

0 commit comments

Comments
 (0)