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.
- package/LICENSE +21 -0
- package/README.md +875 -0
- package/carousel.js +86 -0
- package/components/accessibility.css +51 -0
- package/components/actions.css +76 -0
- package/components/alert.css +122 -0
- package/components/application-patterns.css +122 -0
- package/components/badge.css +125 -0
- package/components/box-extra.css +220 -0
- package/components/box.css +75 -0
- package/components/card.css +130 -0
- package/components/carousel.css +76 -0
- package/components/chip.css +71 -0
- package/components/container.css +55 -0
- package/components/content-patterns.css +234 -0
- package/components/disclosure.css +581 -0
- package/components/divider.css +68 -0
- package/components/flex.css +59 -0
- package/components/form-patterns.css +273 -0
- package/components/form.css +130 -0
- package/components/grid.css +82 -0
- package/components/identity.css +59 -0
- package/components/img-container.css +141 -0
- package/components/img-container.js +75 -0
- package/components/list.css +69 -0
- package/components/loading.css +112 -0
- package/components/masonry.css +48 -0
- package/components/modal.css +73 -0
- package/components/navigation-patterns.css +245 -0
- package/components/navigation.css +200 -0
- package/components/popover.css +49 -0
- package/components/site-shell.css +180 -0
- package/components/status.css +110 -0
- package/components/table.css +98 -0
- package/components/tabs.css +103 -0
- package/components/tooltip.css +87 -0
- package/components/tooltips.css +73 -0
- package/components/view-transition.css +73 -0
- package/core/base.css +62 -0
- package/core/defaults.css +490 -0
- package/core/engine.css +32 -0
- package/core/mixins.css +376 -0
- package/core/palette-accent.css +8 -0
- package/core/palette-base.css +107 -0
- package/core/palette-extended.css +142 -0
- package/core/palette-feedback.css +62 -0
- package/core/palette.css +7 -0
- package/core/reset.css +270 -0
- package/core/text.css +171 -0
- package/core/theme.css +608 -0
- package/core/tokens.css +488 -0
- package/core/typography.css +327 -0
- package/index.css +66 -0
- package/layouts/layout-extra.css +204 -0
- package/layouts/layout-extras-helpers.css +19 -0
- package/layouts/layout.css +348 -0
- package/package.json +66 -0
- package/theme-generator.css +979 -0
- package/themes/example-brand.css +59 -0
- package/themes/theme-packs.css +31 -0
- package/types/css-tags.d.ts +482 -0
- package/utilities/utilities.css +564 -0
- 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; } }
|