@pascal-app/viewer 1.1.0 → 1.1.1

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 (224) hide show
  1. package/README.md +157 -0
  2. package/dist/components/viewer/drone-controller.d.ts.map +1 -1
  3. package/dist/components/viewer/drone-controller.js +1 -5
  4. package/dist/components/viewer/first-person/build-collider-world.d.ts +14 -0
  5. package/dist/components/viewer/first-person/build-collider-world.d.ts.map +1 -0
  6. package/dist/components/viewer/first-person/build-collider-world.js +426 -0
  7. package/dist/components/viewer/first-person/ground-holes.d.ts +22 -0
  8. package/dist/components/viewer/first-person/ground-holes.d.ts.map +1 -0
  9. package/dist/components/viewer/first-person/ground-holes.js +116 -0
  10. package/dist/components/viewer/first-person/mechanism-targets.d.ts +27 -0
  11. package/dist/components/viewer/first-person/mechanism-targets.d.ts.map +1 -0
  12. package/dist/components/viewer/first-person/mechanism-targets.js +79 -0
  13. package/dist/components/viewer/first-person/terrain-collider.d.ts +32 -0
  14. package/dist/components/viewer/first-person/terrain-collider.d.ts.map +1 -0
  15. package/dist/components/viewer/first-person/terrain-collider.js +175 -0
  16. package/dist/components/viewer/glb-walkthrough-controller.d.ts +1 -1
  17. package/dist/components/viewer/glb-walkthrough-controller.d.ts.map +1 -1
  18. package/dist/components/viewer/glb-walkthrough-controller.js +3 -4
  19. package/dist/components/viewer/live-walkthrough-controller.d.ts +17 -0
  20. package/dist/components/viewer/live-walkthrough-controller.d.ts.map +1 -0
  21. package/dist/components/viewer/live-walkthrough-controller.js +1449 -0
  22. package/dist/components/viewer/post-processing.d.ts.map +1 -1
  23. package/dist/components/viewer/post-processing.js +22 -1
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +3 -0
  27. package/dist/lib/daylight/room-map.d.ts +29 -4
  28. package/dist/lib/daylight/room-map.d.ts.map +1 -1
  29. package/dist/lib/daylight/room-map.js +219 -36
  30. package/dist/lib/daylight/room-scene.d.ts.map +1 -1
  31. package/dist/lib/daylight/room-scene.js +9 -3
  32. package/dist/lib/daylight/rooms.d.ts +15 -6
  33. package/dist/lib/daylight/rooms.d.ts.map +1 -1
  34. package/dist/lib/daylight/rooms.js +49 -9
  35. package/dist/lib/measurement-presentation.d.ts +2 -0
  36. package/dist/lib/measurement-presentation.d.ts.map +1 -1
  37. package/dist/lib/measurement-presentation.js +6 -0
  38. package/dist/lib/typing-target.d.ts +2 -0
  39. package/dist/lib/typing-target.d.ts.map +1 -0
  40. package/dist/lib/typing-target.js +7 -0
  41. package/dist/lib/viewer-config.d.ts +6 -0
  42. package/dist/lib/viewer-config.d.ts.map +1 -1
  43. package/dist/lib/viewer-config.js +2 -0
  44. package/dist/sfx/audio-settings.d.ts +81 -0
  45. package/dist/sfx/audio-settings.d.ts.map +1 -0
  46. package/dist/sfx/audio-settings.js +166 -0
  47. package/dist/sfx/index.d.ts +6 -0
  48. package/dist/sfx/index.d.ts.map +1 -0
  49. package/dist/sfx/index.js +5 -0
  50. package/dist/sfx/interaction-sounds.d.ts +7 -0
  51. package/dist/sfx/interaction-sounds.d.ts.map +1 -0
  52. package/dist/sfx/interaction-sounds.js +39 -0
  53. package/dist/sfx/player.d.ts +31 -0
  54. package/dist/sfx/player.d.ts.map +1 -0
  55. package/dist/sfx/player.js +255 -0
  56. package/dist/sfx/sounds.d.ts +60 -0
  57. package/dist/sfx/sounds.d.ts.map +1 -0
  58. package/dist/sfx/sounds.js +25 -0
  59. package/dist/sfx/use-viewer-ui-sounds.d.ts +8 -0
  60. package/dist/sfx/use-viewer-ui-sounds.d.ts.map +1 -0
  61. package/dist/sfx/use-viewer-ui-sounds.js +42 -0
  62. package/dist/store/use-first-person-hud.d.ts +13 -0
  63. package/dist/store/use-first-person-hud.d.ts.map +1 -0
  64. package/dist/store/use-first-person-hud.js +21 -0
  65. package/dist/systems/roof/roof-system.d.ts.map +1 -1
  66. package/dist/systems/roof/roof-system.js +27 -13
  67. package/dist/ui/components/action-button.d.ts +14 -0
  68. package/dist/ui/components/action-button.d.ts.map +1 -0
  69. package/dist/ui/components/action-button.js +21 -0
  70. package/dist/ui/components/action-menu-placement.d.ts +7 -0
  71. package/dist/ui/components/action-menu-placement.d.ts.map +1 -0
  72. package/dist/ui/components/action-menu-placement.js +10 -0
  73. package/dist/ui/components/floorplan-compass-button.d.ts +10 -0
  74. package/dist/ui/components/floorplan-compass-button.d.ts.map +1 -0
  75. package/dist/ui/components/floorplan-compass-button.js +22 -0
  76. package/dist/ui/components/follow-pascal-toggle.d.ts +6 -0
  77. package/dist/ui/components/follow-pascal-toggle.d.ts.map +1 -0
  78. package/dist/ui/components/follow-pascal-toggle.js +21 -0
  79. package/dist/ui/components/localized-html.d.ts +9 -0
  80. package/dist/ui/components/localized-html.d.ts.map +1 -0
  81. package/dist/ui/components/localized-html.js +16 -0
  82. package/dist/ui/components/render-settings-menu.d.ts +9 -0
  83. package/dist/ui/components/render-settings-menu.d.ts.map +1 -0
  84. package/dist/ui/components/render-settings-menu.js +145 -0
  85. package/dist/ui/components/rooms/room-highlight.d.ts +10 -0
  86. package/dist/ui/components/rooms/room-highlight.d.ts.map +1 -0
  87. package/dist/ui/components/rooms/room-highlight.js +56 -0
  88. package/dist/ui/components/rooms/room-labels.d.ts +278 -0
  89. package/dist/ui/components/rooms/room-labels.d.ts.map +1 -0
  90. package/dist/ui/components/rooms/room-labels.js +1295 -0
  91. package/dist/ui/components/rooms/viewer-rooms.d.ts +14 -0
  92. package/dist/ui/components/rooms/viewer-rooms.d.ts.map +1 -0
  93. package/dist/ui/components/rooms/viewer-rooms.js +123 -0
  94. package/dist/ui/components/scene-loader.d.ts +18 -0
  95. package/dist/ui/components/scene-loader.d.ts.map +1 -0
  96. package/dist/ui/components/scene-loader.js +29 -0
  97. package/dist/ui/components/sky-control.d.ts +37 -0
  98. package/dist/ui/components/sky-control.d.ts.map +1 -0
  99. package/dist/ui/components/sky-control.js +382 -0
  100. package/dist/ui/components/use-viewer-camera-navigation-sync.d.ts +4 -0
  101. package/dist/ui/components/use-viewer-camera-navigation-sync.d.ts.map +1 -0
  102. package/dist/ui/components/use-viewer-camera-navigation-sync.js +117 -0
  103. package/dist/ui/components/viewer-controls-bar.d.ts +20 -0
  104. package/dist/ui/components/viewer-controls-bar.d.ts.map +1 -0
  105. package/dist/ui/components/viewer-controls-bar.js +130 -0
  106. package/dist/ui/components/viewer-hover-label.d.ts +14 -0
  107. package/dist/ui/components/viewer-hover-label.d.ts.map +1 -0
  108. package/dist/ui/components/viewer-hover-label.js +28 -0
  109. package/dist/ui/components/viewer-scene-header.d.ts +34 -0
  110. package/dist/ui/components/viewer-scene-header.d.ts.map +1 -0
  111. package/dist/ui/components/viewer-scene-header.js +92 -0
  112. package/dist/ui/components/viewer-selection-manager.d.ts +7 -0
  113. package/dist/ui/components/viewer-selection-manager.d.ts.map +1 -0
  114. package/dist/ui/components/viewer-selection-manager.js +116 -0
  115. package/dist/ui/components/viewer-stage-modes.d.ts +7 -0
  116. package/dist/ui/components/viewer-stage-modes.d.ts.map +1 -0
  117. package/dist/ui/components/viewer-stage-modes.js +42 -0
  118. package/dist/ui/components/viewer-stage-switcher.d.ts +10 -0
  119. package/dist/ui/components/viewer-stage-switcher.d.ts.map +1 -0
  120. package/dist/ui/components/viewer-stage-switcher.js +16 -0
  121. package/dist/ui/components/viewer-stage.d.ts +25 -0
  122. package/dist/ui/components/viewer-stage.d.ts.map +1 -0
  123. package/dist/ui/components/viewer-stage.js +107 -0
  124. package/dist/ui/components/walkthrough-hud.d.ts +29 -0
  125. package/dist/ui/components/walkthrough-hud.d.ts.map +1 -0
  126. package/dist/ui/components/walkthrough-hud.js +55 -0
  127. package/dist/ui/floorplan/floorplan-camera-sync.d.ts +22 -0
  128. package/dist/ui/floorplan/floorplan-camera-sync.d.ts.map +1 -0
  129. package/dist/ui/floorplan/floorplan-camera-sync.js +157 -0
  130. package/dist/ui/floorplan/floorplan-dimension-renderer.d.ts +61 -0
  131. package/dist/ui/floorplan/floorplan-dimension-renderer.d.ts.map +1 -0
  132. package/dist/ui/floorplan/floorplan-dimension-renderer.js +280 -0
  133. package/dist/ui/floorplan/floorplan-geometry-renderer.d.ts +54 -0
  134. package/dist/ui/floorplan/floorplan-geometry-renderer.d.ts.map +1 -0
  135. package/dist/ui/floorplan/floorplan-geometry-renderer.js +317 -0
  136. package/dist/ui/floorplan/floorplan-label-angle.d.ts +24 -0
  137. package/dist/ui/floorplan/floorplan-label-angle.d.ts.map +1 -0
  138. package/dist/ui/floorplan/floorplan-label-angle.js +60 -0
  139. package/dist/ui/floorplan/floorplan-navigation-sync.d.ts +18 -0
  140. package/dist/ui/floorplan/floorplan-navigation-sync.d.ts.map +1 -0
  141. package/dist/ui/floorplan/floorplan-navigation-sync.js +41 -0
  142. package/dist/ui/floorplan/floorplan-preview-geometry.d.ts +26 -0
  143. package/dist/ui/floorplan/floorplan-preview-geometry.d.ts.map +1 -0
  144. package/dist/ui/floorplan/floorplan-preview-geometry.js +173 -0
  145. package/dist/ui/floorplan/floorplan-preview-navigation.d.ts +22 -0
  146. package/dist/ui/floorplan/floorplan-preview-navigation.d.ts.map +1 -0
  147. package/dist/ui/floorplan/floorplan-preview-navigation.js +41 -0
  148. package/dist/ui/floorplan/floorplan-preview-visibility.d.ts +8 -0
  149. package/dist/ui/floorplan/floorplan-preview-visibility.d.ts.map +1 -0
  150. package/dist/ui/floorplan/floorplan-preview-visibility.js +21 -0
  151. package/dist/ui/floorplan/floorplan-preview.d.ts +19 -0
  152. package/dist/ui/floorplan/floorplan-preview.d.ts.map +1 -0
  153. package/dist/ui/floorplan/floorplan-preview.js +700 -0
  154. package/dist/ui/hooks/use-mobile.d.ts +2 -0
  155. package/dist/ui/hooks/use-mobile.d.ts.map +1 -0
  156. package/dist/ui/hooks/use-mobile.js +14 -0
  157. package/dist/ui/index.d.ts +49 -0
  158. package/dist/ui/index.d.ts.map +1 -0
  159. package/dist/ui/index.js +48 -0
  160. package/dist/ui/lib/below-grade.d.ts +38 -0
  161. package/dist/ui/lib/below-grade.d.ts.map +1 -0
  162. package/dist/ui/lib/below-grade.js +102 -0
  163. package/dist/ui/lib/camera-pose.d.ts +19 -0
  164. package/dist/ui/lib/camera-pose.d.ts.map +1 -0
  165. package/dist/ui/lib/camera-pose.js +113 -0
  166. package/dist/ui/lib/cn.d.ts +3 -0
  167. package/dist/ui/lib/cn.d.ts.map +1 -0
  168. package/dist/ui/lib/cn.js +5 -0
  169. package/dist/ui/lib/level-name.d.ts +10 -0
  170. package/dist/ui/lib/level-name.d.ts.map +1 -0
  171. package/dist/ui/lib/level-name.js +33 -0
  172. package/dist/ui/lib/node-display-label.d.ts +8 -0
  173. package/dist/ui/lib/node-display-label.d.ts.map +1 -0
  174. package/dist/ui/lib/node-display-label.js +36 -0
  175. package/dist/ui/lib/room-area.d.ts +3 -0
  176. package/dist/ui/lib/room-area.d.ts.map +1 -0
  177. package/dist/ui/lib/room-area.js +8 -0
  178. package/dist/ui/lib/room-assembly-overlay.d.ts +46 -0
  179. package/dist/ui/lib/room-assembly-overlay.d.ts.map +1 -0
  180. package/dist/ui/lib/room-assembly-overlay.js +222 -0
  181. package/dist/ui/lib/room-name-messages.d.ts +28 -0
  182. package/dist/ui/lib/room-name-messages.d.ts.map +1 -0
  183. package/dist/ui/lib/room-name-messages.js +112 -0
  184. package/dist/ui/lib/room-selection.d.ts +58 -0
  185. package/dist/ui/lib/room-selection.d.ts.map +1 -0
  186. package/dist/ui/lib/room-selection.js +297 -0
  187. package/dist/ui/lib/scene-theme-name.d.ts +4 -0
  188. package/dist/ui/lib/scene-theme-name.d.ts.map +1 -0
  189. package/dist/ui/lib/scene-theme-name.js +22 -0
  190. package/dist/ui/lib/selection-modifiers.d.ts +20 -0
  191. package/dist/ui/lib/selection-modifiers.d.ts.map +1 -0
  192. package/dist/ui/lib/selection-modifiers.js +15 -0
  193. package/dist/ui/lib/viewer-selection.d.ts +132 -0
  194. package/dist/ui/lib/viewer-selection.d.ts.map +1 -0
  195. package/dist/ui/lib/viewer-selection.js +462 -0
  196. package/dist/ui/lib/zone-content.d.ts +6 -0
  197. package/dist/ui/lib/zone-content.d.ts.map +1 -0
  198. package/dist/ui/lib/zone-content.js +96 -0
  199. package/dist/ui/primitives/button.d.ts +11 -0
  200. package/dist/ui/primitives/button.d.ts.map +1 -0
  201. package/dist/ui/primitives/button.js +35 -0
  202. package/dist/ui/primitives/dropdown-menu.d.ts +26 -0
  203. package/dist/ui/primitives/dropdown-menu.d.ts.map +1 -0
  204. package/dist/ui/primitives/dropdown-menu.js +53 -0
  205. package/dist/ui/primitives/popover.d.ts +8 -0
  206. package/dist/ui/primitives/popover.d.ts.map +1 -0
  207. package/dist/ui/primitives/popover.js +17 -0
  208. package/dist/ui/primitives/switch.d.ts +5 -0
  209. package/dist/ui/primitives/switch.d.ts.map +1 -0
  210. package/dist/ui/primitives/switch.js +8 -0
  211. package/dist/ui/primitives/tooltip.d.ts +8 -0
  212. package/dist/ui/primitives/tooltip.d.ts.map +1 -0
  213. package/dist/ui/primitives/tooltip.js +17 -0
  214. package/dist/ui/store/camera-pose-store.d.ts +17 -0
  215. package/dist/ui/store/camera-pose-store.d.ts.map +1 -0
  216. package/dist/ui/store/camera-pose-store.js +15 -0
  217. package/dist/ui/store/navigation-sync-pose-store.d.ts +26 -0
  218. package/dist/ui/store/navigation-sync-pose-store.d.ts.map +1 -0
  219. package/dist/ui/store/navigation-sync-pose-store.js +16 -0
  220. package/dist/ui/store/use-follow-pascal.d.ts +30 -0
  221. package/dist/ui/store/use-follow-pascal.d.ts.map +1 -0
  222. package/dist/ui/store/use-follow-pascal.js +28 -0
  223. package/dist/ui/theme.css +339 -0
  224. package/package.json +34 -7
