css-tags 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.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +875 -0
  3. package/carousel.js +86 -0
  4. package/components/accessibility.css +51 -0
  5. package/components/actions.css +76 -0
  6. package/components/alert.css +122 -0
  7. package/components/application-patterns.css +122 -0
  8. package/components/badge.css +125 -0
  9. package/components/box-extra.css +220 -0
  10. package/components/box.css +75 -0
  11. package/components/card.css +130 -0
  12. package/components/carousel.css +76 -0
  13. package/components/chip.css +71 -0
  14. package/components/container.css +55 -0
  15. package/components/content-patterns.css +234 -0
  16. package/components/disclosure.css +581 -0
  17. package/components/divider.css +68 -0
  18. package/components/flex.css +59 -0
  19. package/components/form-patterns.css +273 -0
  20. package/components/form.css +130 -0
  21. package/components/grid.css +82 -0
  22. package/components/identity.css +59 -0
  23. package/components/img-container.css +141 -0
  24. package/components/img-container.js +75 -0
  25. package/components/list.css +69 -0
  26. package/components/loading.css +112 -0
  27. package/components/masonry.css +48 -0
  28. package/components/modal.css +73 -0
  29. package/components/navigation-patterns.css +245 -0
  30. package/components/navigation.css +200 -0
  31. package/components/popover.css +49 -0
  32. package/components/site-shell.css +180 -0
  33. package/components/status.css +110 -0
  34. package/components/table.css +98 -0
  35. package/components/tabs.css +103 -0
  36. package/components/tooltip.css +87 -0
  37. package/components/tooltips.css +73 -0
  38. package/components/view-transition.css +73 -0
  39. package/core/base.css +62 -0
  40. package/core/defaults.css +490 -0
  41. package/core/engine.css +32 -0
  42. package/core/mixins.css +376 -0
  43. package/core/palette-accent.css +8 -0
  44. package/core/palette-base.css +107 -0
  45. package/core/palette-extended.css +142 -0
  46. package/core/palette-feedback.css +62 -0
  47. package/core/palette.css +7 -0
  48. package/core/reset.css +270 -0
  49. package/core/text.css +171 -0
  50. package/core/theme.css +608 -0
  51. package/core/tokens.css +488 -0
  52. package/core/typography.css +327 -0
  53. package/index.css +66 -0
  54. package/layouts/layout-extra.css +204 -0
  55. package/layouts/layout-extras-helpers.css +19 -0
  56. package/layouts/layout.css +348 -0
  57. package/package.json +66 -0
  58. package/theme-generator.css +979 -0
  59. package/themes/example-brand.css +59 -0
  60. package/themes/theme-packs.css +31 -0
  61. package/types/css-tags.d.ts +482 -0
  62. package/utilities/utilities.css +564 -0
  63. package/view-transition.js +111 -0
