@veluai/velu 0.2.25 → 0.2.28

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.
Files changed (114) hide show
  1. package/README.md +80 -80
  2. package/dist/cli.js +44 -44
  3. package/package.json +64 -64
  4. package/runtime/velu-ui/base.css +320 -320
  5. package/runtime/velu-ui/components/Accordion.jsx +64 -64
  6. package/runtime/velu-ui/components/ApiClient.jsx +207 -207
  7. package/runtime/velu-ui/components/ApiField.jsx +87 -87
  8. package/runtime/velu-ui/components/ApiPath.jsx +63 -63
  9. package/runtime/velu-ui/components/ApiReferencePage.jsx +384 -384
  10. package/runtime/velu-ui/components/ApiSamples.jsx +36 -36
  11. package/runtime/velu-ui/components/ApiSidebar.jsx +125 -125
  12. package/runtime/velu-ui/components/AskBar.jsx +71 -71
  13. package/runtime/velu-ui/components/Callout.jsx +114 -114
  14. package/runtime/velu-ui/components/Card.jsx +131 -131
  15. package/runtime/velu-ui/components/ChangelogFilters.jsx +75 -75
  16. package/runtime/velu-ui/components/Chatbot.jsx +972 -972
  17. package/runtime/velu-ui/components/CodeBlock.jsx +375 -375
  18. package/runtime/velu-ui/components/Columns.jsx +56 -56
  19. package/runtime/velu-ui/components/ContextMenu.jsx +327 -327
  20. package/runtime/velu-ui/components/ErrorCard.jsx +138 -138
  21. package/runtime/velu-ui/components/Field.jsx +81 -81
  22. package/runtime/velu-ui/components/Image.jsx +163 -163
  23. package/runtime/velu-ui/components/Logo.jsx +31 -31
  24. package/runtime/velu-ui/components/MethodBadge.jsx +31 -31
  25. package/runtime/velu-ui/components/NavSelect.jsx +108 -108
  26. package/runtime/velu-ui/components/NotFound.jsx +63 -63
  27. package/runtime/velu-ui/components/PageFeedback.jsx +219 -219
  28. package/runtime/velu-ui/components/PageFooter.jsx +145 -145
  29. package/runtime/velu-ui/components/PageHeader.jsx +422 -422
  30. package/runtime/velu-ui/components/PageNav.jsx +77 -77
  31. package/runtime/velu-ui/components/PoweredBy.jsx +51 -51
  32. package/runtime/velu-ui/components/Prompt.jsx +115 -115
  33. package/runtime/velu-ui/components/Search.jsx +460 -460
  34. package/runtime/velu-ui/components/Sidebar.jsx +246 -246
  35. package/runtime/velu-ui/components/SocialLinks.jsx +90 -90
  36. package/runtime/velu-ui/components/Steps.jsx +65 -65
  37. package/runtime/velu-ui/components/ThemeToggle.jsx +48 -48
  38. package/runtime/velu-ui/components/Toc.jsx +537 -537
  39. package/runtime/velu-ui/components/TocBar.jsx +195 -195
  40. package/runtime/velu-ui/components/Tree.jsx +87 -87
  41. package/runtime/velu-ui/components/TryItBar.jsx +102 -102
  42. package/runtime/velu-ui/components/Update.jsx +92 -92
  43. package/runtime/velu-ui/components/accordion.css +92 -92
  44. package/runtime/velu-ui/components/api-page.css +208 -208
  45. package/runtime/velu-ui/components/api.css +635 -635
  46. package/runtime/velu-ui/components/ask-bar.css +103 -103
  47. package/runtime/velu-ui/components/card.css +105 -105
  48. package/runtime/velu-ui/components/changelog-filters.css +43 -43
  49. package/runtime/velu-ui/components/chatbot.css +687 -687
  50. package/runtime/velu-ui/components/code-block.css +263 -263
  51. package/runtime/velu-ui/components/context-menu.css +199 -199
  52. package/runtime/velu-ui/components/docs-layout.css +822 -822
  53. package/runtime/velu-ui/components/field.css +82 -82
  54. package/runtime/velu-ui/components/image.css +237 -237
  55. package/runtime/velu-ui/components/nav-select.css +157 -157
  56. package/runtime/velu-ui/components/not-found.css +94 -94
  57. package/runtime/velu-ui/components/page-feedback.css +261 -261
  58. package/runtime/velu-ui/components/page-footer.css +130 -130
  59. package/runtime/velu-ui/components/page-header.css +558 -558
  60. package/runtime/velu-ui/components/page-nav.css +50 -50
  61. package/runtime/velu-ui/components/powered-by.css +92 -92
  62. package/runtime/velu-ui/components/prompt.css +99 -99
  63. package/runtime/velu-ui/components/search.css +307 -307
  64. package/runtime/velu-ui/components/sidebar.css +205 -205
  65. package/runtime/velu-ui/components/steps.css +77 -77
  66. package/runtime/velu-ui/components/theme-toggle.css +102 -102
  67. package/runtime/velu-ui/components/toc-bar.css +234 -234
  68. package/runtime/velu-ui/components/tree.css +49 -49
  69. package/runtime/velu-ui/components/update.css +111 -111
  70. package/runtime/velu-ui/index.js +58 -58
  71. package/runtime/velu-ui/lib/api-send.js +118 -118
  72. package/runtime/velu-ui/lib/brand-icons.jsx +103 -103
  73. package/runtime/velu-ui/lib/component-schemas.js +100 -100
  74. package/runtime/velu-ui/lib/copyText.js +64 -64
  75. package/runtime/velu-ui/lib/docs-assistant.js +273 -273
  76. package/runtime/velu-ui/lib/lang-icons.jsx +147 -147
  77. package/runtime/velu-ui/lib/page-feedback.js +72 -72
  78. package/runtime/velu-ui/lib/pagefind.js +116 -116
  79. package/runtime/velu-ui/lib/prism-langs.js +957 -957
  80. package/runtime/velu-ui/lib/prism-loader.js +74 -74
  81. package/runtime/velu-ui/lib/resolveIcon.jsx +29 -29
  82. package/runtime/velu-ui/lib/scrollIntoNearestView.js +66 -66
  83. package/runtime/velu-ui/mdx-components.jsx +107 -107
  84. package/runtime/velu-ui/primitives/Cluster.jsx +49 -49
  85. package/runtime/velu-ui/primitives/Stack.jsx +63 -63
  86. package/runtime/velu-ui/primitives/Switcher.jsx +57 -57
  87. package/runtime/velu-ui/primitives/stack.css +3 -3
  88. package/runtime/velu-ui/primitives/switcher.css +25 -25
  89. package/runtime/velu-ui/styles.css +48 -48
  90. package/runtime/velu-ui/tokens.css +4 -4
  91. package/schema/velu.schema.json +419 -419
  92. package/src/lib/extract-mdx-error.js +170 -170
  93. package/src/lib/issues.js +159 -159
  94. package/src/lib/known-components.js +35 -35
  95. package/src/navigation.js +459 -459
  96. package/src/runtime/App.jsx +1754 -1754
  97. package/src/runtime/ErrorBoundary.jsx +54 -54
  98. package/src/runtime/client-entry.jsx +27 -27
  99. package/src/runtime/server-entry.jsx +24 -24
  100. package/src/template.html +48 -48
  101. package/templates/starter/ai-tools/claude-code.mdx +26 -26
  102. package/templates/starter/ai-tools/cursor.mdx +17 -17
  103. package/templates/starter/api-reference/introduction.mdx +43 -43
  104. package/templates/starter/development.mdx +19 -19
  105. package/templates/starter/essentials/code.mdx +29 -29
  106. package/templates/starter/essentials/images.mdx +29 -29
  107. package/templates/starter/essentials/markdown.mdx +25 -25
  108. package/templates/starter/essentials/navigation.mdx +39 -39
  109. package/templates/starter/essentials/settings.mdx +30 -30
  110. package/templates/starter/favicon.svg +6 -6
  111. package/templates/starter/index.mdx +31 -31
  112. package/templates/starter/openapi.json +160 -160
  113. package/templates/starter/quickstart.mdx +31 -31
  114. package/templates/starter/velu.json +40 -40
