@livestorm/ui-vue 3.0.0 → 4.0.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 (291) hide show
  1. package/README.md +3 -3
  2. package/components-vite.js +2 -2
  3. package/dist/UiButton-uyW8EHRJ.mjs +602 -0
  4. package/dist/UiTimelineItem-EiOEi1yF.mjs +7293 -0
  5. package/dist/UiTooltip-DZcPD6_N.mjs +158 -0
  6. package/dist/a11y-CaZxRWzo.mjs +6 -0
  7. package/dist/breakpoints.mjs +4 -9
  8. package/dist/bus.mjs +5 -5
  9. package/dist/components.mjs +236 -231
  10. package/dist/i18n-B8QOMuFD.mjs +46 -0
  11. package/dist/index.mjs +4 -91
  12. package/dist/integrations.mjs +3 -14
  13. package/dist/layouts.mjs +228 -236
  14. package/dist/responsive.mjs +31 -36
  15. package/dist/slot.mjs +11 -17
  16. package/dist/toastDSV2-D3xDZPe5.mjs +105 -0
  17. package/dist/types/index.d.ts +19 -1
  18. package/dist/types/src/components/Toast/ToastMessage.vue.d.ts +17 -7
  19. package/dist/types/src/components/Toast/toastDSV2.d.ts +89 -64
  20. package/dist/types/src/components/UiActionBar/types.d.ts +2 -0
  21. package/dist/types/src/components/UiAvatar/UiAvatar.vue.d.ts +4 -2
  22. package/dist/types/src/components/UiAvatarList/UiAvatarList.vue.d.ts +3 -2
  23. package/dist/types/src/components/UiBanner/UiBanner.vue.d.ts +13 -1
  24. package/dist/types/src/components/UiButton/UiButton.vue.d.ts +95 -35
  25. package/dist/types/src/components/UiButtonGroup/UiButtonGroup.vue.d.ts +8 -2
  26. package/dist/types/src/components/UiButtonGroup/types.d.ts +4 -0
  27. package/dist/types/src/components/UiChoice/UiChoice.vue.d.ts +71 -0
  28. package/dist/types/src/components/UiChoice/index.d.ts +2 -0
  29. package/dist/types/src/components/UiChoice/types.d.ts +7 -0
  30. package/dist/types/src/components/UiColorField/UiColorField.vue.d.ts +1 -1
  31. package/dist/types/src/components/UiColorPicker/UiColorPicker.vue.d.ts +2 -2
  32. package/dist/types/src/components/UiCombobox/UiCombobox.types.d.ts +47 -0
  33. package/dist/types/src/components/UiCombobox/UiCombobox.vue.d.ts +40 -0
  34. package/dist/types/src/components/UiCombobox/index.d.ts +2 -0
  35. package/dist/types/src/components/UiDataTable/UiDataTable.types.d.ts +46 -0
  36. package/dist/types/src/components/UiDataTable/UiDataTable.vue.d.ts +136 -0
  37. package/dist/types/src/components/UiDataTable/index.d.ts +5 -0
  38. package/dist/types/src/components/UiDrawer/UiDrawer.vue.d.ts +28 -0
  39. package/dist/types/src/components/UiDrawer/UiDrawerContent.vue.d.ts +18 -0
  40. package/dist/types/src/components/UiDrawer/UiDrawerTrigger.vue.d.ts +14 -0
  41. package/dist/types/src/components/UiDropdown/DropdownItemCheckbox.vue.d.ts +3 -0
  42. package/dist/types/src/components/UiDropdown/UiDropdownContent.vue.d.ts +10 -0
  43. package/dist/types/src/components/UiDropdown/UiDropdownGroup.vue.d.ts +17 -0
  44. package/dist/types/src/components/UiDropdown/UiDropdownItem.vue.d.ts +8 -5
  45. package/dist/types/src/components/UiDropdown/UiDropdownTrigger.vue.d.ts +21 -5
  46. package/dist/types/src/components/UiDropdown/index.d.ts +1 -0
  47. package/dist/types/src/components/UiEmojiPickerList/UiEmojiPickerList.vue.d.ts +22 -0
  48. package/dist/types/src/components/UiEmptyState/UiEmptyState.vue.d.ts +8 -3
  49. package/dist/types/src/components/UiFieldWrapper/UiFieldWrapper.vue.d.ts +2 -2
  50. package/dist/types/src/components/UiInputCheckbox/CheckboxGlyph.vue.d.ts +17 -0
  51. package/dist/types/src/components/UiInputCheckbox/UiInputCheckbox.vue.d.ts +35 -4
  52. package/dist/types/src/components/UiInputRadio/RadioGlyph.vue.d.ts +19 -0
  53. package/dist/types/src/components/UiInputRadio/UiInputRadio.vue.d.ts +21 -8
  54. package/dist/types/src/components/UiInputRadio/UiInputRadioGroup.vue.d.ts +6 -1
  55. package/dist/types/src/components/UiInputRadio/types.d.ts +1 -1
  56. package/dist/types/src/components/UiInputSelect/UiInputSelect.vue.d.ts +5 -5
  57. package/dist/types/src/components/UiInputTextarea/UiInputTextarea.vue.d.ts +5 -5
  58. package/dist/types/src/components/UiListItem/UiListItem.vue.d.ts +18 -4
  59. package/dist/types/src/components/UiLoader/UiSpinnerIcon.vue.d.ts +3 -0
  60. package/dist/types/src/components/UiMenu/UiMenuContent.vue.d.ts +15 -2
  61. package/dist/types/src/components/UiMenu/UiMenuItem.vue.d.ts +9 -3
  62. package/dist/types/src/components/UiNestedOptions/UiNestedOptions.vue.d.ts +13 -0
  63. package/dist/types/src/components/UiPage/UiPage.vue.d.ts +79 -15
  64. package/dist/types/src/components/UiPagination/UiPagination.vue.d.ts +36 -0
  65. package/dist/types/src/components/UiPagination/index.d.ts +2 -0
  66. package/dist/types/src/components/UiPagination/types.d.ts +4 -0
  67. package/dist/types/src/components/UiPane/UiPane.vue.d.ts +22 -0
  68. package/dist/types/src/components/UiPane/UiPaneContent.vue.d.ts +75 -0
  69. package/dist/types/src/components/UiPane/UiPaneTrigger.vue.d.ts +14 -0
  70. package/dist/types/src/components/UiPane/index.d.ts +5 -0
  71. package/dist/types/src/components/UiRating/UiRating.vue.d.ts +62 -0
  72. package/dist/types/src/components/UiRating/types.d.ts +1 -0
  73. package/dist/types/src/components/UiRoomButton/UiRoomButton.vue.d.ts +5 -3
  74. package/dist/types/src/components/UiRoomCountdown/UiRoomCountdown.vue.d.ts +32 -0
  75. package/dist/types/src/components/UiShell/UiShell.vue.d.ts +3 -0
  76. package/dist/types/src/components/UiSideMenu/UiSideMenu.vue.d.ts +22 -1
  77. package/dist/types/src/components/UiSideMenu/UiSideMenuItemContent.vue.d.ts +2 -2
  78. package/dist/types/src/components/UiSwitch/UiSwitch.vue.d.ts +10 -5
  79. package/dist/types/src/components/UiTable/UiTable.vue.d.ts +13 -4
  80. package/dist/types/src/components/UiTable/UiTableActionsCell.vue.d.ts +49 -0
  81. package/dist/types/src/components/UiTable/UiTableActionsHeaderCell.vue.d.ts +3 -0
  82. package/dist/types/src/components/UiTable/UiTableBody.vue.d.ts +11 -1
  83. package/dist/types/src/components/UiTable/UiTableCell.vue.d.ts +16 -1
  84. package/dist/types/src/components/UiTable/UiTableHeaderCell.vue.d.ts +31 -2
  85. package/dist/types/src/components/UiTable/UiTableRow.vue.d.ts +32 -2
  86. package/dist/types/src/components/UiTable/context.d.ts +3 -0
  87. package/dist/types/src/components/UiTable/index.d.ts +4 -0
  88. package/dist/types/src/components/UiTabs/UiTabs.vue.d.ts +3 -0
  89. package/dist/types/src/components/UiTag/UiTag.types.d.ts +25 -0
  90. package/dist/types/src/components/UiTag/UiTag.vue.d.ts +5 -26
  91. package/dist/types/src/components/UiTag/index.d.ts +2 -1
  92. package/dist/types/src/components/UiTextField/UiTextField.vue.d.ts +10 -5
  93. package/dist/types/src/components/UiTooltip/UiTooltipProvider.vue.d.ts +1 -0
  94. package/dist/types/src/components/UiTooltip/UiTooltipTrigger.vue.d.ts +2 -2
  95. package/dist/types/src/composables/storedThemingApplies.d.ts +17 -0
  96. package/dist/types/src/composables/useButtonStyles.d.ts +1 -0
  97. package/dist/types/src/composables/useChoiceboxSurface.d.ts +11 -0
  98. package/dist/types/src/composables/useContentMode.d.ts +7 -9
  99. package/dist/types/src/composables/useControlModes.d.ts +7 -0
  100. package/dist/types/src/composables/useControlShape.d.ts +24 -0
  101. package/dist/types/src/composables/useFieldFocusEvents.d.ts +12 -0
  102. package/dist/types/src/composables/useIconSize.d.ts +2 -0
  103. package/dist/types/src/composables/usePullGesture.d.ts +42 -0
  104. package/dist/types/src/composables/useThemeAndModes.d.ts +4 -0
  105. package/dist/types/src/theming/colorScale.d.ts +165 -0
  106. package/dist/types/src/theming/legacyColorScale.d.ts +27 -0
  107. package/dist/types/src/theming/presetColors.d.ts +11 -0
  108. package/dist/types/src/theming/primitiveTokens.d.ts +2 -0
  109. package/dist/types/src/utils/effectiveOpacity.d.ts +2 -0
  110. package/dist/types/src/utils/numbers.d.ts +1 -2
  111. package/dist/types/src/utils/tokenColor.d.ts +2 -0
  112. package/dist/ui-vue.css +2 -1
  113. package/dist/utils.mjs +165 -194
  114. package/index.d.ts +18 -0
  115. package/index.js +36 -0
  116. package/package.json +26 -21
  117. package/src/components/Toast/LayoutToasts.vue +19 -11
  118. package/src/components/Toast/ToastMessage.vue +125 -68
  119. package/src/components/Toast/toastDSV2.ts +238 -67
  120. package/src/components/UiActionBar/UiActionBar.vue +4 -3
  121. package/src/components/UiActionBar/UiActionBarItem.vue +9 -6
  122. package/src/components/UiActionBar/types.ts +13 -0
  123. package/src/components/UiAvatar/UiAvatar.vue +8 -2
  124. package/src/components/UiAvatarList/UiAvatarList.vue +51 -20
  125. package/src/components/UiBadge/UiBadge.vue +1 -1
  126. package/src/components/UiBanner/UiBanner.vue +71 -21
  127. package/src/components/UiBreadcrumb/UiBreadcrumb.vue +1 -1
  128. package/src/components/UiButton/UiButton.vue +92 -25
  129. package/src/components/UiButtonGroup/UiButtonGroup.vue +21 -17
  130. package/src/components/UiButtonGroup/UiButtonGroupItem.vue +33 -15
  131. package/src/components/UiButtonGroup/types.ts +19 -0
  132. package/src/components/UiCard/UiCard.vue +20 -23
  133. package/src/components/UiChoice/UiChoice.vue +187 -0
  134. package/src/components/UiChoice/index.ts +2 -0
  135. package/src/components/UiChoice/types.ts +11 -0
  136. package/src/components/UiColorField/UiColorField.vue +2 -2
  137. package/src/components/UiColorPicker/UiColorPicker.vue +11 -8
  138. package/src/components/UiCombobox/UiCombobox.types.ts +52 -0
  139. package/src/components/UiCombobox/UiCombobox.vue +296 -0
  140. package/src/components/UiCombobox/index.ts +2 -0
  141. package/src/components/UiDataTable/UiDataTable.types.ts +47 -0
  142. package/src/components/UiDataTable/UiDataTable.vue +422 -0
  143. package/src/components/UiDataTable/index.ts +12 -0
  144. package/src/components/UiDialog/UiDialogContent.vue +22 -7
  145. package/src/components/UiDrawer/UiDrawer.vue +16 -0
  146. package/src/components/UiDrawer/UiDrawerContent.vue +42 -0
  147. package/src/components/UiDrawer/UiDrawerTrigger.vue +17 -0
  148. package/src/components/UiDropdown/DropdownItemCheckbox.vue +10 -0
  149. package/src/components/UiDropdown/UiDropdownContent.vue +32 -21
  150. package/src/components/UiDropdown/UiDropdownGroup.vue +23 -0
  151. package/src/components/UiDropdown/UiDropdownItem.vue +38 -18
  152. package/src/components/UiDropdown/UiDropdownSeparator.vue +1 -1
  153. package/src/components/UiDropdown/UiDropdownTrigger.vue +138 -43
  154. package/src/components/UiDropdown/index.ts +1 -0
  155. package/src/components/UiEmojiPickerList/UiEmojiPickerList.vue +122 -0
  156. package/src/components/UiEmptyState/UiEmptyState.vue +16 -4
  157. package/src/components/UiFieldWrapper/UiFieldWrapper.vue +9 -3
  158. package/src/components/UiHorizontalSeparator/UiHorizontalSeparator.vue +2 -2
  159. package/src/components/UiInputCheckbox/CheckboxGlyph.vue +78 -0
  160. package/src/components/UiInputCheckbox/UiInputCheckbox.vue +213 -177
  161. package/src/components/UiInputEmoji/UiInputEmoji.vue +18 -95
  162. package/src/components/UiInputRadio/RadioGlyph.vue +45 -0
  163. package/src/components/UiInputRadio/UiInputRadio.vue +177 -169
  164. package/src/components/UiInputRadio/UiInputRadioGroup.vue +15 -5
  165. package/src/components/UiInputRadio/types.ts +1 -2
  166. package/src/components/UiInputSelect/UiInputSelect.vue +9 -7
  167. package/src/components/UiInputTextarea/UiInputTextarea.vue +20 -35
  168. package/src/components/UiLabel/UiLabel.vue +1 -1
  169. package/src/components/UiListItem/UiListItem.vue +55 -9
  170. package/src/components/UiLoader/UiLoader.vue +4 -20
  171. package/src/components/UiLoader/UiSpinnerIcon.vue +21 -0
  172. package/src/components/UiMenu/UiMenuContent.vue +24 -3
  173. package/src/components/UiMenu/UiMenuGroup.vue +1 -1
  174. package/src/components/UiMenu/UiMenuItem.vue +14 -3
  175. package/src/components/UiMenu/UiMenuSubContent.vue +1 -1
  176. package/src/components/UiMenu/UiMenuSubTrigger.vue +1 -1
  177. package/src/components/UiNestedOptions/UiNestedOptions.vue +6 -0
  178. package/src/components/UiPage/UiPage.vue +190 -32
  179. package/src/components/UiPagination/UiPagination.vue +99 -0
  180. package/src/components/UiPagination/index.ts +2 -0
  181. package/src/components/UiPagination/types.ts +28 -0
  182. package/src/components/UiPane/UiPane.vue +20 -0
  183. package/src/components/UiPane/UiPaneContent.vue +232 -0
  184. package/src/components/UiPane/UiPaneTrigger.vue +14 -0
  185. package/src/components/UiPane/index.ts +12 -0
  186. package/src/components/UiPopover/UiPopoverContent.vue +21 -1
  187. package/src/components/UiProgress/UiProgress.vue +2 -2
  188. package/src/components/UiRating/UiRating.vue +258 -0
  189. package/src/components/UiRating/types.ts +1 -0
  190. package/src/components/UiRoomButton/UiRoomButton.vue +10 -41
  191. package/src/components/UiRoomCountdown/UiRoomCountdown.vue +376 -0
  192. package/src/components/UiShell/UiShell.vue +9 -3
  193. package/src/components/UiSideMenu/UiSideMenu.vue +155 -18
  194. package/src/components/UiSideMenu/UiSideMenuItemContent.vue +20 -16
  195. package/src/components/UiStepper/UiStepper.vue +3 -16
  196. package/src/components/UiStepper/UiStepperDescription.vue +1 -13
  197. package/src/components/UiStepper/UiStepperIndicator.vue +11 -48
  198. package/src/components/UiStepper/UiStepperItem.vue +1 -8
  199. package/src/components/UiStepper/UiStepperSeparator.vue +5 -16
  200. package/src/components/UiStepper/UiStepperTitle.vue +1 -10
  201. package/src/components/UiSwitch/UiSwitch.vue +44 -28
  202. package/src/components/UiTable/UiTable.vue +98 -8
  203. package/src/components/UiTable/UiTableActionsCell.vue +135 -0
  204. package/src/components/UiTable/UiTableActionsHeaderCell.vue +19 -0
  205. package/src/components/UiTable/UiTableBody.vue +16 -1
  206. package/src/components/UiTable/UiTableCell.vue +33 -16
  207. package/src/components/UiTable/UiTableHeader.vue +6 -5
  208. package/src/components/UiTable/UiTableHeaderCell.vue +61 -9
  209. package/src/components/UiTable/UiTableRow.vue +46 -10
  210. package/src/components/UiTable/context.ts +5 -0
  211. package/src/components/UiTable/index.ts +4 -0
  212. package/src/components/UiTabs/UiTabs.vue +56 -61
  213. package/src/components/UiTag/UiTag.types.ts +28 -0
  214. package/src/components/UiTag/UiTag.vue +24 -42
  215. package/src/components/UiTag/index.ts +2 -0
  216. package/src/components/UiTextField/UiTextField.vue +21 -36
  217. package/src/components/UiTooltip/UiTooltipContent.vue +1 -1
  218. package/src/components/UiTooltip/UiTooltipProvider.vue +3 -0
  219. package/src/components/UiTooltip/UiTooltipTrigger.vue +16 -1
  220. package/src/composables/storedThemingApplies.ts +19 -0
  221. package/src/composables/useButtonStyles.ts +9 -13
  222. package/src/composables/useChoiceboxSurface.ts +36 -0
  223. package/src/composables/useContentMode.ts +29 -16
  224. package/src/composables/useControlModes.ts +11 -0
  225. package/src/composables/useControlShape.ts +34 -0
  226. package/src/composables/useFieldFocusEvents.ts +30 -0
  227. package/src/composables/useIconSize.ts +15 -0
  228. package/src/composables/usePullGesture.ts +142 -0
  229. package/src/composables/useThemeAndModes.ts +28 -1
  230. package/src/css/body.css +16 -1
  231. package/src/css/fonts.css +39 -5
  232. package/src/global.d.ts +36 -0
  233. package/src/theming/colorScale.ts +173 -0
  234. package/src/theming/legacyColorScale.ts +58 -0
  235. package/src/theming/presetColors.ts +33 -0
  236. package/src/theming/primitiveTokens.ts +71 -0
  237. package/src/utils/effectiveOpacity.ts +8 -0
  238. package/src/utils/i18n.ts +6 -0
  239. package/src/utils/numbers.ts +1 -1
  240. package/src/utils/responsive.d.ts +14 -0
  241. package/src/utils/tokenColor.ts +9 -0
  242. package/dist/UiTimelineItem.vue_vue_type_style_index_0_lang-LpdvGf5X.mjs +0 -6093
  243. package/dist/a11y-BhF_nl7L.mjs +0 -159
  244. package/dist/i18n-Cktw9hIu.mjs +0 -49
  245. package/dist/toastDSV2-wMh-UMzW.mjs +0 -74
  246. package/dist/types/src/components/UiAvatar/index.d.ts +0 -1
  247. package/dist/types/src/components/UiAvatarList/index.d.ts +0 -1
  248. package/dist/types/src/components/UiBadge/index.d.ts +0 -1
  249. package/dist/types/src/components/UiBanner/index.d.ts +0 -2
  250. package/dist/types/src/components/UiButtonGroup/index.d.ts +0 -3
  251. package/dist/types/src/components/UiCarousel/index.d.ts +0 -2
  252. package/dist/types/src/components/UiColorField/index.d.ts +0 -2
  253. package/dist/types/src/components/UiDialog/MarketplaceHeaderExample.vue.d.ts +0 -28
  254. package/dist/types/src/components/UiDialog/index.d.ts +0 -7
  255. package/dist/types/src/components/UiFieldWrapper/index.d.ts +0 -1
  256. package/dist/types/src/components/UiInputCheckbox/index.d.ts +0 -2
  257. package/dist/types/src/components/UiInputEmoji/index.d.ts +0 -1
  258. package/dist/types/src/components/UiInputRadio/index.d.ts +0 -3
  259. package/dist/types/src/components/UiInputSelect/index.d.ts +0 -2
  260. package/dist/types/src/components/UiInputTextarea/index.d.ts +0 -2
  261. package/dist/types/src/components/UiMenu/index.d.ts +0 -10
  262. package/dist/types/src/components/UiProgress/index.d.ts +0 -2
  263. package/dist/types/src/components/UiSwitch/index.d.ts +0 -2
  264. package/dist/types/src/components/UiTabs/index.d.ts +0 -2
  265. package/dist/types/src/components/UiTimeline/index.d.ts +0 -2
  266. package/dist/types/src/components/UiTooltip/index.d.ts +0 -4
  267. package/dist/types/src/mixins/DynamicAction.d.ts +0 -30
  268. package/dist/useThemeAndModes-BzYwSOEv.mjs +0 -108
  269. package/src/components/UiAvatar/index.js +0 -1
  270. package/src/components/UiAvatarList/index.js +0 -1
  271. package/src/components/UiBadge/index.ts +0 -2
  272. package/src/components/UiBanner/index.ts +0 -2
  273. package/src/components/UiButtonGroup/index.ts +0 -3
  274. package/src/components/UiCarousel/index.ts +0 -2
  275. package/src/components/UiColorField/index.ts +0 -2
  276. package/src/components/UiDialog/MarketplaceHeaderExample.vue +0 -217
  277. package/src/components/UiDialog/index.ts +0 -18
  278. package/src/components/UiFieldWrapper/index.ts +0 -1
  279. package/src/components/UiInputCheckbox/index.ts +0 -2
  280. package/src/components/UiInputEmoji/index.ts +0 -1
  281. package/src/components/UiInputRadio/index.ts +0 -3
  282. package/src/components/UiInputSelect/index.ts +0 -2
  283. package/src/components/UiInputTextarea/index.ts +0 -2
  284. package/src/components/UiMenu/index.ts +0 -10
  285. package/src/components/UiProgress/index.ts +0 -2
  286. package/src/components/UiSwitch/index.ts +0 -2
  287. package/src/components/UiTabs/index.ts +0 -5
  288. package/src/components/UiTag/index.js +0 -1
  289. package/src/components/UiTimeline/index.ts +0 -2
  290. package/src/components/UiTooltip/index.js +0 -4
  291. package/src/mixins/DynamicAction.js +0 -61
