@veluai/velu 0.1.0
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/dist/cli.js +11 -0
- package/package.json +52 -0
- package/runtime/velu-ui/base.css +311 -0
- package/runtime/velu-ui/components/Accordion.jsx +64 -0
- package/runtime/velu-ui/components/ApiClient.jsx +121 -0
- package/runtime/velu-ui/components/ApiField.jsx +87 -0
- package/runtime/velu-ui/components/ApiPath.jsx +63 -0
- package/runtime/velu-ui/components/ApiSidebar.jsx +122 -0
- package/runtime/velu-ui/components/AskBar.jsx +71 -0
- package/runtime/velu-ui/components/Callout.jsx +114 -0
- package/runtime/velu-ui/components/Card.jsx +131 -0
- package/runtime/velu-ui/components/Chatbot.jsx +596 -0
- package/runtime/velu-ui/components/CodeBlock.jsx +375 -0
- package/runtime/velu-ui/components/Columns.jsx +56 -0
- package/runtime/velu-ui/components/Field.jsx +81 -0
- package/runtime/velu-ui/components/Image.jsx +163 -0
- package/runtime/velu-ui/components/MethodBadge.jsx +31 -0
- package/runtime/velu-ui/components/NavSelect.jsx +108 -0
- package/runtime/velu-ui/components/PageFeedback.jsx +219 -0
- package/runtime/velu-ui/components/PageFooter.jsx +213 -0
- package/runtime/velu-ui/components/PageHeader.jsx +414 -0
- package/runtime/velu-ui/components/PageNav.jsx +77 -0
- package/runtime/velu-ui/components/PoweredBy.jsx +51 -0
- package/runtime/velu-ui/components/Prompt.jsx +115 -0
- package/runtime/velu-ui/components/Search.jsx +366 -0
- package/runtime/velu-ui/components/Sidebar.jsx +191 -0
- package/runtime/velu-ui/components/Steps.jsx +65 -0
- package/runtime/velu-ui/components/ThemeToggle.jsx +48 -0
- package/runtime/velu-ui/components/Toc.jsx +537 -0
- package/runtime/velu-ui/components/TocBar.jsx +195 -0
- package/runtime/velu-ui/components/Tree.jsx +87 -0
- package/runtime/velu-ui/components/TryItBar.jsx +90 -0
- package/runtime/velu-ui/components/accordion.css +92 -0
- package/runtime/velu-ui/components/api.css +479 -0
- package/runtime/velu-ui/components/ask-bar.css +94 -0
- package/runtime/velu-ui/components/card.css +105 -0
- package/runtime/velu-ui/components/chatbot.css +617 -0
- package/runtime/velu-ui/components/code-block.css +263 -0
- package/runtime/velu-ui/components/docs-layout.css +775 -0
- package/runtime/velu-ui/components/field.css +82 -0
- package/runtime/velu-ui/components/image.css +237 -0
- package/runtime/velu-ui/components/nav-select.css +157 -0
- package/runtime/velu-ui/components/page-feedback.css +241 -0
- package/runtime/velu-ui/components/page-footer.css +130 -0
- package/runtime/velu-ui/components/page-header.css +520 -0
- package/runtime/velu-ui/components/page-nav.css +50 -0
- package/runtime/velu-ui/components/powered-by.css +66 -0
- package/runtime/velu-ui/components/prompt.css +99 -0
- package/runtime/velu-ui/components/search.css +307 -0
- package/runtime/velu-ui/components/sidebar.css +144 -0
- package/runtime/velu-ui/components/steps.css +77 -0
- package/runtime/velu-ui/components/theme-toggle.css +70 -0
- package/runtime/velu-ui/components/toc-bar.css +234 -0
- package/runtime/velu-ui/components/tree.css +49 -0
- package/runtime/velu-ui/index.js +45 -0
- package/runtime/velu-ui/lib/copyText.js +64 -0
- package/runtime/velu-ui/lib/lang-icons.jsx +156 -0
- package/runtime/velu-ui/lib/prism-langs.js +957 -0
- package/runtime/velu-ui/lib/prism-loader.js +74 -0
- package/runtime/velu-ui/lib/resolveIcon.jsx +29 -0
- package/runtime/velu-ui/lib/scrollIntoNearestView.js +66 -0
- package/runtime/velu-ui/mdx-components.jsx +85 -0
- package/runtime/velu-ui/primitives/Cluster.jsx +49 -0
- package/runtime/velu-ui/primitives/Stack.jsx +63 -0
- package/runtime/velu-ui/primitives/Switcher.jsx +57 -0
- package/runtime/velu-ui/primitives/stack.css +3 -0
- package/runtime/velu-ui/primitives/switcher.css +25 -0
- package/runtime/velu-ui/styles.css +43 -0
- package/runtime/velu-ui/tokens.css +4 -0
- package/schema/velu.schema.json +167 -0
- package/src/navigation.js +434 -0
- package/src/runtime/App.jsx +1473 -0
- package/src/runtime/client-entry.jsx +22 -0
- package/src/runtime/server-entry.jsx +16 -0
- package/src/template.html +48 -0
- package/templates/starter/ai-tools/claude-code.mdx +26 -0
- package/templates/starter/ai-tools/cursor.mdx +17 -0
- package/templates/starter/api-reference/endpoint/create.mdx +24 -0
- package/templates/starter/api-reference/endpoint/get.mdx +27 -0
- package/templates/starter/api-reference/introduction.mdx +28 -0
- package/templates/starter/development.mdx +19 -0
- package/templates/starter/essentials/code.mdx +28 -0
- package/templates/starter/essentials/images.mdx +29 -0
- package/templates/starter/essentials/markdown.mdx +25 -0
- package/templates/starter/essentials/navigation.mdx +39 -0
- package/templates/starter/essentials/settings.mdx +30 -0
- package/templates/starter/favicon.svg +6 -0
- package/templates/starter/index.mdx +31 -0
- package/templates/starter/quickstart.mdx +31 -0
- package/templates/starter/velu.json +33 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* Field — parameter docs row. All values are tokens; light/dark via
|
|
2
|
+
[data-theme]. The chip / pill recipes are kept simple so they read
|
|
3
|
+
identically against both `--surface-color` and `--page-bg`. */
|
|
4
|
+
|
|
5
|
+
.velu-field {
|
|
6
|
+
display: block;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/* Header row of chips + name + type + required + default + post.
|
|
10
|
+
flex-wrap so a long set of badges falls cleanly onto a second line
|
|
11
|
+
on narrow widths. Items align on text baseline so the bold `name`
|
|
12
|
+
never visually shifts when chips have different padding. */
|
|
13
|
+
/* The chip row layout lives in <Cluster> now (primitives/Cluster.jsx) —
|
|
14
|
+
no .velu-field__head selector needed. */
|
|
15
|
+
|
|
16
|
+
/* Generic chip — used for pre / type / post. Hugs the line-height
|
|
17
|
+
vertically (zero block padding) with 8px / --s-3 horizontal padding;
|
|
18
|
+
reads as a tiny code-like badge. */
|
|
19
|
+
.velu-field__chip {
|
|
20
|
+
display: inline-flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
padding-block: 0;
|
|
23
|
+
padding-inline: var(--s-3);
|
|
24
|
+
background: var(--surface-color);
|
|
25
|
+
border-radius: var(--radius-sm);
|
|
26
|
+
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
27
|
+
font-size: var(--f-h6);
|
|
28
|
+
line-height: var(--lh-h6);
|
|
29
|
+
color: var(--muted-color);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* The parameter name — accent, medium weight, slightly larger than the
|
|
33
|
+
chips so it reads as the row's primary token. */
|
|
34
|
+
.velu-field__name {
|
|
35
|
+
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
36
|
+
font-size: var(--f-h5);
|
|
37
|
+
line-height: var(--lh-h5);
|
|
38
|
+
font-weight: var(--weight-medium);
|
|
39
|
+
color: var(--accent-color);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Required pill — accent-tinted background + accent text. Same hugging
|
|
43
|
+
line-height as the generic chip. */
|
|
44
|
+
.velu-field__required {
|
|
45
|
+
display: inline-flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
padding-block: 0;
|
|
48
|
+
padding-inline: var(--s-3);
|
|
49
|
+
background: color-mix(in srgb, var(--accent-color) 18%, transparent);
|
|
50
|
+
border-radius: var(--radius-sm);
|
|
51
|
+
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
52
|
+
font-size: var(--f-h6);
|
|
53
|
+
line-height: var(--lh-h6);
|
|
54
|
+
color: var(--accent-color);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* default: VALUE — light italic Google Sans Code, regular text color
|
|
58
|
+
(not muted). */
|
|
59
|
+
.velu-field__default {
|
|
60
|
+
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
61
|
+
font-style: italic;
|
|
62
|
+
font-weight: var(--weight-light);
|
|
63
|
+
font-size: var(--f-h6);
|
|
64
|
+
line-height: var(--lh-h6);
|
|
65
|
+
color: var(--text-color);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Description block beneath the chip row. */
|
|
69
|
+
.velu-field__body {
|
|
70
|
+
margin-block-start: var(--s-1);
|
|
71
|
+
color: var(--text-color);
|
|
72
|
+
font-size: var(--f-body);
|
|
73
|
+
line-height: var(--lh-body);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* Sibling separator — drop two <Field> next to each other and the
|
|
77
|
+
hairline divider appears between them. No wrapper component needed. */
|
|
78
|
+
.velu-field + .velu-field {
|
|
79
|
+
margin-block-start: var(--s2);
|
|
80
|
+
padding-block-start: var(--s2);
|
|
81
|
+
border-block-start: var(--border-width) solid var(--border-color);
|
|
82
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/* Image — plain / captioned / window-chrome / device-frame variants.
|
|
2
|
+
Tokenized; light/dark via [data-theme]. The window + frame variants share
|
|
3
|
+
an accent-glow + noise backdrop, plus the liquid-glass layered surface
|
|
4
|
+
(effect/tint/shine/content) for chrome bar + device bezel — SVG
|
|
5
|
+
feTurbulence→feDisplacementMap provides the actual refraction. */
|
|
6
|
+
|
|
7
|
+
.velu-image {
|
|
8
|
+
display: block;
|
|
9
|
+
margin: 0; /* reset <figure> default margin */
|
|
10
|
+
}
|
|
11
|
+
/* Chrome variants: figure hugs the contained card so the caption
|
|
12
|
+
naturally centers under it instead of under the full content column. */
|
|
13
|
+
.velu-image--chrome {
|
|
14
|
+
inline-size: fit-content;
|
|
15
|
+
margin-inline: auto;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.velu-image__img {
|
|
19
|
+
display: block;
|
|
20
|
+
inline-size: 100%;
|
|
21
|
+
block-size: auto;
|
|
22
|
+
border-radius: var(--radius-md);
|
|
23
|
+
object-fit: cover;
|
|
24
|
+
}
|
|
25
|
+
.velu-image__img--flush {
|
|
26
|
+
border-radius: 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.velu-image__caption {
|
|
30
|
+
margin-block-start: var(--s-1);
|
|
31
|
+
text-align: center;
|
|
32
|
+
font-size: var(--f-h6);
|
|
33
|
+
line-height: var(--lh-h6);
|
|
34
|
+
color: var(--muted-color);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* ── Accent glow + noise grain (shared by window + frame) ────────────────── */
|
|
38
|
+
/* Big soft blob peeking from outside the container. The position uses
|
|
39
|
+
negative insets so the blob's center is outside; overflow:hidden on
|
|
40
|
+
the parent clips it to a quarter visible. */
|
|
41
|
+
.velu-image__glow {
|
|
42
|
+
position: absolute;
|
|
43
|
+
inset-block-start: calc(var(--s4) * -1);
|
|
44
|
+
inset-inline-start: calc(var(--s4) * -1);
|
|
45
|
+
inline-size: calc(var(--s5) * 5);
|
|
46
|
+
block-size: calc(var(--s5) * 5);
|
|
47
|
+
background: var(--accent-color);
|
|
48
|
+
border-radius: 50%;
|
|
49
|
+
filter: blur(var(--s3));
|
|
50
|
+
opacity: 0.95;
|
|
51
|
+
pointer-events: none;
|
|
52
|
+
z-index: 0;
|
|
53
|
+
}
|
|
54
|
+
.velu-image__noise {
|
|
55
|
+
position: absolute;
|
|
56
|
+
inset: 0;
|
|
57
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
|
|
58
|
+
opacity: 0.6;
|
|
59
|
+
mix-blend-mode: overlay;
|
|
60
|
+
pointer-events: none;
|
|
61
|
+
z-index: 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* ── Liquid-glass surface (lucasromerodb pattern) ────────────────────────── */
|
|
65
|
+
/* Four-layer stack: effect (backdrop-blur + SVG displacement filter),
|
|
66
|
+
tint (translucent white), shine (inset highlights), content (children).
|
|
67
|
+
Stays usable across themes — tint+shine are universal optical constants
|
|
68
|
+
(white), not palette tokens. */
|
|
69
|
+
.velu-glass {
|
|
70
|
+
position: relative;
|
|
71
|
+
display: flex;
|
|
72
|
+
/* No overflow:hidden — each inner layer rounds itself via
|
|
73
|
+
`border-radius: inherit`, so we don't need to clip at the parent.
|
|
74
|
+
Skipping the clip lets children's box-shadows (e.g. the raised
|
|
75
|
+
screen inside the bezel) extend outside the glass surface. */
|
|
76
|
+
box-shadow:
|
|
77
|
+
0 var(--s-1) var(--s-1) color-mix(in srgb, #000 20%, transparent),
|
|
78
|
+
0 0 var(--s1) color-mix(in srgb, #000 10%, transparent);
|
|
79
|
+
}
|
|
80
|
+
/* Each layer rounds itself rather than relying on parent overflow:hidden —
|
|
81
|
+
Chrome doesn't reliably clip backdrop-filter / inset-box-shadow to a
|
|
82
|
+
rounded parent, which produces 90° corners poking through curves. */
|
|
83
|
+
.velu-glass__effect,
|
|
84
|
+
.velu-glass__tint,
|
|
85
|
+
.velu-glass__shine,
|
|
86
|
+
.velu-glass__content {
|
|
87
|
+
border-radius: inherit;
|
|
88
|
+
}
|
|
89
|
+
/* Displacement must be applied to the BACKDROP (what's behind the element),
|
|
90
|
+
not to the element itself. `filter: url()` would apply to the (empty)
|
|
91
|
+
effect div; `backdrop-filter: url()` refracts the actual backdrop.
|
|
92
|
+
Chromium-only; Safari/Firefox fall back to plain blur. */
|
|
93
|
+
.velu-glass__effect {
|
|
94
|
+
position: absolute;
|
|
95
|
+
inset: 0;
|
|
96
|
+
z-index: 0;
|
|
97
|
+
-webkit-backdrop-filter: blur(3px) url(#velu-glass-distortion);
|
|
98
|
+
backdrop-filter: blur(3px) url(#velu-glass-distortion);
|
|
99
|
+
isolation: isolate;
|
|
100
|
+
}
|
|
101
|
+
.velu-glass__tint {
|
|
102
|
+
position: absolute;
|
|
103
|
+
inset: 0;
|
|
104
|
+
z-index: 1;
|
|
105
|
+
background: rgba(255, 255, 255, 0.25);
|
|
106
|
+
}
|
|
107
|
+
.velu-glass__shine {
|
|
108
|
+
position: absolute;
|
|
109
|
+
inset: 0;
|
|
110
|
+
z-index: 2;
|
|
111
|
+
box-shadow:
|
|
112
|
+
inset 2px 2px 1px 0 rgba(255, 255, 255, 0.5),
|
|
113
|
+
inset -1px -1px 1px 1px rgba(255, 255, 255, 0.5);
|
|
114
|
+
}
|
|
115
|
+
.velu-glass__content {
|
|
116
|
+
position: relative;
|
|
117
|
+
z-index: 3;
|
|
118
|
+
inline-size: 100%;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* ── Window-chrome variant ──────────────────────────────────────────────── */
|
|
122
|
+
/* Outer = grey card. Nested radii are properly concentric:
|
|
123
|
+
outer_radius ▸ surface_radius (= outer - outer_padding) ▸
|
|
124
|
+
inner_radius (= surface - surface_padding). Padding is kept small
|
|
125
|
+
enough that every level's curve stays positive. */
|
|
126
|
+
.velu-image__window {
|
|
127
|
+
position: relative;
|
|
128
|
+
padding: var(--s-1);
|
|
129
|
+
border-radius: var(--radius-lg);
|
|
130
|
+
overflow: hidden;
|
|
131
|
+
background: var(--surface-color);
|
|
132
|
+
max-inline-size: 36rem;
|
|
133
|
+
margin-inline: auto;
|
|
134
|
+
}
|
|
135
|
+
/* Glass surface (tray) that the chrome+image card sits on. Peeks out
|
|
136
|
+
around the inner card as a visible glass border.
|
|
137
|
+
radius = outer_radius - outer_padding (concentric with outer card). */
|
|
138
|
+
.velu-image__window-surface {
|
|
139
|
+
position: relative;
|
|
140
|
+
z-index: 1;
|
|
141
|
+
inline-size: 100%;
|
|
142
|
+
border-radius: calc(var(--radius-lg) - var(--s-1));
|
|
143
|
+
}
|
|
144
|
+
.velu-image__window-surface > .velu-glass__content {
|
|
145
|
+
padding: var(--s-2);
|
|
146
|
+
}
|
|
147
|
+
/* Inner card holds the chrome bar + image.
|
|
148
|
+
radius = surface_radius - surface_padding (concentric with surface).
|
|
149
|
+
A soft drop-shadow lifts it off the glass tray. */
|
|
150
|
+
.velu-image__window-inner {
|
|
151
|
+
position: relative;
|
|
152
|
+
inline-size: 100%;
|
|
153
|
+
border-radius: calc(var(--radius-lg) - var(--s-1) - var(--s-2));
|
|
154
|
+
overflow: hidden;
|
|
155
|
+
box-shadow:
|
|
156
|
+
0 var(--s-2) var(--s-1) color-mix(in srgb, #000 18%, transparent),
|
|
157
|
+
0 var(--s-4) var(--s-3) color-mix(in srgb, #000 12%, transparent);
|
|
158
|
+
}
|
|
159
|
+
/* Chrome bar sits ABOVE the image (in flow, no overlap). The image
|
|
160
|
+
renders below it. Chrome is glass-styled via the Glass wrapper.
|
|
161
|
+
Top corners match the window's radius; bottom stays flat where it
|
|
162
|
+
meets the image. Inner glass layers inherit via `border-radius:
|
|
163
|
+
inherit`. */
|
|
164
|
+
.velu-image__chrome {
|
|
165
|
+
border-start-start-radius: calc(var(--radius-lg) - var(--s-1) - var(--s-2));
|
|
166
|
+
border-start-end-radius: calc(var(--radius-lg) - var(--s-1) - var(--s-2));
|
|
167
|
+
/* The default `.velu-glass` drop-shadow casts a dark line onto the
|
|
168
|
+
image below — undesired here since the chrome meets the image
|
|
169
|
+
directly. The bezel keeps its shadow because it sits in a padded
|
|
170
|
+
grey card that absorbs it. */
|
|
171
|
+
box-shadow: none;
|
|
172
|
+
}
|
|
173
|
+
.velu-image__chrome > .velu-glass__content {
|
|
174
|
+
display: flex;
|
|
175
|
+
align-items: center;
|
|
176
|
+
gap: var(--s-1);
|
|
177
|
+
padding: var(--s-1);
|
|
178
|
+
}
|
|
179
|
+
.velu-image__dots {
|
|
180
|
+
display: inline-flex;
|
|
181
|
+
gap: var(--s-3);
|
|
182
|
+
padding-inline: var(--s-3);
|
|
183
|
+
}
|
|
184
|
+
.velu-image__dot {
|
|
185
|
+
inline-size: 0.75em;
|
|
186
|
+
block-size: 0.75em;
|
|
187
|
+
border-radius: 50%;
|
|
188
|
+
}
|
|
189
|
+
.velu-image__dot--red { background: #ff5f57; }
|
|
190
|
+
.velu-image__dot--yellow { background: #febc2e; }
|
|
191
|
+
.velu-image__dot--green { background: #28c840; }
|
|
192
|
+
/* URL bar is absolutely centered in the chrome regardless of the dots'
|
|
193
|
+
width on the left — the .velu-glass__content already has
|
|
194
|
+
position: relative, so this anchors to that. */
|
|
195
|
+
.velu-image__urlbar {
|
|
196
|
+
position: absolute;
|
|
197
|
+
inset-inline-start: 50%;
|
|
198
|
+
transform: translateX(-50%);
|
|
199
|
+
inline-size: 15%;
|
|
200
|
+
block-size: 0.5em;
|
|
201
|
+
border-radius: 999px;
|
|
202
|
+
background: color-mix(in srgb, var(--text-color) 14%, transparent);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/* ── Device-frame variant ───────────────────────────────────────────────── */
|
|
206
|
+
/* Outer = grey card. Concentric nesting: outer → bezel → screen, each
|
|
207
|
+
radius = parent_radius - padding so all corner curves align. */
|
|
208
|
+
.velu-image__frame {
|
|
209
|
+
position: relative;
|
|
210
|
+
display: flex;
|
|
211
|
+
justify-content: center;
|
|
212
|
+
padding: var(--s-1);
|
|
213
|
+
border-radius: var(--radius-lg);
|
|
214
|
+
overflow: hidden;
|
|
215
|
+
background: var(--surface-color);
|
|
216
|
+
max-inline-size: 18rem;
|
|
217
|
+
margin-inline: auto;
|
|
218
|
+
}
|
|
219
|
+
/* Bezel: concentric with outer card. */
|
|
220
|
+
.velu-image__frame-bezel {
|
|
221
|
+
position: relative;
|
|
222
|
+
z-index: 1;
|
|
223
|
+
inline-size: 13rem;
|
|
224
|
+
max-inline-size: 100%;
|
|
225
|
+
border-radius: calc(var(--radius-lg) - var(--s-1));
|
|
226
|
+
}
|
|
227
|
+
.velu-image__frame-bezel > .velu-glass__content {
|
|
228
|
+
padding: var(--s-2);
|
|
229
|
+
}
|
|
230
|
+
/* Screen: concentric with bezel. Soft drop-shadow lifts it off the bezel. */
|
|
231
|
+
.velu-image__frame-screen {
|
|
232
|
+
border-radius: calc(var(--radius-lg) - var(--s-1) - var(--s-2));
|
|
233
|
+
overflow: hidden;
|
|
234
|
+
box-shadow:
|
|
235
|
+
0 var(--s-2) var(--s-1) color-mix(in srgb, #000 18%, transparent),
|
|
236
|
+
0 var(--s-4) var(--s-3) color-mix(in srgb, #000 12%, transparent);
|
|
237
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/* NavSelect — dropdown switcher for product / version / language.
|
|
2
|
+
Shares the visual recipe with the docs drawer's doc-select. All
|
|
3
|
+
values are tokens; light/dark via [data-theme]. */
|
|
4
|
+
|
|
5
|
+
.velu-nav-select {
|
|
6
|
+
position: relative;
|
|
7
|
+
display: inline-block;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.velu-nav-select__btn {
|
|
11
|
+
display: inline-flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
gap: var(--s-3);
|
|
14
|
+
inline-size: 100%;
|
|
15
|
+
padding-block: var(--s-3);
|
|
16
|
+
padding-inline: var(--s0);
|
|
17
|
+
background: var(--page-bg);
|
|
18
|
+
border: var(--border-width) solid var(--border-color);
|
|
19
|
+
border-radius: var(--radius-sm);
|
|
20
|
+
font: inherit;
|
|
21
|
+
font-size: var(--f-h5);
|
|
22
|
+
color: var(--text-color);
|
|
23
|
+
text-align: start;
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
transition: border-color 0.12s ease;
|
|
26
|
+
}
|
|
27
|
+
.velu-nav-select__btn:hover {
|
|
28
|
+
border-color: var(--accent-color);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Bare variant — borderless text trigger (e.g. the language switcher
|
|
32
|
+
at the header's bottom-right, GitBook-style). */
|
|
33
|
+
.velu-nav-select--bare .velu-nav-select__btn {
|
|
34
|
+
inline-size: auto;
|
|
35
|
+
padding-inline: 0;
|
|
36
|
+
background: transparent;
|
|
37
|
+
border: 0;
|
|
38
|
+
font-size: var(--f-h6);
|
|
39
|
+
}
|
|
40
|
+
.velu-nav-select--bare .velu-nav-select__btn:hover {
|
|
41
|
+
color: var(--accent-color);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Language (or other) code shown uppercase before the name. Kept at
|
|
45
|
+
text color (not muted) — distinguished by case + size, not grey. */
|
|
46
|
+
.velu-nav-select__code {
|
|
47
|
+
flex: none;
|
|
48
|
+
color: var(--text-color);
|
|
49
|
+
text-transform: uppercase;
|
|
50
|
+
font-size: 0.85em;
|
|
51
|
+
letter-spacing: 0.02em;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Compact variant — the version pill sitting next to the brand. */
|
|
55
|
+
.velu-nav-select--sm .velu-nav-select__btn {
|
|
56
|
+
padding-block: var(--s-5);
|
|
57
|
+
padding-inline: var(--s-2);
|
|
58
|
+
font-size: var(--f-h6);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.velu-nav-select__btn-icon {
|
|
62
|
+
display: inline-flex;
|
|
63
|
+
flex: none;
|
|
64
|
+
color: var(--text-color);
|
|
65
|
+
}
|
|
66
|
+
.velu-nav-select__value {
|
|
67
|
+
flex: 1;
|
|
68
|
+
min-inline-size: 0;
|
|
69
|
+
overflow: hidden;
|
|
70
|
+
text-overflow: ellipsis;
|
|
71
|
+
white-space: nowrap;
|
|
72
|
+
}
|
|
73
|
+
.velu-nav-select__chev {
|
|
74
|
+
flex: none;
|
|
75
|
+
inline-size: 1em;
|
|
76
|
+
block-size: 1em;
|
|
77
|
+
stroke-width: 1;
|
|
78
|
+
color: var(--text-color);
|
|
79
|
+
transition: transform 0.18s ease;
|
|
80
|
+
}
|
|
81
|
+
.velu-nav-select[data-open='true'] .velu-nav-select__chev {
|
|
82
|
+
transform: rotate(180deg);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Menu — anchored below the button, fades + slides in. Always in DOM
|
|
86
|
+
so the transition runs both directions; visibility delayed so the
|
|
87
|
+
closed menu isn't focusable. */
|
|
88
|
+
.velu-nav-select__menu {
|
|
89
|
+
position: absolute;
|
|
90
|
+
inset-block-start: calc(100% + var(--s-3));
|
|
91
|
+
inset-inline-start: 0;
|
|
92
|
+
min-inline-size: 100%;
|
|
93
|
+
margin: 0;
|
|
94
|
+
padding-block: var(--s-2);
|
|
95
|
+
padding-inline: 0;
|
|
96
|
+
list-style: none;
|
|
97
|
+
background: var(--page-bg);
|
|
98
|
+
border: var(--border-width) solid var(--border-color);
|
|
99
|
+
border-radius: var(--radius-sm);
|
|
100
|
+
box-shadow: 0 var(--s-2) var(--s1)
|
|
101
|
+
color-mix(in srgb, #000 12%, transparent);
|
|
102
|
+
opacity: 0;
|
|
103
|
+
visibility: hidden;
|
|
104
|
+
transform: translateY(-0.25rem);
|
|
105
|
+
pointer-events: none;
|
|
106
|
+
transition:
|
|
107
|
+
opacity 0.15s ease,
|
|
108
|
+
transform 0.15s ease,
|
|
109
|
+
visibility 0s linear 0.15s;
|
|
110
|
+
z-index: 40;
|
|
111
|
+
}
|
|
112
|
+
.velu-nav-select[data-open='true'] .velu-nav-select__menu {
|
|
113
|
+
opacity: 1;
|
|
114
|
+
visibility: visible;
|
|
115
|
+
transform: translateY(0);
|
|
116
|
+
pointer-events: auto;
|
|
117
|
+
transition:
|
|
118
|
+
opacity 0.15s ease,
|
|
119
|
+
transform 0.15s ease,
|
|
120
|
+
visibility 0s;
|
|
121
|
+
}
|
|
122
|
+
/* Right-align the menu when the trigger sits at the trailing edge
|
|
123
|
+
(e.g. the language switcher at the header's bottom-right). */
|
|
124
|
+
.velu-nav-select--align-end .velu-nav-select__menu {
|
|
125
|
+
inset-inline-start: auto;
|
|
126
|
+
inset-inline-end: 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.velu-nav-select__item {
|
|
130
|
+
display: flex;
|
|
131
|
+
align-items: center;
|
|
132
|
+
gap: var(--s-3);
|
|
133
|
+
padding-block: var(--s-2);
|
|
134
|
+
padding-inline: var(--s0);
|
|
135
|
+
font-size: var(--f-h5);
|
|
136
|
+
color: var(--text-color);
|
|
137
|
+
text-decoration: none;
|
|
138
|
+
white-space: nowrap;
|
|
139
|
+
cursor: pointer;
|
|
140
|
+
transition: background 0.12s ease, color 0.12s ease;
|
|
141
|
+
}
|
|
142
|
+
.velu-nav-select__item:hover {
|
|
143
|
+
background: var(--surface-color);
|
|
144
|
+
color: var(--accent-color);
|
|
145
|
+
}
|
|
146
|
+
.velu-nav-select__item--active {
|
|
147
|
+
color: var(--accent-color);
|
|
148
|
+
}
|
|
149
|
+
.velu-nav-select__item-icon {
|
|
150
|
+
display: inline-flex;
|
|
151
|
+
flex: none;
|
|
152
|
+
color: var(--text-color);
|
|
153
|
+
}
|
|
154
|
+
.velu-nav-select__item:hover .velu-nav-select__item-icon,
|
|
155
|
+
.velu-nav-select__item--active .velu-nav-select__item-icon {
|
|
156
|
+
color: var(--accent-color);
|
|
157
|
+
}
|