@slotted/styles 0.0.0-stage → 0.1.0-beta.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 (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -2
  3. package/package.json +276 -3
  4. package/src/accordion/accordion.css +96 -0
  5. package/src/accordion/accordion.tokens.json +14 -0
  6. package/src/action-bar/action-bar.css +455 -0
  7. package/src/action-bar/action-bar.tokens.json +50 -0
  8. package/src/action-sheet/action-sheet.css +462 -0
  9. package/src/action-sheet/action-sheet.tokens.json +59 -0
  10. package/src/alert/alert.css +764 -0
  11. package/src/alert/alert.tokens.json +77 -0
  12. package/src/app-shell/app-shell.css +1899 -0
  13. package/src/app-shell/app-shell.tokens.json +88 -0
  14. package/src/aspect-ratio/aspect-ratio.css +131 -0
  15. package/src/aspect-ratio/aspect-ratio.tokens.json +1 -0
  16. package/src/attachment/attachment.css +906 -0
  17. package/src/attachment/attachment.tokens.json +85 -0
  18. package/src/avatar/avatar.css +598 -0
  19. package/src/avatar/avatar.tokens.json +64 -0
  20. package/src/avatar-group/avatar-group.css +268 -0
  21. package/src/avatar-group/avatar-group.tokens.json +16 -0
  22. package/src/badge/badge.css +462 -0
  23. package/src/badge/badge.tokens.json +58 -0
  24. package/src/breadcrumb/breadcrumb.css +441 -0
  25. package/src/breadcrumb/breadcrumb.tokens.json +50 -0
  26. package/src/button/button.css +754 -0
  27. package/src/button/button.tokens.json +72 -0
  28. package/src/button-group/button-group.css +455 -0
  29. package/src/button-group/button-group.tokens.json +11 -0
  30. package/src/calendar/calendar.css +846 -0
  31. package/src/calendar/calendar.tokens.json +67 -0
  32. package/src/card/card.css +602 -0
  33. package/src/card/card.tokens.json +68 -0
  34. package/src/carousel/carousel.css +860 -0
  35. package/src/carousel/carousel.tokens.json +62 -0
  36. package/src/cascader/cascader.css +1320 -0
  37. package/src/cascader/cascader.tokens.json +103 -0
  38. package/src/chart/chart.css +1473 -0
  39. package/src/chart/chart.tokens.json +107 -0
  40. package/src/checkbox/checkbox.css +1011 -0
  41. package/src/checkbox/checkbox.tokens.json +102 -0
  42. package/src/checkbox-group/checkbox-group.css +70 -0
  43. package/src/checkbox-group/checkbox-group.tokens.json +6 -0
  44. package/src/code-block/code-block.css +555 -0
  45. package/src/code-block/code-block.tokens.json +69 -0
  46. package/src/collapsible/collapsible.css +546 -0
  47. package/src/collapsible/collapsible.tokens.json +55 -0
  48. package/src/color-picker/color-picker.css +607 -0
  49. package/src/color-picker/color-picker.tokens.json +58 -0
  50. package/src/column-manager/column-manager.css +452 -0
  51. package/src/column-manager/column-manager.tokens.json +43 -0
  52. package/src/combobox/combobox.css +1048 -0
  53. package/src/combobox/combobox.tokens.json +112 -0
  54. package/src/command-palette/command-palette.css +1000 -0
  55. package/src/command-palette/command-palette.tokens.json +75 -0
  56. package/src/container/container.css +198 -0
  57. package/src/container/container.tokens.json +18 -0
  58. package/src/context-menu/context-menu.css +104 -0
  59. package/src/context-menu/context-menu.tokens.json +11 -0
  60. package/src/currency-field/currency-field.css +787 -0
  61. package/src/currency-field/currency-field.tokens.json +80 -0
  62. package/src/dashboard-grid/dashboard-grid.css +748 -0
  63. package/src/dashboard-grid/dashboard-grid.tokens.json +67 -0
  64. package/src/data-grid/data-grid.css +2484 -0
  65. package/src/data-grid/data-grid.tokens.json +100 -0
  66. package/src/data-list/data-list.css +455 -0
  67. package/src/data-list/data-list.tokens.json +35 -0
  68. package/src/date-field/date-field.css +560 -0
  69. package/src/date-field/date-field.tokens.json +80 -0
  70. package/src/date-picker/date-picker.css +420 -0
  71. package/src/date-picker/date-picker.tokens.json +49 -0
  72. package/src/date-range-picker/date-range-picker.css +983 -0
  73. package/src/date-range-picker/date-range-picker.tokens.json +109 -0
  74. package/src/datetime-field/datetime-field.css +850 -0
  75. package/src/datetime-field/datetime-field.tokens.json +91 -0
  76. package/src/datetime-picker/datetime-picker.css +843 -0
  77. package/src/datetime-picker/datetime-picker.tokens.json +78 -0
  78. package/src/datetime-range-picker/datetime-range-picker.css +1375 -0
  79. package/src/datetime-range-picker/datetime-range-picker.tokens.json +135 -0
  80. package/src/description-list/description-list.css +675 -0
  81. package/src/description-list/description-list.tokens.json +66 -0
  82. package/src/detail-panel/detail-panel.css +329 -0
  83. package/src/detail-panel/detail-panel.tokens.json +33 -0
  84. package/src/dialog/dialog.css +968 -0
  85. package/src/dialog/dialog.tokens.json +66 -0
  86. package/src/divider/divider.css +131 -0
  87. package/src/divider/divider.tokens.json +18 -0
  88. package/src/drawer/drawer.css +1303 -0
  89. package/src/drawer/drawer.tokens.json +75 -0
  90. package/src/entity-picker/entity-picker.css +1367 -0
  91. package/src/entity-picker/entity-picker.tokens.json +118 -0
  92. package/src/event-calendar/event-calendar.css +2148 -0
  93. package/src/event-calendar/event-calendar.tokens.json +87 -0
  94. package/src/field/field.css +707 -0
  95. package/src/field/field.tokens.json +58 -0
  96. package/src/field-group/field-group.css +226 -0
  97. package/src/field-group/field-group.tokens.json +33 -0
  98. package/src/filter-bar/filter-bar.css +1306 -0
  99. package/src/filter-bar/filter-bar.tokens.json +78 -0
  100. package/src/form/form.css +218 -0
  101. package/src/form/form.tokens.json +32 -0
  102. package/src/fullscreen/fullscreen.css +376 -0
  103. package/src/fullscreen/fullscreen.tokens.json +50 -0
  104. package/src/grid/grid.css +173 -0
  105. package/src/grid/grid.tokens.json +20 -0
  106. package/src/highlight/highlight.css +135 -0
  107. package/src/highlight/highlight.tokens.json +16 -0
  108. package/src/hover-card/hover-card.css +93 -0
  109. package/src/hover-card/hover-card.tokens.json +17 -0
  110. package/src/icon/icon.css +136 -0
  111. package/src/icon/icon.tokens.json +14 -0
  112. package/src/image/image.css +449 -0
  113. package/src/image/image.tokens.json +27 -0
  114. package/src/import-export-center/import-export-center.css +1175 -0
  115. package/src/import-export-center/import-export-center.tokens.json +84 -0
  116. package/src/inline/inline.css +149 -0
  117. package/src/inline/inline.tokens.json +14 -0
  118. package/src/inline-message/inline-message.css +396 -0
  119. package/src/inline-message/inline-message.tokens.json +19 -0
  120. package/src/kbd/kbd.css +490 -0
  121. package/src/kbd/kbd.tokens.json +40 -0
  122. package/src/link/link.css +237 -0
  123. package/src/link/link.tokens.json +25 -0
  124. package/src/list/list.css +240 -0
  125. package/src/list/list.tokens.json +42 -0
  126. package/src/list-item/list-item.css +937 -0
  127. package/src/list-item/list-item.tokens.json +114 -0
  128. package/src/listbox/listbox.css +674 -0
  129. package/src/listbox/listbox.tokens.json +72 -0
  130. package/src/loading-overlay/loading-overlay.css +730 -0
  131. package/src/loading-overlay/loading-overlay.tokens.json +48 -0
  132. package/src/markdown/markdown.css +168 -0
  133. package/src/markdown/markdown.tokens.json +18 -0
  134. package/src/menu/menu.css +817 -0
  135. package/src/menu/menu.tokens.json +78 -0
  136. package/src/menubar/menubar.css +170 -0
  137. package/src/menubar/menubar.tokens.json +32 -0
  138. package/src/message/message.css +1453 -0
  139. package/src/message/message.tokens.json +85 -0
  140. package/src/message-scroller/message-scroller.css +371 -0
  141. package/src/message-scroller/message-scroller.tokens.json +47 -0
  142. package/src/multi-select/multi-select.css +1427 -0
  143. package/src/multi-select/multi-select.tokens.json +114 -0
  144. package/src/navigation-menu/navigation-menu.css +1029 -0
  145. package/src/navigation-menu/navigation-menu.tokens.json +70 -0
  146. package/src/notification-center/notification-center.css +856 -0
  147. package/src/notification-center/notification-center.tokens.json +84 -0
  148. package/src/number-field/number-field.css +794 -0
  149. package/src/number-field/number-field.tokens.json +80 -0
  150. package/src/otp-input/otp-input.css +525 -0
  151. package/src/otp-input/otp-input.tokens.json +69 -0
  152. package/src/page/page.css +179 -0
  153. package/src/page/page.tokens.json +20 -0
  154. package/src/page-header/page-header.css +1181 -0
  155. package/src/page-header/page-header.tokens.json +71 -0
  156. package/src/pagination/pagination.css +500 -0
  157. package/src/pagination/pagination.tokens.json +56 -0
  158. package/src/popover/popover.css +526 -0
  159. package/src/popover/popover.tokens.json +60 -0
  160. package/src/progress-indicator/progress-indicator.css +1584 -0
  161. package/src/progress-indicator/progress-indicator.tokens.json +50 -0
  162. package/src/prompt-composer/prompt-composer.css +680 -0
  163. package/src/prompt-composer/prompt-composer.tokens.json +99 -0
  164. package/src/prose/prose.css +733 -0
  165. package/src/prose/prose.tokens.json +79 -0
  166. package/src/radio-group/radio-group.css +778 -0
  167. package/src/radio-group/radio-group.tokens.json +103 -0
  168. package/src/rating/rating.css +1071 -0
  169. package/src/rating/rating.tokens.json +88 -0
  170. package/src/result-state/result-state.css +980 -0
  171. package/src/result-state/result-state.tokens.json +63 -0
  172. package/src/runtime-properties.mjs +321 -0
  173. package/src/saved-views/saved-views.css +394 -0
  174. package/src/saved-views/saved-views.tokens.json +41 -0
  175. package/src/scroll-area/scroll-area.css +481 -0
  176. package/src/scroll-area/scroll-area.tokens.json +15 -0
  177. package/src/section/section.css +177 -0
  178. package/src/section/section.tokens.json +39 -0
  179. package/src/segmented-control/segmented-control.css +564 -0
  180. package/src/segmented-control/segmented-control.tokens.json +67 -0
  181. package/src/select/select.css +1593 -0
  182. package/src/select/select.tokens.json +110 -0
  183. package/src/side-navigation/side-navigation.css +1096 -0
  184. package/src/side-navigation/side-navigation.tokens.json +87 -0
  185. package/src/skeleton/skeleton.css +431 -0
  186. package/src/skeleton/skeleton.tokens.json +29 -0
  187. package/src/slider/slider.css +792 -0
  188. package/src/slider/slider.tokens.json +75 -0
  189. package/src/sparkline/sparkline.css +282 -0
  190. package/src/sparkline/sparkline.tokens.json +45 -0
  191. package/src/spinner/spinner.css +224 -0
  192. package/src/spinner/spinner.tokens.json +8 -0
  193. package/src/split-button/split-button.css +253 -0
  194. package/src/split-button/split-button.tokens.json +12 -0
  195. package/src/splitter/splitter.css +336 -0
  196. package/src/splitter/splitter.tokens.json +24 -0
  197. package/src/stack/stack.css +128 -0
  198. package/src/stack/stack.tokens.json +14 -0
  199. package/src/stat-card/stat-card.css +641 -0
  200. package/src/stat-card/stat-card.tokens.json +95 -0
  201. package/src/status-indicator/status-indicator.css +481 -0
  202. package/src/status-indicator/status-indicator.tokens.json +38 -0
  203. package/src/stepper/stepper.css +629 -0
  204. package/src/stepper/stepper.tokens.json +72 -0
  205. package/src/switch/switch.css +703 -0
  206. package/src/switch/switch.tokens.json +75 -0
  207. package/src/table/table.css +1482 -0
  208. package/src/table/table.tokens.json +69 -0
  209. package/src/table-of-contents/table-of-contents.css +533 -0
  210. package/src/table-of-contents/table-of-contents.tokens.json +53 -0
  211. package/src/tabs/tabs.css +998 -0
  212. package/src/tabs/tabs.tokens.json +82 -0
  213. package/src/tag/tag.css +768 -0
  214. package/src/tag/tag.tokens.json +85 -0
  215. package/src/tags-input/tags-input.css +757 -0
  216. package/src/tags-input/tags-input.tokens.json +84 -0
  217. package/src/text-field/text-field.css +900 -0
  218. package/src/text-field/text-field.tokens.json +87 -0
  219. package/src/textarea/textarea.css +365 -0
  220. package/src/textarea/textarea.tokens.json +59 -0
  221. package/src/time-field/time-field.css +719 -0
  222. package/src/time-field/time-field.tokens.json +86 -0
  223. package/src/time-picker/time-picker.css +665 -0
  224. package/src/time-picker/time-picker.tokens.json +66 -0
  225. package/src/time-range-picker/time-range-picker.css +1287 -0
  226. package/src/time-range-picker/time-range-picker.tokens.json +134 -0
  227. package/src/timeline/timeline.css +1596 -0
  228. package/src/timeline/timeline.tokens.json +96 -0
  229. package/src/toast/toast.css +943 -0
  230. package/src/toast/toast.tokens.json +90 -0
  231. package/src/toggle/toggle.css +290 -0
  232. package/src/toggle/toggle.tokens.json +54 -0
  233. package/src/toggle-group/toggle-group.css +463 -0
  234. package/src/toggle-group/toggle-group.tokens.json +54 -0
  235. package/src/toolbar/toolbar.css +434 -0
  236. package/src/toolbar/toolbar.tokens.json +49 -0
  237. package/src/tooltip/tooltip.css +368 -0
  238. package/src/tooltip/tooltip.tokens.json +39 -0
  239. package/src/top-navigation/top-navigation.css +1287 -0
  240. package/src/top-navigation/top-navigation.tokens.json +91 -0
  241. package/src/tour/tour.css +680 -0
  242. package/src/tour/tour.tokens.json +67 -0
  243. package/src/transfer/transfer.css +571 -0
  244. package/src/transfer/transfer.tokens.json +49 -0
  245. package/src/tree/tree.css +1000 -0
  246. package/src/tree/tree.tokens.json +80 -0
  247. package/src/typography/typography.css +211 -0
  248. package/src/typography/typography.tokens.json +31 -0
  249. package/src/upload/upload.css +1706 -0
  250. package/src/upload/upload.tokens.json +123 -0
  251. package/src/visually-hidden/visually-hidden.css +52 -0
  252. package/src/visually-hidden/visually-hidden.tokens.json +1 -0
  253. package/src/wizard/wizard.css +740 -0
  254. package/src/wizard/wizard.tokens.json +63 -0
@@ -0,0 +1,368 @@
1
+ @layer slotted.components {
2
+ /**
3
+ * A short, non-interactive sentence about the element under the pointer or
4
+ * under focus.
5
+ *
6
+ * Two boxes, and the split is what makes the family animate at all. The
7
+ * **layer** is what `packages/core/src/positioner` writes `position`, `left`
8
+ * and `top` onto; the module deliberately leaves `transform` alone, so the
9
+ * layer is also what slides and fades. The **content** inside it is the
10
+ * painted surface, and the arrow is the layer's other child, painted behind
11
+ * the content so only its two outer edges show.
12
+ *
13
+ * ┌─ root ─ the layer, positioned, animated ──────────┐
14
+ * │ padding = the gap │
15
+ * │ ┌─ content ─ role="tooltip", painted ────────┐ │
16
+ * │ │ Saves the draft without publishing it │ │
17
+ * │ └────────────────────────────────────────────┘ │
18
+ * │ ◆ arrow │
19
+ * └───────────────────────────────────────────────────┘
20
+ *
21
+ * ── Why the gap is padding and not an offset ─────────────────────────
22
+ *
23
+ * WCAG 2.2 SC 1.4.13 Hoverable requires that the pointer be able to move onto
24
+ * the tooltip without it disappearing. A gap made of the positioner's
25
+ * `sideOffset` is empty page between the trigger and the layer, and a pointer
26
+ * crossing it has left both. A gap made of the layer's own padding belongs to
27
+ * the layer, so the pointer never leaves. `sideOffset` is therefore `0` by
28
+ * default and means additional distance beyond this one.
29
+ *
30
+ * It also removes four rules. A bridge drawn per side would have to answer
31
+ * `data-side`, which names a **physical** edge, and a physical edge cannot be
32
+ * answered in logical properties without mirroring in the wrong direction.
33
+ * Symmetric padding answers every side at once.
34
+ */
35
+ [data-ui='tooltip'] {
36
+ /**
37
+ * The distance between the trigger and the painted surface, and the band
38
+ * the arrow stands in. A consumer who raises `sideOffset` past it leaves
39
+ * page the pointer can fall through, and retunes this token to match.
40
+ */
41
+ --_gap: var(--slotted-tooltip-gap, var(--slotted-space-4, 0.5rem));
42
+
43
+ --_surface: var(--slotted-tooltip-surface, var(--slotted-surface-inverse, #172033));
44
+ --_text: var(--slotted-tooltip-text, var(--slotted-text-inverse, #f8fafc));
45
+ /**
46
+ * The inverse variant carries no edge, because an inverted surface is
47
+ * already separated from every scheme's page. `surface` fills both in.
48
+ */
49
+ --_border-color: transparent;
50
+ --_border-width: 0;
51
+ --_radius: var(--slotted-tooltip-radius, var(--slotted-radius-sm, 4px));
52
+ /**
53
+ * The smallest step on the scale, which makes the three overlay families an
54
+ * elevation ladder rather than three boxes at one height: a hint at `xs`, a
55
+ * panel at `md`, a modal dialog at `lg`. The `inverse` variant hides its own
56
+ * shadow; the first `surface` capture showed `sm` reading heavier than the
57
+ * inverse box beside it, which is the difference this step removes.
58
+ */
59
+ --_shadow: var(--slotted-tooltip-shadow, var(--slotted-shadow-xs));
60
+ --_arrow-size: var(--slotted-tooltip-arrow-size, 0.5rem);
61
+ /* The point, softened to the same degree the surface's own corners are.
62
+ A 90-degree tip beside a rounded panel reads as a different object. */
63
+ --_arrow-tip-radius: var(--slotted-tooltip-arrow-tip-radius, var(--slotted-radius-xs, 2px));
64
+
65
+ /**
66
+ * The control scales, so `size` is one decision and the three densities
67
+ * come for free: a dense tooltip is a tighter tooltip rather than a smaller
68
+ * one, which is what "density changes size without changing meaning" asks.
69
+ */
70
+ --_padding-inline: var(--slotted-control-padding-inline-md, 0.8125rem);
71
+ --_padding-block: var(--slotted-control-gap-md, 0.5rem);
72
+ --_font-size: var(--slotted-control-font-size-md, 0.8125rem);
73
+ --_line-height: var(--slotted-line-height-sm, 1.45);
74
+ /**
75
+ * ── Why the family caps its own width ────────────────────────────────
76
+ *
77
+ * `docs/build-briefing.md` gives measure to `container` and to it alone, so
78
+ * no `measure` axis is offered here. A cap is still needed: a layer in a
79
+ * portal is `max-content` wide, and one long sentence would otherwise set a
80
+ * single line the width of the viewport. It is a token rather than an axis,
81
+ * and a consumer who needs a paragraph is holding a popover.
82
+ */
83
+ --_measure: var(--slotted-tooltip-measure, 18rem);
84
+
85
+ /**
86
+ * ── Only the block inset is stated ───────────────────────────────────
87
+ *
88
+ * The positioner writes `left` and `top` inline on its first measurement
89
+ * and never writes `right`. `inset-inline-start: 0` resolves to `right: 0`
90
+ * in a right-to-left document, and a box with a definite width that is
91
+ * given both `left` and `right` is over-constrained: in that direction
92
+ * `right` wins, and every layer in the page pins itself to the far edge.
93
+ * The first right-to-left capture showed exactly that. `inset-block-start`
94
+ * does not mirror with `dir`, so it is safe and it is what keeps an
95
+ * unmeasured layer from sitting at the end of the document and lengthening
96
+ * the page for a frame.
97
+ */
98
+ position: absolute;
99
+ inset-block-start: 0;
100
+
101
+ /**
102
+ * One stack, no new step in the scale. A tooltip draws above the popover it
103
+ * was opened inside because `dismissable-layer` gave it a greater depth,
104
+ * not because it was given a larger number of its own.
105
+ */
106
+ z-index: calc(var(--slotted-z-index-popover, 1100) + var(--slotted-layer-depth, 0));
107
+ /* So the arrow's negative z-index stays inside this layer in every case. */
108
+ isolation: isolate;
109
+
110
+ box-sizing: border-box;
111
+ padding: var(--_gap);
112
+ inline-size: max-content;
113
+ /**
114
+ * The measure, and then the room the positioner says is actually left. A
115
+ * tooltip near the edge of a 240-pixel viewport narrows instead of pushing
116
+ * the page sideways.
117
+ */
118
+ max-inline-size: min(var(--_measure), var(--slotted-positioner-available-width, 100vw));
119
+
120
+ /**
121
+ * The layer never blocks the target — `docs/component-features.md` §8 — so
122
+ * the pointer passes through it. Only a hoverable tooltip takes the pointer
123
+ * back, and only while it is open.
124
+ */
125
+ pointer-events: none;
126
+
127
+ opacity: 0;
128
+ /**
129
+ * R7: the layer arrives along the axis it opens on — from one space step
130
+ * above its place when it opens downward, from one step below when it
131
+ * opens upward — and never along the inline axis. A `scale` from the
132
+ * corner the positioner named as origin moved the far edge by four per
133
+ * cent of the width, which read as an entrance from the left.
134
+ */
135
+ --_enter-distance: var(--slotted-space-2, 0.25rem);
136
+ translate: 0 calc(-1 * var(--_enter-distance));
137
+ transition:
138
+ opacity var(--slotted-duration-short) var(--slotted-easing-exit),
139
+ translate var(--slotted-duration-short) var(--slotted-easing-exit);
140
+ }
141
+
142
+ [data-ui='tooltip'][data-side='top'] {
143
+ translate: 0 var(--_enter-distance);
144
+ }
145
+
146
+ /* A lateral side has no block direction to arrive from, so it only fades. */
147
+ [data-ui='tooltip']:is([data-side='left'], [data-side='right']) {
148
+ translate: 0 0;
149
+ }
150
+
151
+ /**
152
+ * Entering is a shade slower than leaving, which is what makes a layer read
153
+ * as placed rather than thrown. Both durations are motion tokens, so the
154
+ * theme's one reduced-motion query collapses them together.
155
+ */
156
+ /**
157
+ * The entrance is a keyframe animation and not a transition. A transition
158
+ * starts from the style the browser computed last, and the positioner
159
+ * writes `data-side` in the same style update as the family opens the
160
+ * layer, so a transition set out from the closed style of the side the
161
+ * layer had before it had one — the bottom's — whatever side it opens on.
162
+ * A keyframe states where it starts. The exit stays a transition: it
163
+ * leaves from wherever the layer is, on the closed rule's durations.
164
+ */
165
+ [data-ui='tooltip'][data-open] {
166
+ opacity: 1;
167
+ translate: 0 0;
168
+ transition: none;
169
+ }
170
+
171
+ /**
172
+ * Only a layer the positioner placed arrives: it writes `data-positioned`
173
+ * with the side, and a layer written open in static markup — the harness,
174
+ * a docs snippet — is simply there, and is photographed where it stands.
175
+ */
176
+ [data-ui='tooltip'][data-open][data-positioned] {
177
+ animation: slotted-tooltip-enter-down var(--slotted-duration-medium) var(--slotted-easing-enter);
178
+ }
179
+
180
+ [data-ui='tooltip'][data-open][data-positioned][data-side='top'] {
181
+ animation-name: slotted-tooltip-enter-up;
182
+ }
183
+
184
+ [data-ui='tooltip'][data-open][data-positioned]:is([data-side='left'], [data-side='right']) {
185
+ animation-name: slotted-tooltip-fade;
186
+ }
187
+
188
+ @keyframes slotted-tooltip-enter-down {
189
+ from {
190
+ opacity: 0;
191
+ translate: 0 calc(-1 * var(--_enter-distance));
192
+ }
193
+ }
194
+
195
+ @keyframes slotted-tooltip-enter-up {
196
+ from {
197
+ opacity: 0;
198
+ translate: 0 var(--_enter-distance);
199
+ }
200
+ }
201
+
202
+ @keyframes slotted-tooltip-fade {
203
+ from {
204
+ opacity: 0;
205
+ }
206
+ }
207
+
208
+ /* Stillness keeps the fade and drops the movement (R7). */
209
+ @media (prefers-reduced-motion: reduce) {
210
+ [data-ui='tooltip'],
211
+ [data-ui='tooltip'][data-side='top'],
212
+ [data-ui='tooltip'][data-side='left'],
213
+ [data-ui='tooltip'][data-side='right'] {
214
+ translate: 0 0;
215
+ transition: opacity var(--slotted-duration-short) var(--slotted-easing-exit);
216
+ }
217
+
218
+ [data-ui='tooltip'][data-open][data-positioned],
219
+ [data-ui='tooltip'][data-open][data-positioned][data-side='top'],
220
+ [data-ui='tooltip'][data-open][data-positioned][data-side='left'],
221
+ [data-ui='tooltip'][data-open][data-positioned][data-side='right'] {
222
+ animation-name: slotted-tooltip-fade;
223
+ }
224
+ }
225
+
226
+ [data-ui='tooltip'][data-open][data-hoverable] {
227
+ pointer-events: auto;
228
+ }
229
+
230
+ /**
231
+ * The anchor left the screen or its clipping ancestor. Hiding is the whole of
232
+ * `hideWhenDetached`: the layer comes back when the anchor does, and nothing
233
+ * has moved the consumer's own `open` because a rectangle changed size.
234
+ */
235
+ [data-ui='tooltip'][data-detached] {
236
+ visibility: hidden;
237
+ }
238
+
239
+ [data-ui='tooltip'][data-size='sm'] {
240
+ --_padding-inline: var(--slotted-control-padding-inline-sm, 0.625rem);
241
+ --_padding-block: var(--slotted-control-gap-sm, 0.375rem);
242
+ --_font-size: var(--slotted-control-font-size-sm, 0.75rem);
243
+ --_measure: var(--slotted-tooltip-measure-sm, 14rem);
244
+ }
245
+
246
+ /**
247
+ * A tooltip on a page that is already dark, or one holding two lines that
248
+ * want to read as a small panel rather than as a label. It takes the raised
249
+ * surface and the edge that surface needs to separate from the page.
250
+ */
251
+ [data-ui='tooltip'][data-variant='surface'] {
252
+ --_surface: var(--slotted-tooltip-surface-raised, var(--slotted-surface-raised, #ffffff));
253
+ --_text: var(--slotted-tooltip-text-raised, var(--slotted-text, #0f172a));
254
+ --_border-color: var(--slotted-tooltip-border-color, var(--slotted-border-subtle, #e2e8f0));
255
+ --_border-width: var(--slotted-border-width-thin, 1px);
256
+ }
257
+
258
+ [data-ui='tooltip'] > [data-part='content'] {
259
+ box-sizing: border-box;
260
+ display: block;
261
+ max-inline-size: 100%;
262
+
263
+ border: var(--_border-width) solid var(--_border-color);
264
+ border-radius: var(--_radius);
265
+ background: var(--_surface);
266
+ color: var(--_text);
267
+ box-shadow: var(--_shadow);
268
+
269
+ padding-block: var(--_padding-block);
270
+ padding-inline: var(--_padding-inline);
271
+
272
+ font-family: var(--slotted-font-family-sans, ui-sans-serif, system-ui, sans-serif);
273
+ font-size: var(--_font-size);
274
+ font-weight: var(--slotted-font-weight-regular, 400);
275
+ line-height: var(--_line-height);
276
+ text-align: start;
277
+
278
+ /**
279
+ * A hostile string is a single unbroken token, and a translated one is
280
+ * three times the length of the English. `anywhere` breaks the first rather
281
+ * than letting it run past the measure.
282
+ *
283
+ * `plaintext` rather than the `isolate` a heading takes: the layer shrinks
284
+ * to its own content, so there is no far edge for a short string to be
285
+ * stranded against — the objection that made `collapsible` choose `isolate`
286
+ * for a title in a full-width row. What is left is the ordering, and it is
287
+ * wrong under `isolate`: the first right-to-left capture set an English
288
+ * sentence with its full stop at the head of the last line. `plaintext`
289
+ * takes each paragraph's direction from its own first strong character, so
290
+ * a sentence reads the way it was written whichever page it is on.
291
+ */
292
+ overflow-wrap: anywhere;
293
+ unicode-bidi: plaintext;
294
+ }
295
+
296
+ /**
297
+ * ── Why this rule is written in physical properties ──────────────────
298
+ *
299
+ * `packages/core/src/positioner` measures the arrow with the engine and
300
+ * writes `--slotted-positioner-arrow-x` and `-arrow-y` as offsets from the
301
+ * layer's own left and top — the same physical coordinates
302
+ * `transform-origin` is written in. `data-side` is physical for the same
303
+ * reason: it names the edge of the anchor the layer landed on, not an edge of
304
+ * the reader's writing direction. Mirroring either would move an already
305
+ * correct arrow to the wrong edge in a right-to-left document, so
306
+ * `packages/styles/src/logical.test.mjs` exempts exactly the rules that
307
+ * select `[data-part='arrow']`, and nothing else.
308
+ *
309
+ * ── Why it is painted over the surface and not behind it ─────────────
310
+ *
311
+ * The square is rotated about its own centre, and the centre sits on the
312
+ * content's edge. Painted behind, its inner half disappears and the content's
313
+ * own border still runs straight across the base — a bordered tooltip then
314
+ * reads as a box with a separate triangle hanging off it, which is what the
315
+ * first capture showed. Painted over, the arrow's background covers that
316
+ * border where they meet and its two outward-facing edges carry the border
317
+ * instead, so the outline is continuous. The two inward-facing edges carry
318
+ * none, and which two are which is what the four rules below say.
319
+ *
320
+ * `arrowPadding` keeps it clear of the corners, where the content's radius
321
+ * would leave the base uncovered.
322
+ */
323
+ [data-ui='tooltip'] > [data-part='arrow'] {
324
+ position: absolute;
325
+ z-index: 1;
326
+ inline-size: var(--_arrow-size);
327
+ block-size: var(--_arrow-size);
328
+ rotate: 45deg;
329
+ background: var(--_surface);
330
+ border: 0 solid var(--_border-color);
331
+ }
332
+
333
+ [data-ui='tooltip'][data-side='top'] > [data-part='arrow'] {
334
+ left: var(--slotted-positioner-arrow-x, 0);
335
+ top: auto;
336
+ bottom: calc(var(--_gap) - var(--_arrow-size) / 2);
337
+ border-right-width: var(--_border-width);
338
+ border-bottom-width: var(--_border-width);
339
+ border-bottom-right-radius: var(--_arrow-tip-radius);
340
+ }
341
+
342
+ [data-ui='tooltip'][data-side='bottom'] > [data-part='arrow'] {
343
+ left: var(--slotted-positioner-arrow-x, 0);
344
+ top: calc(var(--_gap) - var(--_arrow-size) / 2);
345
+ bottom: auto;
346
+ border-top-width: var(--_border-width);
347
+ border-left-width: var(--_border-width);
348
+ border-top-left-radius: var(--_arrow-tip-radius);
349
+ }
350
+
351
+ [data-ui='tooltip'][data-side='left'] > [data-part='arrow'] {
352
+ top: var(--slotted-positioner-arrow-y, 0);
353
+ left: auto;
354
+ right: calc(var(--_gap) - var(--_arrow-size) / 2);
355
+ border-top-width: var(--_border-width);
356
+ border-right-width: var(--_border-width);
357
+ border-top-right-radius: var(--_arrow-tip-radius);
358
+ }
359
+
360
+ [data-ui='tooltip'][data-side='right'] > [data-part='arrow'] {
361
+ top: var(--slotted-positioner-arrow-y, 0);
362
+ left: calc(var(--_gap) - var(--_arrow-size) / 2);
363
+ right: auto;
364
+ border-bottom-width: var(--_border-width);
365
+ border-left-width: var(--_border-width);
366
+ border-bottom-left-radius: var(--_arrow-tip-radius);
367
+ }
368
+ }
@@ -0,0 +1,39 @@
1
+ [
2
+ "--slotted-border-subtle",
3
+ "--slotted-border-width-thin",
4
+ "--slotted-control-font-size-md",
5
+ "--slotted-control-font-size-sm",
6
+ "--slotted-control-gap-md",
7
+ "--slotted-control-gap-sm",
8
+ "--slotted-control-padding-inline-md",
9
+ "--slotted-control-padding-inline-sm",
10
+ "--slotted-duration-medium",
11
+ "--slotted-duration-short",
12
+ "--slotted-easing-enter",
13
+ "--slotted-easing-exit",
14
+ "--slotted-font-family-sans",
15
+ "--slotted-font-weight-regular",
16
+ "--slotted-line-height-sm",
17
+ "--slotted-radius-sm",
18
+ "--slotted-radius-xs",
19
+ "--slotted-shadow-xs",
20
+ "--slotted-space-2",
21
+ "--slotted-space-4",
22
+ "--slotted-surface-inverse",
23
+ "--slotted-surface-raised",
24
+ "--slotted-text",
25
+ "--slotted-text-inverse",
26
+ "--slotted-tooltip-arrow-size",
27
+ "--slotted-tooltip-arrow-tip-radius",
28
+ "--slotted-tooltip-border-color",
29
+ "--slotted-tooltip-gap",
30
+ "--slotted-tooltip-measure",
31
+ "--slotted-tooltip-measure-sm",
32
+ "--slotted-tooltip-radius",
33
+ "--slotted-tooltip-shadow",
34
+ "--slotted-tooltip-surface",
35
+ "--slotted-tooltip-surface-raised",
36
+ "--slotted-tooltip-text",
37
+ "--slotted-tooltip-text-raised",
38
+ "--slotted-z-index-popover"
39
+ ]