@@ -0,0 +1,376 @@
1
+ <template>
2
+ <div class="ui-room-countdown">
3
+ <div
4
+ class="ui-room-countdown__dial"
5
+ :style="{ '--ui-room-countdown-size': sizeValue }"
6
+ role="timer"
7
+ aria-live="assertive"
8
+ :aria-label="isFinished ? label : `${remaining}`"
9
+ >
10
+ <div
11
+ class="ui-room-countdown__glass"
12
+ :class="{ 'ui-room-countdown__glass--out': live }"
13
+ aria-hidden="true"
14
+ />
15
+
16
+ <svg
17
+ class="ui-room-countdown__ring"
18
+ :class="{ 'ui-room-countdown__ring--out': live }"
19
+ viewBox="0 0 100 100"
20
+ aria-hidden="true"
21
+ >
22
+ <circle
23
+ class="ui-room-countdown__track"
24
+ cx="50"
25
+ cy="50"
26
+ r="46"
27
+ />
28
+ <circle
29
+ v-if="!isFinished"
30
+ class="ui-room-countdown__progress"
31
+ cx="50"
32
+ cy="50"
33
+ r="46"
34
+ path-length="1"
35
+ :style="{ animationDuration: `${seconds}s` }"
36
+ />
37
+ <g
38
+ v-if="!isFinished"
39
+ class="ui-room-countdown__head"
40
+ :style="{ animationDuration: `${seconds}s` }"
41
+ >
42
+ <circle
43
+ cx="50"
44
+ cy="4"
45
+ r="2"
46
+ />
47
+ </g>
48
+ <circle
49
+ v-if="isStarting"
50
+ class="ui-room-countdown__spinner"
51
+ cx="50"
52
+ cy="50"
53
+ r="46"
54
+ path-length="1"
55
+ />
56
+ </svg>
57
+
58
+ <Transition
59
+ name="ui-room-countdown-digit"
60
+ mode="out-in"
61
+ >
62
+ <span
63
+ v-if="!isFinished"
64
+ :key="remaining"
65
+ class="ui-room-countdown__digit"
66
+ >
67
+ {{ remaining }}
68
+ </span>
69
+ </Transition>
70
+
71
+ <span
72
+ v-if="isFinished"
73
+ class="ui-room-countdown__label"
74
+ >
75
+ <span
76
+ v-if="live"
77
+ class="ui-room-countdown__rec"
78
+ aria-hidden="true"
79
+ />
80
+ {{ label }}
81
+ </span>
82
+ </div>
83
+
84
+ <div
85
+ v-if="$slots.action"
86
+ class="ui-room-countdown__action"
87
+ >
88
+ <slot name="action" />
89
+ </div>
90
+ </div>
91
+ </template>
92
+
93
+ <script setup lang="ts">
94
+ import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
95
+
96
+ const props = withDefaults(defineProps<{
97
+ seconds?: number
98
+ label?: string
99
+ size?: 'sm' | 'md' | 'lg'
100
+ finished?: boolean
101
+ live?: boolean
102
+ }>(), {
103
+ seconds: 5,
104
+ label: 'You are live',
105
+ size: 'md',
106
+ finished: false,
107
+ live: false,
108
+ })
109
+
110
+ const emit = defineEmits<{
111
+ tick: [remaining: number]
112
+ finished: []
113
+ }>()
114
+
115
+ const remaining = ref(props.seconds)
116
+ let timer: ReturnType<typeof setInterval> | undefined
117
+
118
+ const isFinished = computed(() => props.finished || remaining.value <= 0)
119
+
120
+ const isStarting = computed(() => isFinished.value && !props.live)
121
+
122
+ const sizeValue = computed(() => ({
123
+ sm: '96px',
124
+ md: '200px',
125
+ lg: '288px',
126
+ }[props.size]))
127
+
128
+ function stop () {
129
+ clearInterval(timer)
130
+ }
131
+
132
+ watch(isFinished, (value) => {
133
+ if (!value) return
134
+
135
+ stop()
136
+ emit('finished')
137
+ })
138
+
139
+ onMounted(() => {
140
+ if (isFinished.value) return
141
+
142
+ timer = setInterval(() => {
143
+ remaining.value -= 1
144
+ emit('tick', remaining.value)
145
+
146
+ if (remaining.value <= 0) stop()
147
+ }, 1000)
148
+ })
149
+
150
+ onBeforeUnmount(stop)
151
+ </script>
152
+
153
+ <style scoped>
154
+ @reference '@livestorm/ui-tokens/output/supernova/index.css';
155
+
156
+ .ui-room-countdown {
157
+ @apply flex flex-col items-center gap-6 text-text-neutral-base;
158
+ }
159
+
160
+ .ui-room-countdown__dial {
161
+ @apply relative grid place-items-center;
162
+ width: var(--ui-room-countdown-size);
163
+ height: var(--ui-room-countdown-size);
164
+ font-size: var(--ui-room-countdown-size);
165
+ }
166
+
167
+ .ui-room-countdown__glass {
168
+ @apply absolute inset-[7%] rounded-full bg-surface-neutral-alpha-100;
169
+ backdrop-filter: blur(var(--blur-blur-lg));
170
+ transition: all 0.8s cubic-bezier(0.16, 1, 0.3, 1);
171
+ }
172
+
173
+ .ui-room-countdown__glass::after {
174
+ @apply absolute inset-0 rounded-full content-[''];
175
+ background: radial-gradient(circle, var(--color-surface-neutral-alpha-200) 0%, transparent 70%);
176
+ animation: ui-room-countdown-breath 1.4s ease-in-out infinite;
177
+ }
178
+
179
+ .ui-room-countdown__glass--out {
180
+ @apply opacity-0;
181
+ transform: scale(1.2);
182
+ }
183
+
184
+ .ui-room-countdown__ring {
185
+ @apply absolute inset-0 h-full w-full -rotate-90 overflow-visible;
186
+ fill: none;
187
+ stroke: currentColor;
188
+ stroke-width: 1;
189
+ stroke-linecap: round;
190
+ }
191
+
192
+ .ui-room-countdown__track {
193
+ @apply opacity-20;
194
+ }
195
+
196
+ .ui-room-countdown__ring--out {
197
+ @apply opacity-0;
198
+ transform: rotate(-90deg) scale(1.3);
199
+ transition: all 0.8s cubic-bezier(0.16, 1, 0.3, 1);
200
+ }
201
+
202
+ .ui-room-countdown__progress {
203
+ stroke-dasharray: 1;
204
+ animation: ui-room-countdown-drain linear forwards;
205
+ }
206
+
207
+ .ui-room-countdown__spinner {
208
+ stroke-dasharray: 0.18 0.82;
209
+ transform-origin: 50px 50px;
210
+ animation: ui-room-countdown-spin 1.4s linear infinite;
211
+ }
212
+
213
+ .ui-room-countdown__head {
214
+ fill: currentColor;
215
+ stroke: none;
216
+ transform-origin: 50px 50px;
217
+ animation: ui-room-countdown-orbit linear forwards;
218
+ }
219
+
220
+ .ui-room-countdown__action {
221
+ @apply flex items-center justify-center;
222
+ }
223
+
224
+ .ui-room-countdown__digit {
225
+ @apply absolute inset-0 grid place-items-center leading-none;
226
+ }
227
+
228
+ .ui-room-countdown__label {
229
+ @apply absolute inset-0 flex items-center justify-center leading-none;
230
+ }
231
+
232
+ .ui-room-countdown__digit {
233
+ font-size: 0.44em;
234
+ font-weight: 600;
235
+ font-variant-numeric: tabular-nums;
236
+ letter-spacing: -0.03em;
237
+ }
238
+
239
+ .ui-room-countdown__label {
240
+ font-size: 0.095em;
241
+ font-weight: 500;
242
+ letter-spacing: -0.01em;
243
+ white-space: nowrap;
244
+ gap: 0.5em;
245
+ animation: ui-room-countdown-zoom 0.6s cubic-bezier(0.16, 1, 0.3, 1) 0.25s backwards;
246
+ }
247
+
248
+ .ui-room-countdown__rec {
249
+ @apply relative h-[0.5em] w-[0.5em] shrink-0 rounded-full bg-actions-danger-idle;
250
+ transform-origin: right center;
251
+ animation: ui-room-countdown-rec-in 0.45s cubic-bezier(0.16, 1, 0.3, 1) 0.4s backwards;
252
+ }
253
+
254
+ .ui-room-countdown__rec::after {
255
+ @apply absolute inset-0 rounded-full bg-actions-danger-idle content-[''];
256
+ animation: ui-room-countdown-rec-ping 1.8s cubic-bezier(0.16, 1, 0.3, 1) 0.6s infinite;
257
+ }
258
+
259
+ .ui-room-countdown-digit-enter-active {
260
+ animation: ui-room-countdown-digit-in 0.65s cubic-bezier(0.16, 1, 0.3, 1);
261
+ }
262
+
263
+ .ui-room-countdown-digit-leave-active {
264
+ transition: all 0.22s cubic-bezier(0.7, 0, 0.84, 0);
265
+ }
266
+
267
+ .ui-room-countdown-digit-leave-to {
268
+ opacity: 0;
269
+ filter: blur(0.03em);
270
+ transform: scale(0.6);
271
+ }
272
+
273
+ @keyframes ui-room-countdown-drain {
274
+ to {
275
+ stroke-dashoffset: 1;
276
+ }
277
+ }
278
+
279
+ @keyframes ui-room-countdown-digit-in {
280
+ 0% {
281
+ opacity: 0;
282
+ filter: blur(0.03em);
283
+ transform: scale(1.3);
284
+ }
285
+ 45% {
286
+ opacity: 1;
287
+ filter: blur(0);
288
+ }
289
+ 70% {
290
+ transform: scale(0.98);
291
+ }
292
+ 100% {
293
+ opacity: 1;
294
+ filter: blur(0);
295
+ transform: scale(1);
296
+ }
297
+ }
298
+
299
+ @keyframes ui-room-countdown-breath {
300
+ 0%,
301
+ 100% {
302
+ opacity: 0.4;
303
+ transform: scale(0.9);
304
+ }
305
+ 50% {
306
+ opacity: 0.9;
307
+ transform: scale(1.05);
308
+ }
309
+ }
310
+
311
+ @keyframes ui-room-countdown-spin {
312
+ to {
313
+ transform: rotate(360deg);
314
+ }
315
+ }
316
+
317
+ @keyframes ui-room-countdown-orbit {
318
+ to {
319
+ transform: rotate(360deg);
320
+ }
321
+ }
322
+
323
+ @keyframes ui-room-countdown-zoom {
324
+ from {
325
+ opacity: 0;
326
+ filter: blur(0.02em);
327
+ transform: scale(0.88);
328
+ }
329
+ to {
330
+ opacity: 1;
331
+ filter: blur(0);
332
+ transform: scale(1);
333
+ }
334
+ }
335
+
336
+ @keyframes ui-room-countdown-rec-in {
337
+ from {
338
+ opacity: 0;
339
+ transform: scale(0.5);
340
+ margin-right: -1em;
341
+ }
342
+ to {
343
+ opacity: 1;
344
+ transform: scale(1);
345
+ margin-right: 0;
346
+ }
347
+ }
348
+
349
+ @keyframes ui-room-countdown-rec-ping {
350
+ from {
351
+ opacity: 0.45;
352
+ transform: scale(1);
353
+ }
354
+ to {
355
+ opacity: 0;
356
+ transform: scale(2.2);
357
+ }
358
+ }
359
+
360
+ @media (prefers-reduced-motion: reduce) {
361
+ .ui-room-countdown__progress,
362
+ .ui-room-countdown__spinner,
363
+ .ui-room-countdown__label,
364
+ .ui-room-countdown__glass,
365
+ .ui-room-countdown__glass::after,
366
+ .ui-room-countdown__rec,
367
+ .ui-room-countdown__rec::after,
368
+ .ui-room-countdown__head,
369
+ .ui-room-countdown__ring--out,
370
+ .ui-room-countdown-digit-enter-active,
371
+ .ui-room-countdown-digit-leave-active {
372
+ animation: none;
373
+ transition: none;
374
+ }
375
+ }
376
+ </style>
@@ -6,8 +6,11 @@ import UiButton from '../UiButton/UiButton.vue'
6
6
 
