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
@@ -0,0 +1,110 @@
1
+ /**
2
+ * status.css
3
+ *
4
+ * Token-driven defaults for native progress and meter elements.
5
+ * Native elements are canonical so value, range, and status semantics remain
6
+ * available to browsers and assistive technology.
7
+ */
8
+
9
+ @keyframes progress-indeterminate {
10
+ to { background-position-x: -200%; }
11
+ }
12
+
13
+ :is(progress, progress.progress, progress[data-progress]) {
14
+ --_progress-height: var(--progress-height, 0.75rem);
15
+ --_progress-radius: var(--progress-radius, var(--radius-full, 9999px));
16
+ --_progress-bg: var(--progress-background, var(--surface-muted, #e5e7eb));
17
+ --_progress-border: var(--progress-border, var(--outline-subtle, transparent));
18
+ --_progress-value: var(--progress-value-background, var(--accent));
19
+
20
+ appearance: none;
21
+ display: block;
22
+ inline-size: 100%;
23
+ block-size: var(--_progress-height);
24
+ overflow: hidden;
25
+ border: var(--border-width, 1px) solid var(--_progress-border);
26
+ border-radius: var(--_progress-radius);
27
+ background: var(--_progress-bg);
28
+ color: var(--_progress-value);
29
+ }
30
+
31
+ :is(progress, progress.progress, progress[data-progress])::-webkit-progress-bar {
32
+ border-radius: inherit;
33
+ background: var(--_progress-bg);
34
+ }
35
+
36
+ :is(progress, progress.progress, progress[data-progress])::-webkit-progress-value {
37
+ border-radius: inherit;
38
+ background: var(--_progress-value);
39
+ }
40
+
41
+ :is(progress, progress.progress, progress[data-progress])::-moz-progress-bar {
42
+ border-radius: inherit;
43
+ background: var(--_progress-value);
44
+ }
45
+
46
+ :is(progress, progress.progress, progress[data-progress]):not([value]) {
47
+ background-image: linear-gradient(
48
+ 100deg,
49
+ var(--_progress-bg) 20%,
50
+ var(--progress-indeterminate-background, var(--_progress-value)) 50%,
51
+ var(--_progress-bg) 80%
52
+ );
53
+ background-size: 200% 100%;
54
+ animation: progress-indeterminate var(--progress-indeterminate-speed, 1.4s) linear infinite;
55
+ }
56
+
57
+ :is(progress, progress.progress, progress[data-progress]):not([value])::-webkit-progress-bar {
58
+ background: transparent;
59
+ }
60
+
61
+ :is(meter, meter.meter, meter[data-meter]) {
62
+ --_meter-height: var(--meter-height, 0.75rem);
63
+ --_meter-radius: var(--meter-radius, var(--radius-full, 9999px));
64
+ --_meter-bg: var(--meter-background, var(--surface-muted, #e5e7eb));
65
+ --_meter-border: var(--meter-border, var(--outline-subtle, transparent));
66
+ --_meter-optimum: var(--meter-optimum-background, var(--success));
67
+ --_meter-suboptimum: var(--meter-suboptimum-background, var(--warning));
68
+ --_meter-low: var(--meter-even-less-good-background, var(--error));
69
+
70
+ appearance: none;
71
+ display: block;
72
+ inline-size: 100%;
73
+ block-size: var(--_meter-height);
74
+ overflow: hidden;
75
+ border: var(--border-width, 1px) solid var(--_meter-border);
76
+ border-radius: var(--_meter-radius);
77
+ background: var(--_meter-bg);
78
+ }
79
+
80
+ :is(meter, meter.meter, meter[data-meter])::-webkit-meter-bar {
81
+ border: 0;
82
+ border-radius: inherit;
83
+ background: var(--_meter-bg);
84
+ }
85
+
86
+ :is(meter, meter.meter, meter[data-meter])::-webkit-meter-optimum-value {
87
+ border-radius: inherit;
88
+ background: var(--_meter-optimum);
89
+ }
90
+
91
+ :is(meter, meter.meter, meter[data-meter])::-webkit-meter-suboptimum-value {
92
+ border-radius: inherit;
93
+ background: var(--_meter-suboptimum);
94
+ }
95
+
96
+ :is(meter, meter.meter, meter[data-meter])::-webkit-meter-even-less-good-value {
97
+ border-radius: inherit;
98
+ background: var(--_meter-low);
99
+ }
100
+
101
+ :is(meter, meter.meter, meter[data-meter])::-moz-meter-bar {
102
+ border-radius: inherit;
103
+ background: var(--_meter-optimum);
104
+ }
105
+
106
+ @media (prefers-reduced-motion: reduce) {
107
+ :is(progress, progress.progress, progress[data-progress]):not([value]) {
108
+ animation: none;
109
+ }
110
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Responsive data tables.
3
+ *
4
+ * Prefer a native table with `data-table` or `.data-table`. A custom
5
+ * `<data-table>` can be used as an overflow wrapper around a native table;
6
+ * keeping `<table>`, `<th>`, and `<td>` preserves browser table semantics.
7
+ */
8
+
9
+ :is(data-table, [data-table-scroll], .table-scroll) {
10
+ display: block;
11
+ max-width: 100%;
12
+ overflow-x: auto;
13
+ border-radius: var(--table-radius, var(--radius-md, 0.5rem));
14
+ overscroll-behavior-inline: contain;
15
+ scrollbar-gutter: stable;
16
+ }
17
+
18
+ :is(table[data-table], table.data-table, data-table > table) {
19
+ width: 100%;
20
+ min-width: var(--table-min-width, 36rem);
21
+ border-spacing: 0;
22
+ border-collapse: separate;
23
+ overflow: hidden;
24
+ color: var(--table-text, var(--text-default, inherit));
25
+ background: var(--table-bg, var(--surface-default, Canvas));
26
+ border: var(--table-border-width, 1px) solid
27
+ var(--table-border-color, var(--outline-subtle, currentColor));
28
+ border-radius: var(--table-radius, var(--radius-md, 0.5rem));
29
+ font-size: var(--table-font-size, var(--font-size-sm, 0.875rem));
30
+ }
31
+
32
+ :is(table[data-table], table.data-table, data-table > table) caption {
33
+ padding-block-end: var(--table-caption-gap, var(--space-sm, 0.5rem));
34
+ color: var(--table-caption-color, var(--text-subtle, currentColor));
35
+ font-weight: var(--font-weight-medium, 500);
36
+ text-align: start;
37
+ }
38
+
39
+ :is(table[data-table], table.data-table, data-table > table) :is(th, td) {
40
+ padding: var(--table-cell-padding-block, var(--space-sm, 0.5rem))
41
+ var(--table-cell-padding-inline, var(--space-md, 1rem));
42
+ border-block-end: 1px solid
43
+ var(--table-divider-color, var(--outline-subtle, currentColor));
44
+ text-align: start;
45
+ vertical-align: middle;
46
+ }
47
+
48
+ :is(table[data-table], table.data-table, data-table > table) th {
49
+ color: var(--table-heading-color, var(--text-overt, inherit));
50
+ background: var(--table-heading-bg, var(--surface-subtle, transparent));
51
+ font-weight: var(--font-weight-semibold, 600);
52
+ }
53
+
54
+ :is(table[data-table], table.data-table, data-table > table) tbody tr:last-child > * {
55
+ border-block-end: 0;
56
+ }
57
+
58
+ :is(table[data-table], table.data-table, data-table > table, .table-striped)
59
+ tbody tr:nth-child(even) {
60
+ background: var(--table-stripe-bg, var(--surface-muted, transparent));
61
+ }
62
+
63
+ :is(table[data-table], table.data-table, data-table > table, .table-hover)
64
+ tbody tr:hover {
65
+ background: var(--table-row-hover-bg, var(--surface-subtle, transparent));
66
+ }
67
+
68
+ :is(table[data-table], table.data-table, data-table > table) :is(a, button):focus-visible {
69
+ outline: var(--focus-ring-width, 2px) solid
70
+ var(--focus-ring-color, Highlight);
71
+ outline-offset: var(--focus-ring-offset, 2px);
72
+ }
73
+
74
+ .table-bordered {
75
+ --table-border-width: var(--border-width-thick, 2px);
76
+ }
77
+
78
+ .table-borderless {
79
+ --table-border-width: 0;
80
+ --table-divider-color: transparent;
81
+ }
82
+
83
+ @media (max-width: 40rem) {
84
+ :is(table[data-table], table.data-table):not(
85
+ :is(data-table, [data-table-scroll], .table-scroll) > table
86
+ ) {
87
+ display: block;
88
+ max-width: 100%;
89
+ overflow-x: auto;
90
+ overscroll-behavior-inline: contain;
91
+ }
92
+
93
+ :is(data-table, [data-table-scroll], .table-scroll)
94
+ > :is(table[data-table], table.data-table) {
95
+ display: table;
96
+ overflow: visible;
97
+ }
98
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * tabs.css
3
+ *
4
+ * ARIA-first tab styling. JavaScript owns selection, focus movement, and panel
5
+ * visibility; CSS uses the semantic roles and state attributes as its contract.
6
+ */
7
+
8
+ :is([role="tablist"], [data-tablist], .tablist) {
9
+ --_tabs-gap: var(--tabs-gap, 0.25rem);
10
+ --_tabs-border: var(--tabs-border-color, var(--outline-subtle));
11
+ --_tabs-bg: var(--tabs-background, transparent);
12
+
13
+ display: flex;
14
+ align-items: end;
15
+ gap: var(--_tabs-gap);
16
+ padding-inline: var(--tabs-padding-inline, 0);
17
+ padding-block: var(--tabs-padding-block, 0);
18
+ overflow-x: auto;
19
+ border-block-end: 1px solid var(--_tabs-border);
20
+ background: var(--_tabs-bg);
21
+ scrollbar-width: thin;
22
+ }
23
+
24
+ :is([role="tab"], [data-tab], .tab) {
25
+ position: relative;
26
+ flex: 0 0 auto;
27
+ margin: 0 0 -1px;
28
+ padding: var(--tabs-tab-padding, 0.65rem 1rem);
29
+ border: 0;
30
+ border-block-end: var(--tabs-indicator-width, 2px) solid transparent;
31
+ border-radius: var(--tabs-tab-radius, var(--radius-sm, 0.375rem)) var(--tabs-tab-radius, var(--radius-sm, 0.375rem)) 0 0;
32
+ background: var(--tabs-tab-background, transparent);
33
+ color: var(--tabs-tab-color, var(--text-subtle));
34
+ font: inherit;
35
+ font-weight: var(--font-weight-medium, 500);
36
+ white-space: nowrap;
37
+ cursor: pointer;
38
+ transition: color 150ms ease-out, background-color 150ms ease-out, border-color 150ms ease-out;
39
+ }
40
+
41
+ :is([role="tab"], [data-tab], .tab):hover:not(:disabled, [aria-disabled="true"]) {
42
+ background: var(--tabs-tab-hover-background, var(--highlight-bg-subtle));
43
+ color: var(--tabs-tab-hover-color, var(--text-overt));
44
+ }
45
+
46
+ :is([role="tab"], [data-tab], .tab)[aria-selected="true"] {
47
+ border-block-end-color: var(--tabs-tab-active-border, var(--accent));
48
+ background: var(--tabs-tab-active-background, transparent);
49
+ color: var(--tabs-tab-active-color, var(--text-overt));
50
+ font-weight: var(--font-weight-semibold, 600);
51
+ }
52
+
53
+ :is([role="tab"], [data-tab], .tab):focus-visible {
54
+ z-index: 1;
55
+ outline: var(--focus-ring-width, 2px) solid var(--focus-ring-color, var(--outline-focus));
56
+ outline-offset: calc(-1 * var(--focus-ring-width, 2px));
57
+ }
58
+
59
+ :is([role="tab"], [data-tab], .tab):is(:disabled, [aria-disabled="true"]) {
60
+ opacity: var(--tabs-tab-disabled-opacity, 0.5);
61
+ cursor: not-allowed;
62
+ }
63
+
64
+ :is([role="tabpanel"], [data-tabpanel], .tabpanel) {
65
+ padding: var(--tabs-panel-padding, 1rem);
66
+ border: var(--tabs-panel-border, 1px solid var(--outline-subtle));
67
+ border-block-start: 0;
68
+ border-radius: 0 0 var(--tabs-panel-radius, var(--radius-md, 0.5rem)) var(--tabs-panel-radius, var(--radius-md, 0.5rem));
69
+ background: var(--tabs-panel-background, var(--surface-default));
70
+ color: var(--tabs-panel-color, inherit);
71
+ }
72
+
73
+ :is([role="tabpanel"], [data-tabpanel], .tabpanel)[hidden] {
74
+ display: none;
75
+ }
76
+
77
+ :is([role="tablist"], [data-tablist], .tablist)[aria-orientation="vertical"] {
78
+ flex-direction: column;
79
+ align-items: stretch;
80
+ overflow-x: visible;
81
+ border-block-end: 0;
82
+ border-inline-end: 1px solid var(--_tabs-border);
83
+ }
84
+
85
+ :is([role="tablist"], [data-tablist], .tablist)[aria-orientation="vertical"]
86
+ > :is([role="tab"], [data-tab], .tab) {
87
+ margin: 0 -1px 0 0;
88
+ border-block-end: 0;
89
+ border-inline-end: var(--tabs-indicator-width, 2px) solid transparent;
90
+ border-radius: var(--tabs-tab-radius, var(--radius-sm, 0.375rem)) 0 0 var(--tabs-tab-radius, var(--radius-sm, 0.375rem));
91
+ text-align: start;
92
+ }
93
+
94
+ :is([role="tablist"], [data-tablist], .tablist)[aria-orientation="vertical"]
95
+ > :is([role="tab"], [data-tab], .tab)[aria-selected="true"] {
96
+ border-inline-end-color: var(--tabs-tab-active-border, var(--accent));
97
+ }
98
+
99
+ @media (prefers-reduced-motion: reduce) {
100
+ :is([role="tab"], [data-tab], .tab) {
101
+ transition: none;
102
+ }
103
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * tooltip.css
3
+ *
4
+ * A small CSS-only text tooltip. The host wraps the trigger and reveals the
5
+ * generated bubble on pointer hover or keyboard focus.
6
+ */
7
+
8
+ :is(tooltip[content], [data-tooltip], .tooltip[data-tooltip]) {
9
+ position: relative;
10
+ display: inline-flex;
11
+ inline-size: fit-content;
12
+ }
13
+
14
+ :is(tooltip[content], [data-tooltip], .tooltip[data-tooltip])::after {
15
+ position: absolute;
16
+ z-index: var(--tooltip-z-index, 1000);
17
+ inline-size: max-content;
18
+ max-inline-size: min(var(--tooltip-max-width, 28ch), 80vw);
19
+ padding: var(--tooltip-padding, 0.4rem 0.6rem);
20
+ border: var(--tooltip-border-width, 1px) solid var(--tooltip-border-color, var(--outline-overt, currentColor));
21
+ border-radius: var(--tooltip-radius, var(--radius-sm, 0.25rem));
22
+ background: var(--tooltip-background, var(--bedrock, #1f2937));
23
+ color: var(--tooltip-color, var(--text-on-bedrock, Canvas));
24
+ box-shadow: var(--tooltip-shadow, var(--shadow-sm, none));
25
+ font-size: var(--tooltip-font-size, var(--font-size-sm, 0.875rem));
26
+ font-weight: var(--font-weight-normal, 400);
27
+ line-height: var(--line-height-snug, 1.3);
28
+ text-align: start;
29
+ white-space: normal;
30
+ pointer-events: none;
31
+ opacity: 0;
32
+ visibility: hidden;
33
+ transition: opacity 120ms ease-out, transform 120ms ease-out, visibility 0s linear 120ms;
34
+ }
35
+
36
+ tooltip[content]::after { content: attr(content); }
37
+ :is([data-tooltip], .tooltip[data-tooltip])::after { content: attr(data-tooltip); }
38
+
39
+ :is(tooltip[content], [data-tooltip], .tooltip[data-tooltip]):is(:hover, :focus-within)::after {
40
+ opacity: 1;
41
+ visibility: visible;
42
+ transition-delay: var(--tooltip-delay, 150ms), var(--tooltip-delay, 150ms), 0s;
43
+ }
44
+
45
+ :is(tooltip[content], [data-tooltip], .tooltip[data-tooltip]):is(:not([place]), [place="top"])::after {
46
+ inset-block-end: calc(100% + var(--tooltip-offset, 0.5rem));
47
+ inset-inline-start: 50%;
48
+ transform: translate(-50%, 0.25rem);
49
+ }
50
+
51
+ :is(tooltip[content], [data-tooltip], .tooltip[data-tooltip]):is(:not([place]), [place="top"]):is(:hover, :focus-within)::after {
52
+ transform: translate(-50%, 0);
53
+ }
54
+
55
+ :is(tooltip[content], [data-tooltip], .tooltip[data-tooltip])[place="bottom"]::after {
56
+ inset-block-start: calc(100% + var(--tooltip-offset, 0.5rem));
57
+ inset-inline-start: 50%;
58
+ transform: translate(-50%, -0.25rem);
59
+ }
60
+
61
+ :is(tooltip[content], [data-tooltip], .tooltip[data-tooltip])[place="bottom"]:is(:hover, :focus-within)::after {
62
+ transform: translate(-50%, 0);
63
+ }
64
+
65
+ :is(tooltip[content], [data-tooltip], .tooltip[data-tooltip])[place="right"]::after {
66
+ inset-block-start: 50%;
67
+ inset-inline-start: calc(100% + var(--tooltip-offset, 0.5rem));
68
+ transform: translate(-0.25rem, -50%);
69
+ }
70
+
71
+ :is(tooltip[content], [data-tooltip], .tooltip[data-tooltip])[place="right"]:is(:hover, :focus-within)::after {
72
+ transform: translate(0, -50%);
73
+ }
74
+
75
+ :is(tooltip[content], [data-tooltip], .tooltip[data-tooltip])[place="left"]::after {
76
+ inset-block-start: 50%;
77
+ inset-inline-end: calc(100% + var(--tooltip-offset, 0.5rem));
78
+ transform: translate(0.25rem, -50%);
79
+ }
80
+
81
+ :is(tooltip[content], [data-tooltip], .tooltip[data-tooltip])[place="left"]:is(:hover, :focus-within)::after {
82
+ transform: translate(0, -50%);
83
+ }
84
+
85
+ @media (prefers-reduced-motion: reduce) {
86
+ :is(tooltip[content], [data-tooltip], .tooltip[data-tooltip])::after { transition: none; }
87
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * tooltips.css
3
+ *
4
+ * Structured tooltips with a stable absolute-positioning baseline. Anchor
5
+ * positioning can enhance this later without being required for correctness.
6
+ */
7
+
8
+ :where([data-tooltip-host], .tooltip-host, :has(> :is(tooltip:not([content]), [data-rich-tooltip], .rich-tooltip))) {
9
+ position: relative;
10
+ }
11
+
12
+ :is(tooltip:not([content]), [data-rich-tooltip], .rich-tooltip) {
13
+ position: absolute;
14
+ z-index: var(--tooltip-z-index, 1000);
15
+ display: none;
16
+ inline-size: max-content;
17
+ max-inline-size: min(var(--tooltip-max-width, 32ch), 80vw);
18
+ padding: var(--tooltip-padding, 0.5rem 0.7rem);
19
+ border: var(--tooltip-border-width, 1px) solid var(--tooltip-border-color, var(--outline-overt, currentColor));
20
+ border-radius: var(--tooltip-radius, var(--radius-sm, 0.25rem));
21
+ background: var(--tooltip-background, var(--bedrock, #1f2937));
22
+ color: var(--tooltip-color, var(--text-on-bedrock, Canvas));
23
+ box-shadow: var(--tooltip-shadow, var(--shadow-sm, none));
24
+ font-size: var(--tooltip-font-size, var(--font-size-sm, 0.875rem));
25
+ font-weight: var(--font-weight-normal, 400);
26
+ line-height: var(--line-height-snug, 1.3);
27
+ text-align: start;
28
+ pointer-events: none;
29
+ opacity: 0;
30
+ visibility: hidden;
31
+ transition: opacity 120ms ease-out, transform 120ms ease-out, visibility 0s linear 120ms;
32
+ }
33
+
34
+ :where([data-tooltip-host], .tooltip-host, :has(> :is(tooltip:not([content]), [data-rich-tooltip], .rich-tooltip))):is(:hover, :focus-visible, :focus-within)
35
+ > :is(tooltip:not([content]), [data-rich-tooltip], .rich-tooltip) {
36
+ display: block;
37
+ opacity: 1;
38
+ visibility: visible;
39
+ transition-delay: var(--tooltip-delay, 150ms), var(--tooltip-delay, 150ms), 0s;
40
+ }
41
+
42
+ :is(tooltip:not([content]), [data-rich-tooltip], .rich-tooltip):is(:not([position], [data-position]), [position="top"], [data-position="top"], .tooltip-top) {
43
+ inset-block-end: calc(100% + var(--tooltip-offset, 0.5rem));
44
+ inset-inline-start: 50%;
45
+ transform: translate(-50%, 0.25rem);
46
+ }
47
+
48
+ :where([data-tooltip-host], .tooltip-host, :has(> :is(tooltip:not([content]), [data-rich-tooltip], .rich-tooltip))):is(:hover, :focus-visible, :focus-within)
49
+ > :is(tooltip:not([content]), [data-rich-tooltip], .rich-tooltip):is(:not([position], [data-position]), [position="top"], [data-position="top"], .tooltip-top) {
50
+ transform: translate(-50%, 0);
51
+ }
52
+
53
+ :is(tooltip:not([content]), [data-rich-tooltip], .rich-tooltip):is([position="bottom"], [data-position="bottom"], .tooltip-bottom) {
54
+ inset-block-start: calc(100% + var(--tooltip-offset, 0.5rem));
55
+ inset-inline-start: 50%;
56
+ transform: translate(-50%, -0.25rem);
57
+ }
58
+
59
+ :is(tooltip:not([content]), [data-rich-tooltip], .rich-tooltip):is([position="left"], [data-position="left"], .tooltip-left) {
60
+ inset-block-start: 50%;
61
+ inset-inline-end: calc(100% + var(--tooltip-offset, 0.5rem));
62
+ transform: translate(0.25rem, -50%);
63
+ }
64
+
65
+ :is(tooltip:not([content]), [data-rich-tooltip], .rich-tooltip):is([position="right"], [data-position="right"], .tooltip-right) {
66
+ inset-block-start: 50%;
67
+ inset-inline-start: calc(100% + var(--tooltip-offset, 0.5rem));
68
+ transform: translate(-0.25rem, -50%);
69
+ }
70
+
71
+ @media (prefers-reduced-motion: reduce) {
72
+ :is(tooltip:not([content]), [data-rich-tooltip], .rich-tooltip) { transition: none; }
73
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * View Transition defaults plus a progressively enhanced view router.
3
+ * Router host: view-transitions, view-transition, [data-view-transitions], .view-transitions
4
+ * Page host: view-page, [data-view-page], .view-page
5
+ */
6
+
7
+ ::view-transition-old(root),
8
+ ::view-transition-new(root) {
9
+ animation-duration: var(--view-transition-duration, 400ms);
10
+ animation-timing-function: var(--view-transition-easing, cubic-bezier(0.45, 0, 0.55, 1));
11
+ animation-fill-mode: both;
12
+ }
13
+
14
+ ::view-transition-old(root) {
15
+ animation-name: view-slide-to-left-fade-out;
16
+ }
17
+
18
+ ::view-transition-new(root) {
19
+ animation-name: view-slide-from-right-fade-in;
20
+ }
21
+
22
+ ::view-transition-group(hero-element) {
23
+ animation-timing-function: var(--view-transition-hero-easing, cubic-bezier(0.76, 0, 0.24, 1));
24
+ }
25
+
26
+ :is(view-transitions, view-transition, [data-view-transitions], .view-transitions) {
27
+ position: relative;
28
+ display: block;
29
+ }
30
+
31
+ :is(view-page, [data-view-page], .view-page) {
32
+ display: none;
33
+ }
34
+
35
+ :is(view-page, [data-view-page], .view-page)[active] {
36
+ display: block;
37
+ }
38
+
39
+ /* Before JavaScript initializes, hash targets provide view switching. */
40
+ :is(view-transitions, view-transition, [data-view-transitions], .view-transitions):not(
41
+ [data-view-transitions-initialized="true"]
42
+ ):has(
43
+ :is(view-page, [data-view-page], .view-page):target
44
+ ) :is(view-page, [data-view-page], .view-page):target {
45
+ display: block;
46
+ }
47
+
48
+ /* A hash target wins over the server-rendered initial page before enhancement. */
49
+ :is(view-transitions, view-transition, [data-view-transitions], .view-transitions):not(
50
+ [data-view-transitions-initialized="true"]
51
+ ):has(
52
+ :is(view-page, [data-view-page], .view-page):target
53
+ ) :is(view-page, [data-view-page], .view-page)[active]:not(:target) {
54
+ display: none;
55
+ }
56
+
57
+ @keyframes view-slide-to-left-fade-out {
58
+ from { opacity: 1; transform: translateX(0); }
59
+ to { opacity: 0; transform: translateX(-3rem); }
60
+ }
61
+
62
+ @keyframes view-slide-from-right-fade-in {
63
+ from { opacity: 0; transform: translateX(3rem); }
64
+ to { opacity: 1; transform: translateX(0); }
65
+ }
66
+
67
+ @media (prefers-reduced-motion: reduce) {
68
+ ::view-transition-old(root),
69
+ ::view-transition-new(root),
70
+ ::view-transition-group(hero-element) {
71
+ animation: none;
72
+ }
73
+ }
package/core/base.css ADDED
@@ -0,0 +1,62 @@
1
+ /**
2
+ * base.css
3
+ *
4
+ * Foundational Styles, Design Tokens, & Global State
5
+ * ------------------------------------------------------------------------------
6
+ * This module contains CSS resets, global design tokens (using typed custom
7
+ * properties), and a global state manager for responsive breakpoints.
8
+ *
9
+ * @feature {@property} - Defines typed CSS variables for type safety and animation.
10
+ * @feature {Style Queries} - The <body> is a style container, providing a global
11
+ * `--breakpoint-active` state that all components can react to.
12
+ * @feature {Modern Color} - Uses `oklch` for more perceptually uniform colors.
13
+ */
14
+
15
+ /* Universal box-sizing reset and modern reset for base elements. */
16
+ *, *::before, *::after { box-sizing: border-box; }
17
+ body, h1, h2, h3, h4, p { margin: 0; }
18
+
19
+ :root {
20
+ /*
21
+ * 1. Define typed design tokens.
22
+ * Using @property allows for animation and type-checking.
23
+ */
24
+ @property --theme-primary { syntax: '<color>'; inherits: true; initial-value: oklch(55% 0.15 240); }
25
+ @property --theme-bg { syntax: '<color>'; inherits: true; initial-value: oklch(98% 0.01 240); }
26
+ @property --theme-text { syntax: '<color>'; inherits: true; initial-value: oklch(20% 0.02 240); }
27
+
28
+ /* 2. Define breakpoint thresholds as design tokens. */
29
+ --bp-sm: 640px;
30
+ --bp-md: 768px;
31
+ --bp-lg: 1024px;
32
+ --bp-xl: 1280px;
33
+
34
+ /* Announce support for light/dark color schemes to the browser. */
35
+ color-scheme: light dark;
36
+ }
37
+
38
+ :root[data-color-scheme="light"] { color-scheme: light; }
39
+ :root[data-color-scheme="dark"] { color-scheme: dark; }
40
+
41
+ body {
42
+ /*
43
+ * 3. Set up the global breakpoint state machine.
44
+ * Make the body a container for style queries and initialize the state.
45
+ */
46
+ container-type: style;
47
+ --breakpoint-active: xl; /* Default to the largest state */
48
+
49
+ /* Apply base theme colors */
50
+ background-color: var(--theme-bg);
51
+ color: var(--theme-text);
52
+ font-family: var(--font-family-body, system-ui, sans-serif);
53
+ line-height: var(--line-height-body, 1.6);
54
+ }
55
+
56
+
57
+ /*
58
+ * 4. Use media queries for ONE purpose: updating the global state variable.
59
+ */
60
+ @media (max-width: var(--bp-xl)) { body { --breakpoint-active: lg; } }
61
+ @media (max-width: var(--bp-lg)) { body { --breakpoint-active: md; } }
62
+ @media (max-width: var(--bp-md)) { body { --breakpoint-active: sm; } }