@digiko-npm/designsystem 0.8.2 → 0.9.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digiko-npm/designsystem",
3
- "version": "0.8.2",
3
+ "version": "0.9.0",
4
4
  "description": "Design system — installable, extensible, indestructible.",
5
5
  "main": "dist/designsystem.css",
6
6
  "style": "dist/designsystem.css",
@@ -35,6 +35,7 @@
35
35
  "./components/empty-state": "./src/components/empty-state.css",
36
36
  "./components/field": "./src/components/field.css",
37
37
  "./components/gallery": "./src/components/gallery.css",
38
+ "./components/hero": "./src/components/hero.css",
38
39
  "./components/icon-btn": "./src/components/icon-btn.css",
39
40
  "./components/input": "./src/components/input.css",
40
41
  "./components/kbd": "./src/components/kbd.css",
@@ -45,6 +46,7 @@
45
46
  "./components/pin-input": "./src/components/pin-input.css",
46
47
  "./components/popover": "./src/components/popover.css",
47
48
  "./components/progress": "./src/components/progress.css",
49
+ "./components/prose": "./src/components/prose.css",
48
50
  "./components/result": "./src/components/result.css",
49
51
  "./components/scroll-area": "./src/components/scroll-area.css",
50
52
  "./components/search": "./src/components/search.css",
@@ -81,7 +81,7 @@
81
81
  }
82
82
 
83
83
  /* Stand-alone input (no input-area wrapper) */