7
7
  const props = withDefaults(defineProps<{
8
8
  openMenuLabel?: string
9
+ /** The shell canvas (gradient and overlays). Off when the host paints its own surface. */
10
+ showBackground?: boolean
9
11
  }>(), {
10
12
  openMenuLabel: 'Menu',
13
+ showBackground: true,
11
14
  })
12
15
 
13
16
  const slots = useSlots() as {
@@ -29,7 +32,10 @@ const fallbackLabel = computed(() => menuLabel.value ?? props.openMenuLabel)
29
32
  class="ui-shell h-dvh flex flex-col relative"
30
33
  data-sizes-primitives="Mode-1"
31
34
  >
32
- <div class="ui-shell-backgrounds absolute inset-0 grid grid-cols-1 grid-rows-1 z-0">
35
+ <div
36
+ v-if="showBackground"
37
+ class="ui-shell-backgrounds absolute inset-0 grid grid-cols-1 grid-rows-1 z-0"
38
+ >
33
39
  <div class="ui-shell-background col-span-full row-span-full bg-gradient-to-tl from-surface-primary-100 to-surface-primary-300" />
34
40
  <div class="ui-shell-background col-span-full row-span-full bg-surface-neutral-invert-alpha-600" />
35
41
  <div class="ui-shell-background col-span-full row-span-full bg-surface-primary-alpha-100" />
@@ -44,7 +50,7 @@ const fallbackLabel = computed(() => menuLabel.value ?? props.openMenuLabel)
44
50
  <div class="flex-1 flex w-full relative min-h-0">
45
51
  <div
46
52
  v-if="slots.sidemenu"
47
- class="dashboard-sidebar md:flex shrink-0 text-text-neutral-base flex z-40"
53
+ class="dashboard-sidebar md:flex shrink-0 text-text-neutral-base flex z-40 [anchor-name:--ui-shell-side-menu]"
48
54
  >
49
55
  <slot
50
56
  name="sidemenu"
@@ -52,7 +58,7 @@ const fallbackLabel = computed(() => menuLabel.value ?? props.openMenuLabel)
52
58
  />
53
59
  </div>
54
60
 
55
- <div class="dashboard-content flex-1 flex flex-col z-10 min-h-0">
61
+ <div class="dashboard-content flex-1 flex flex-col z-10 min-w-0 min-h-0">
56
62
  <!--
57
63
  Fallback mobile menu trigger. The hamburger normally lives in
58
64
  UiPageHeader, but a page can render without a header — leaving no way
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import type { Slot } from 'vue'
2
+ import type { ComponentPublicInstance, Slot } from 'vue'
3
3
  import type { SideMenuCollapsedItem, SideMenuItemProps, SideMenuMoreItem } from './types'
4
4
  import UiSideMenuItem from './UiSideMenuItem.vue'
5
5
  import UiLogo from '../UiLogo/UiLogo.vue'
@@ -7,10 +7,15 @@ import UiButton from '../UiButton/UiButton.vue'
7
7
  import UiPopover from '../UiPopover/UiPopover.vue'
8
8
  import UiPopoverTrigger from '../UiPopover/UiPopoverTrigger.vue'
9
9
  import UiPopoverContent from '../UiPopover/UiPopoverContent.vue'
10
+ import UiTooltipProvider from '../UiTooltip/UiTooltipProvider.vue'
11
+ import UiTooltip from '../UiTooltip/UiTooltip.vue'
12
+ import UiTooltipTrigger from '../UiTooltip/UiTooltipTrigger.vue'
13
+ import UiTooltipContent from '../UiTooltip/UiTooltipContent.vue'
10
14
  import { useMobileMenu } from '../../composables/useMobileMenu'
15
+ import { usePullGesture } from '../../composables/usePullGesture'
11
16
  import { useTranslate } from '../../utils/i18n'
12
- import { focusFirstMenuItem } from '../../utils'
13
- import { computed, onBeforeUnmount, onMounted, provide, ref } from 'vue'
17
+ import { focusFirstMenuItem } from '../../utils/a11y'
18
+ import { computed, onBeforeUnmount, onMounted, provide, ref, watch } from 'vue'
14
19
  import { SIDE_MENU_LAYOUT_KEY } from './injection'
15
20
  const { close, isOpen } = useMobileMenu()
16
21
  const translate = useTranslate()
@@ -81,6 +86,8 @@ const slots = defineSlots<{
81
86
  * `close` callback to dismiss the popover (e.g. when a nested popover opens).
82
87
  */
83
88
  collapsedMenuExtra?(props: { close: () => void }): Slot
89
+ /** Tooltip shown under the logo while it is pulled, with the stage reached so far. */
90
+ logoPullHint?(props: { stage: number }): Slot
84
91
  }>()
85
92
 
86
93
  const props = withDefaults(defineProps<{
@@ -105,6 +112,16 @@ const props = withDefaults(defineProps<{
105
112
  */
106
113
  moreBadge?: number | boolean
107
114
  showLivestormLogo?: boolean
115
+ /**
116
+ * Pointer travel (px, ascending) at which pulling the logo, in any
117
+ * direction, reaches each stage; `logoPull` emits the stage reached on
118
+ * release. Empty disables the gesture.
119
+ */
120
+ logoPullStages?: number[]
121
+ /** Travel (px) after which the pulled logo starts resisting; defaults to the last stage. */
122
+ logoPullResistFrom?: number
123
+ /** Visible travel the resisting logo tends toward; defaults to five times the last stage. */
124
+ logoPullMaxOffset?: number
108
125
  // Accessibility labels
109
126
  logoAlt?: string
110
127
  closeMenuLabel?: string
@@ -116,6 +133,9 @@ const props = withDefaults(defineProps<{
116
133
  organizationId?: string
117
134
  }>(), {
118
135
  showLivestormLogo: true,
136
+ logoPullStages: () => [],
137
+ logoPullResistFrom: undefined,
138
+ logoPullMaxOffset: undefined,
119
139
  logoAlt: 'Livestorm',
120
140
  closeMenuLabel: 'Close navigation menu',
121
141
  mainNavigationLabel: 'Main navigation',
@@ -162,7 +182,53 @@ const hasCollapsedMenu = computed(
162
182
  () => (!!props.collapsedMenuItems && props.collapsedMenuItems.length > 0) || !!slots.collapsedMenuExtra,
163
183
  )
164
184
 
185
+ const emit = defineEmits<{
186
+ logoPull: [stage: number]
187
+ }>()
188
+
189
+ const pull = usePullGesture({
190
+ stages: () => props.logoPullStages,
191
+ resistFrom: () => props.logoPullResistFrom,
192
+ maxOffset: () => props.logoPullMaxOffset,
193
+ onRelease: stage => emit('logoPull', stage),
194
+ })
195
+
196
+ // A lean toward the pull and a size step per stage make the gesture legible;
197
+ // grabbing shrinks the logo a touch, as if lifted out of its socket.
198
+ const LOGO_PULL_DEG_PER_PX = 0.15
199
+ const LOGO_PULL_MAX_DEG = 30
200
+ const LOGO_PULL_GRAB_SHRINK_PCT = 4
201
+ const LOGO_PULL_STAGE_GROWTH_PCT = 6
202
+
203
+ const logoPullStyle = computed(() => {
204
+ if (!pull.enabled.value) return undefined
205
+ const { x, y } = pull.offset.value
206
+ const shrink = pull.isPulling.value ? LOGO_PULL_GRAB_SHRINK_PCT : 0
207
+ const lean = Math.max(-LOGO_PULL_MAX_DEG, Math.min(LOGO_PULL_MAX_DEG, x * LOGO_PULL_DEG_PER_PX))
208
+ return {
209
+ translate: `${x}px ${y}px`,
210
+ rotate: `${lean}deg`,
211
+ scale: String((100 - shrink + pull.stage.value * LOGO_PULL_STAGE_GROWTH_PCT) / 100),
212
+ }
213
+ })
214
+
215
+ // Each new stage ticks: a quick overshoot of the logo and a haptic where
216
+ // supported. Reduced motion keeps the haptic only.
217
+ const logo = ref<ComponentPublicInstance | null>(null)
218
+ watch(pull.stage, (stage, previous) => {
219
+ if (stage <= previous) return
220
+ if ('vibrate' in navigator) navigator.vibrate(10)
221
+ if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) return
222
+ const el = logo.value?.$el as HTMLElement | undefined
223
+ el?.animate?.(
224
+ [{ transform: 'scale(1)' }, { transform: 'scale(1.18)', offset: 0.4 }, { transform: 'scale(1)' }],
225
+ { duration: 220, easing: 'ease-out' },
226
+ )
227
+ })
228
+
165
229
  function handleLogoClick (event: MouseEvent) {
230
+ // The browser still fires a click after a pull; keep it off the click count.
231
+ if (pull.consumeDrag()) return
166
232
  if (event.detail === 4) {
167
233
  if (navigator.clipboard && props.organizationId) {
168
234
  navigator.clipboard.writeText(props.organizationId)
@@ -182,24 +248,63 @@ function handleLogoClick (event: MouseEvent) {
182
248
  <!-- Skip link for accessibility -->
183
249
  <router-link
184
250
  to="/"
185
- class="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:bg-blue-600 focus:text-white focus:px-4 focus:py-2 focus:rounded bg-surface-overlay-alpha"
251
+ class="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:bg-actions-primary-idle focus:text-text-neutral-invert-base focus:px-4 focus:py-2 focus:rounded-row bg-surface-overlay-alpha"
186
252
  >
187
253
  {{ skipToMainContentLabel }}
188
254
  </router-link>
189
255
  <!-- Top -->
190
256
  <div class="flex flex-col md:items-center gap-8">
191
257
  <div class="flex items-center justify-between">
192
- <UiLogo
258
+ <div
193
259
  v-if="showLivestormLogo"
194
- :height="2.5"
195
- :width="2.5"
196
- :themed="false"
197
- :animated="false"
198
- inverted="auto"
199
- :label="logoAlt"
200
- class="ml-4 md:ml-0"
201
- @click="handleLogoClick"
202
- />
260
+ class="relative ml-4 md:ml-0"
261
+ :class="{ 'z-10': pull.enabled.value }"
262
+ >
263
+ <div
264
+ v-if="pull.enabled.value"
265
+ class="logo-pull-socket absolute top-0 left-0 w-10 h-10 rounded-[35%] pointer-events-none"
266
+ :class="{ 'logo-pull-socket-visible': pull.isPulling.value }"
267
+ />
268
+ <!-- Controlled tooltip: shown only while pulling, never on hover. -->
269
+ <UiTooltipProvider>
270
+ <UiTooltip :open="!!slots.logoPullHint && pull.isPulling.value">
271
+ <UiTooltipTrigger as-child>
272
+ <div
273
+ :class="{
274
+ 'logo-pull touch-none select-none cursor-grab': pull.enabled.value,
275
+ 'logo-pull-active cursor-grabbing': pull.isPulling.value,
276
+ }"
277
+ :style="logoPullStyle"
278
+ @pointerdown="pull.onPointerDown"
279
+ @pointermove="pull.onPointerMove"
280
+ @pointerup="pull.onPointerUp"
281
+ @pointercancel="pull.onPointerCancel"
282
+ @click="handleLogoClick"
283
+ >
284
+ <UiLogo
285
+ ref="logo"
286
+ :height="2.5"
287
+ :width="2.5"
288
+ :themed="false"
289
+ :animated="false"
290
+ inverted="auto"
291
+ :label="logoAlt"
292
+ />
293
+ </div>
294
+ </UiTooltipTrigger>
295
+ <UiTooltipContent
296
+ side="bottom"
297
+ :side-offset="8"
298
+ update-position-strategy="always"
299
+ >
300
+ <slot
301
+ name="logoPullHint"
302
+ :stage="pull.stage.value"
303
+ />
304
+ </UiTooltipContent>
305
+ </UiTooltip>
306
+ </UiTooltipProvider>
307
+ </div>
203
308
  <div class="md:hidden">
204
309
  <UiButton
205
310
  icon="i-ph-x"
@@ -311,14 +416,14 @@ function handleLogoClick (event: MouseEvent) {
311
416
  :align="isMobile ? 'center' : 'end'"
312
417
  :side-offset="8"
313
418
  :collision-padding="16"
314
- class="border-none bg-surface-neutral-300 rounded-2xl shadow-shadows-drop-shadow-2xl overflow-hidden data-[state=closed]:hidden"
419
+ class="border-none bg-surface-neutral-300 shadow-shadows-drop-shadow-2xl overflow-hidden data-[state=closed]:hidden"
315
420
  :class="isMobile
316
421
  ? 'w-(--reka-popover-trigger-width)'
317
422
  : 'w-[calc(var(--reka-popover-trigger-width)+2rem)]'"
318
423
  data-colors-semantic="light"
319
424
  @open-auto-focus="handleOpenAutoFocus"
320
425
  >
321
- <ul class="flex flex-col md:items-center gap-2 p-2">
426
+ <ul class="flex flex-col md:items-center gap-2 px-1 py-2">
322
427
  <li
323
428
  v-for="item in collapsedMenuItems"
324
429
  :key="`collapsed-menu-item-${item.label}`"
@@ -432,11 +537,11 @@ function handleLogoClick (event: MouseEvent) {
432
537
  side="right"
433
538
  align="end"
434
539
  :side-offset="8"
435
- class="border-none bg-surface-neutral-300 rounded-2xl shadow-shadows-drop-shadow-2xl overflow-hidden"
540
+ class="border-none bg-surface-neutral-300 shadow-shadows-drop-shadow-2xl overflow-hidden"
436
541
  data-colors-semantic="light"
437
542
  @open-auto-focus="handleOpenAutoFocus"
438
543
  >
439
- <div class="flex flex-col md:items-center gap-2 p-2">
544
+ <div class="flex flex-col md:items-center gap-2 px-1 py-2">
440
545
  <li
441
546
  v-for="item in bottomMenuItems"
442
547
  :key="`popover-menu-item-${item.label}`"
@@ -489,6 +594,38 @@ function handleLogoClick (event: MouseEvent) {
489
594
  </template>
490
595
 
491
596
  <style scoped>
597
+ /* Logo pull: free while dragging, springs back on release. */
598
+ .logo-pull {
599
+ transition:
600
+ translate 400ms cubic-bezier(0.34, 1.56, 0.64, 1),
601
+ rotate 400ms cubic-bezier(0.34, 1.56, 0.64, 1),
602
+ scale 150ms ease-out;
603
+ }
604
+
605
+ .logo-pull-active {
606
+ transition: scale 150ms ease-out;
607
+ }
608
+
609
+ /* Recess left where the logo rests; lingers until the logo has landed. */
610
+ .logo-pull-socket {
611
+ background: rgb(0 0 0 / 0.12);
612
+ box-shadow: inset 0 1px 3px rgb(0 0 0 / 0.25);
613
+ opacity: 0;
614
+ transition: opacity 200ms ease 250ms;
615
+ }
616
+
617
+ .logo-pull-socket-visible {
618
+ opacity: 1;
619
+ transition-delay: 0ms;
620
+ }
621
+
622
+ @media (prefers-reduced-motion: reduce) {
623
+ .logo-pull,
624
+ .logo-pull-socket {
625
+ transition: none;
626
+ }
627
+ }
628
+
492
629
  /* Hide the more menu by default */
493
630
  .show-on-short-height-desktop-only {
494
631
  display: none;