@@ -1,205 +1,205 @@
1
- /* Sidebar — sidebar-specific styling ONLY.
2
-
3
- Vertical rhythm (nav, section lists, nested sublists) is composed from the
4
- Stack primitive in Sidebar.jsx (DRY) — Stack supplies display/flex/gap
5
- inline. This file holds only what Stack cannot express: the indent rails,
6
- active accent rail, the horizontal item rows, summary marker, chevron
7
- rotation, and centralized icon sizing/stroke. All values are tokens. */
8
-
9
- .velu-sidebar {
10
- position: relative; /* anchors the gliding active indicator */
11
- margin-left: var(--s1);
12
- }
13
-
14
- /* The single active indicator — a crimson tint band with a flush-left 2px bar
15
- that GLIDES between items (one element animating its position/height) instead
16
- of each item painting its own active state. z-index 0 keeps it BEHIND the
17
- items + sticky headings (both positioned, z-index 1), so the text reads over
18
- the tint and a pinned heading's opaque background covers the indicator when an
19
- item scrolls under it. Driven imperatively from JS (transform/height/opacity);
20
- the easing curve makes the slide feel continuous. */
21
- .velu-sidebar__indicator {
22
- position: absolute;
23
- inset-inline-start: 0;
24
- inset-inline-end: var(--s-3);
25
- inset-block-start: 0;
26
- height: 0;
27
- opacity: 0;
28
- z-index: 0;
29
- pointer-events: none;
30
- background: color-mix(in srgb, var(--accent-color) 8%, transparent);
31
- border-radius: var(--radius-sm);
32
- transition:
33
- transform 0.3s cubic-bezier(0.32, 0.72, 0, 1),
34
- height 0.3s cubic-bezier(0.32, 0.72, 0, 1),
35
- opacity 0.2s ease;
36
- will-change: transform, height;
37
- }
38
- .velu-sidebar__indicator::before {
39
- content: '';
40
- position: absolute;
41
- inset-inline-start: 0;
42
- inset-block: 15%;
43
- inline-size: 2px;
44
- border-start-end-radius: 2px;
45
- border-end-end-radius: 2px;
46
- background: var(--accent-color);
47
- }
48
- /* Honour reduced-motion: snap instead of glide. */
49
- @media (prefers-reduced-motion: reduce) {
50
- .velu-sidebar__indicator {
51
- transition: opacity 0.2s ease;
52
- }
53
- }
54
-
55
- .velu-sidebar__section {
56
- /* Sticky section header: each heading pins to the top of the scroll
57
- region until its own section scrolls past, then the next heading
58
- takes over (iOS-list style). It sticks within its section wrapper
59
- (Sidebar.jsx renders each section in its own Stack), which bounds
60
- the push-out. Full-width opaque background so scrolling items
61
- don't show behind it; --page-bg matches the surroundings, so the
62
- bar is invisible until it's actually covering scrolled content. */
63
- position: sticky;
64
- inset-block-start: 0;
65
- /* Above the items (z-index 1) so scrolled rows tuck UNDER the heading (its
66
- opaque bg + the ::after fade hide them), not over it; above the gliding
67
- indicator (z-index 0) too. */
68
- z-index: 2;
69
- background: var(--page-bg);
70
- display: flex;
71
- align-items: center;
72
- gap: var(--s-2);
73
- padding-block: var(--s-4);
74
- padding-inline: var(--s-3);
75
- /* A notch smaller than the default h5, with a little tracking so the
76
- uppercase label stays legible at the reduced size. */
77
- font-size: var(--f-h6);
78
- font-weight: 500;
79
- letter-spacing: 0.02em;
80
- text-transform: uppercase;
81
- }
82
- /* Fade zone just below the pinned heading: a gradient overlay
83
- (page-bg → transparent) that sits directly under the sticky header
84
- and scrolls with it. Items sliding up pass behind it and fade out
85
- before they tuck under the (crisp) heading. Absolutely positioned
86
- so it adds no resting layout space; pointer-events:none so it never
87
- eats clicks. Hidden by default — only shown once the nav is actually
88
- scrolled (the layout toggles it via data-fade-top on the scroll
89
- region), so a section's first item isn't faded at rest. */
90
- .velu-sidebar__section::after {
91
- content: '';
92
- position: absolute;
93
- inset-inline: 0;
94
- inset-block-start: 100%;
95
- block-size: var(--s3);
96
- background: linear-gradient(
97
- to bottom,
98
- var(--page-bg),
99
- color-mix(in srgb, var(--page-bg) 55%, transparent),
100
- transparent
101
- );
102
- pointer-events: none;
103
- opacity: 0;
104
- transition: opacity 0.15s ease;
105
- }
106
- /* When a heading becomes the newly-pinned one (data-stuck set by the
107
- runtime as you scroll past sections), fade + slide it in so the
108
- handoff from the previous heading reads as a transition rather than
109
- a hard swap. */
110
- .velu-sidebar__section[data-stuck='true'] {
111
- animation: velu-sidebar-stick-in 0.2s ease;
112
- }
113
- @keyframes velu-sidebar-stick-in {
114
- from {
115
- opacity: 0.3;
116
- transform: translateY(-0.2rem);
117
- }
118
- to {
119
- opacity: 1;
120
- transform: translateY(0);
121
- }
122
- }
123
-
124
- /* Lists are Stacks (flex/gap come from Stack inline) — only reset list chrome. */
125
- .velu-sidebar__list,
126
- .velu-sidebar__sublist {
127
- list-style: none;
128
- margin: 0;
129
- padding: 0;
130
- }
131
-
132
- .velu-sidebar__sublist {
133
- margin-left: var(--s0);
134
- border-left: var(--border-width) solid var(--border-color);
135
- }
136
-
137
- /* Item rows are horizontal (icon · label · chevron) — Stack is vertical-only,
138
- so these stay CSS until/if a Cluster/Inline primitive exists. */
139
- .velu-sidebar__item,
140
- .velu-sidebar__subitem {
141
- /* Positioned above the gliding indicator (z-index 0) so the label reads over
142
- the tint band. */
143
- position: relative;
144
- z-index: 1;
145
- display: flex;
146
- align-items: center;
147
- gap: var(--s-3);
148
- padding-inline: var(--s0);
149
- color: var(--text-color);
150
- text-decoration: none;
151
- transition: color 0.2s ease;
152
- }
153
-
154
- .velu-sidebar__subitem {
155
- padding-block: var(--s-5);
156
- }
157
-
158
- /* Active = colour + weight only; the moving indicator paints the bar + tint. */
159
- .velu-sidebar__item--active {
160
- color: var(--accent-color);
161
- font-weight: 500;
162
- }
163
- .velu-sidebar__item--active .velu-sidebar__icon {
164
- color: var(--accent-color);
165
- }
166
-
167
- /* The label fills the row so the group chevron (and any external-link icon)
168
- sit flush at the row's RIGHT end, not crowded against the label — faithful
169
- to the design's `flex: 1` label. */
170
- .velu-sidebar__label {
171
- flex: 1;
172
- min-inline-size: 0;
173
- }
174
-
175
- .velu-sidebar__summary {
176
- cursor: pointer;
177
- list-style: none;
178
- }
179
- .velu-sidebar__summary::-webkit-details-marker {
180
- display: none;
181
- }
182
-
183
- /* Icon sizing centralized here; stroke weight is the global --icon-stroke
184
- token (.lucide rule in base.css), not set per-component. */
185
- .velu-sidebar__icon {
186
- display: inline-flex;
187
- flex: none;
188
- inline-size: var(--f-body);
189
- block-size: var(--f-body);
190
- }
191
- .velu-sidebar__icon svg {
192
- inline-size: 100%;
193
- block-size: 100%;
194
- }
195
-
196
- .velu-sidebar__chevron {
197
- flex: none;
198
- inline-size: var(--f-body);
199
- block-size: var(--f-body);
200
- transition: transform 0.15s ease;
201
- }
202
-
203
- details[open] > .velu-sidebar__summary .velu-sidebar__chevron {
204
- transform: rotate(90deg);
205
- }
1
+ /* Sidebar — sidebar-specific styling ONLY.
2
+
3
+ Vertical rhythm (nav, section lists, nested sublists) is composed from the
4
+ Stack primitive in Sidebar.jsx (DRY) — Stack supplies display/flex/gap
5
+ inline. This file holds only what Stack cannot express: the indent rails,
6
+ active accent rail, the horizontal item rows, summary marker, chevron
7
+ rotation, and centralized icon sizing/stroke. All values are tokens. */
8
+
9
+ .velu-sidebar {
10
+ position: relative; /* anchors the gliding active indicator */
11
+ margin-left: var(--s1);
12
+ }
13
+
14
+ /* The single active indicator — a crimson tint band with a flush-left 2px bar
15
+ that GLIDES between items (one element animating its position/height) instead
16
+ of each item painting its own active state. z-index 0 keeps it BEHIND the
17
+ items + sticky headings (both positioned, z-index 1), so the text reads over
18
+ the tint and a pinned heading's opaque background covers the indicator when an
19
+ item scrolls under it. Driven imperatively from JS (transform/height/opacity);
20
+ the easing curve makes the slide feel continuous. */
21
+ .velu-sidebar__indicator {
22
+ position: absolute;
23
+ inset-inline-start: 0;
24
+ inset-inline-end: var(--s-3);
25
+ inset-block-start: 0;
26
+ height: 0;
27
+ opacity: 0;
28
+ z-index: 0;
29
+ pointer-events: none;
30
+ background: color-mix(in srgb, var(--accent-color) 8%, transparent);
31
+ border-radius: var(--radius-sm);
32
+ transition:
33
+ transform 0.3s cubic-bezier(0.32, 0.72, 0, 1),
34
+ height 0.3s cubic-bezier(0.32, 0.72, 0, 1),
35
+ opacity 0.2s ease;
36
+ will-change: transform, height;
37
+ }
38
+ .velu-sidebar__indicator::before {
39
+ content: '';
40
+ position: absolute;
41
+ inset-inline-start: 0;
42
+ inset-block: 15%;
43
+ inline-size: 2px;
44
+ border-start-end-radius: 2px;
45
+ border-end-end-radius: 2px;
46
+ background: var(--accent-color);
47
+ }
48
+ /* Honour reduced-motion: snap instead of glide. */
49
+ @media (prefers-reduced-motion: reduce) {
50
+ .velu-sidebar__indicator {
51
+ transition: opacity 0.2s ease;
52
+ }
53
+ }
54
+
55
+ .velu-sidebar__section {
56
+ /* Sticky section header: each heading pins to the top of the scroll
57
+ region until its own section scrolls past, then the next heading
58
+ takes over (iOS-list style). It sticks within its section wrapper
59
+ (Sidebar.jsx renders each section in its own Stack), which bounds
60
+ the push-out. Full-width opaque background so scrolling items
61
+ don't show behind it; --page-bg matches the surroundings, so the
62
+ bar is invisible until it's actually covering scrolled content. */
63
+ position: sticky;
64
+ inset-block-start: 0;
65
+ /* Above the items (z-index 1) so scrolled rows tuck UNDER the heading (its
66
+ opaque bg + the ::after fade hide them), not over it; above the gliding
67
+ indicator (z-index 0) too. */
68
+ z-index: 2;
69
+ background: var(--page-bg);
70
+ display: flex;
71
+ align-items: center;
72
+ gap: var(--s-2);
73
+ padding-block: var(--s-4);
74
+ padding-inline: var(--s-3);
75
+ /* A notch smaller than the default h5, with a little tracking so the
76
+ uppercase label stays legible at the reduced size. */
77
+ font-size: var(--f-h6);
78
+ font-weight: 500;
79
+ letter-spacing: 0.02em;
80
+ text-transform: uppercase;
81
+ }
82
+ /* Fade zone just below the pinned heading: a gradient overlay
83
+ (page-bg → transparent) that sits directly under the sticky header
84
+ and scrolls with it. Items sliding up pass behind it and fade out
85
+ before they tuck under the (crisp) heading. Absolutely positioned
86
+ so it adds no resting layout space; pointer-events:none so it never
87
+ eats clicks. Hidden by default — only shown once the nav is actually
88
+ scrolled (the layout toggles it via data-fade-top on the scroll
89
+ region), so a section's first item isn't faded at rest. */
90
+ .velu-sidebar__section::after {
91
+ content: '';
92
+ position: absolute;
93
+ inset-inline: 0;
94
+ inset-block-start: 100%;
95
+ block-size: var(--s3);
96
+ background: linear-gradient(
97
+ to bottom,
98
+ var(--page-bg),
99
+ color-mix(in srgb, var(--page-bg) 55%, transparent),
100
+ transparent
101
+ );
102
+ pointer-events: none;
103
+ opacity: 0;
104
+ transition: opacity 0.15s ease;
105
+ }
106
+ /* When a heading becomes the newly-pinned one (data-stuck set by the
107
+ runtime as you scroll past sections), fade + slide it in so the
108
+ handoff from the previous heading reads as a transition rather than
109
+ a hard swap. */
110
+ .velu-sidebar__section[data-stuck='true'] {
111
+ animation: velu-sidebar-stick-in 0.2s ease;
112
+ }
113
+ @keyframes velu-sidebar-stick-in {
114
+ from {
115
+ opacity: 0.3;
116
+ transform: translateY(-0.2rem);
117
+ }
118
+ to {
119
+ opacity: 1;
120
+ transform: translateY(0);
121
+ }
122
+ }
123
+
124
+ /* Lists are Stacks (flex/gap come from Stack inline) — only reset list chrome. */
125
+ .velu-sidebar__list,
126
+ .velu-sidebar__sublist {
127
+ list-style: none;
128
+ margin: 0;
129
+ padding: 0;
130
+ }
131
+
132
+ .velu-sidebar__sublist {
133
+ margin-left: var(--s0);
134
+ border-left: var(--border-width) solid var(--border-color);
135
+ }
136
+
137
+ /* Item rows are horizontal (icon · label · chevron) — Stack is vertical-only,
138
+ so these stay CSS until/if a Cluster/Inline primitive exists. */
139
+ .velu-sidebar__item,
140
+ .velu-sidebar__subitem {
141
+ /* Positioned above the gliding indicator (z-index 0) so the label reads over
142
+ the tint band. */
143
+ position: relative;
144
+ z-index: 1;
145
+ display: flex;
146
+ align-items: center;
147
+ gap: var(--s-3);
148
+ padding-inline: var(--s0);
149
+ color: var(--text-color);
150
+ text-decoration: none;
151
+ transition: color 0.2s ease;
152
+ }
153
+
154
+ .velu-sidebar__subitem {
155
+ padding-block: var(--s-5);
156
+ }
157
+
158
+ /* Active = colour + weight only; the moving indicator paints the bar + tint. */
159
+ .velu-sidebar__item--active {
160
+ color: var(--accent-color);
161
+ font-weight: 500;
162
+ }
163
+ .velu-sidebar__item--active .velu-sidebar__icon {
164
+ color: var(--accent-color);
165
+ }
166
+
167
+ /* The label fills the row so the group chevron (and any external-link icon)
168
+ sit flush at the row's RIGHT end, not crowded against the label — faithful
169
+ to the design's `flex: 1` label. */
170
+ .velu-sidebar__label {
171
+ flex: 1;
172
+ min-inline-size: 0;
173
+ }
174
+
175
+ .velu-sidebar__summary {
176
+ cursor: pointer;
177
+ list-style: none;
178
+ }
179
+ .velu-sidebar__summary::-webkit-details-marker {
180
+ display: none;
181
+ }
182
+
183
+ /* Icon sizing centralized here; stroke weight is the global --icon-stroke
184
+ token (.lucide rule in base.css), not set per-component. */
185
+ .velu-sidebar__icon {
186
+ display: inline-flex;
187
+ flex: none;
188
+ inline-size: var(--f-body);
189
+ block-size: var(--f-body);
190
+ }
191
+ .velu-sidebar__icon svg {
192
+ inline-size: 100%;
193
+ block-size: 100%;
194
+ }
195
+
196
+ .velu-sidebar__chevron {
197
+ flex: none;
198
+ inline-size: var(--f-body);
199
+ block-size: var(--f-body);
200
+ transition: transform 0.15s ease;
201
+ }
202
+
203
+ details[open] > .velu-sidebar__summary .velu-sidebar__chevron {
204
+ transform: rotate(90deg);
205
+ }
@@ -1,77 +1,77 @@
1
- /* Steps — numbered procedural list with a continuous accent rail
2
- running through every step's left margin. All values are tokens;
3
- light/dark via [data-theme]. */
4
-
5
- .velu-steps {
6
- display: block;
7
- }
8
-
9
- /* Each step is a 2-col / 2-row grid placed explicitly:
10
-
11
- col 1 col 2
12
- ┌──────────────────┬────────────────────┐
13
- │ circle (row 1, │ title (row 1, │
14
- │ align-self: end) │ align-self: end) │
15
- ├──────────────────┼────────────────────┤
16
- │ line (row 2, │ body (row 2) │
17
- │ 100% block-size) │ │
18
- └──────────────────┴────────────────────┘
19
-
20
- `align-self: end` on both row-1 items puts the circle's bottom and
21
- the title's bottom flush together — so an oversize circle no longer
22
- hovers above the title. Row 1 height is whichever child is taller
23
- (the circle). row-gap stays at 0 so the line touches the next step's
24
- circle with no visible break in the rail. */
25
- .velu-step {
26
- display: grid;
27
- grid-template-columns: var(--step-circle, 2em) 1fr;
28
- column-gap: var(--s0);
29
- row-gap: 0;
30
- }
31
-
32
- .velu-step__circle {
33
- grid-row: 1;
34
- grid-column: 1;
35
- align-self: center;
36
- justify-self: center;
37
- inline-size: var(--step-circle, 2em);
38
- block-size: var(--step-circle, 2em);
39
- border-radius: 50%;
40
- background: var(--accent-color);
41
- color: var(--page-bg);
42
- display: inline-flex;
43
- align-items: center;
44
- justify-content: center;
45
- font-size: var(--f-h6);
46
- line-height: 1;
47
- font-weight: var(--weight-medium);
48
- }
49
-
50
- .velu-step__line {
51
- grid-row: 2;
52
- grid-column: 1;
53
- justify-self: center;
54
- inline-size: 2px;
55
- block-size: 100%;
56
- min-block-size: var(--s2);
57
- background: var(--accent-color);
58
- }
59
-
60
- .velu-step__title {
61
- grid-row: 1;
62
- grid-column: 2;
63
- align-self: center;
64
- font-size: var(--f-h4);
65
- line-height: var(--lh-h4);
66
- font-weight: var(--weight-medium);
67
- color: var(--text-color);
68
- }
69
-
70
- .velu-step__body {
71
- grid-row: 2;
72
- grid-column: 2;
73
- padding-block: var(--s-1) var(--s2);
74
- color: var(--text-color);
75
- font-size: var(--f-body);
76
- line-height: var(--lh-body);
77
- }
1
+ /* Steps — numbered procedural list with a continuous accent rail
2
+ running through every step's left margin. All values are tokens;
3
+ light/dark via [data-theme]. */
4
+
5
+ .velu-steps {
6
+ display: block;
7
+ }
8
+
9
+ /* Each step is a 2-col / 2-row grid placed explicitly:
10
+
11
+ col 1 col 2
12
+ ┌──────────────────┬────────────────────┐
13
+ │ circle (row 1, │ title (row 1, │
14
+ │ align-self: end) │ align-self: end) │
15
+ ├──────────────────┼────────────────────┤
16
+ │ line (row 2, │ body (row 2) │
17
+ │ 100% block-size) │ │
18
+ └──────────────────┴────────────────────┘
19
+
20
+ `align-self: end` on both row-1 items puts the circle's bottom and
21
+ the title's bottom flush together — so an oversize circle no longer
22
+ hovers above the title. Row 1 height is whichever child is taller
23
+ (the circle). row-gap stays at 0 so the line touches the next step's
24
+ circle with no visible break in the rail. */
25
+ .velu-step {
26
+ display: grid;
27
+ grid-template-columns: var(--step-circle, 2em) 1fr;
28
+ column-gap: var(--s0);
29
+ row-gap: 0;
30
+ }
31
+
32
+ .velu-step__circle {
33
+ grid-row: 1;
34
+ grid-column: 1;
35
+ align-self: center;
36
+ justify-self: center;
37
+ inline-size: var(--step-circle, 2em);
38
+ block-size: var(--step-circle, 2em);
39
+ border-radius: 50%;
40
+ background: var(--accent-color);
41
+ color: var(--page-bg);
42
+ display: inline-flex;
43
+ align-items: center;
44
+ justify-content: center;
45
+ font-size: var(--f-h6);
46
+ line-height: 1;
47
+ font-weight: var(--weight-medium);
48
+ }
49
+
50
+ .velu-step__line {
51
+ grid-row: 2;
52
+ grid-column: 1;
53
+ justify-self: center;
54
+ inline-size: 2px;
55
+ block-size: 100%;
56
+ min-block-size: var(--s2);
57
+ background: var(--accent-color);
58
+ }
59
+
60
+ .velu-step__title {
61
+ grid-row: 1;
62
+ grid-column: 2;
63
+ align-self: center;
64
+ font-size: var(--f-h4);
65
+ line-height: var(--lh-h4);
66
+ font-weight: var(--weight-medium);
67
+ color: var(--text-color);
68
+ }
69
+
70
+ .velu-step__body {
71
+ grid-row: 2;
72
+ grid-column: 2;
73
+ padding-block: var(--s-1) var(--s2);
74
+ color: var(--text-color);
75
+ font-size: var(--f-body);
76
+ line-height: var(--lh-body);
77
+ }