package/carousel.js ADDED
@@ -0,0 +1,86 @@
1
+ /**
2
+ * carousel.js
3
+ *
4
+ * Logic for the responsive and touch-friendly carousel component.
5
+ * ------------------------------------------------------------------------------
6
+ * This script initializes all carousels on the page, adding support for:
7
+ * - Next/Previous button navigation and state management.
8
+ * - Looping behavior.
9
+ * - Touch-based swipe navigation for mobile devices.
10
+ * - It overrides scroll-snap behavior for transform-based animations.
11
+ */
12
+ function initializeCarousels(root = document) {
13
+ const carousels = root.querySelectorAll(':is(carousel, [data-carousel], .carousel)');
14
+
15
+ carousels.forEach(carousel => {
16
+ if (carousel.dataset.carouselInitialized === 'true') return;
17
+
18
+ const slidesContainer = carousel.querySelector(':is(.carousel-slides, [data-carousel-slides])');
19
+ const items = carousel.querySelectorAll(':is(carousel-item, [data-carousel-item], .carousel-item)');
20
+ const prevTrigger = carousel.querySelector(':is(carousel-trigger, [data-carousel-trigger], .carousel-trigger)[direction="prev"]');
21
+ const nextTrigger = carousel.querySelector(':is(carousel-trigger, [data-carousel-trigger], .carousel-trigger)[direction="next"]');
22
+
23
+ if (!slidesContainer || items.length === 0) return;
24
+ carousel.dataset.carouselInitialized = 'true';
25
+
26
+ const totalSlides = items.length;
27
+ const isLooping = carousel.hasAttribute('loop');
28
+
29
+ // Set the slides container width to accommodate all slides
30
+ slidesContainer.style.width = `${totalSlides * 100}%`;
31
+
32
+ // Set each item width to match the carousel width
33
+ items.forEach(item => {
34
+ item.style.width = `${100 / totalSlides}%`;
35
+ });
36
+
37
+ let currentIndex = 0;
38
+
39
+ function updateCarousel(isInstant = false) {
40
+ if (isInstant) slidesContainer.style.transition = 'none';
41
+
42
+ slidesContainer.style.transform = `translateX(-${currentIndex * (100 / totalSlides)}%)`;
43
+
44
+ if (isInstant) {
45
+ // Restore transition after the instant move
46
+ setTimeout(() => slidesContainer.style.transition = '', 50);
47
+ }
48
+
49
+ if (!isLooping) {
50
+ prevTrigger?.toggleAttribute('disabled', currentIndex === 0);
51
+ nextTrigger?.toggleAttribute('disabled', currentIndex === totalSlides - 1);
52
+ }
53
+ }
54
+
55
+ function goToSlide(index) {
56
+ if (isLooping) {
57
+ currentIndex = (index + totalSlides) % totalSlides;
58
+ } else {
59
+ currentIndex = Math.max(0, Math.min(index, totalSlides - 1));
60
+ }
61
+ updateCarousel();
62
+ }
63
+
64
+ prevTrigger?.addEventListener('click', () => goToSlide(currentIndex - 1));
65
+ nextTrigger?.addEventListener('click', () => goToSlide(currentIndex + 1));
66
+
67
+ let touchStartX = 0;
68
+ carousel.addEventListener('touchstart', e => { touchStartX = e.changedTouches[0].screenX; }, { passive: true });
69
+ carousel.addEventListener('touchend', e => {
70
+ const touchEndX = e.changedTouches[0].screenX;
71
+ if (Math.abs(touchEndX - touchStartX) > 50) {
72
+ goToSlide(touchEndX < touchStartX ? currentIndex + 1 : currentIndex - 1);
73
+ }
74
+ });
75
+
76
+ updateCarousel(true); // Initial setup without animation
77
+ });
78
+ }
79
+
80
+ if (document.readyState === 'loading') {
81
+ document.addEventListener('DOMContentLoaded', () => initializeCarousels(), { once: true });
82
+ } else {
83
+ initializeCarousels();
84
+ }
85
+
86
+ export { initializeCarousels };
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Accessibility primitives
3
+ *
4
+ * Skip links intentionally enhance anchors only: the navigation semantics and
5
+ * keyboard behavior belong in HTML, while CSS controls their presentation.
6
+ */
7
+
8
+ :is(a.skip-link, a[data-skip-link]) {
9
+ position: fixed;
10
+ inset-block-start: var(--skip-link-inset-block, var(--space-sm, 0.5rem));
11
+ inset-inline-start: var(--skip-link-inset-inline, var(--space-sm, 0.5rem));
12
+ z-index: var(--skip-link-z-index, var(--z-index-skip-link, 10001));
13
+ padding: var(--skip-link-padding, var(--space-sm, 0.5rem) var(--space-md, 1rem));
14
+ border: var(--skip-link-border, 1px solid currentColor);
15
+ border-radius: var(--skip-link-radius, var(--border-radius-md, 0.5rem));
16
+ background: var(--skip-link-background, var(--accent, CanvasText));
17
+ color: var(--skip-link-color, var(--on-accent, Canvas));
18
+ box-shadow: var(--skip-link-shadow, var(--shadow-md, 0 0.25rem 0.75rem rgb(0 0 0 / 0.2)));
19
+ font-weight: var(--skip-link-font-weight, var(--font-weight-semibold, 600));
20
+ line-height: var(--line-height-tight, 1.25);
21
+ text-decoration: none;
22
+ opacity: 0;
23
+ transform: translateY(calc(-100% - var(--skip-link-inset-block, var(--space-sm, 0.5rem))));
24
+ transition:
25
+ transform var(--skip-link-duration, var(--transition-fast, 150ms)) ease,
26
+ opacity var(--skip-link-duration, var(--transition-fast, 150ms)) ease;
27
+ }
28
+
29
+ :is(a.skip-link, a[data-skip-link]):is(:focus, :focus-visible) {
30
+ opacity: 1;
31
+ transform: translateY(0);
32
+ }
33
+
34
+ :is(a.skip-link, a[data-skip-link]):focus-visible {
35
+ outline: var(--skip-link-focus-outline, 3px solid var(--focus-ring-color, currentColor));
36
+ outline-offset: var(--skip-link-focus-offset, 3px);
37
+ }
38
+
39
+ @media (prefers-reduced-motion: reduce) {
40
+ :is(a.skip-link, a[data-skip-link]) {
41
+ transition: none;
42
+ }
43
+ }
44
+
45
+ @media (forced-colors: active) {
46
+ :is(a.skip-link, a[data-skip-link]) {
47
+ border-color: CanvasText;
48
+ background: Canvas;
49
+ color: CanvasText;
50
+ }
51
+ }
@@ -0,0 +1,76 @@
1
+ /** Compact action controls. Native buttons remain the canonical API. */
2
+
3
+ :is(button[data-icon-button], button.icon-button, icon-button,
4
+ button[data-fab], button.fab, floating-action) {
5
+ --_icon-button-size: var(--icon-button-size, 2.75rem);
6
+
7
+ box-sizing: border-box;
8
+ display: inline-grid;
9
+ place-items: center;
10
+ flex: 0 0 auto;
11
+ inline-size: var(--_icon-button-size);
12
+ block-size: var(--_icon-button-size);
13
+ min-inline-size: var(--_icon-button-size);
14
+ padding: var(--icon-button-padding, 0.625rem);
15
+ border: var(--icon-button-border-width, var(--border-width, 1px)) solid
16
+ var(--icon-button-border-color, var(--outline-default));
17
+ border-radius: var(--icon-button-radius, var(--radius-md, 0.5rem));
18
+ background: var(--icon-button-background, var(--surface-default));
19
+ color: var(--icon-button-color, var(--text-default));
20
+ line-height: 1;
21
+ }
22
+
23
+ :is(button[data-icon-button], button.icon-button, icon-button,
24
+ button[data-fab], button.fab, floating-action)
25
+ > :is(svg, img, [data-icon]) {
26
+ inline-size: var(--icon-button-icon-size, 1.25rem);
27
+ block-size: var(--icon-button-icon-size, 1.25rem);
28
+ object-fit: contain;
29
+ }
30
+
31
+ :is(button[data-icon-button], button.icon-button, icon-button,
32
+ button[data-fab], button.fab, floating-action):is(:hover, :focus-visible) {
33
+ background: var(--icon-button-hover-background, var(--surface-subtle));
34
+ border-color: var(--icon-button-hover-border-color, var(--outline-overt));
35
+ }
36
+
37
+ :is(button[data-icon-button], button.icon-button, icon-button,
38
+ button[data-fab], button.fab, floating-action):focus-visible {
39
+ outline: var(--focus-ring-width, 2px) solid var(--focus-ring-color);
40
+ outline-offset: var(--focus-ring-offset, 2px);
41
+ }
42
+
43
+ :is(button[data-icon-button], button.icon-button, icon-button):is([data-size="sm"], [size="sm"]) {
44
+ --icon-button-size: 2.25rem;
45
+ --icon-button-icon-size: 1rem;
46
+ }
47
+
48
+ :is(button[data-icon-button], button.icon-button, icon-button):is([data-size="lg"], [size="lg"]) {
49
+ --icon-button-size: 3.25rem;
50
+ --icon-button-icon-size: 1.5rem;
51
+ }
52
+
53
+ :is(button[data-fab], button.fab, floating-action) {
54
+ --icon-button-size: var(--fab-size, 3.5rem);
55
+ --icon-button-radius: var(--fab-radius, var(--radius-full, 9999px));
56
+ --icon-button-background: var(--fab-background, var(--accent));
57
+ --icon-button-color: var(--fab-color, var(--text-on-accent));
58
+ --icon-button-border-color: var(--fab-border-color, transparent);
59
+
60
+ position: fixed;
61
+ z-index: var(--fab-z-index, var(--z-index-50, 50));
62
+ inset-inline-end: max(var(--fab-inset-inline, 1.25rem), env(safe-area-inset-right));
63
+ inset-block-end: max(var(--fab-inset-block, 1.25rem), env(safe-area-inset-bottom));
64
+ box-shadow: var(--fab-shadow, var(--shadow-lg));
65
+ }
66
+
67
+ :is(button[data-fab], button.fab, floating-action):is(:hover, :focus-visible) {
68
+ --icon-button-hover-background: var(--fab-hover-background, var(--accent-overt));
69
+ }
70
+
71
+ @media (forced-colors: active) {
72
+ :is(button[data-icon-button], button.icon-button, icon-button,
73
+ button[data-fab], button.fab, floating-action) {
74
+ border-color: ButtonText;
75
+ }
76
+ }
@@ -0,0 +1,122 @@
1
+ /** Native-first feedback surfaces with optional icon, body, and actions. */
2
+
3
+ :is(alert-message, [data-alert], .alert) {
4
+ --_alert-background: var(--alert-background, var(--surface-info, var(--surface-subtle)));
5
+ --_alert-border-color: var(--alert-border-color, var(--outline-info, var(--outline-subtle)));
6
+ --_alert-color: var(--alert-color, var(--text-info, var(--text-default)));
7
+
8
+ display: grid;
9
+ min-inline-size: 0;
10
+ gap: var(--alert-gap, var(--space-md, var(--spacing-md, 1rem)));
11
+ align-items: start;
12
+ padding: var(--alert-padding, var(--space-md, var(--spacing-md, 1rem)));
13
+ border: var(--alert-border-width, var(--border-width, 1px)) solid var(--_alert-border-color);
14
+ border-radius: var(--alert-radius, var(--radius-md, var(--border-radius-md, 0.5rem)));
15
+ background: var(--_alert-background);
16
+ color: var(--_alert-color);
17
+ }
18
+
19
+ :is(alert-message, [data-alert], .alert)
20
+ :is([slot="icon"], [data-alert-icon], .alert__icon) {
21
+ align-self: start;
22
+ }
23
+
24
+ :is(alert-message, [data-alert], .alert)
25
+ :is([slot="title"], [data-alert-title], .alert__title) {
26
+ font-weight: var(--alert-title-weight, var(--font-weight-semibold, 600));
27
+ }
28
+
29
+ :is(alert-message, [data-alert], .alert)
30
+ :is([slot="body"], [data-alert-body], .alert__body) {
31
+ min-inline-size: 0;
32
+ }
33
+
34
+ :is(alert-message, [data-alert], .alert)
35
+ > :is([slot="actions"], [data-alert-actions], .alert__actions) {
36
+ display: flex;
37
+ flex-wrap: wrap;
38
+ gap: var(--alert-actions-gap, var(--space-sm, 0.5rem));
39
+ min-inline-size: 0;
40
+ }
41
+
42
+ :is(alert-message, [data-alert], .alert):is([density="compact"], [data-density="compact"], .alert-compact) {
43
+ --alert-gap: var(--alert-compact-gap, var(--space-sm, var(--spacing-sm, 0.75rem)));
44
+ --alert-padding: var(--alert-compact-padding, var(--space-sm, var(--spacing-sm, 0.75rem)));
45
+ }
46
+
47
+ :is(alert-message, [data-alert], .alert):is([density="spacious"], [data-density="spacious"], .alert-spacious) {
48
+ --alert-gap: var(--alert-spacious-gap, var(--space-lg, var(--spacing-lg, 1.5rem)));
49
+ --alert-padding: var(--alert-spacious-padding, var(--space-lg, var(--spacing-lg, 1.5rem)));
50
+ }
51
+
52
+ :is(alert-message, [data-alert], .alert):is([status="success"], [data-status="success"], .alert-success) {
53
+ --_alert-background: var(--alert-background, var(--alert-success-background, var(--surface-success)));
54
+ --_alert-border-color: var(--alert-border-color, var(--alert-success-border-color, var(--outline-success)));
55
+ --_alert-color: var(--alert-color, var(--alert-success-color, var(--text-success)));
56
+ }
57
+
58
+ :is(alert-message, [data-alert], .alert):is([status="warning"], [data-status="warning"], .alert-warning) {
59
+ --_alert-background: var(--alert-background, var(--alert-warning-background, var(--surface-warning)));
60
+ --_alert-border-color: var(--alert-border-color, var(--alert-warning-border-color, var(--outline-warning)));
61
+ --_alert-color: var(--alert-color, var(--alert-warning-color, var(--text-warning)));
62
+ }
63
+
64
+ :is(alert-message, [data-alert], .alert):is([status="error"], [data-status="error"], .alert-error) {
65
+ --_alert-background: var(--alert-background, var(--alert-error-background, var(--surface-error)));
66
+ --_alert-border-color: var(--alert-border-color, var(--alert-error-border-color, var(--outline-error)));
67
+ --_alert-color: var(--alert-color, var(--alert-error-color, var(--text-error)));
68
+ }
69
+
70
+ :is(alert-message, [data-alert], .alert):is([status="info"], [data-status="info"], .alert-info) {
71
+ --_alert-background: var(--alert-background, var(--alert-info-background, var(--surface-info)));
72
+ --_alert-border-color: var(--alert-border-color, var(--alert-info-border-color, var(--outline-info)));
73
+ --_alert-color: var(--alert-color, var(--alert-info-color, var(--text-info)));
74
+ }
75
+
76
+ /* The single-column layout above is the fallback when :has() is unavailable. */
77
+ @supports selector(:has(*)) {
78
+ :is(alert-message, [data-alert], .alert):has(
79
+ > :is([slot="icon"], [data-alert-icon], .alert__icon)
80
+ ) {
81
+ grid-template-columns: auto minmax(0, 1fr);
82
+ }
83
+
84
+ :is(alert-message, [data-alert], .alert):has(
85
+ > :is([slot="actions"], [data-alert-actions], .alert__actions)
86
+ ) {
87
+ grid-template-columns: minmax(0, 1fr) auto;
88
+ }
89
+
90
+ :is(alert-message, [data-alert], .alert):has(
91
+ > :is([slot="icon"], [data-alert-icon], .alert__icon)
92
+ ):has(
93
+ > :is([slot="actions"], [data-alert-actions], .alert__actions)
94
+ ) {
95
+ grid-template-columns: auto minmax(0, 1fr) auto;
96
+ }
97
+ }
98
+
99
+ @media (max-width: 30rem) {
100
+ @supports selector(:has(*)) {
101
+ :is(alert-message, [data-alert], .alert):has(
102
+ > :is([slot="icon"], [data-alert-icon], .alert__icon)
103
+ ):has(
104
+ > :is([slot="actions"], [data-alert-actions], .alert__actions)
105
+ ) {
106
+ grid-template-columns: auto minmax(0, 1fr);
107
+ }
108
+
109
+ :is(alert-message, [data-alert], .alert):has(
110
+ > :is([slot="icon"], [data-alert-icon], .alert__icon)
111
+ )
112
+ > :is([slot="actions"], [data-alert-actions], .alert__actions) {
113
+ grid-column: 2;
114
+ }
115
+ }
116
+ }
117
+
118
+ @media (forced-colors: active) {
119
+ :is(alert-message, [data-alert], .alert) {
120
+ border-color: CanvasText;
121
+ }
122
+ }
@@ -0,0 +1,122 @@
1
+ /** Application and feed patterns built on semantic content. */
2
+
3
+ :is(message-bubble, [data-bubble], .bubble) {
4
+ display: grid;
5
+ inline-size: fit-content;
6
+ max-inline-size: var(--bubble-max-width, min(42rem, 85%));
7
+ gap: var(--bubble-gap, var(--space-xs, 0.5rem));
8
+ padding: var(--bubble-padding, var(--space-sm, 0.75rem) var(--space-md, 1rem));
9
+ border: var(--bubble-border-width, var(--border-width, 1px)) solid
10
+ var(--bubble-border-color, var(--outline-subtle));
11
+ border-radius: var(--bubble-radius, var(--radius-lg, 0.75rem));
12
+ background: var(--bubble-background, var(--surface-subtle));
13
+ color: var(--bubble-color, var(--text-default));
14
+ }
15
+
16
+ :is(message-bubble, [data-bubble], .bubble):is([data-sender="self"], .bubble-self) {
17
+ justify-self: end;
18
+ border-end-end-radius: var(--bubble-tail-radius, var(--radius-xs, 0.25rem));
19
+ background: var(--bubble-self-background, var(--accent));
20
+ color: var(--bubble-self-color, var(--text-on-accent));
21
+ }
22
+
23
+ :is(message-bubble, [data-bubble], .bubble):is([data-sender="other"], .bubble-other) {
24
+ justify-self: start;
25
+ border-end-start-radius: var(--bubble-tail-radius, var(--radius-xs, 0.25rem));
26
+ }
27
+
28
+ :is([data-chat], .chat) {
29
+ display: grid;
30
+ gap: var(--chat-gap, var(--space-sm, 0.75rem));
31
+ }
32
+
33
+ :is([data-bubble-meta], .bubble-meta) {
34
+ color: inherit;
35
+ font-size: var(--bubble-meta-size, var(--font-size-xs, 0.75rem));
36
+ opacity: var(--bubble-meta-opacity, 0.72);
37
+ }
38
+
39
+ :is(message-bubble, [data-bubble], .bubble)[aria-busy="true"]::after {
40
+ content: "•••";
41
+ inline-size: 1.5em;
42
+ overflow: hidden;
43
+ animation: bubble-thinking 1.2s steps(4, end) infinite;
44
+ }
45
+
46
+ @keyframes bubble-thinking {
47
+ from { inline-size: 0; }
48
+ }
49
+
50
+ :is(log-card, [data-log-card], .log-card) {
51
+ display: grid;
52
+ overflow: hidden;
53
+ border: var(--log-card-border-width, var(--border-width, 1px)) solid
54
+ var(--log-card-border-color, var(--outline-subtle));
55
+ border-radius: var(--log-card-radius, var(--radius-lg, 0.75rem));
56
+ background: var(--log-card-background, var(--surface-default));
57
+ color: var(--log-card-color, var(--text-default));
58
+ }
59
+
60
+ :is([data-log-header], .log-card-header) {
61
+ display: flex;
62
+ align-items: center;
63
+ justify-content: space-between;
64
+ gap: var(--log-card-gap, var(--space-sm, 0.75rem));
65
+ padding: var(--log-card-header-padding, var(--space-sm, 0.75rem) var(--space-md, 1rem));
66
+ border-block-end: var(--border-width, 1px) solid var(--log-card-border-color, var(--outline-subtle));
67
+ background: var(--log-card-header-background, var(--surface-subtle));
68
+ }
69
+
70
+ :is([data-log-body], .log-card-body) {
71
+ max-block-size: var(--log-card-max-height, 24rem);
72
+ padding: var(--log-card-body-padding, var(--space-sm, 0.75rem));
73
+ overflow: auto;
74
+ font-family: var(--font-family-mono, ui-monospace, monospace);
75
+ font-size: var(--log-card-font-size, var(--font-size-sm, 0.875rem));
76
+ }
77
+
78
+ :is([data-log-row], .log-row) {
79
+ display: grid;
80
+ grid-template-columns: auto minmax(0, 1fr) auto;
81
+ gap: var(--log-row-gap, var(--space-sm, 0.75rem));
82
+ padding: var(--log-row-padding, var(--space-xs, 0.5rem));
83
+ border-radius: var(--log-row-radius, var(--radius-sm, 0.25rem));
84
+ }
85
+
86
+ :is([data-log-row], .log-row)::before {
87
+ content: "";
88
+ align-self: center;
89
+ inline-size: var(--log-marker-size, 0.5rem);
90
+ block-size: var(--log-marker-size, 0.5rem);
91
+ border-radius: 50%;
92
+ background: var(--log-marker-color, var(--text-muted));
93
+ }
94
+
95
+ :is([data-log-row="success"], .log-row-success) { --log-marker-color: var(--success); }
96
+ :is([data-log-row="warning"], .log-row-warning) { --log-marker-color: var(--warning); }
97
+ :is([data-log-row="error"], .log-row-error) { --log-marker-color: var(--error); }
98
+ :is([data-log-row="running"], .log-row-running) { --log-marker-color: var(--info); }
99
+
100
+ :is(snap-feed, [data-snap-feed], .snap-feed) {
101
+ display: flex;
102
+ flex-direction: column;
103
+ block-size: var(--snap-feed-height, min(80dvh, 48rem));
104
+ overflow-y: auto;
105
+ overscroll-behavior-block: contain;
106
+ scroll-snap-type: y var(--snap-feed-strictness, mandatory);
107
+ scrollbar-gutter: stable;
108
+ }
109
+
110
+ :is(snap-feed, [data-snap-feed], .snap-feed) > * {
111
+ flex: 0 0 var(--snap-feed-item-min-height, 100%);
112
+ min-block-size: 0;
113
+ scroll-snap-align: var(--snap-feed-align, start);
114
+ scroll-snap-stop: var(--snap-feed-stop, normal);
115
+ }
116
+
117
+ @media (prefers-reduced-motion: reduce) {
118
+ :is(message-bubble, [data-bubble], .bubble)[aria-busy="true"]::after {
119
+ animation: none;
120
+ inline-size: auto;
121
+ }
122
+ }
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Compact, non-interactive metadata with custom-element, data, and class hosts.
3
+ * `variant` is the visual surface API; `role` is reserved for ARIA semantics.
4
+ */
5
+
6
+ :is(badge, [data-badge], .badge) {
7
+ --_badge-background: var(--badge-background, var(--surface-overt));
8
+ --_badge-color: var(--badge-color, var(--text-on-surface-overt, var(--text-default)));
9
+ --_badge-border-color: var(--badge-border-color, var(--outline-overt));
10
+ --_badge-border-width: var(--badge-border-width, var(--border-width, 1px));
11
+ --_badge-radius: var(--badge-radius, var(--radius-full, var(--border-radius-full, 9999px)));
12
+ --_badge-padding-inline: var(--badge-padding-inline, 0.55em);
13
+ --_badge-padding-block: var(--badge-padding-block, 0.15em);
14
+ --_badge-gap: var(--badge-gap, var(--space-2xs, 0.25rem));
15
+
16
+ display: inline-flex;
17
+ align-items: center;
18
+ gap: var(--_badge-gap);
19
+ max-inline-size: 100%;
20
+ padding: var(--_badge-padding-block) var(--_badge-padding-inline);
21
+ border: var(--_badge-border-width) solid var(--_badge-border-color);
22
+ border-radius: var(--_badge-radius);
23
+ background: var(--_badge-background);
24
+ color: var(--_badge-color);
25
+ font-size: 0.85em;
26
+ line-height: 1;
27
+ overflow-wrap: anywhere;
28
+ }
29
+
30
+ @supports (text-box: trim-both cap alphabetic) {
31
+ :is(badge, [data-badge], .badge) {
32
+ text-box: var(--text-box-badge, var(--text-box-ui));
33
+ }
34
+ }
35
+
36
+ @supports (text-box-trim: trim-both) and (text-box-edge: cap alphabetic) {
37
+ :is(badge, [data-badge], .badge) {
38
+ text-box-trim: var(--text-box-trim-badge, var(--text-box-trim-ui));
39
+ text-box-edge: var(--text-box-edge-badge, var(--text-box-edge-ui));
40
+ }
41
+ }
42
+
43
+ :is(badge, [data-badge], .badge):is([size="sm"], [data-size="sm"], .badge-sm) {
44
+ --_badge-padding-block: 0.1em;
45
+ --_badge-padding-inline: 0.45em;
46
+ font-size: 0.75em;
47
+ }
48
+
49
+ :is(badge, [data-badge], .badge):is([size="md"], [data-size="md"], .badge-md) {
50
+ --_badge-padding-block: 0.15em;
51
+ --_badge-padding-inline: 0.55em;
52
+ font-size: 0.85em;
53
+ }
54
+
55
+ :is(badge, [data-badge], .badge):is([size="lg"], [data-size="lg"], .badge-lg) {
56
+ --_badge-padding-block: 0.25em;
57
+ --_badge-padding-inline: 0.7em;
58
+ font-size: 0.95em;
59
+ }
60
+
61
+ :is(badge, [data-badge], .badge):is([variant="subtle"], [data-variant="subtle"], .badge-subtle) {
62
+ --_badge-background: var(--surface-subtle);
63
+ --_badge-color: var(--text-on-surface-subtle, var(--text-default));
64
+ --_badge-border-color: var(--outline-subtle);
65
+ }
66
+
67
+ :is(badge, [data-badge], .badge):is([variant="default"], [data-variant="default"], .badge-default) {
68
+ --_badge-background: var(--surface-default);
69
+ --_badge-color: var(--text-on-surface, var(--text-default));
70
+ --_badge-border-color: var(--outline-default);
71
+ }
72
+
73
+ :is(badge, [data-badge], .badge):is([variant="muted"], [data-variant="muted"], .badge-muted) {
74
+ --_badge-background: var(--surface-muted);
75
+ --_badge-color: var(--text-on-surface-muted, var(--text-default));
76
+ --_badge-border-color: var(--outline-subtle);
77
+ }
78
+
79
+ :is(badge, [data-badge], .badge):is([variant="overt"], [data-variant="overt"], .badge-overt) {
80
+ --_badge-background: var(--surface-overt);
81
+ --_badge-color: var(--text-on-surface-overt, var(--text-default));
82
+ --_badge-border-color: var(--outline-overt);
83
+ }
84
+
85
+ /* Deprecated compatibility: use `variant`; `role` must describe accessibility. */
86
+ :is(badge, [data-badge], .badge)[role="subtle"] { --_badge-background: var(--surface-subtle); --_badge-color: var(--text-on-surface-subtle, var(--text-default)); --_badge-border-color: var(--outline-subtle); }
87
+ :is(badge, [data-badge], .badge)[role="default"] { --_badge-background: var(--surface-default); --_badge-color: var(--text-on-surface, var(--text-default)); --_badge-border-color: var(--outline-default); }
88
+ :is(badge, [data-badge], .badge)[role="muted"] { --_badge-background: var(--surface-muted); --_badge-color: var(--text-on-surface-muted, var(--text-default)); --_badge-border-color: var(--outline-subtle); }
89
+ :is(badge, [data-badge], .badge)[role="overt"] { --_badge-background: var(--surface-overt); --_badge-color: var(--text-on-surface-overt, var(--text-default)); --_badge-border-color: var(--outline-overt); }
90
+
91
+ :is(badge, [data-badge], .badge):is([status="success"], [data-status="success"], .badge-success) {
92
+ --_badge-background: var(--surface-success);
93
+ --_badge-color: var(--text-success);
94
+ --_badge-border-color: var(--outline-success);
95
+ }
96
+
97
+ :is(badge, [data-badge], .badge):is([status="warning"], [data-status="warning"], .badge-warning) {
98
+ --_badge-background: var(--surface-warning);
99
+ --_badge-color: var(--text-warning);
100
+ --_badge-border-color: var(--outline-warning);
101
+ }
102
+
103
+ :is(badge, [data-badge], .badge):is([status="error"], [data-status="error"], .badge-error) {
104
+ --_badge-background: var(--surface-error);
105
+ --_badge-color: var(--text-error);
106
+ --_badge-border-color: var(--outline-error);
107
+ }
108
+
109
+ :is(badge, [data-badge], .badge):is([status="info"], [data-status="info"], .badge-info) {
110
+ --_badge-background: var(--surface-info);
111
+ --_badge-color: var(--text-info);
112
+ --_badge-border-color: var(--outline-info);
113
+ }
114
+
115
+ :is(badge, [data-badge], .badge):is([status="primary"], [data-status="primary"], .badge-primary) {
116
+ --_badge-background: var(--accent);
117
+ --_badge-color: var(--text-on-accent);
118
+ --_badge-border-color: var(--accent-overt, var(--accent));
119
+ }
120
+
121
+ :is(badge, [data-badge], .badge):is([status="overt"], [data-status="overt"], .badge-status-overt) {
122
+ --_badge-background: var(--surface-overt);
123
+ --_badge-color: var(--text-on-surface-overt, var(--text-default));
124
+ --_badge-border-color: var(--outline-overt);
125
+ }