@24vlh/vds 0.1.0 → 0.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.
@@ -1,498 +1 @@
1
- /************************************************************
2
- * VLAH DESIGN SYSTEM (VDS) - Hero Component
3
- *
4
- * Responsibilities:
5
- * - Provide the complete hero system: title, description, points,
6
- * metrics, accent lines, call-to-action groups, and optional media
7
- * - Support density variants (A / B / C / compact / minimal)
8
- * and layout variants (split, with-media, inset, full-bleed)
9
- * - Expose loading, error, and skeleton states with fully tokenised
10
- * animation and surface interactions
11
- * - Maintain strict composability: works inside marketing pages,
12
- * documentation pages, product pages, and landing layouts
13
- *
14
- * System Notes:
15
- * - Fully token-driven: spacing, typography, surfaces, shadows, radii
16
- * - Pure CSS; media behaviour and async loading are external
17
- * - Responsive from first principles: text scaling, grid collapse,
18
- * metric condensation, and surface switching
19
- ************************************************************/
20
-
21
- /*---------------------------------------------------------
22
- 1. HERO TOKEN DEFINITIONS
23
- ---------------------------------------------------------*/
24
-
25
- [data-vds-hero],
26
- .vds-hero {
27
- --hero-skeleton-speed: 1.2s;
28
- --hero-eyebrow-letter-spacing: var(--letter-loose);
29
-
30
- --hero-text-max-default: 60ch;
31
- --hero-text-max-a: 70ch;
32
- --hero-text-max-c: 55ch;
33
- --hero-text-max-compact: 50ch;
34
-
35
- --hero-media-aspect-ratio: 16/9;
36
- --hero-media-max-width: 32rem;
37
-
38
- --hero-metric-min-width: 11rem;
39
-
40
- --hero-accent-line-thickness: 3px;
41
-
42
- --hero-full-overlay: linear-gradient(to bottom, rgba(0,0,0,0.4), rgba(0,0,0,0.0));
43
- }
44
-
45
- /* ---------------------------------------------------------
46
- 2. GLOBAL HERO CONTAINER
47
- --------------------------------------------------------- */
48
-
49
- .hero {
50
- width: 100%;
51
- background-color: var(--color-surface);
52
- color: var(--color-text);
53
- padding-top: var(--space-12);
54
- padding-bottom: var(--space-16);
55
- }
56
-
57
- .hero__inner {
58
- max-width: var(--content-width-xl);
59
- margin-left: auto;
60
- margin-right: auto;
61
- display: flex;
62
- flex-direction: column;
63
- gap: var(--space-8);
64
- }
65
-
66
- .hero__eyebrow {
67
- font-size: var(--text-xs);
68
- font-weight: var(--font-weight-semibold);
69
- text-transform: uppercase;
70
- letter-spacing: var(--hero-eyebrow-letter-spacing);
71
- color: var(--color-text-muted);
72
- }
73
-
74
- .hero__title {
75
- font-size: var(--text-4xl);
76
- font-weight: var(--font-weight-bold);
77
- max-width: var(--hero-text-max-default);
78
- line-height: 1.15;
79
- }
80
-
81
- .hero__desc {
82
- font-size: var(--text-md);
83
- line-height: var(--line-height-normal);
84
- color: var(--color-text-muted);
85
- max-width: var(--hero-text-max-default);
86
- }
87
-
88
- .hero__actions {
89
- display: flex;
90
- gap: var(--space-4);
91
- flex-wrap: wrap;
92
- margin-top: var(--space-6);
93
- }
94
-
95
- .hero__text-pill {
96
- background: var(--color-surface-translucent-strong);
97
- color: var(--color-text-on-strong);
98
- border-radius: var(--radius-sm);
99
- display: inline-block;
100
- }
101
-
102
- /*---------------------------------------------------------
103
- 3. DENSITY VARIANTS (MUTUALLY EXCLUSIVE)
104
- ---------------------------------------------------------*/
105
-
106
- .hero--a .hero {
107
- padding-top: var(--space-20);
108
- padding-bottom: var(--space-24);
109
- }
110
-
111
- .hero--a .hero__title {
112
- font-size: var(--text-5xl);
113
- max-width: var(--hero-text-max-a);
114
- }
115
-
116
- .hero--a .hero__desc {
117
- font-size: var(--text-lg);
118
- }
119
-
120
- .hero--b .hero {
121
- padding-top: var(--space-16);
122
- padding-bottom: var(--space-20);
123
- }
124
-
125
- .hero--b .hero__title {
126
- font-size: var(--text-4xl);
127
- }
128
-
129
- .hero--b .hero__desc {
130
- font-size: var(--text-md);
131
- }
132
-
133
- .hero--c .hero {
134
- padding-top: var(--space-12);
135
- padding-bottom: var(--space-16);
136
- }
137
-
138
- .hero--c .hero__title {
139
- font-size: var(--text-3xl);
140
- max-width: var(--hero-text-max-c);
141
- }
142
-
143
- .hero--c .hero__desc {
144
- font-size: var(--text-sm);
145
- }
146
-
147
- .hero--compact .hero {
148
- padding-top: var(--space-10);
149
- padding-bottom: var(--space-12);
150
- }
151
-
152
- .hero--compact .hero__title {
153
- font-size: var(--text-2xl);
154
- max-width: var(--hero-text-max-compact);
155
- }
156
-
157
- .hero--compact .hero__desc {
158
- font-size: var(--text-sm);
159
- }
160
-
161
- .hero--minimal .hero {
162
- padding-top: var(--space-8);
163
- padding-bottom: var(--space-10);
164
- }
165
-
166
- .hero--minimal .hero__title {
167
- font-size: var(--text-xl);
168
- }
169
-
170
- .hero--minimal .hero__desc {
171
- display: none;
172
- }
173
-
174
- /*---------------------------------------------------------
175
- 4. LAYOUT VARIANTS (MUTUALLY EXCLUSIVE)
176
- ---------------------------------------------------------*/
177
-
178
- .hero--split .hero__inner {
179
- display: grid;
180
- grid-template-columns: 1fr 1fr;
181
- grid-gap: var(--space-12);
182
- gap: var(--space-12);
183
- }
184
-
185
- .hero--with-media .hero__inner {
186
- display: grid;
187
- grid-template-columns: 1fr var(--hero-media-max-width);
188
- grid-gap: var(--space-12);
189
- gap: var(--space-12);
190
- }
191
-
192
- .hero__media {
193
- display: flex;
194
- justify-content: center;
195
- align-items: center;
196
- }
197
-
198
- .hero__media-inner {
199
- width: 100%;
200
- max-width: 100%;
201
- border-radius: var(--radius-lg);
202
- overflow: hidden;
203
- display: flex;
204
- align-items: stretch;
205
- justify-content: center;
206
- background-color: var(--color-surface-subtle);
207
- }
208
-
209
- .hero__media-inner > * {
210
- width: 100%;
211
- height: 100%;
212
- }
213
-
214
- .hero__media img,
215
- .hero__media picture {
216
- width: 100%;
217
- aspect-ratio: var(--hero-media-aspect-ratio);
218
- -o-object-fit: cover;
219
- object-fit: cover;
220
- border-radius: var(--radius-lg);
221
- }
222
-
223
- /*---------------------------------------------------------*
224
- 5. FULL-BLEED VARIANT
225
- *---------------------------------------------------------*/
226
-
227
- .hero--full {
228
- position: relative;
229
- background-color: var(--color-bg-elevated);
230
- color: var(--color-text-on-strong);
231
- padding-top: var(--space-24);
232
- padding-bottom: var(--space-32);
233
- }
234
-
235
- .hero--full::before {
236
- content: "";
237
- position: absolute;
238
- top: 0;
239
- right: 0;
240
- bottom: 0;
241
- left: 0;
242
- background: var(--hero-full-overlay, var(--color-surface-translucent-strong));
243
- z-index: 0;
244
- }
245
-
246
- .hero--full .hero__inner {
247
- position: relative;
248
- z-index: 1;
249
- }
250
-
251
- .hero--full,
252
- .hero--full .hero__body,
253
- .hero--full .hero__eyebrow,
254
- .hero--full .hero__subtitle,
255
- .hero--full .hero__actions,
256
- .hero--full .hero__actions *,
257
- .hero--full .hero__metrics *,
258
- .hero--full .hero__points *,
259
- .hero--full .hero__desc {
260
- color: var(--color-text-on-strong);
261
- }
262
-
263
- .hero--full .hero__title,
264
- .hero--full .hero__subtitle,
265
- .hero--full .hero__eyebrow,
266
- .hero--full .hero__desc {
267
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
268
- }
269
-
270
- /*---------------------------------------------------------*
271
- 6. INSET VARIANT
272
- *---------------------------------------------------------*/
273
-
274
- .hero--inset {
275
- background: var(--color-bg);
276
- padding: var(--space-8);
277
- }
278
-
279
- .hero--inset .hero {
280
- background-color: var(--color-surface);
281
- border-radius: var(--radius-lg);
282
- box-shadow: var(--shadow-1);
283
- padding-top: var(--space-12);
284
- padding-bottom: var(--space-16);
285
- }
286
-
287
- /*---------------------------------------------------------*
288
- 7. ACCENT LINE (TOKENIZED)
289
- *---------------------------------------------------------*/
290
-
291
- .hero__accent-line {
292
- width: var(--hero-accent-line-thickness);
293
- height: var(--space-20);
294
- background-color: var(--hero-accent-line, var(--color-accent));
295
- border-radius: var(--radius-pill);
296
- }
297
-
298
- /*---------------------------------------------------------*
299
- 8. METRICS BLOCK
300
- *---------------------------------------------------------*/
301
-
302
- .hero__metrics {
303
- display: grid;
304
- grid-gap: var(--space-6);
305
- gap: var(--space-6);
306
- grid-template-columns: repeat(auto-fit, minmax(var(--hero-metric-min-width), 1fr));
307
- margin-top: var(--space-8);
308
- }
309
-
310
- .hero__metric {
311
- background-color: var(--hero-metric-bg);
312
- padding: var(--space-4);
313
- border-radius: var(--radius-md);
314
- display: flex;
315
- flex-direction: column;
316
- gap: var(--space-2);
317
- }
318
-
319
- .hero__metric-value {
320
- font-size: var(--text-xl);
321
- font-weight: var(--font-weight-bold);
322
- }
323
-
324
- .hero__metric-label {
325
- font-size: var(--text-sm);
326
- color: var(--color-text-muted);
327
- }
328
-
329
- .hero__metric-trend {
330
- font-size: var(--text-xs);
331
- font-weight: var(--font-weight-semibold);
332
- }
333
-
334
- .hero__metric-trend--up {
335
- color: var(--hero-trend-up, var(--color-success-strong));
336
- }
337
-
338
- .hero__metric-trend--down {
339
- color: var(--hero-trend-down, var(--color-danger-strong));
340
- }
341
-
342
- .hero__metric-trend--neutral {
343
- color: var(--hero-trend-neutral, var(--color-text-muted));
344
- }
345
-
346
- .hero__metric--muted {
347
- background-color: var(--color-muted-bg);
348
- border-left: var(--border-width) solid var(--color-border-subtle);
349
- }
350
-
351
- .hero__metric--error {
352
- background-color: var(--hero-error-bg, var(--color-danger-soft));
353
- border-left: var(--border-width-strong) solid var(--hero-error-border, var(--color-danger-strong));
354
- }
355
-
356
- /*---------------------------------------------------------*
357
- 8B. HERO POINTS (SUPPORTING BULLETS)
358
- *---------------------------------------------------------*/
359
-
360
- .hero__points {
361
- display: flex;
362
- flex-wrap: wrap;
363
- gap: var(--space-4);
364
- margin-top: var(--space-6);
365
- }
366
-
367
- .hero__point {
368
- display: flex;
369
- align-items: flex-start;
370
- gap: var(--space-2);
371
- font-size: var(--text-sm);
372
- color: var(--color-text-muted);
373
- max-width: var(--hero-text-max-default);
374
- }
375
-
376
- .hero__point-icon {
377
- width: var(--icon-sm);
378
- height: var(--icon-sm);
379
- flex-shrink: 0;
380
- margin-top: 0.125rem;
381
- color: var(--color-accent);
382
- }
383
-
384
- /*---------------------------------------------------------*
385
- 9. LOADING STATE (TOKENIZED ANIMATION)
386
- *---------------------------------------------------------*/
387
-
388
- .hero--loading .hero__body {
389
- visibility: hidden;
390
- }
391
-
392
- .hero--loading .hero__skeleton {
393
- display: block;
394
- }
395
-
396
- .hero__skeleton {
397
- width: 100%;
398
- display: none;
399
- height: var(--space-40);
400
- border-radius: var(--radius-md);
401
- background: linear-gradient(
402
- 90deg,
403
- var(--color-surface-subtle) 0%,
404
- var(--color-surface-soft) 50%,
405
- var(--color-surface-subtle) 100%
406
- );
407
- background-size: 200% 100%;
408
- animation: hero-skeleton-shimmer var(--hero-skeleton-speed) linear infinite;
409
- }
410
-
411
- .hero__skeleton-line {
412
- width: 100%;
413
- height: var(--space-3);
414
- border-radius: var(--radius-sm);
415
- background: linear-gradient(
416
- 90deg,
417
- var(--color-surface-subtle) 0%,
418
- var(--color-surface-soft) 50%,
419
- var(--color-surface-subtle) 100%
420
- );
421
- background-size: 200% 100%;
422
- animation: hero-skeleton-shimmer var(--hero-skeleton-speed) linear infinite;
423
- margin-top: var(--space-1);
424
- margin-bottom: var(--space-1);
425
- }
426
-
427
- @keyframes hero-skeleton-shimmer {
428
- 0% {
429
- background-position: 200% 0;
430
- }
431
- 100% {
432
- background-position: -200% 0;
433
- }
434
- }
435
-
436
- /*---------------------------------------------------------*
437
- 10. ERROR STATE
438
- *---------------------------------------------------------*/
439
-
440
- .hero--error .hero__body {
441
- opacity: 0.4;
442
- }
443
-
444
- .hero--error .hero__error {
445
- display: flex;
446
- gap: var(--space-2);
447
- align-items: center;
448
- padding: var(--space-4);
449
- background-color: var(--hero-error-banner-bg, var(--color-danger-soft));
450
- border-left: var(--border-width-strong) solid var(--hero-error-banner-border, var(--color-danger));
451
- border-radius: var(--radius-md);
452
- }
453
-
454
- .hero__error-title {
455
- font-size: var(--text-sm);
456
- font-weight: var(--font-weight-semibold);
457
- margin: 0;
458
- color: var(--hero-error-title, var(--color-danger-strong));
459
- }
460
-
461
- .hero__error-actions {
462
- margin-left: auto;
463
- display: inline-flex;
464
- gap: var(--space-2);
465
- flex-wrap: wrap;
466
- }
467
-
468
- /*---------------------------------------------------------*
469
- 11. RESPONSIVE
470
- *---------------------------------------------------------*/
471
-
472
- @media (max-width: 1024px) {
473
- .hero--split .hero__inner,
474
- .hero--with-media .hero__inner {
475
- grid-template-columns: 1fr;
476
- }
477
- }
478
-
479
- @media (max-width: 768px) {
480
- .hero {
481
- padding-top: var(--space-10);
482
- padding-bottom: var(--space-14);
483
- }
484
-
485
- .hero__title {
486
- font-size: var(--text-3xl);
487
- }
488
- }
489
-
490
- @media (max-width: 640px) {
491
- .hero__title {
492
- font-size: var(--text-2xl);
493
- }
494
-
495
- .hero__metrics {
496
- grid-template-columns: repeat(auto-fit, minmax(calc(var(--hero-metric-min-width) * 0.8), 1fr));
497
- }
498
- }
1
+ .vds-hero,[data-vds-hero]{--hero-skeleton-speed:1.2s;--hero-eyebrow-letter-spacing:var(--letter-loose);--hero-text-max-default:60ch;--hero-text-max-a:70ch;--hero-text-max-c:55ch;--hero-text-max-compact:50ch;--hero-media-aspect-ratio:16/9;--hero-media-max-width:32rem;--hero-metric-min-width:11rem;--hero-accent-line-thickness:3px;--hero-full-overlay:linear-gradient(180deg,rgba(0,0,0,.4),transparent)}.hero{background-color:var(--color-surface);color:var(--color-text);padding-bottom:var(--space-16);padding-top:var(--space-12);width:100%}.hero__inner{display:flex;flex-direction:column;gap:var(--space-8);margin-left:auto;margin-right:auto;max-width:var(--content-width-xl)}.hero__eyebrow{color:var(--color-text-muted);font-size:var(--text-xs);font-weight:var(--font-weight-semibold);letter-spacing:var(--hero-eyebrow-letter-spacing);text-transform:uppercase}.hero__title{font-size:var(--text-4xl);font-weight:var(--font-weight-bold);line-height:1.15}.hero__desc,.hero__title{max-width:var(--hero-text-max-default)}.hero__desc{color:var(--color-text-muted);font-size:var(--text-md);line-height:var(--line-height-normal)}.hero__actions{display:flex;flex-wrap:wrap;gap:var(--space-4);margin-top:var(--space-6)}.hero__text-pill{background:var(--color-surface-translucent-strong);border-radius:var(--radius-sm);color:var(--color-text-on-strong);display:inline-block}.hero--a .hero{padding-bottom:var(--space-24);padding-top:var(--space-20)}.hero--a .hero__title{font-size:var(--text-5xl);max-width:var(--hero-text-max-a)}.hero--a .hero__desc{font-size:var(--text-lg)}.hero--b .hero{padding-bottom:var(--space-20);padding-top:var(--space-16)}.hero--b .hero__title{font-size:var(--text-4xl)}.hero--b .hero__desc{font-size:var(--text-md)}.hero--c .hero{padding-bottom:var(--space-16);padding-top:var(--space-12)}.hero--c .hero__title{font-size:var(--text-3xl);max-width:var(--hero-text-max-c)}.hero--c .hero__desc{font-size:var(--text-sm)}.hero--compact .hero{padding-bottom:var(--space-12);padding-top:var(--space-10)}.hero--compact .hero__title{font-size:var(--text-2xl);max-width:var(--hero-text-max-compact)}.hero--compact .hero__desc{font-size:var(--text-sm)}.hero--minimal .hero{padding-bottom:var(--space-10);padding-top:var(--space-8)}.hero--minimal .hero__title{font-size:var(--text-xl)}.hero--minimal .hero__desc{display:none}.hero--split .hero__inner{grid-gap:var(--space-12);display:grid;gap:var(--space-12);grid-template-columns:1fr 1fr}.hero--with-media .hero__inner{grid-gap:var(--space-12);display:grid;gap:var(--space-12);grid-template-columns:1fr var(--hero-media-max-width)}.hero__media{align-items:center}.hero__media,.hero__media-inner{display:flex;justify-content:center}.hero__media-inner{align-items:stretch;background-color:var(--color-surface-subtle);border-radius:var(--radius-lg);max-width:100%;overflow:hidden;width:100%}.hero__media-inner>*{height:100%;width:100%}.hero__media img,.hero__media picture{aspect-ratio:var(--hero-media-aspect-ratio);border-radius:var(--radius-lg);-o-object-fit:cover;object-fit:cover;width:100%}.hero--full{background-color:var(--color-bg-elevated);color:var(--color-text-on-strong);padding-bottom:var(--space-32);padding-top:var(--space-24);position:relative}.hero--full:before{background:var(--hero-full-overlay,var(--color-surface-translucent-strong));bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:0}.hero--full .hero__inner{position:relative;z-index:1}.hero--full,.hero--full .hero__actions,.hero--full .hero__actions *,.hero--full .hero__body,.hero--full .hero__desc,.hero--full .hero__eyebrow,.hero--full .hero__metrics *,.hero--full .hero__points *,.hero--full .hero__subtitle{color:var(--color-text-on-strong)}.hero--full .hero__desc,.hero--full .hero__eyebrow,.hero--full .hero__subtitle,.hero--full .hero__title{text-shadow:0 1px 2px rgba(0,0,0,.45)}.hero--inset{background:var(--color-bg);padding:var(--space-8)}.hero--inset .hero{background-color:var(--color-surface);border-radius:var(--radius-lg);box-shadow:var(--shadow-1);padding-bottom:var(--space-16);padding-top:var(--space-12)}.hero__accent-line{background-color:var(--hero-accent-line,var(--color-accent));border-radius:var(--radius-pill);height:var(--space-20);width:var(--hero-accent-line-thickness)}.hero__metrics{grid-gap:var(--space-6);display:grid;gap:var(--space-6);grid-template-columns:repeat(auto-fit,minmax(var(--hero-metric-min-width),1fr));margin-top:var(--space-8)}.hero__metric{background-color:var(--hero-metric-bg);border-radius:var(--radius-md);display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-4)}.hero__metric-value{font-size:var(--text-xl);font-weight:var(--font-weight-bold)}.hero__metric-label{color:var(--color-text-muted);font-size:var(--text-sm)}.hero__metric-trend{font-size:var(--text-xs);font-weight:var(--font-weight-semibold)}.hero__metric-trend--up{color:var(--hero-trend-up,var(--color-success-strong))}.hero__metric-trend--down{color:var(--hero-trend-down,var(--color-danger-strong))}.hero__metric-trend--neutral{color:var(--hero-trend-neutral,var(--color-text-muted))}.hero__metric--muted{background-color:var(--color-muted-bg);border-left:var(--border-width) solid var(--color-border-subtle)}.hero__metric--error{background-color:var(--hero-error-bg,var(--color-danger-soft));border-left:var(--border-width-strong) solid var(--hero-error-border,var(--color-danger-strong))}.hero__points{display:flex;flex-wrap:wrap;gap:var(--space-4);margin-top:var(--space-6)}.hero__point{align-items:flex-start;color:var(--color-text-muted);display:flex;font-size:var(--text-sm);gap:var(--space-2);max-width:var(--hero-text-max-default)}.hero__point-icon{color:var(--color-accent);flex-shrink:0;height:var(--icon-sm);margin-top:.125rem;width:var(--icon-sm)}.hero--loading .hero__body{visibility:hidden}.hero--loading .hero__skeleton{display:block}.hero__skeleton{border-radius:var(--radius-md);display:none;height:var(--space-40)}.hero__skeleton,.hero__skeleton-line{animation:hero-skeleton-shimmer var(--hero-skeleton-speed) linear infinite;background:linear-gradient(90deg,var(--color-surface-subtle) 0,var(--color-surface-soft) 50%,var(--color-surface-subtle) 100%);background-size:200% 100%;width:100%}.hero__skeleton-line{border-radius:var(--radius-sm);height:var(--space-3);margin-bottom:var(--space-1);margin-top:var(--space-1)}@keyframes hero-skeleton-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.hero--error .hero__body{opacity:.4}.hero--error .hero__error{align-items:center;background-color:var(--hero-error-banner-bg,var(--color-danger-soft));border-left:var(--border-width-strong) solid var(--hero-error-banner-border,var(--color-danger));border-radius:var(--radius-md);display:flex;gap:var(--space-2);padding:var(--space-4)}.hero__error-title{color:var(--hero-error-title,var(--color-danger-strong));font-size:var(--text-sm);font-weight:var(--font-weight-semibold);margin:0}.hero__error-actions{display:inline-flex;flex-wrap:wrap;gap:var(--space-2);margin-left:auto}@media (max-width:1024px){.hero--split .hero__inner,.hero--with-media .hero__inner{grid-template-columns:1fr}}@media (max-width:768px){.hero{padding-bottom:var(--space-14);padding-top:var(--space-10)}.hero__title{font-size:var(--text-3xl)}}@media (max-width:640px){.hero__title{font-size:var(--text-2xl)}.hero__metrics{grid-template-columns:repeat(auto-fit,minmax(calc(var(--hero-metric-min-width)*.8),1fr))}}