@@ -0,0 +1,53 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
4
+ import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';
5
+ import { cn } from '../lib/cn';
6
+ function DropdownMenu({ ...props }) {
7
+ return _jsx(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
8
+ }
9
+ function DropdownMenuPortal({ ...props }) {
10
+ return _jsx(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
11
+ }
12
+ function DropdownMenuTrigger({ ...props }) {
13
+ return _jsx(DropdownMenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
14
+ }
15
+ function DropdownMenuContent({ className, sideOffset = 4, ...props }) {
16
+ return (_jsx(DropdownMenuPrimitive.Portal, { children: _jsx(DropdownMenuPrimitive.Content, { className: cn('data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=closed]:animate-out data-[state=open]:animate-in', className), "data-slot": "dropdown-menu-content", sideOffset: sideOffset, ...props }) }));
17
+ }
18
+ function DropdownMenuGroup({ ...props }) {
19
+ return _jsx(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
20
+ }
21
+ function DropdownMenuItem({ className, inset, variant = 'default', ...props }) {
22
+ return (_jsx(DropdownMenuPrimitive.Item, { className: cn("relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 font-barlow text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-inset:pl-8 data-[variant=destructive]:text-destructive data-disabled:opacity-50 data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 data-[variant=destructive]:*:[svg]:text-destructive!", className), "data-inset": inset, "data-slot": "dropdown-menu-item", "data-variant": variant, ...props }));
23
+ }
24
+ function DropdownMenuCheckboxItem({ className, children, checked, ...props }) {
25
+ return (_jsxs(DropdownMenuPrimitive.CheckboxItem, { checked: checked, className: cn("relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 font-barlow text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0", className), "data-slot": "dropdown-menu-checkbox-item", ...props, children: [_jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: _jsx(DropdownMenuPrimitive.ItemIndicator, { children: _jsx(CheckIcon, { className: "size-4" }) }) }), children] }));
26
+ }
27
+ function DropdownMenuRadioGroup({ ...props }) {
28
+ return _jsx(DropdownMenuPrimitive.RadioGroup, { "data-slot": "dropdown-menu-radio-group", ...props });
29
+ }
30
+ function DropdownMenuRadioItem({ className, children, ...props }) {
31
+ return (_jsxs(DropdownMenuPrimitive.RadioItem, { className: cn("relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 font-barlow text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0", className), "data-slot": "dropdown-menu-radio-item", ...props, children: [_jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: _jsx(DropdownMenuPrimitive.ItemIndicator, { children: _jsx(CircleIcon, { className: "size-2 fill-current" }) }) }), children] }));
32
+ }
33
+ function DropdownMenuLabel({ className, inset, ...props }) {
34
+ return (_jsx(DropdownMenuPrimitive.Label, { className: cn('px-2 py-1.5 font-barlow font-medium text-sm data-inset:pl-8', className), "data-inset": inset, "data-slot": "dropdown-menu-label", ...props }));
35
+ }
36
+ function DropdownMenuSeparator({ className, ...props }) {
37
+ return (_jsx(DropdownMenuPrimitive.Separator, { className: cn('-mx-1 my-1 h-px bg-border', className), "data-slot": "dropdown-menu-separator", ...props }));
38
+ }
39
+ function DropdownMenuShortcut({ className, ...props }) {
40
+ return (_jsx("span", { className: cn('ml-auto text-muted-foreground text-xs tracking-widest', className), "data-slot": "dropdown-menu-shortcut", ...props }));
41
+ }
42
+ function DropdownMenuSub({ ...props }) {
43
+ return _jsx(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
44
+ }
45
+ function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
46
+ return (_jsxs(DropdownMenuPrimitive.SubTrigger, { className: cn("flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 font-barlow text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-inset:pl-8 data-[state=open]:text-accent-foreground [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0", className), "data-inset": inset, "data-slot": "dropdown-menu-sub-trigger", ...props, children: [children, _jsx(ChevronRightIcon, { className: "ml-auto size-4" })] }));
47
+ }
48
+ function DropdownMenuSubContent({ className, ...props }) {
49
+ // Portalled so the side-opening submenu escapes the parent content's
50
+ // `overflow-x-hidden` clip (otherwise it renders but is invisible).
51
+ return (_jsx(DropdownMenuPrimitive.Portal, { children: _jsx(DropdownMenuPrimitive.SubContent, { className: cn('data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=closed]:animate-out data-[state=open]:animate-in', className), "data-slot": "dropdown-menu-sub-content", ...props }) }));
52
+ }
53
+ export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, };
@@ -0,0 +1,8 @@
1
+ import * as PopoverPrimitive from '@radix-ui/react-popover';
2
+ import type * as React from 'react';
3
+ declare function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>): React.JSX.Element;
4
+ declare function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>): React.JSX.Element;
5
+ declare function PopoverContent({ className, align, sideOffset, ...props }: React.ComponentProps<typeof PopoverPrimitive.Content>): React.JSX.Element;
6
+ declare function PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Anchor>): React.JSX.Element;
7
+ export { Popover, PopoverAnchor, PopoverContent, PopoverTrigger };
8
+ //# sourceMappingURL=popover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../../src/ui/primitives/popover.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAA;AAC3D,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AAInC,iBAAS,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,IAAI,CAAC,qBAEhF;AAED,iBAAS,cAAc,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,qBAE1F;AAED,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,KAAgB,EAChB,UAAc,EACd,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,qBAevD;AAED,iBAAS,aAAa,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,MAAM,CAAC,qBAExF;AAED,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,CAAA"}
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import * as PopoverPrimitive from '@radix-ui/react-popover';
4
+ import { cn } from '../lib/cn';
5
+ function Popover({ ...props }) {
6
+ return _jsx(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
7
+ }
8
+ function PopoverTrigger({ ...props }) {
9
+ return _jsx(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
10
+ }
11
+ function PopoverContent({ className, align = 'center', sideOffset = 4, ...props }) {
12
+ return (_jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { align: align, className: cn('data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-hidden data-[state=closed]:animate-out data-[state=open]:animate-in', className), "data-slot": "popover-content", sideOffset: sideOffset, ...props }) }));
13
+ }
14
+ function PopoverAnchor({ ...props }) {
15
+ return _jsx(PopoverPrimitive.Anchor, { "data-slot": "popover-anchor", ...props });
16
+ }
17
+ export { Popover, PopoverAnchor, PopoverContent, PopoverTrigger };
@@ -0,0 +1,5 @@
1
+ import * as SwitchPrimitives from '@radix-ui/react-switch';
2
+ import * as React from 'react';
3
+ declare const Switch: React.ForwardRefExoticComponent<Omit<SwitchPrimitives.SwitchProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
4
+ export { Switch };
5
+ //# sourceMappingURL=switch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/ui/primitives/switch.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAA;AAC1D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,QAAA,MAAM,MAAM,8JAkBV,CAAA;AAGF,OAAO,EAAE,MAAM,EAAE,CAAA"}
@@ -0,0 +1,8 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import * as SwitchPrimitives from '@radix-ui/react-switch';
4
+ import * as React from 'react';
5
+ import { cn } from '../lib/cn';
6
+ const Switch = React.forwardRef(({ className, ...props }, ref) => (_jsx(SwitchPrimitives.Root, { className: cn('peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-xs transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input', className), ...props, ref: ref, children: _jsx(SwitchPrimitives.Thumb, { className: cn('pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0') }) })));
7
+ Switch.displayName = SwitchPrimitives.Root.displayName;
8
+ export { Switch };
@@ -0,0 +1,8 @@
1
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
2
+ import type * as React from 'react';
3
+ declare function TooltipProvider({ delayDuration, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>): React.JSX.Element;
4
+ declare function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>): React.JSX.Element;
5
+ declare function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>): React.JSX.Element;
6
+ declare function TooltipContent({ className, sideOffset, children, ...props }: React.ComponentProps<typeof TooltipPrimitive.Content>): React.JSX.Element;
7
+ export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
8
+ //# sourceMappingURL=tooltip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../../src/ui/primitives/tooltip.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAA;AAC3D,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AAInC,iBAAS,eAAe,CAAC,EACvB,aAAiB,EACjB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,qBAQxD;AAED,iBAAS,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,IAAI,CAAC,qBAMhF;AAED,iBAAS,cAAc,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,qBAE1F;AAED,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,UAAc,EACd,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,qBAiBvD;AAED,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,CAAA"}
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
4
+ import { cn } from '../lib/cn';
5
+ function TooltipProvider({ delayDuration = 0, ...props }) {
6
+ return (_jsx(TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", delayDuration: delayDuration, ...props }));
7
+ }
8
+ function Tooltip({ ...props }) {
9
+ return (_jsx(TooltipProvider, { children: _jsx(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props }) }));
10
+ }
11
+ function TooltipTrigger({ ...props }) {
12
+ return _jsx(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
13
+ }
14
+ function TooltipContent({ className, sideOffset = 0, children, ...props }) {
15
+ return (_jsx(TooltipPrimitive.Portal, { children: _jsxs(TooltipPrimitive.Content, { className: cn('fade-in-0 zoom-in-95 data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) animate-in text-balance rounded-md bg-foreground px-3 py-1.5 font-barlow text-background text-xs data-[state=closed]:animate-out', className), "data-slot": "tooltip-content", sideOffset: sideOffset, ...props, children: [children, _jsx(TooltipPrimitive.Arrow, { className: "z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" })] }) }));
16
+ }
17
+ export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
@@ -0,0 +1,17 @@
1
+ import type { CameraPose } from '@pascal-app/core';
2
+ type CameraPoseState = {
3
+ pose: CameraPose | null;
4
+ };
5
+ export declare const cameraPoseStore: Omit<import("zustand").StoreApi<CameraPoseState>, "subscribe"> & {
6
+ subscribe: {
7
+ (listener: (selectedState: CameraPoseState, previousSelectedState: CameraPoseState) => void): () => void;
8
+ <U>(selector: (state: CameraPoseState) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
9
+ equalityFn?: ((a: U, b: U) => boolean) | undefined;
10
+ fireImmediately?: boolean;
11
+ } | undefined): () => void;
12
+ };
13
+ };
14
+ export declare function publishCameraPose(pose: CameraPose): void;
15
+ export declare function subscribeCameraPose(listener: (pose: CameraPose) => void): () => void;
16
+ export {};
17
+ //# sourceMappingURL=camera-pose-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera-pose-store.d.ts","sourceRoot":"","sources":["../../../src/ui/store/camera-pose-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAIlD,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,UAAU,GAAG,IAAI,CAAA;CACxB,CAAA;AAED,eAAO,MAAM,eAAe;;;;;;;;CAE3B,CAAA;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,QAEjD;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,cAUvE"}
@@ -0,0 +1,15 @@
1
+ import { subscribeWithSelector } from 'zustand/middleware';
2
+ import { createStore } from 'zustand/vanilla';
3
+ export const cameraPoseStore = createStore()(subscribeWithSelector(() => ({ pose: null })));
4
+ export function publishCameraPose(pose) {
5
+ cameraPoseStore.setState({ pose });
6
+ }
7
+ export function subscribeCameraPose(listener) {
8
+ const currentPose = cameraPoseStore.getState().pose;
9
+ if (currentPose)
10
+ listener(currentPose);
11
+ return cameraPoseStore.subscribe((state) => state.pose, (pose) => {
12
+ if (pose)
13
+ listener(pose);
14
+ });
15
+ }
@@ -0,0 +1,26 @@
1
+ export type NavigationSyncSource = '2d' | '3d';
2
+ /** Where the plan is looking, shared between the 2D plan and the 3D camera. */
3
+ export type NavigationSyncPose = {
4
+ source: NavigationSyncSource;
5
+ revision: number;
6
+ target: [number, number, number];
7
+ azimuth: number;
8
+ viewWidth: number;
9
+ };
10
+ export type NavigationSyncPoseInput = Omit<NavigationSyncPose, 'revision'>;
11
+ type NavigationSyncPoseState = {
12
+ pose: NavigationSyncPose | null;
13
+ };
14
+ export declare const navigationSyncPoseStore: Omit<import("zustand").StoreApi<NavigationSyncPoseState>, "subscribe"> & {
15
+ subscribe: {
16
+ (listener: (selectedState: NavigationSyncPoseState, previousSelectedState: NavigationSyncPoseState) => void): () => void;
17
+ <U>(selector: (state: NavigationSyncPoseState) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
18
+ equalityFn?: ((a: U, b: U) => boolean) | undefined;
19
+ fireImmediately?: boolean;
20
+ } | undefined): () => void;
21
+ };
22
+ };
23
+ export declare function publishNavigationSyncPose(pose: NavigationSyncPoseInput): void;
24
+ export declare function subscribeNavigationSyncPose(listener: (pose: NavigationSyncPose) => void): () => void;
25
+ export {};
26
+ //# sourceMappingURL=navigation-sync-pose-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation-sync-pose-store.d.ts","sourceRoot":"","sources":["../../../src/ui/store/navigation-sync-pose-store.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAAA;AAE9C,+EAA+E;AAC/E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,oBAAoB,CAAA;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAA;AAE1E,KAAK,uBAAuB,GAAG;IAC7B,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAAA;CAChC,CAAA;AAED,eAAO,MAAM,uBAAuB;;;;;;;;CAEnC,CAAA;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,uBAAuB,QAGtE;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,cAUvF"}
@@ -0,0 +1,16 @@
1
+ import { subscribeWithSelector } from 'zustand/middleware';
2
+ import { createStore } from 'zustand/vanilla';
3
+ export const navigationSyncPoseStore = createStore()(subscribeWithSelector(() => ({ pose: null })));
4
+ export function publishNavigationSyncPose(pose) {
5
+ const revision = (navigationSyncPoseStore.getState().pose?.revision ?? 0) + 1;
6
+ navigationSyncPoseStore.setState({ pose: { ...pose, revision } });
7
+ }
8
+ export function subscribeNavigationSyncPose(listener) {
9
+ const currentPose = navigationSyncPoseStore.getState().pose;
10
+ if (currentPose)
11
+ listener(currentPose);
12
+ return navigationSyncPoseStore.subscribe((state) => state.pose, (pose) => {
13
+ if (pose)
14
+ listener(pose);
15
+ });
16
+ }
@@ -0,0 +1,30 @@
1
+ export declare const FOLLOW_PASCAL_STORAGE_KEY = "pascal-follow-pascal";
2
+ type FollowPascalState = {
3
+ /** The person's switch: the camera follows what a build works on. Kept across sessions. */
4
+ on: boolean;
5
+ /** The person took the camera: it stays theirs until they resume or the next build begins. */
6
+ paused: boolean;
7
+ /** A build is playing (set by the follower from the reveal's own words). */
8
+ building: boolean;
9
+ setOn: (on: boolean) => void;
10
+ pause: () => void;
11
+ resume: () => void;
12
+ beginBuild: () => void;
13
+ endBuild: () => void;
14
+ };
15
+ /** Follow Pascal's switch, its pause and whether a build is being followed. */
16
+ export declare const useFollowPascal: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<FollowPascalState>, "persist" | "setState"> & {
17
+ setState(partial: FollowPascalState | Partial<FollowPascalState> | ((state: FollowPascalState) => FollowPascalState | Partial<FollowPascalState>), replace?: false | undefined): unknown;
18
+ setState(state: FollowPascalState | ((state: FollowPascalState) => FollowPascalState), replace: true): unknown;
19
+ persist: {
20
+ setOptions: (options: Partial<import("zustand/middleware").PersistOptions<FollowPascalState, unknown, unknown>>) => void;
21
+ clearStorage: () => void;
22
+ rehydrate: () => Promise<void> | void;
23
+ hasHydrated: () => boolean;
24
+ onHydrate: (fn: (state: FollowPascalState) => void) => () => void;
25
+ onFinishHydration: (fn: (state: FollowPascalState) => void) => () => void;
26
+ getOptions: () => Partial<import("zustand/middleware").PersistOptions<FollowPascalState, unknown, unknown>>;
27
+ };
28
+ }>;
29
+ export {};
30
+ //# sourceMappingURL=use-follow-pascal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-follow-pascal.d.ts","sourceRoot":"","sources":["../../../src/ui/store/use-follow-pascal.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,yBAAyB,yBAAyB,CAAA;AAS/D,KAAK,iBAAiB,GAAG;IACvB,2FAA2F;IAC3F,EAAE,EAAE,OAAO,CAAA;IACX,8FAA8F;IAC9F,MAAM,EAAE,OAAO,CAAA;IACf,4EAA4E;IAC5E,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,KAAK,IAAI,CAAA;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,UAAU,EAAE,MAAM,IAAI,CAAA;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAA;CACrB,CAAA;AAED,+EAA+E;AAC/E,eAAO,MAAM,eAAe;;;;;;;;;;;;EAoB3B,CAAA"}
@@ -0,0 +1,28 @@
1
+ 'use client';
2
+ import { create } from 'zustand';
3
+ import { createJSONStorage, persist } from 'zustand/middleware';
4
+ export const FOLLOW_PASCAL_STORAGE_KEY = 'pascal-follow-pascal';
5
+ /** Reads `localStorage` on each call, so a page without it (a test, a sandbox) still has the store's persist API. */
6
+ const browserStorage = createJSONStorage(() => ({
7
+ getItem: (key) => globalThis.localStorage?.getItem(key) ?? null,
8
+ setItem: (key, value) => globalThis.localStorage?.setItem(key, value),
9
+ removeItem: (key) => globalThis.localStorage?.removeItem(key),
10
+ }));
11
+ /** Follow Pascal's switch, its pause and whether a build is being followed. */
12
+ export const useFollowPascal = create()(persist((set, get) => ({
13
+ on: true,
14
+ paused: false,
15
+ building: false,
16
+ setOn: (on) => set({ on, paused: false }),
17
+ pause: () => {
18
+ if (get().on)
19
+ set({ paused: true });
20
+ },
21
+ resume: () => set({ paused: false }),
22
+ beginBuild: () => set({ building: true, paused: false }),
23
+ endBuild: () => set({ building: false }),
24
+ }), {
25
+ name: FOLLOW_PASCAL_STORAGE_KEY,
26
+ storage: browserStorage,
27
+ partialize: (state) => ({ on: state.on }),
28
+ }));
@@ -0,0 +1,339 @@
1
+ /*
2
+ * @pascal-app/viewer/ui theme — the tokens and utilities its components use (Tailwind v4).
3
+ *
4
+ * @import "tailwindcss";
5
+ * @import "@pascal-app/viewer/ui/theme.css";
6
+ * @source "../node_modules/@pascal-app/viewer/dist/ui";
7
+ *
8
+ * Defaults match Pascal's hosted viewer. Override any token after the import, e.g.
9
+ * `:root { --radius: 0.5rem; }`. The docks and menus scope themselves with a `dark`
10
+ * class, so the `.dark` values are what they show.
11
+ */
12
+ @import "tw-animate-css";
13
+
14
+ @custom-variant dark (&:is(.dark *));
15
+
16
+ @theme inline {
17
+ --color-background: var(--background);
18
+ --color-foreground: var(--foreground);
19
+ --color-card: var(--card);
20
+ --color-card-foreground: var(--card-foreground);
21
+ --color-popover: var(--popover);
22
+ --color-popover-foreground: var(--popover-foreground);
23
+ --color-primary: var(--primary);
24
+ --color-primary-foreground: var(--primary-foreground);
25
+ --color-secondary: var(--secondary);
26
+ --color-secondary-foreground: var(--secondary-foreground);
27
+ --color-muted: var(--muted);
28
+ --color-muted-foreground: var(--muted-foreground);
29
+ --color-accent: var(--accent);
30
+ --color-accent-foreground: var(--accent-foreground);
31
+ --color-destructive: var(--destructive);
32
+ --color-border: var(--border);
33
+ --color-input: var(--input);
34
+ --color-ring: var(--ring);
35
+ --radius-sm: calc(var(--radius) - 4px);
36
+ --radius-md: calc(var(--radius) - 2px);
37
+ --radius-lg: var(--radius);
38
+ --radius-xl: calc(var(--radius) + 4px);
39
+ --shadow-elevation-0: var(--shadow-elevation-0);
40
+ --shadow-elevation-1: var(--shadow-elevation-1);
41
+ --shadow-elevation-2: var(--shadow-elevation-2);
42
+ --shadow-elevation-3: var(--shadow-elevation-3);
43
+ --shadow-elevation-4: var(--shadow-elevation-4);
44
+ --shadow-elevation-5: var(--shadow-elevation-5);
45
+ --shadow-elevation-6: var(--shadow-elevation-6);
46
+ }
47
+
48
+ /* Light: an ambient ring plus diffusion layers doubling 1 → 3 → 6 → 12 → 24 → 48. */
49
+ :root {
50
+ --radius: 0.625rem;
51
+ --background: #ffffff;
52
+ --foreground: #18181b;
53
+ --card: #ffffff;
54
+ --card-foreground: #18181b;
55
+ --popover: #ffffff;
56
+ --popover-foreground: #18181b;
57
+ --primary: #18181b;
58
+ --primary-foreground: #fafafa;
59
+ --secondary: #f4f4f5;
60
+ --secondary-foreground: #18181b;
61
+ --muted: #f4f4f5;
62
+ --muted-foreground: #6b6b77;
63
+ --accent: #f4f4f5;
64
+ --accent-foreground: #18181b;
65
+ --destructive: oklch(0.577 0.245 27.325);
66
+ --border: #e4e4e7;
67
+ --input: #e4e4e7;
68
+ --ring: #9f9faa;
69
+
70
+ --shadow-color: rgb(0 0 0 / 0.06);
71
+ --shadow-elevation-0: 0 0 0 1px var(--shadow-color);
72
+ --shadow-elevation-1: 0 0 0 1px var(--shadow-color), 0 1px 1px -0.5px var(--shadow-color);
73
+ --shadow-elevation-2:
74
+ 0 0 0 1px var(--shadow-color), 0 1px 1px -0.5px var(--shadow-color),
75
+ 0 3px 3px -1.5px var(--shadow-color);
76
+ --shadow-elevation-3:
77
+ 0 0 0 1px var(--shadow-color), 0 1px 1px -0.5px var(--shadow-color),
78
+ 0 3px 3px -1.5px var(--shadow-color), 0 6px 6px -3px var(--shadow-color);
79
+ --shadow-elevation-4:
80
+ 0 0 0 1px var(--shadow-color), 0 1px 1px -0.5px var(--shadow-color),
81
+ 0 3px 3px -1.5px var(--shadow-color), 0 6px 6px -3px var(--shadow-color),
82
+ 0 12px 12px -6px var(--shadow-color);
83
+ --shadow-elevation-5:
84
+ 0 0 0 1px var(--shadow-color), 0 1px 1px -0.5px var(--shadow-color),
85
+ 0 3px 3px -1.5px var(--shadow-color), 0 6px 6px -3px var(--shadow-color),
86
+ 0 12px 12px -6px var(--shadow-color), 0 24px 24px -12px var(--shadow-color);
87
+ --shadow-elevation-6:
88
+ 0 0 0 1px var(--shadow-color), 0 1px 1px -0.5px var(--shadow-color),
89
+ 0 3px 3px -1.5px var(--shadow-color), 0 6px 6px -3px var(--shadow-color),
90
+ 0 12px 12px -6px var(--shadow-color), 0 24px 24px -12px var(--shadow-color),
91
+ 0 48px 48px -24px var(--shadow-color);
92
+ }
93
+
94
+ /* Dark: raised surfaces catch light on their top edge and rim, over a grounding drop stack. */
95
+ .dark {
96
+ --background: #0d0d0f;
97
+ --foreground: #fafafa;
98
+ --card: #18181b;
99
+ --card-foreground: #fafafa;
100
+ --popover: #18181b;
101
+ --popover-foreground: #e4e4e7;
102
+ --primary: #e4e4e7;
103
+ --primary-foreground: #0d0d0f;
104
+ --secondary: #27272a;
105
+ --secondary-foreground: #e4e4e7;
106
+ --muted: #27272a;
107
+ --muted-foreground: #9f9faa;
108
+ --accent: #27272a;
109
+ --accent-foreground: #e4e4e7;
110
+ --destructive: oklch(0.704 0.191 22.216);
111
+ --border: #27272a;
112
+ --input: #27272a;
113
+ --ring: #52525e;
114
+
115
+ --shadow-color: rgba(0, 0, 0, 0.18);
116
+ --dm-hi-base: rgba(255, 255, 255, 0.02);
117
+ --dm-hi-mid: rgba(255, 255, 255, 0.05);
118
+ --dm-hi-high: rgba(255, 255, 255, 0.08);
119
+ --dm-hi-peak: rgba(255, 255, 255, 0.11);
120
+ --dm-ring-base: rgba(255, 255, 255, 0.02);
121
+ --dm-ring-mid: rgba(255, 255, 255, 0.04);
122
+ --dm-ring-high: rgba(255, 255, 255, 0.06);
123
+ --shadow-elevation-0: inset 0 0 0 1px var(--dm-ring-base);
124
+ --shadow-elevation-1:
125
+ inset 0 1px 0 0 var(--dm-hi-base), inset 0 0 0 1px var(--dm-ring-base),
126
+ 0 1px 1px -0.5px var(--shadow-color);
127
+ --shadow-elevation-2:
128
+ inset 0 1px 0 0 var(--dm-hi-mid), inset 0 0 0 1px var(--dm-ring-base),
129
+ 0 0 0 1px rgba(0, 0, 0, 0.12), 0 1px 1px -0.5px var(--shadow-color),
130
+ 0 3px 3px -1.5px var(--shadow-color);
131
+ --shadow-elevation-3:
132
+ inset 0 1px 0 0 var(--dm-hi-mid), inset 0 0 0 1px var(--dm-ring-mid),
133
+ 0 0 0 1px rgba(0, 0, 0, 0.14), 0 1px 1px -0.5px var(--shadow-color),
134
+ 0 3px 3px -1.5px var(--shadow-color), 0 6px 6px -3px var(--shadow-color);
135
+ --shadow-elevation-4:
136
+ inset 0 1px 0 0 var(--dm-hi-high), inset 0 0 0 1px var(--dm-ring-mid),
137
+ 0 0 0 1px rgba(0, 0, 0, 0.16), 0 1px 1px -0.5px var(--shadow-color),
138
+ 0 3px 3px -1.5px var(--shadow-color), 0 6px 6px -3px var(--shadow-color),
139
+ 0 12px 12px -6px var(--shadow-color);
140
+ --shadow-elevation-5:
141
+ inset 0 1px 0 0 var(--dm-hi-high), inset 0 0 0 1px var(--dm-ring-high),
142
+ 0 0 0 1px rgba(0, 0, 0, 0.18), 0 1px 1px -0.5px var(--shadow-color),
143
+ 0 3px 3px -1.5px var(--shadow-color), 0 6px 6px -3px var(--shadow-color),
144
+ 0 12px 12px -6px var(--shadow-color), 0 24px 24px -12px var(--shadow-color);
145
+ --shadow-elevation-6:
146
+ inset 0 1px 0 0 var(--dm-hi-peak), inset 0 0 0 1px var(--dm-ring-high),
147
+ 0 0 0 1px rgba(0, 0, 0, 0.2), 0 1px 1px -0.5px var(--shadow-color),
148
+ 0 3px 3px -1.5px var(--shadow-color), 0 6px 6px -3px var(--shadow-color),
149
+ 0 12px 12px -6px var(--shadow-color), 0 24px 24px -12px var(--shadow-color),
150
+ 0 48px 48px -24px var(--shadow-color);
151
+ }
152
+
153
+ /* Progressive enhancement: pair with any rounded-* class. */
154
+ @utility corner-smooth {
155
+ corner-shape: squircle;
156
+ }
157
+
158
+ /* SceneLoader picks one of these at random. */
159
+ .pascal-loader-1,
160
+ .pascal-loader-4,
161
+ .pascal-loader-5 {
162
+ width: 45px;
163
+ aspect-ratio: 1;
164
+ --c: no-repeat linear-gradient(currentColor 0 0);
165
+ background: var(--c), var(--c), var(--c);
166
+ }
167
+ .pascal-loader-2,
168
+ .pascal-loader-3 {
169
+ width: 45px;
170
+ aspect-ratio: 0.75;
171
+ --c: no-repeat linear-gradient(currentColor 0 0);
172
+ }
173
+ .pascal-loader-1 {
174
+ animation:
175
+ pascal-l1-1 1s infinite,
176
+ pascal-l1-2 1s infinite;
177
+ }
178
+ @keyframes pascal-l1-1 {
179
+ 0%,
180
+ 100% {
181
+ background-size: 20% 100%;
182
+ }
183
+ 33%,
184
+ 66% {
185
+ background-size: 20% 20%;
186
+ }
187
+ }
188
+ @keyframes pascal-l1-2 {
189
+ 0%,
190
+ 33% {
191
+ background-position:
192
+ 0 0,
193
+ 50% 50%,
194
+ 100% 100%;
195
+ }
196
+ 66%,
197
+ 100% {
198
+ background-position:
199
+ 100% 0,
200
+ 50% 50%,
201
+ 0 100%;
202
+ }
203
+ }
204
+ .pascal-loader-2 {
205
+ background:
206
+ var(--c) 0% 50%,
207
+ var(--c) 50% 50%,
208
+ var(--c) 100% 50%;
209
+ background-size: 20% 50%;
210
+ animation: pascal-l2 1s infinite linear;
211
+ }
212
+ @keyframes pascal-l2 {
213
+ 20% {
214
+ background-position:
215
+ 0% 0%,
216
+ 50% 50%,
217
+ 100% 50%;
218
+ }
219
+ 40% {
220
+ background-position:
221
+ 0% 100%,
222
+ 50% 0%,
223
+ 100% 50%;
224
+ }
225
+ 60% {
226
+ background-position:
227
+ 0% 50%,
228
+ 50% 100%,
229
+ 100% 0%;
230
+ }
231
+ 80% {
232
+ background-position:
233
+ 0% 50%,
234
+ 50% 50%,
235
+ 100% 100%;
236
+ }
237
+ }
238
+ .pascal-loader-3 {
239
+ background:
240
+ var(--c) 0% 100%,
241
+ var(--c) 50% 100%,
242
+ var(--c) 100% 100%;
243
+ background-size: 20% 65%;
244
+ animation: pascal-l3 1s infinite linear;
245
+ }
246
+ @keyframes pascal-l3 {
247
+ 16.67% {
248
+ background-position:
249
+ 0% 0%,
250
+ 50% 100%,
251
+ 100% 100%;
252
+ }
253
+ 33.33% {
254
+ background-position:
255
+ 0% 0%,
256
+ 50% 0%,
257
+ 100% 100%;
258
+ }
259
+ 50% {
260
+ background-position:
261
+ 0% 0%,
262
+ 50% 0%,
263
+ 100% 0%;
264
+ }
265
+ 66.67% {
266
+ background-position:
267
+ 0% 100%,
268
+ 50% 0%,
269
+ 100% 0%;
270
+ }
271
+ 83.33% {
272
+ background-position:
273
+ 0% 100%,
274
+ 50% 100%,
275
+ 100% 0%;
276
+ }
277
+ }
278
+ .pascal-loader-4 {
279
+ animation:
280
+ pascal-l4-1 1s infinite,
281
+ pascal-l4-2 1s infinite;
282
+ }
283
+ @keyframes pascal-l4-1 {
284
+ 0%,
285
+ 100% {
286
+ background-size: 20% 100%;
287
+ }
288
+ 33%,
289
+ 66% {
290
+ background-size: 20% 40%;
291
+ }
292
+ }
293
+ @keyframes pascal-l4-2 {
294
+ 0%,
295
+ 33% {
296
+ background-position:
297
+ 0 0,
298
+ 50% 100%,
299
+ 100% 100%;
300
+ }
301
+ 66%,
302
+ 100% {
303
+ background-position:
304
+ 100% 0,
305
+ 0 100%,
306
+ 50% 100%;
307
+ }
308
+ }
309
+ .pascal-loader-5 {
310
+ animation:
311
+ pascal-l5-1 1s infinite,
312
+ pascal-l5-2 1s infinite;
313
+ }
314
+ @keyframes pascal-l5-1 {
315
+ 0%,
316
+ 100% {
317
+ background-size: 20% 100%;
318
+ }
319
+ 33%,
320
+ 66% {
321
+ background-size: 20% 40%;
322
+ }
323
+ }
324
+ @keyframes pascal-l5-2 {
325
+ 0%,
326
+ 33% {
327
+ background-position:
328
+ 0 0,
329
+ 50% 100%,
330
+ 100% 0;
331
+ }
332
+ 66%,
333
+ 100% {
334
+ background-position:
335
+ 0 100%,
336
+ 50% 0,
337
+ 100% 100%;
338
+ }
339
+ }