@med-o/ui 0.0.0-stage → 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 (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -2
  3. package/dist/index.d.ts +2021 -0
  4. package/dist/index.js +4721 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +78 -4
  7. package/src/accordion/accordion.css +184 -0
  8. package/src/alert/alert.css +147 -0
  9. package/src/avatar/avatar.css +221 -0
  10. package/src/badge/badge.css +153 -0
  11. package/src/bottom-sheet/bottom-sheet.css +202 -0
  12. package/src/breadcrumbs/breadcrumbs.css +147 -0
  13. package/src/bulk-action-bar/bulk-action-bar.css +98 -0
  14. package/src/button/button.css +319 -0
  15. package/src/card/card.css +217 -0
  16. package/src/checkbox/choice.css +196 -0
  17. package/src/combobox/combobox.css +125 -0
  18. package/src/date-time/date-time.css +474 -0
  19. package/src/dialog/dialog.css +319 -0
  20. package/src/drawer/drawer.css +156 -0
  21. package/src/empty-state/empty-state.css +161 -0
  22. package/src/field/field.css +115 -0
  23. package/src/link/link.css +103 -0
  24. package/src/list/list.css +172 -0
  25. package/src/list-view/list-view.css +473 -0
  26. package/src/listbox/listbox.css +203 -0
  27. package/src/media/media.css +298 -0
  28. package/src/menu/menu.css +183 -0
  29. package/src/navigation/navigation.css +626 -0
  30. package/src/pagination/pagination.css +132 -0
  31. package/src/popover/popover.css +166 -0
  32. package/src/progress/progress.css +225 -0
  33. package/src/search/search.css +309 -0
  34. package/src/select/select.css +229 -0
  35. package/src/slider/slider.css +212 -0
  36. package/src/styles.css +40 -0
  37. package/src/switch/switch.css +160 -0
  38. package/src/table/table.css +276 -0
  39. package/src/tabs/tabs.css +211 -0
  40. package/src/tag/tag.css +225 -0
  41. package/src/text-field/input.css +206 -0
  42. package/src/toast/toast.css +184 -0
  43. package/src/toggle-button/toggle-button.css +143 -0
  44. package/src/tooltip/tooltip.css +66 -0
  45. package/src/upload/upload.css +380 -0
  46. package/src/utils/utilities.css +14 -0
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Badge – med.o Design System
3
+ *
4
+ * Short, non-interactive status label. Plain CSS, works in every framework:
5
+ * <span class="medo-badge medo-badge--success medo-badge--md">
6
+ * <span class="medo-badge__dot" aria-hidden="true"></span>Active
7
+ * </span>
8
+ *
9
+ * Count (notifications): <span class="medo-badge-count medo-badge-count--danger medo-badge-count--md">3</span>
10
+ * Dot (unread, presence): <span class="medo-badge-dot medo-badge-dot--success"></span>
11
+ *
12
+ * Tones: neutral · brand · success · warning · danger · info
13
+ */
14
+
15
+ .medo-badge {
16
+ --_bg: var(--medo-color-surface-subtle);
17
+ --_fg: var(--medo-color-text-secondary);
18
+
19
+ box-sizing: border-box;
20
+ display: inline-flex;
21
+ align-items: center;
22
+ gap: var(--medo-space-1);
23
+ block-size: var(--medo-space-6);
24
+ padding-inline: var(--medo-space-2);
25
+ border-radius: var(--medo-radius-sm);
26
+ background-color: var(--_bg);
27
+ color: var(--_fg);
28
+ font: var(--medo-typography-label-sm);
29
+ white-space: nowrap;
30
+ vertical-align: middle;
31
+ }
32
+
33
+ .medo-badge--sm {
34
+ block-size: var(--medo-space-5);
35
+ padding-inline: var(--medo-space-1-5);
36
+ }
37
+
38
+ .medo-badge--brand {
39
+ --_bg: var(--medo-color-surface-brand-subtle);
40
+ --_fg: var(--medo-color-text-brand);
41
+ }
42
+ .medo-badge--success {
43
+ --_bg: var(--medo-color-feedback-success-surface);
44
+ --_fg: var(--medo-color-feedback-success-text);
45
+ }
46
+ .medo-badge--warning {
47
+ --_bg: var(--medo-color-feedback-warning-surface);
48
+ --_fg: var(--medo-color-feedback-warning-text);
49
+ }
50
+ .medo-badge--danger {
51
+ --_bg: var(--medo-color-feedback-danger-surface);
52
+ --_fg: var(--medo-color-feedback-danger-text);
53
+ }
54
+ .medo-badge--info {
55
+ --_bg: var(--medo-color-feedback-info-surface);
56
+ --_fg: var(--medo-color-feedback-info-text);
57
+ }
58
+
59
+ /* Leading dot (6 px) or icon (12 px) in the text colour – status not by colour alone. */
60
+ .medo-badge__dot {
61
+ flex-shrink: 0;
62
+ inline-size: var(--medo-space-1-5);
63
+ block-size: var(--medo-space-1-5);
64
+ border-radius: var(--medo-radius-full);
65
+ background-color: currentColor;
66
+ }
67
+
68
+ .medo-badge__icon {
69
+ display: inline-flex;
70
+ flex-shrink: 0;
71
+ }
72
+
73
+ .medo-badge__icon > svg {
74
+ inline-size: var(--medo-space-3);
75
+ block-size: var(--medo-space-3);
76
+ stroke-width: 3; /* 1.5 px at 12 px */
77
+ }
78
+
79
+ /* ---------- Count ---------- */
80
+
81
+ .medo-badge-count {
82
+ --_bg: var(--medo-color-feedback-danger-solid);
83
+ --_fg: var(--medo-color-feedback-danger-on-solid);
84
+
85
+ box-sizing: border-box;
86
+ display: inline-flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ min-inline-size: var(--medo-space-5);
90
+ block-size: var(--medo-space-5);
91
+ padding-inline: var(--medo-space-1);
92
+ border-radius: var(--medo-radius-full);
93
+ background-color: var(--_bg);
94
+ color: var(--_fg);
95
+ font: var(--medo-typography-label-sm);
96
+ font-variant-numeric: tabular-nums;
97
+ white-space: nowrap;
98
+ }
99
+
100
+ .medo-badge-count--sm {
101
+ min-inline-size: var(--medo-space-4);
102
+ block-size: var(--medo-space-4);
103
+ font: var(--medo-typography-label-xs);
104
+ }
105
+
106
+ .medo-badge-count--brand {
107
+ --_bg: var(--medo-color-action-primary);
108
+ --_fg: var(--medo-color-text-on-action);
109
+ }
110
+ .medo-badge-count--neutral {
111
+ --_bg: var(--medo-color-surface-inverse);
112
+ --_fg: var(--medo-color-text-inverse);
113
+ }
114
+
115
+ /* ---------- Dot ---------- */
116
+
117
+ .medo-badge-dot {
118
+ display: inline-block;
119
+ flex-shrink: 0;
120
+ inline-size: var(--medo-space-2);
121
+ block-size: var(--medo-space-2);
122
+ border-radius: var(--medo-radius-full);
123
+ background-color: var(--medo-color-text-secondary);
124
+ }
125
+
126
+ .medo-badge-dot--brand {
127
+ background-color: var(--medo-color-action-primary);
128
+ }
129
+ .medo-badge-dot--success {
130
+ background-color: var(--medo-color-feedback-success-solid);
131
+ }
132
+ .medo-badge-dot--warning {
133
+ background-color: var(--medo-color-feedback-warning-solid);
134
+ }
135
+ .medo-badge-dot--danger {
136
+ background-color: var(--medo-color-feedback-danger-solid);
137
+ }
138
+ .medo-badge-dot--info {
139
+ background-color: var(--medo-color-feedback-info-solid);
140
+ }
141
+
142
+ /* Windows high contrast mode removes backgrounds: keep the shapes visible. */
143
+ @media (forced-colors: active) {
144
+ .medo-badge,
145
+ .medo-badge-count {
146
+ border: var(--medo-border-width-thin) solid CanvasText;
147
+ }
148
+ .medo-badge__dot,
149
+ .medo-badge-dot {
150
+ forced-color-adjust: none;
151
+ background-color: CanvasText;
152
+ }
153
+ }
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Bottom Sheet – med.o Design System
3
+ *
4
+ * Modal layer from the bottom on small screens.
5
+ * <div class="medo-sheet-overlay"> scrim, overlay/scrim
6
+ * <div class="medo-sheet [medo-sheet--full]"> surface/raised, top radius/xl, elevation/4
7
+ * <section class="medo-sheet__dialog" role="dialog">
8
+ * <div class="medo-sheet__grab"> handle (decorative) + header: title and close button </div>
9
+ * <div class="medo-sheet__content">…scrolls…</div>
10
+ * <div class="medo-sheet__footer">…sticky, safe area…</div>
11
+ * </section>
12
+ * </div>
13
+ * </div>
14
+ * Height = content, max 90dvh (full: fixed 90dvh, e.g. with search). In: smooth spring; out: 250 ms ease-in; reduced motion: fade.
15
+ * State contract: [data-entering] [data-exiting] on overlay and sheet (React Aria).
16
+ */
17
+
18
+ .medo-sheet-overlay {
19
+ position: fixed;
20
+ inset: 0;
21
+ z-index: var(--medo-layer-modal);
22
+ display: flex;
23
+ align-items: flex-end;
24
+ background-color: var(--medo-color-overlay-scrim);
25
+ }
26
+
27
+ .medo-sheet-overlay {
28
+ transition: opacity var(--medo-motion-duration-normal) var(--medo-motion-easing-enter);
29
+ }
30
+ .medo-sheet-overlay[data-entering] {
31
+ opacity: 0;
32
+ }
33
+ .medo-sheet-overlay[data-exiting] {
34
+ opacity: 0;
35
+ transition: opacity var(--medo-motion-duration-normal) var(--medo-motion-easing-exit);
36
+ }
37
+
38
+ .medo-sheet {
39
+ box-sizing: border-box;
40
+ display: flex;
41
+ flex-direction: column;
42
+ inline-size: 100%;
43
+ max-block-size: 90dvh;
44
+ border-start-start-radius: var(--medo-radius-xl);
45
+ border-start-end-radius: var(--medo-radius-xl);
46
+ background-color: var(--medo-color-surface-raised);
47
+ box-shadow: var(--medo-shadow-elevation-4);
48
+ color: var(--medo-color-text-primary);
49
+ outline: none;
50
+ touch-action: pan-y;
51
+ /* Slides with a smooth spring (iOS sheet) – also back when a swipe is too short. */
52
+ transition: transform var(--medo-motion-spring-smooth-duration) var(--medo-motion-spring-smooth);
53
+ }
54
+
55
+ /* With search: fixed height, so the sheet does not jump while typing or when the keyboard opens. */
56
+ .medo-sheet--full {
57
+ block-size: 90dvh;
58
+ }
59
+
60
+ .medo-sheet[data-entering],
61
+ .medo-sheet-overlay[data-entering] .medo-sheet {
62
+ transform: translateY(100%);
63
+ }
64
+ .medo-sheet[data-exiting],
65
+ .medo-sheet-overlay[data-exiting] .medo-sheet {
66
+ transform: translateY(100%);
67
+ transition: transform var(--medo-motion-duration-normal) var(--medo-motion-easing-exit);
68
+ }
69
+
70
+ /*
71
+ * Select sheet (popover): React Aria positions popovers with inline styles next to the trigger.
72
+ * The sheet covers the viewport instead – !important is the only way to beat inline styles.
73
+ */
74
+ .medo-sheet-overlay--popover {
75
+ position: fixed !important;
76
+ inset: 0 !important;
77
+ inline-size: auto !important;
78
+ block-size: auto !important;
79
+ max-block-size: none !important;
80
+ max-inline-size: none !important;
81
+ }
82
+
83
+ /* Select sheet (popover): the scrim fills the popover, the sheet sits at the bottom. */
84
+ .medo-sheet-scrim {
85
+ display: flex;
86
+ flex: 1;
87
+ align-items: flex-end;
88
+ block-size: 100%;
89
+ }
90
+
91
+ /* While dragging: follow the finger, no transition. */
92
+ .medo-sheet[data-dragging] {
93
+ transition: none;
94
+ }
95
+
96
+ .medo-sheet__dialog {
97
+ display: flex;
98
+ flex: 1;
99
+ flex-direction: column;
100
+ min-block-size: 0;
101
+ outline: none;
102
+ }
103
+
104
+ /* Handle + header: the area that can be swiped down. */
105
+ .medo-sheet__grab {
106
+ flex: none;
107
+ touch-action: none;
108
+ cursor: grab;
109
+ }
110
+
111
+ .medo-sheet__handle {
112
+ display: block;
113
+ inline-size: var(--medo-space-8);
114
+ block-size: var(--medo-space-1);
115
+ margin: var(--medo-space-2) auto var(--medo-space-1);
116
+ border-radius: var(--medo-radius-full);
117
+ background-color: var(--medo-color-border-default);
118
+ }
119
+
120
+ .medo-sheet__header {
121
+ display: flex;
122
+ align-items: center;
123
+ justify-content: space-between;
124
+ gap: var(--medo-space-2);
125
+ padding-inline: var(--medo-space-4) var(--medo-space-2);
126
+ }
127
+
128
+ .medo-sheet__title {
129
+ flex: 1;
130
+ min-inline-size: 0;
131
+ margin: 0;
132
+ font: var(--medo-typography-heading-sm);
133
+ color: var(--medo-color-text-primary);
134
+ }
135
+
136
+ .medo-sheet__content {
137
+ flex: 1;
138
+ min-block-size: 0;
139
+ overflow: auto;
140
+ overscroll-behavior: contain;
141
+ }
142
+
143
+ /* Last block without footer: keep clear of the iPhone home indicator. */
144
+ .medo-sheet__content:last-child {
145
+ padding-block-end: env(safe-area-inset-bottom);
146
+ }
147
+
148
+ .medo-sheet__footer {
149
+ display: grid;
150
+ gap: var(--medo-space-2);
151
+ padding: var(--medo-space-4);
152
+ padding-block-end: calc(var(--medo-space-4) + env(safe-area-inset-bottom));
153
+ border-block-start: var(--medo-border-width-thin) solid var(--medo-color-border-default);
154
+ }
155
+
156
+ .medo-sheet__footer .medo-button {
157
+ inline-size: 100%;
158
+ }
159
+
160
+ .medo-sheet__count {
161
+ margin: 0;
162
+ font: var(--medo-typography-caption);
163
+ color: var(--medo-color-text-secondary);
164
+ }
165
+
166
+ /* With a back button the header starts closer to the edge. */
167
+ .medo-sheet__header:has(> .medo-button:first-child) {
168
+ padding-inline-start: var(--medo-space-1);
169
+ }
170
+
171
+ /* ---------- Select sheet ---------- */
172
+
173
+ .medo-sheet__search {
174
+ flex: none;
175
+ padding: var(--medo-space-2) var(--medo-space-4);
176
+ }
177
+
178
+ .medo-sheet .medo-listbox {
179
+ max-block-size: none;
180
+ padding-inline: var(--medo-space-1);
181
+ }
182
+
183
+ @media (forced-colors: active) {
184
+ .medo-sheet {
185
+ border: 1px solid CanvasText;
186
+ }
187
+ }
188
+
189
+ @media (prefers-reduced-motion: reduce) {
190
+ /* Reduced motion: the sheet fades with the scrim instead of sliding. */
191
+ .medo-sheet-overlay {
192
+ transition: opacity var(--medo-motion-duration-fast) var(--medo-motion-easing-standard);
193
+ }
194
+ .medo-sheet {
195
+ transition: opacity var(--medo-motion-duration-fast) var(--medo-motion-easing-standard);
196
+ }
197
+ .medo-sheet:is([data-entering], [data-exiting]),
198
+ .medo-sheet-overlay:is([data-entering], [data-exiting]) .medo-sheet {
199
+ transform: none;
200
+ opacity: 0;
201
+ }
202
+ }
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Breadcrumbs – med.o Design System
3
+ *
4
+ * <nav class="medo-breadcrumbs medo-breadcrumbs--md" aria-label="Breadcrumb">
5
+ * <ol class="medo-breadcrumbs__list">
6
+ * <li class="medo-breadcrumbs__item"><a class="medo-breadcrumbs__icon-part" aria-label="Home">⌂</a> ›</li>
7
+ * <li class="medo-breadcrumbs__item"><a class="medo-breadcrumbs__link"><span class="medo-breadcrumbs__label">Projects</span></a> ›</li>
8
+ * <li class="medo-breadcrumbs__item"><span class="medo-breadcrumbs__link medo-breadcrumbs__current" aria-current="page">…</span></li>
9
+ * </ol>
10
+ * </nav>
11
+ * sm: caption, current label/sm, height 24, icons 16, separator 12, gap 2 · md: body/sm, label/md, 28, 20, 16, gap 4.
12
+ * Parts: padding space/1, radius/sm, gap icon–text space/0-5. Labels max 200 px with „…“.
13
+ * State contract: [data-hovered] [data-pressed] [data-focus-visible] [data-current] (React Aria).
14
+ */
15
+
16
+ .medo-breadcrumbs {
17
+ --_height: var(--medo-space-6); /* sm 24 */
18
+ --_icon: var(--medo-size-icon-sm);
19
+ --_sep: var(--medo-space-3);
20
+ --_gap: var(--medo-space-0-5);
21
+ --_text: var(--medo-typography-caption);
22
+ --_current: var(--medo-typography-label-sm);
23
+ }
24
+
25
+ .medo-breadcrumbs--md {
26
+ --_height: calc(var(--medo-space-6) + var(--medo-space-1)); /* 28 */
27
+ --_icon: var(--medo-size-icon-md);
28
+ --_sep: var(--medo-space-4);
29
+ --_gap: var(--medo-space-1);
30
+ --_text: var(--medo-typography-body-sm);
31
+ --_current: var(--medo-typography-label-md);
32
+ }
33
+
34
+ .medo-breadcrumbs__list {
35
+ display: flex;
36
+ flex-wrap: wrap;
37
+ align-items: center;
38
+ gap: var(--_gap);
39
+ margin: 0;
40
+ padding: 0;
41
+ list-style: none;
42
+ }
43
+
44
+ .medo-breadcrumbs__item {
45
+ display: inline-flex;
46
+ align-items: center;
47
+ gap: var(--_gap);
48
+ min-inline-size: 0;
49
+ }
50
+
51
+ .medo-breadcrumbs__link,
52
+ .medo-breadcrumbs__icon-part {
53
+ box-sizing: border-box;
54
+ display: inline-flex;
55
+ align-items: center;
56
+ gap: var(--medo-space-0-5);
57
+ min-block-size: var(--_height);
58
+ padding: var(--medo-space-1);
59
+ border: 0;
60
+ border-radius: var(--medo-radius-sm);
61
+ background: none;
62
+ color: var(--medo-color-text-secondary);
63
+ font: var(--_text);
64
+ text-decoration: none;
65
+ outline: none;
66
+ -webkit-tap-highlight-color: transparent;
67
+ transition:
68
+ background-color var(--medo-motion-duration-fast) var(--medo-motion-easing-standard),
69
+ color var(--medo-motion-duration-fast) var(--medo-motion-easing-standard);
70
+ }
71
+
72
+ .medo-breadcrumbs__link[data-pressed] {
73
+ transition-duration: 0s;
74
+ }
75
+
76
+ .medo-breadcrumbs__link[data-hovered]:not([data-current]) {
77
+ color: var(--medo-color-text-primary);
78
+ text-decoration: underline;
79
+ text-underline-offset: 0.2em;
80
+ }
81
+
82
+ .medo-breadcrumbs__link[data-pressed] {
83
+ background-color: var(--medo-color-state-pressed);
84
+ color: var(--medo-color-text-primary);
85
+ }
86
+
87
+ .medo-breadcrumbs__current {
88
+ color: var(--medo-color-text-primary);
89
+ font: var(--_current);
90
+ cursor: default;
91
+ }
92
+
93
+ .medo-breadcrumbs__label {
94
+ overflow: hidden;
95
+ max-inline-size: 12.5rem; /* 200 */
96
+ text-overflow: ellipsis;
97
+ white-space: nowrap;
98
+ }
99
+
100
+ /* Home and „…“: square, a soft surface on hover so the target is visible. */
101
+ .medo-breadcrumbs__icon-part {
102
+ justify-content: center;
103
+ inline-size: var(--_height);
104
+ padding: 0;
105
+ cursor: pointer;
106
+ }
107
+
108
+ .medo-breadcrumbs__icon-part > svg {
109
+ inline-size: var(--_icon);
110
+ block-size: var(--_icon);
111
+ }
112
+
113
+ .medo-breadcrumbs__icon-part:is([data-hovered], [aria-expanded='true']) {
114
+ background-color: var(--medo-color-state-hover);
115
+ color: var(--medo-color-text-primary);
116
+ }
117
+
118
+ .medo-breadcrumbs__icon-part[data-pressed] {
119
+ background-color: var(--medo-color-state-pressed);
120
+ }
121
+
122
+ .medo-breadcrumbs__link[data-focus-visible],
123
+ .medo-breadcrumbs__icon-part[data-focus-visible] {
124
+ box-shadow: inset 0 0 0 var(--medo-focus-ring-width) var(--medo-color-focus-ring);
125
+ }
126
+
127
+ .medo-breadcrumbs__separator {
128
+ flex: none;
129
+ inline-size: var(--_sep);
130
+ block-size: var(--_sep);
131
+ color: var(--medo-color-text-secondary);
132
+ }
133
+
134
+ /* Mobile: one link to the parent page. */
135
+ .medo-breadcrumbs__back-icon {
136
+ flex: none;
137
+ inline-size: var(--_icon);
138
+ block-size: var(--_icon);
139
+ }
140
+
141
+ @media (forced-colors: active) {
142
+ .medo-breadcrumbs__link[data-focus-visible],
143
+ .medo-breadcrumbs__icon-part[data-focus-visible] {
144
+ outline: 2px solid Highlight;
145
+ outline-offset: -2px;
146
+ }
147
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Bulk action bar – med.o Design System
3
+ *
4
+ * <div class="medo-bulk-bar medo-bulk-bar--desktop" role="toolbar" aria-label="Bulk actions">
5
+ * <span class="medo-bulk-bar__count">3 selected</span> | <button class="medo-toast__button medo-toast__action">Export</button> … | ×
6
+ * </div>
7
+ * Desktop: floating, bottom centre, 24 px above the viewport edge · surface/inverse · radius/lg · elevation/3 ·
8
+ * padding 8 8 8 16 · gap 8 · buttons = _Toast button (32).
9
+ * Mobile: full width at the bottom · surface/raised + top border · Button ghost lg · Icon Button ghost lg · safe area.
10
+ * In: slides up with spring/smooth (a fade with reduced motion).
11
+ */
12
+
13
+ .medo-bulk-bar-host {
14
+ display: contents;
15
+ }
16
+
17
+ .medo-bulk-bar {
18
+ position: fixed;
19
+ z-index: var(--medo-layer-toast);
20
+ box-sizing: border-box;
21
+ display: flex;
22
+ align-items: center;
23
+ /* Slides up with a smooth spring when the first item is selected. */
24
+ transition:
25
+ opacity var(--medo-motion-duration-normal) var(--medo-motion-easing-enter),
26
+ translate var(--medo-motion-spring-smooth-duration) var(--medo-motion-spring-smooth);
27
+ }
28
+ @starting-style {
29
+ .medo-bulk-bar {
30
+ opacity: 0;
31
+ translate: 0 var(--medo-space-4);
32
+ }
33
+ }
34
+
35
+ .medo-bulk-bar--desktop {
36
+ inset-block-end: var(--medo-space-6);
37
+ inset-inline: 0;
38
+ inline-size: fit-content;
39
+ max-inline-size: calc(100vw - 2 * var(--medo-space-4));
40
+ margin-inline: auto;
41
+ gap: var(--medo-space-2);
42
+ padding: var(--medo-space-2) var(--medo-space-2) var(--medo-space-2) var(--medo-space-4);
43
+ border-radius: var(--medo-radius-lg);
44
+ background-color: var(--medo-color-surface-inverse);
45
+ box-shadow: var(--medo-shadow-elevation-3);
46
+ color: var(--medo-color-text-inverse);
47
+ }
48
+
49
+ .medo-bulk-bar__count {
50
+ font: var(--medo-typography-label-md-strong);
51
+ font-variant-numeric: tabular-nums;
52
+ white-space: nowrap;
53
+ }
54
+
55
+ .medo-bulk-bar__divider {
56
+ flex: none;
57
+ inline-size: var(--medo-border-width-thin);
58
+ block-size: var(--medo-space-5);
59
+ background-color: var(--medo-color-text-inverse-secondary);
60
+ opacity: var(--medo-opacity-40);
61
+ }
62
+
63
+ .medo-bulk-bar--mobile {
64
+ inset-inline: 0;
65
+ inset-block-end: 0;
66
+ justify-content: space-between;
67
+ gap: var(--medo-space-1);
68
+ padding: var(--medo-space-2) var(--medo-space-2) max(var(--medo-space-2), env(safe-area-inset-bottom));
69
+ border-block-start: var(--medo-border-width-thin) solid var(--medo-color-border-default);
70
+ background-color: var(--medo-color-surface-raised);
71
+ box-shadow: var(--medo-shadow-elevation-3);
72
+ color: var(--medo-color-text-primary);
73
+ }
74
+
75
+ .medo-bulk-bar__start,
76
+ .medo-bulk-bar__actions {
77
+ display: flex;
78
+ align-items: center;
79
+ gap: var(--medo-space-1);
80
+ min-inline-size: 0;
81
+ }
82
+
83
+ @media (prefers-reduced-motion: reduce) {
84
+ .medo-bulk-bar {
85
+ transition: opacity var(--medo-motion-duration-fast) var(--medo-motion-easing-standard);
86
+ }
87
+ @starting-style {
88
+ .medo-bulk-bar {
89
+ translate: none;
90
+ }
91
+ }
92
+ }
93
+
94
+ @media (forced-colors: active) {
95
+ .medo-bulk-bar {
96
+ border: 1px solid CanvasText;
97
+ }
98
+ }