84
- input.ds-combobox__input {
84
+ .ds-combobox > .ds-combobox__input {
85
85
  width: 100%;
86
86
  min-height: var(--ds-size-3);
87
87
  padding: 0 var(--ds-space-3);
@@ -93,11 +93,11 @@ input.ds-combobox__input {
93
93
  box-shadow var(--ds-duration-fast) var(--ds-ease-default);
94
94
  }
95
95
 
96
- input.ds-combobox__input:hover {
96
+ .ds-combobox > .ds-combobox__input:hover {
97
97
  border-color: var(--ds-color-border-hover);
98
98
  }
99
99
 
100
- input.ds-combobox__input:focus {
100
+ .ds-combobox > .ds-combobox__input:focus {
101
101
  border-color: var(--ds-color-border-active);
102
102
  outline: none;
103
103
  box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
@@ -355,39 +355,36 @@ input.ds-combobox__input:focus {
355
355
 
356
356
  /* XS */
357
357
  .ds-combobox--xs .ds-combobox__input-area,
358
- .ds-combobox--xs input.ds-combobox__input {
358
+ .ds-combobox--xs > .ds-combobox__input {
359
359
  min-height: var(--ds-size-1);
360
360
  padding: 0 var(--ds-space-2);
361
361
  border-radius: var(--ds-radius-md);
362
362
  }
363
363
 
364
- .ds-combobox--xs .ds-combobox__input,
365
- .ds-combobox--xs input.ds-combobox__input {
364
+ .ds-combobox--xs .ds-combobox__input {
366
365
  font-size: var(--ds-text-xs);
367
366
  }
368
367
 
369
368
  /* SM */
370
369
  .ds-combobox--sm .ds-combobox__input-area,
371
- .ds-combobox--sm input.ds-combobox__input {
370
+ .ds-combobox--sm > .ds-combobox__input {
372
371
  min-height: var(--ds-size-2);
373
372
  padding: 0 var(--ds-space-2-5);
374
373
  border-radius: var(--ds-radius-md);
375
374
  }
376
375
 
377
- .ds-combobox--sm .ds-combobox__input,
378
- .ds-combobox--sm input.ds-combobox__input {
376
+ .ds-combobox--sm .ds-combobox__input {
379
377
  font-size: var(--ds-text-sm);
380
378
  }
381
379
 
382
380
  /* LG */
383
381
  .ds-combobox--lg .ds-combobox__input-area,
384
- .ds-combobox--lg input.ds-combobox__input {
382
+ .ds-combobox--lg > .ds-combobox__input {
385
383
  min-height: var(--ds-size-4);
386
384
  padding: 0 var(--ds-space-4);
387
385
  }
388
386
 
389
- .ds-combobox--lg .ds-combobox__input,
390
- .ds-combobox--lg input.ds-combobox__input {
387
+ .ds-combobox--lg .ds-combobox__input {
391
388
  font-size: var(--ds-text-lg);
392
389
  }
393
390
 
@@ -396,12 +393,12 @@ input.ds-combobox__input:focus {
396
393
  ========================================================================== */
397
394
 
398
395
  .ds-combobox--error .ds-combobox__input-area,
399
- .ds-combobox--error input.ds-combobox__input {
396
+ .ds-combobox--error > .ds-combobox__input {
400
397
  border-color: var(--ds-color-error);
401
398
  }
402
399
 
403
400
  .ds-combobox--error .ds-combobox__input-area:focus-within,
404
- .ds-combobox--error input.ds-combobox__input:focus {
401
+ .ds-combobox--error > .ds-combobox__input:focus {
405
402
  box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-color-error);
406
403
  }
407
404
 
@@ -0,0 +1,113 @@
1
+ /* ==========================================================================
2
+ Component: Hero
3
+ Full-width hero section with background image, gradient overlay,
4
+ and optional frosted glass backdrop.
5
+
6
+ Intentionally uses theme-independent colors for text on photo backgrounds.
7
+ The overlay uses color-mix() with --ds-color-bg for theme-aware darkening
8
+ while title/subtitle stay white for readability on any photo.
9
+
10
+ Usage:
11
+ <section class="ds-hero" style="background-image: url(...)">
12
+ <div class="ds-hero__overlay"></div>
13
+ <div class="ds-hero__content ds-container">
14
+ <div class="ds-hero__backdrop">
15
+ <h1 class="ds-hero__title ds-hero-title">Heading</h1>
16
+ <p class="ds-hero__subtitle">Subheading</p>
17
+ </div>
18
+ </div>
19
+ </section>
20
+
21
+ Variants:
22
+ ds-hero--full Generous padding, auto height (no min-height)
23
+ ds-hero__overlay--subtle Lighter overlay, photo shows through more
24
+
25
+ ARIA: role="banner" or within <header>. Background images are decorative
26
+ — add meaningful content in the markup, not in CSS.
27
+ ========================================================================== */
28
+
29
+ .ds-hero {
30
+ position: relative;
31
+ min-height: 28rem;
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+ text-align: center;
36
+ background-size: cover;
37
+ background-position: center;
38
+ }
39
+
40
+ /* --- Full variant (generous padding, no min-height) --- */
41
+ .ds-hero--full {
42
+ min-height: auto;
43
+ padding-block: var(--ds-space-16);
44
+ }
45
+
46
+ @media (min-width: 768px) {
47
+ .ds-hero--full {
48
+ padding-block: var(--ds-space-20);
49
+ }
50
+ }
51
+
52
+ /* --- Gradient overlay (theme-aware darkening) --- */
53
+ .ds-hero__overlay {
54
+ position: absolute;
55
+ inset: 0;
56
+ background: linear-gradient(
57
+ to bottom,
58
+ color-mix(in srgb, var(--ds-color-bg) 70%, transparent),
59
+ color-mix(in srgb, var(--ds-color-bg) 92%, transparent)
60
+ );
61
+ }
62
+
63
+ .ds-hero__overlay--subtle {
64
+ background: linear-gradient(
65
+ to bottom,
66
+ color-mix(in srgb, var(--ds-color-bg) 20%, transparent),
67
+ color-mix(in srgb, var(--ds-color-bg) 40%, transparent)
68
+ );
69
+ }
70
+
71
+ [data-theme="dark"] .ds-hero__overlay {
72
+ background: linear-gradient(
73
+ to bottom,
74
+ color-mix(in srgb, var(--ds-color-bg) 80%, transparent),
75
+ color-mix(in srgb, var(--ds-color-bg) 95%, transparent)
76
+ );
77
+ }
78
+
79
+ [data-theme="dark"] .ds-hero__overlay--subtle {
80
+ background: linear-gradient(
81
+ to bottom,
82
+ color-mix(in srgb, var(--ds-color-bg) 30%, transparent),
83
+ color-mix(in srgb, var(--ds-color-bg) 50%, transparent)
84
+ );
85
+ }
86
+
87
+ /* --- Content wrapper (above overlay) --- */
88
+ .ds-hero__content {
89
+ position: relative;
90
+ z-index: 1;
91
+ width: 100%;
92
+ }
93
+
94
+ /* --- Frosted glass backdrop --- */
95
+ .ds-hero__backdrop {
96
+ display: block;
97
+ padding: var(--ds-space-8);
98
+ border-radius: var(--ds-radius-2xl);
99
+ background: rgba(0, 0, 0, 0.35);
100
+ backdrop-filter: blur(32px) saturate(1.6);
101
+ -webkit-backdrop-filter: blur(32px) saturate(1.6);
102
+ max-width: 40rem;
103
+ margin-inline: auto;
104
+ }
105
+
106
+ /* --- Title & subtitle (theme-independent white for photo readability) --- */
107
+ .ds-hero__title {
108
+ color: #fff;
109
+ }
110
+
111
+ .ds-hero__subtitle {
112
+ color: rgba(255, 255, 255, 0.85);
113
+ }
@@ -1,61 +1,71 @@
1
- /* === Core === */
2
- @import './button.css';
3
- @import './card.css';
4
- @import './stat-card.css';
1
+ /* === Form — Inputs, selectors, and form controls === */
5
2
  @import './input.css';
6
3
  @import './field.css';
7
- @import './badge.css';
8
- @import './nav.css';
9
- @import './modal.css';
10
- @import './toast.css';
11
- @import './table.css';
12
- @import './icon-btn.css';
4
+ @import './toggle.css';
5
+ @import './custom-select.css';
13
6
  @import './combobox.css';
7
+ @import './number-input.css';
8
+ @import './pin-input.css';
9
+ @import './datepicker.css';
10
+ @import './color-picker.css';
11
+ @import './slider.css';
12
+ @import './drop-zone.css';
13
+ @import './star-rating.css';
14
14
 
15
- /* === Tier 1Essential === */
16
- @import './tabs.css';
17
- @import './alert.css';
18
- @import './divider.css';
19
- @import './dropdown.css';
20
- @import './tooltip.css';
15
+ /* === Data DisplayPresent information and status === */
16
+ @import './badge.css';
17
+ @import './tag.css';
18
+ @import './chip.css';
21
19
  @import './avatar.css';
20
+ @import './stat-card.css';
21
+ @import './table.css';
22
+ @import './description-list.css';
23
+ @import './timeline.css';
24
+ @import './progress.css';
22
25
  @import './skeleton.css';
23
- @import './empty-state.css';
24
- @import './search.css';
25
- @import './spinner.css';
26
- @import './segmented-control.css';
26
+ @import './result.css';
27
+ @import './truncated-text.css';
27
28
 
28
- /* === Tier 2 Common === */
29
- @import './datepicker.css';
30
- @import './toggle.css';
29
+ /* === NavigationWayfinding and page structure === */
30
+ @import './nav.css';
31
31
  @import './breadcrumb.css';
32
+ @import './tabs.css';
32
33
  @import './pagination.css';
33
- @import './tag.css';
34
- @import './accordion.css';
34
+ @import './segmented-control.css';
35
+ @import './bottom-nav.css';
36
+ @import './toolbar.css';
37
+
38
+ /* === Feedback — Communicate status and system messages === */
39
+ @import './alert.css';
40
+ @import './toast.css';
41
+ @import './spinner.css';
42
+ @import './empty-state.css';
43
+ @import './tooltip.css';
44
+
45
+ /* === Overlay — Floating panels and dialogs === */
46
+ @import './modal.css';
35
47
  @import './drawer.css';
36
- @import './progress.css';
37
- @import './drop-zone.css';
38
- @import './custom-select.css';
48
+ @import './dropdown.css';
49
+ @import './popover.css';
50
+ @import './bottom-sheet.css';
51
+ @import './command.css';
52
+
53
+ /* === Layout — Structure and organize content === */
54
+ @import './card.css';
55
+ @import './divider.css';
56
+ @import './accordion.css';
39
57
  @import './collapsible.css';
40
- @import './description-list.css';
41
- @import './result.css';
42
- @import './sortable.css';
43
- @import './number-input.css';
44
- @import './pin-input.css';
45
- @import './copy-button.css';
46
58
  @import './scroll-area.css';
47
- @import './truncated-text.css';
48
- @import './color-picker.css';
49
- @import './star-rating.css';
50
59
  @import './gallery.css';
51
- @import './bottom-sheet.css';
60
+ @import './hero.css';
52
61
 
53
- /* === Tier 3 Advanced === */
54
- @import './popover.css';
55
- @import './slider.css';
56
- @import './timeline.css';
62
+ /* === ContentRich text and prose === */
63
+ @import './prose.css';
64
+
65
+ /* === Action — Trigger operations and commands === */
66
+ @import './button.css';
67
+ @import './icon-btn.css';
68
+ @import './copy-button.css';
57
69
  @import './kbd.css';
58
- @import './command.css';
59
- @import './toolbar.css';
60
- @import './chip.css';
61
- @import './bottom-nav.css';
70
+ @import './search.css';
71
+ @import './sortable.css';
@@ -0,0 +1,119 @@
1
+ /* ==========================================================================
2
+ Component: Prose Block
3
+ Full markdown-rendered content styling. Use for CMS output, blog posts,
4
+ documentation, or any container with user-generated rich text.
5
+
6
+ Note: The lighter `.ds-prose` in base/typography.css handles simple
7
+ inline rich text (p + p spacing, links, lists). This component is for
8
+ comprehensive markdown rendering with headings, code blocks, blockquotes,
9
+ images, and horizontal rules.
10
+
11
+ Usage:
12
+ <div class="ds-prose-block">
13
+ <h2>Title</h2>
14
+ <p>Paragraph with <a href="#">link</a> and <code>code</code>.</p>
15
+ <pre><code>code block</code></pre>
16
+ <blockquote>Quote</blockquote>
17
+ </div>
18
+ ========================================================================== */
19
+
20
+ .ds-prose-block {
21
+ line-height: var(--ds-leading-relaxed);
22
+ }
23
+
24
+ .ds-prose-block :is(h1, h2, h3, h4, h5, h6) {
25
+ font-family: var(--ds-font-display);
26
+ font-weight: var(--ds-font-display-weight);
27
+ letter-spacing: var(--ds-tracking-tight);
28
+ color: var(--ds-color-text);
29
+ margin-block-start: 1.5em;
30
+ margin-block-end: 0.5em;
31
+ }
32
+
33
+ .ds-prose-block :is(h1, h2, h3, h4, h5, h6):first-child {
34
+ margin-block-start: 0;
35
+ }
36
+
37
+ .ds-prose-block p {
38
+ color: var(--ds-color-text-secondary);
39
+ margin-block-end: 1em;
40
+ }
41
+
42
+ .ds-prose-block p:last-child {
43
+ margin-block-end: 0;
44
+ }
45
+
46
+ .ds-prose-block a {
47
+ color: var(--ds-color-interactive);
48
+ text-decoration: none;
49
+ }
50
+
51
+ .ds-prose-block a:hover {
52
+ text-decoration: underline;
53
+ }
54
+
55
+ .ds-prose-block strong {
56
+ color: var(--ds-color-text);
57
+ font-weight: var(--ds-weight-semibold);
58
+ }
59
+
60
+ .ds-prose-block code {
61
+ font-family: var(--ds-font-mono);
62
+ font-size: var(--ds-text-sm);
63
+ background-color: var(--ds-color-bg-elevated);
64
+ padding: 0.125em 0.375em;
65
+ border-radius: var(--ds-radius-sm);
66
+ }
67
+
68
+ .ds-prose-block pre {
69
+ background-color: var(--ds-color-bg-elevated);
70
+ padding: var(--ds-space-4);
71
+ border-radius: var(--ds-radius-lg);
72
+ overflow-x: auto;
73
+ margin-block-end: 1em;
74
+ }
75
+
76
+ .ds-prose-block pre code {
77
+ background: none;
78
+ padding: 0;
79
+ border-radius: 0;
80
+ }
81
+
82
+ .ds-prose-block ul,
83
+ .ds-prose-block ol {
84
+ padding-inline-start: 1.5em;
85
+ margin-block-end: 1em;
86
+ color: var(--ds-color-text-secondary);
87
+ }
88
+
89
+ .ds-prose-block li {
90
+ margin-block-end: 0.25em;
91
+ }
92
+
93
+ .ds-prose-block ul {
94
+ list-style-type: disc;
95
+ }
96
+
97
+ .ds-prose-block ol {
98
+ list-style-type: decimal;
99
+ }
100
+
101
+ .ds-prose-block blockquote {
102
+ border-inline-start: 3px solid var(--ds-color-border);
103
+ padding-inline-start: var(--ds-space-4);
104
+ color: var(--ds-color-text-secondary);
105
+ font-style: italic;
106
+ margin-block-end: 1em;
107
+ }
108
+
109
+ .ds-prose-block hr {
110
+ border: none;
111
+ border-block-start: 1px solid var(--ds-color-border);
112
+ margin-block: var(--ds-space-6);
113
+ }
114
+
115
+ .ds-prose-block img {
116
+ max-width: 100%;
117
+ border-radius: var(--ds-radius-lg);
118
+ margin-block-end: 1em;
119
+ }
@@ -4,6 +4,9 @@
4
4
  ========================================================================== */
5
5
 
6
6
  .ds-stat-card {
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: var(--ds-space-1);
7
10
  background-color: var(--ds-color-surface);
8
11
  border: 1px solid var(--ds-color-border);
9
12
  border-radius: var(--ds-radius-xl);
@@ -1,5 +1,7 @@
1
1
  @import './layout.css';
2
2
  @import './spacing.css';
3
+ @import './sizing.css';
3
4
  @import './text.css';
4
5
  @import './interactive.css';
6
+ @import './states.css';
5
7
  @import './a11y.css';
@@ -246,6 +246,27 @@
246
246
  .ds-xl\:grid-cols-6 { grid-template-columns: repeat(6, 1fr); }
247
247
  }
248
248
 
249
+ /* --- Responsive: Flex (extended) --- */
250
+ @media (min-width: 640px) {
251
+ .ds-sm\:flex-none { flex: none; }
252
+ .ds-sm\:items-center { align-items: center; }
253
+ .ds-sm\:justify-between { justify-content: space-between; }
254
+ .ds-sm\:gap-4 { gap: var(--ds-space-4); }
255
+ .ds-sm\:gap-8 { gap: var(--ds-space-8); }
256
+ .ds-sm\:inline { display: inline; }
257
+ }
258
+
259
+ @media (min-width: 768px) {
260
+ .ds-md\:grid-cols-5 { grid-template-columns: repeat(5, 1fr); }
261
+ }
262
+
263
+ @media (min-width: 1024px) /* --ds-breakpoint-lg */ {
264
+ .ds-lg\:flex-row { flex-direction: row; }
265
+ .ds-lg\:gap-4 { gap: var(--ds-space-4); }
266
+ .ds-lg\:gap-6 { gap: var(--ds-space-6); }
267
+ .ds-lg\:gap-8 { gap: var(--ds-space-8); }
268
+ }
269
+
249
270
  /* --- Aspect Ratio --- */
250
271
  .ds-aspect-square { aspect-ratio: 1; }
251
272
  .ds-aspect-video { aspect-ratio: 16/9; }
@@ -0,0 +1,71 @@
1
+ /* ==========================================================================
2
+ Utilities: Sizing
3
+ Width, height, min/max constraints.
4
+ Extends the base sizing in layout.css with the full spacing scale.
5
+ ========================================================================== */
6
+
7
+ /* --- Width (values not already in layout.css) --- */
8
+ .ds-w-0 { width: var(--ds-space-0); }
9
+ .ds-w-1 { width: var(--ds-space-1); }
10
+ .ds-w-1\.5 { width: var(--ds-space-1-5); }
11
+ .ds-w-2 { width: var(--ds-space-2); }
12
+ .ds-w-3\.5 { width: 0.875rem; }
13
+ .ds-w-6 { width: var(--ds-space-6); }
14
+ .ds-w-12 { width: var(--ds-space-12); }
15
+ .ds-w-16 { width: var(--ds-space-16); }
16
+ .ds-w-20 { width: var(--ds-space-20); }
17
+ .ds-w-24 { width: var(--ds-space-24); }
18
+ .ds-w-28 { width: 7rem; }
19
+ .ds-w-32 { width: var(--ds-space-32); }
20
+ .ds-w-48 { width: 12rem; }
21
+ .ds-w-56 { width: 14rem; }
22
+ .ds-w-64 { width: 16rem; }
23
+ .ds-w-80 { width: 20rem; }
24
+ .ds-w-96 { width: 24rem; }
25
+ .ds-w-auto { width: auto; }
26
+ .ds-w-screen { width: 100vw; }
27
+
28
+ /* --- Height (values not already in layout.css) --- */
29
+ .ds-h-0 { height: var(--ds-space-0); }
30
+ .ds-h-0\.5 { height: var(--ds-space-0-5); }
31
+ .ds-h-1 { height: var(--ds-space-1); }
32
+ .ds-h-1\.5 { height: var(--ds-space-1-5); }
33
+ .ds-h-2 { height: var(--ds-space-2); }
34
+ .ds-h-3\.5 { height: 0.875rem; }
35
+ .ds-h-6 { height: var(--ds-space-6); }
36
+ .ds-h-12 { height: var(--ds-space-12); }
37
+ .ds-h-14 { height: 3.5rem; }
38
+ .ds-h-20 { height: var(--ds-space-20); }
39
+ .ds-h-24 { height: var(--ds-space-24); }
40
+ .ds-h-28 { height: 7rem; }
41
+ .ds-h-32 { height: var(--ds-space-32); }
42
+ .ds-h-48 { height: 12rem; }
43
+ .ds-h-64 { height: 16rem; }
44
+ .ds-h-96 { height: 24rem; }
45
+ .ds-h-auto { height: auto; }
46
+ .ds-h-px { height: 1px; }
47
+
48
+ /* --- Max Width (extended) --- */
49
+ .ds-max-w-4xl { max-width: 56rem; }
50
+ .ds-max-w-5xl { max-width: 64rem; }
51
+ .ds-max-w-6xl { max-width: 72rem; }
52
+ .ds-max-w-7xl { max-width: 80rem; }
53
+ .ds-max-w-full { max-width: 100%; }
54
+
55
+ /* --- Max Height --- */
56
+ .ds-max-h-64 { max-height: 16rem; }
57
+ .ds-max-h-80 { max-height: 20rem; }
58
+ .ds-max-h-96 { max-height: 24rem; }
59
+ .ds-max-h-screen { max-height: 100dvh; }
60
+
61
+ /* --- Responsive: Sizing --- */
62
+ @media (min-width: 640px) {
63
+ .ds-sm\:w-12 { width: var(--ds-space-12); }
64
+ .ds-sm\:w-16 { width: var(--ds-space-16); }
65
+ .ds-sm\:w-32 { width: var(--ds-space-32); }
66
+ .ds-sm\:w-64 { width: 16rem; }
67
+ .ds-sm\:w-96 { width: 24rem; }
68
+ .ds-sm\:w-auto { width: auto; }
69
+ .ds-sm\:h-12 { height: var(--ds-space-12); }
70
+ .ds-sm\:h-32 { height: var(--ds-space-32); }
71
+ }
@@ -85,8 +85,15 @@
85
85
 
86
86
  .ds-mt-0\.5 { margin-block-start: var(--ds-space-0-5); }
87
87
  .ds-mt-3 { margin-block-start: var(--ds-space-3); }
88
+ .ds-mt-10 { margin-block-start: var(--ds-space-10); }
89
+ .ds-mt-12 { margin-block-start: var(--ds-space-12); }
90
+ .ds-mt-16 { margin-block-start: var(--ds-space-16); }
88
91
  .ds-mb-0\.5 { margin-block-end: var(--ds-space-0-5); }
89
92
  .ds-mb-3 { margin-block-end: var(--ds-space-3); }
93
+ .ds-mb-10 { margin-block-end: var(--ds-space-10); }
94
+ .ds-mb-12 { margin-block-end: var(--ds-space-12); }
95
+ .ds-mb-16 { margin-block-end: var(--ds-space-16); }
96
+ .ds-mb-20 { margin-block-end: var(--ds-space-20); }
90
97
 
91
98
  /* --- Padding (granular) --- */
92
99
  .ds-p-0\.5 { padding: var(--ds-space-0-5); }
@@ -123,7 +130,19 @@
123
130
  .ds-space-y-6 > * + * { margin-block-start: var(--ds-space-6); }
124
131
  .ds-space-y-8 > * + * { margin-block-start: var(--ds-space-8); }
125
132
 
133
+ /* --- Space-Y (fractional) --- */
134
+ .ds-space-y-1\.5 > * + * { margin-block-start: var(--ds-space-1-5); }
135
+
126
136
  /* --- Responsive: Padding --- */
137
+ @media (min-width: 640px) {
138
+ .ds-sm\:p-6 { padding: var(--ds-space-6); }
139
+ .ds-sm\:px-0 { padding-inline: var(--ds-space-0); }
140
+ .ds-sm\:px-3 { padding-inline: var(--ds-space-3); }
141
+ .ds-sm\:px-4 { padding-inline: var(--ds-space-4); }
142
+ .ds-sm\:px-6 { padding-inline: var(--ds-space-6); }
143
+ .ds-sm\:py-3 { padding-block: var(--ds-space-3); }
144
+ }
145
+
127
146
  @media (min-width: 768px) {
128
147
  .ds-md\:px-4 { padding-inline: var(--ds-space-4); }
129
148
  .ds-md\:px-6 { padding-inline: var(--ds-space-6); }
@@ -0,0 +1,74 @@
1
+ /* ==========================================================================
2
+ Utilities: State Variants
3
+ Hover, focus, active, focus-within, placeholder, and group-hover
4
+ modifiers for DS utility classes.
5
+ ========================================================================== */
6
+
7
+ /* --- Group Marker (enables group-hover on descendants) ---
8
+ Supports both .group and .ds-group for compatibility. */
9
+ .ds-group { /* marker — no styles */ }
10
+
11
+ /* --- Hover: Background --- */
12
+ .hover\:ds-bg-base:hover { background-color: var(--ds-color-bg); }
13
+ .hover\:ds-bg-elevated:hover { background-color: var(--ds-color-bg-elevated); }
14
+ .hover\:ds-bg-muted:hover { background-color: var(--ds-color-bg-muted); }
15
+ .hover\:ds-bg-subtle:hover { background-color: var(--ds-color-bg-subtle); }
16
+ .hover\:ds-bg-surface:hover { background-color: var(--ds-color-surface); }
17
+ .hover\:ds-bg-inverted:hover { background-color: var(--ds-color-inverted); }
18
+ .hover\:ds-bg-info:hover { background-color: var(--ds-color-info); }
19
+
20
+ /* --- Hover: Text --- */
21
+ .hover\:ds-text-primary:hover { color: var(--ds-color-text); }
22
+ .hover\:ds-text-secondary:hover { color: var(--ds-color-text-secondary); }
23
+ .hover\:ds-text-interactive:hover { color: var(--ds-color-interactive); }
24
+
25
+ /* --- Hover: Border --- */
26
+ .hover\:ds-border-hover:hover { border-color: var(--ds-color-border-hover); }
27
+ .hover\:ds-border-interactive:hover { border-color: var(--ds-color-interactive); }
28
+
29
+ /* --- Hover: Decoration --- */
30
+ .hover\:ds-underline:hover { text-decoration: underline; text-underline-offset: 2px; }
31
+
32
+ /* --- Focus --- */
33
+ .focus\:ds-outline-none:focus { outline: none; }
34
+ .focus\:ds-ring-0:focus { box-shadow: none; }
35
+ .focus\:ds-ring-2:focus { box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-color-interactive); }
36
+
37
+ /* --- Focus-Within --- */
38
+ .focus-within\:ds-border-interactive:focus-within { border-color: var(--ds-color-interactive); }
39
+
40
+ /* --- Active --- */
41
+ .active\:ds-bg-elevated:active { background-color: var(--ds-color-bg-elevated); }
42
+ .active\:ds-text-secondary:active { color: var(--ds-color-text-secondary); }
43
+
44
+ /* --- Placeholder --- */
45
+ .placeholder\:ds-text-tertiary::placeholder { color: var(--ds-color-text-tertiary); }
46
+
47
+ /* --- Group Hover (descendants of .group or .ds-group on hover) --- */
48
+ .group:hover > .group-hover\:ds-text-interactive,
49
+ .group:hover .group-hover\:ds-text-interactive,
50
+ .ds-group:hover > .group-hover\:ds-text-interactive,
51
+ .ds-group:hover .group-hover\:ds-text-interactive {
52
+ color: var(--ds-color-interactive);
53
+ }
54
+
55
+ .group:hover > .group-hover\:ds-scale-110,
56
+ .group:hover .group-hover\:ds-scale-110,
57
+ .ds-group:hover > .group-hover\:ds-scale-110,
58
+ .ds-group:hover .group-hover\:ds-scale-110 {
59
+ transform: scale(1.1);
60
+ }
61
+
62
+ .group:hover > .group-hover\:ds-translate-x-1,
63
+ .group:hover .group-hover\:ds-translate-x-1,
64
+ .ds-group:hover > .group-hover\:ds-translate-x-1,
65
+ .ds-group:hover .group-hover\:ds-translate-x-1 {
66
+ transform: translateX(0.25rem);
67
+ }
68
+
69
+ .group:hover > .group-hover\:ds-opacity-100,
70
+ .group:hover .group-hover\:ds-opacity-100,
71
+ .ds-group:hover > .group-hover\:ds-opacity-100,
72
+ .ds-group:hover .group-hover\:ds-opacity-100 {
73
+ opacity: 1;
74
+ }