@donotdev/ui 0.0.8 → 0.0.9

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 (177) hide show
  1. package/dist/components/auth/AuthHeader.d.ts +1 -1
  2. package/dist/components/auth/AuthHeader.d.ts.map +1 -1
  3. package/dist/components/auth/AuthMenu.d.ts +2 -1
  4. package/dist/components/auth/AuthMenu.d.ts.map +1 -1
  5. package/dist/components/auth/AuthMenu.js +1 -1
  6. package/dist/components/common/AppLoading.d.ts +1 -1
  7. package/dist/components/common/AppLoading.d.ts.map +1 -1
  8. package/dist/components/common/AppLoading.js +0 -1
  9. package/dist/components/common/Loader.d.ts +4 -4
  10. package/dist/components/common/Loader.d.ts.map +1 -1
  11. package/dist/components/common/Loader.js +11 -12
  12. package/dist/components/common/LoadingMessage.d.ts +1 -9
  13. package/dist/components/common/LoadingMessage.d.ts.map +1 -1
  14. package/dist/components/common/LoadingMessage.js +0 -1
  15. package/dist/components/common/LoadingScreen.d.ts +1 -9
  16. package/dist/components/common/LoadingScreen.d.ts.map +1 -1
  17. package/dist/components/common/LoadingScreen.js +0 -1
  18. package/dist/components/common/RedirectOverlay.js +1 -1
  19. package/dist/components/common/TechBento.d.ts.map +1 -1
  20. package/dist/components/common/TechBento.js +1 -0
  21. package/dist/components/layout/components/FloatingLanguageSwitcher.d.ts +1 -9
  22. package/dist/components/layout/components/FloatingLanguageSwitcher.d.ts.map +1 -1
  23. package/dist/components/layout/components/FloatingLanguageSwitcher.js +0 -1
  24. package/dist/components/layout/components/header/CacheSettings.d.ts.map +1 -1
  25. package/dist/components/layout/components/header/HeaderMenu.d.ts.map +1 -1
  26. package/dist/components/layout/components/header/SettingsMenu.d.ts.map +1 -1
  27. package/dist/components/layout/components/header/SettingsMenu.js +0 -1
  28. package/dist/components/layout/components/header/ThemeToggle.d.ts +1 -1
  29. package/dist/components/layout/components/header/ThemeToggle.d.ts.map +1 -1
  30. package/dist/components/layout/components/header/ThemeToggle.js +5 -4
  31. package/dist/crud/components/DisplayFieldRenderer.d.ts +3 -11
  32. package/dist/crud/components/DisplayFieldRenderer.d.ts.map +1 -1
  33. package/dist/crud/components/DisplayFieldRenderer.js +3 -2
  34. package/dist/crud/components/EntityDisplayRenderer.d.ts +2 -2
  35. package/dist/crud/components/fields/display/AvatarFieldDisplay.d.ts +2 -2
  36. package/dist/crud/components/fields/display/BadgeFieldDisplay.d.ts +2 -2
  37. package/dist/crud/components/fields/display/ButtonFieldDisplay.d.ts +2 -2
  38. package/dist/crud/components/fields/display/CheckboxFieldDisplay.d.ts +2 -2
  39. package/dist/crud/components/fields/display/DateFieldDisplay.d.ts +3 -11
  40. package/dist/crud/components/fields/display/DateFieldDisplay.d.ts.map +1 -1
  41. package/dist/crud/components/fields/display/DateFieldDisplay.js +0 -1
  42. package/dist/crud/components/fields/display/DropdownDisplay.d.ts +2 -2
  43. package/dist/crud/components/fields/display/FileFieldDisplay.d.ts +2 -2
  44. package/dist/crud/components/fields/display/GeoPointFieldDisplay.d.ts +3 -11
  45. package/dist/crud/components/fields/display/GeoPointFieldDisplay.d.ts.map +1 -1
  46. package/dist/crud/components/fields/display/GeoPointFieldDisplay.js +0 -1
  47. package/dist/crud/components/fields/display/HiddenFieldDisplay.d.ts +3 -3
  48. package/dist/crud/components/fields/display/HiddenFieldDisplay.d.ts.map +1 -1
  49. package/dist/crud/components/fields/display/HiddenFieldDisplay.js +0 -9
  50. package/dist/crud/components/fields/display/ImageFieldDisplay.d.ts +3 -11
  51. package/dist/crud/components/fields/display/ImageFieldDisplay.d.ts.map +1 -1
  52. package/dist/crud/components/fields/display/ImageFieldDisplay.js +0 -1
  53. package/dist/crud/components/fields/display/LinkFieldDisplay.d.ts +3 -11
  54. package/dist/crud/components/fields/display/LinkFieldDisplay.d.ts.map +1 -1
  55. package/dist/crud/components/fields/display/LinkFieldDisplay.js +0 -1
  56. package/dist/crud/components/fields/display/MapFieldDisplay.d.ts +3 -11
  57. package/dist/crud/components/fields/display/MapFieldDisplay.d.ts.map +1 -1
  58. package/dist/crud/components/fields/display/MapFieldDisplay.js +0 -1
  59. package/dist/crud/components/fields/display/MultiDropdownDisplay.d.ts +3 -11
  60. package/dist/crud/components/fields/display/MultiDropdownDisplay.d.ts.map +1 -1
  61. package/dist/crud/components/fields/display/MultiDropdownDisplay.js +0 -1
  62. package/dist/crud/components/fields/display/MultiInputTextFieldDisplay.d.ts +3 -11
  63. package/dist/crud/components/fields/display/MultiInputTextFieldDisplay.d.ts.map +1 -1
  64. package/dist/crud/components/fields/display/MultiInputTextFieldDisplay.js +0 -1
  65. package/dist/crud/components/fields/display/NumberFieldDisplay.d.ts +3 -11
  66. package/dist/crud/components/fields/display/NumberFieldDisplay.d.ts.map +1 -1
  67. package/dist/crud/components/fields/display/NumberFieldDisplay.js +0 -1
  68. package/dist/crud/components/fields/display/PasswordFieldDisplay.d.ts +3 -3
  69. package/dist/crud/components/fields/display/PasswordFieldDisplay.d.ts.map +1 -1
  70. package/dist/crud/components/fields/display/PasswordFieldDisplay.js +0 -1
  71. package/dist/crud/components/fields/display/PhoneNumberDisplay.d.ts +3 -11
  72. package/dist/crud/components/fields/display/PhoneNumberDisplay.d.ts.map +1 -1
  73. package/dist/crud/components/fields/display/PhoneNumberDisplay.js +0 -1
  74. package/dist/crud/components/fields/display/RadioFieldDisplay.d.ts +3 -11
  75. package/dist/crud/components/fields/display/RadioFieldDisplay.d.ts.map +1 -1
  76. package/dist/crud/components/fields/display/RadioFieldDisplay.js +0 -1
  77. package/dist/crud/components/fields/display/RangeFieldDisplay.d.ts +3 -11
  78. package/dist/crud/components/fields/display/RangeFieldDisplay.d.ts.map +1 -1
  79. package/dist/crud/components/fields/display/RangeFieldDisplay.js +0 -1
  80. package/dist/crud/components/fields/display/ReferenceFieldDisplay.d.ts +3 -11
  81. package/dist/crud/components/fields/display/ReferenceFieldDisplay.d.ts.map +1 -1
  82. package/dist/crud/components/fields/display/ReferenceFieldDisplay.js +0 -1
  83. package/dist/crud/components/fields/display/RichTextDisplay.d.ts +25 -0
  84. package/dist/crud/components/fields/display/RichTextDisplay.d.ts.map +1 -0
  85. package/dist/crud/components/fields/display/RichTextDisplay.js +104 -0
  86. package/dist/crud/components/fields/display/TextAreaDisplay.d.ts +3 -11
  87. package/dist/crud/components/fields/display/TextAreaDisplay.d.ts.map +1 -1
  88. package/dist/crud/components/fields/display/TextAreaDisplay.js +0 -1
  89. package/dist/crud/components/fields/display/TextFieldDisplay.d.ts +2 -2
  90. package/dist/crud/components/fields/display/TimestampFieldDisplay.d.ts +3 -11
  91. package/dist/crud/components/fields/display/TimestampFieldDisplay.d.ts.map +1 -1
  92. package/dist/crud/components/fields/display/TimestampFieldDisplay.js +0 -1
  93. package/dist/crud/components/fields/display/index.d.ts +1 -0
  94. package/dist/crud/components/fields/display/index.d.ts.map +1 -1
  95. package/dist/crud/components/fields/display/index.js +1 -0
  96. package/dist/dndev.css +401 -84
  97. package/dist/index.js +64 -4
  98. package/dist/internal/common/ErrorFallback.d.ts +1 -10
  99. package/dist/internal/common/ErrorFallback.d.ts.map +1 -1
  100. package/dist/internal/common/GlobalErrorFallback.d.ts +1 -9
  101. package/dist/internal/common/GlobalErrorFallback.d.ts.map +1 -1
  102. package/dist/internal/common/RouteErrorFallback.js +1 -1
  103. package/dist/internal/devtools/components/DebugDialog.d.ts.map +1 -1
  104. package/dist/internal/devtools/components/DebugDialog.js +3 -1
  105. package/dist/internal/devtools/components/MaskedValue.d.ts.map +1 -1
  106. package/dist/internal/devtools/components/MaskedValue.js +1 -1
  107. package/dist/internal/devtools/components/StoresTab.js +1 -1
  108. package/dist/internal/initializers/BaseStoresInitializer.d.ts.map +1 -1
  109. package/dist/internal/initializers/BaseStoresInitializer.js +1 -2
  110. package/dist/internal/initializers/NextJsStoresInitializer.d.ts.map +1 -1
  111. package/dist/internal/layout/DnDevLayout.d.ts.map +1 -1
  112. package/dist/internal/layout/DnDevLayout.js +4 -5
  113. package/dist/internal/layout/components/AutoMetaTags.d.ts.map +1 -1
  114. package/dist/internal/layout/components/footer/FooterLegalLinks.js +2 -2
  115. package/dist/internal/layout/config/defaults.d.ts +0 -10
  116. package/dist/internal/layout/config/defaults.d.ts.map +1 -1
  117. package/dist/internal/layout/config/defaults.js +12 -1
  118. package/dist/internal/layout/config/presets/admin.d.ts.map +1 -1
  119. package/dist/internal/layout/config/presets/admin.js +7 -2
  120. package/dist/internal/layout/config/presets/blog.d.ts.map +1 -1
  121. package/dist/internal/layout/config/presets/blog.js +7 -1
  122. package/dist/internal/layout/config/presets/docs.d.ts.map +1 -1
  123. package/dist/internal/layout/config/presets/docs.js +7 -5
  124. package/dist/internal/layout/config/presets/game.d.ts.map +1 -1
  125. package/dist/internal/layout/config/presets/game.js +7 -2
  126. package/dist/internal/layout/config/presets/moolti.d.ts.map +1 -1
  127. package/dist/internal/layout/config/presets/moolti.js +10 -3
  128. package/dist/internal/layout/zones/DnDevFooter.d.ts +1 -13
  129. package/dist/internal/layout/zones/DnDevFooter.d.ts.map +1 -1
  130. package/dist/internal/layout/zones/DnDevHeader.d.ts +1 -14
  131. package/dist/internal/layout/zones/DnDevHeader.d.ts.map +1 -1
  132. package/dist/internal/layout/zones/DnDevMergedBar.d.ts +2 -14
  133. package/dist/internal/layout/zones/DnDevMergedBar.d.ts.map +1 -1
  134. package/dist/internal/layout/zones/DnDevMergedBar.js +11 -3
  135. package/dist/internal/layout/zones/DnDevSidebar.d.ts +1 -14
  136. package/dist/internal/layout/zones/DnDevSidebar.d.ts.map +1 -1
  137. package/dist/routing/AuthGuard.d.ts.map +1 -1
  138. package/dist/routing/GoTo.d.ts +3 -1
  139. package/dist/routing/GoTo.d.ts.map +1 -1
  140. package/dist/routing/GoTo.js +6 -2
  141. package/dist/routing/GoToDialog.d.ts +1 -1
  142. package/dist/routing/GoToDialog.d.ts.map +1 -1
  143. package/dist/routing/GoToDialog.js +3 -5
  144. package/dist/routing/NavigationItem.d.ts +1 -1
  145. package/dist/routing/NavigationItem.d.ts.map +1 -1
  146. package/dist/routing/NavigationItem.js +0 -1
  147. package/dist/routing/hooks/hooks.next.js +1 -1
  148. package/dist/routing/hooks/hooks.vite.js +1 -1
  149. package/dist/routing/hooks/useNavigate.next.d.ts.map +1 -1
  150. package/dist/routing/hooks/useNavigate.next.js +1 -1
  151. package/dist/routing/hooks/useNavigate.vite.d.ts.map +1 -1
  152. package/dist/routing/useGoTo.d.ts.map +1 -1
  153. package/dist/styles/index.css +401 -84
  154. package/dist/utils/assetResolver.d.ts +1 -1
  155. package/dist/utils/assetResolver.d.ts.map +1 -1
  156. package/dist/utils/assetResolver.js +1 -2
  157. package/dist/utils/index.d.ts +0 -1
  158. package/dist/utils/index.d.ts.map +1 -1
  159. package/dist/utils/index.js +0 -1
  160. package/dist/utils/tList.d.ts +1 -1
  161. package/dist/utils/tList.d.ts.map +1 -1
  162. package/dist/utils/useAuthSafe.d.ts +0 -33
  163. package/dist/utils/useAuthSafe.d.ts.map +1 -1
  164. package/dist/utils/useAuthSafe.js +34 -1
  165. package/dist/utils/useCrudSafe.d.ts +12 -6
  166. package/dist/utils/useCrudSafe.d.ts.map +1 -1
  167. package/dist/utils/useCrudSafe.js +9 -6
  168. package/dist/utils/useOAuthSafe.d.ts.map +1 -1
  169. package/dist/utils/useStripeBillingSafe.d.ts +1 -34
  170. package/dist/utils/useStripeBillingSafe.d.ts.map +1 -1
  171. package/dist/utils/useStripeBillingSafe.js +34 -1
  172. package/dist/vite-routing/AppRoutes.d.ts +1 -1
  173. package/dist/vite-routing/AppRoutes.d.ts.map +1 -1
  174. package/dist/vite-routing/AppRoutes.js +0 -1
  175. package/dist/vite-routing/RootLayout.d.ts.map +1 -1
  176. package/dist/vite-routing/RootLayout.js +3 -6
  177. package/package.json +1 -1
package/dist/dndev.css CHANGED
@@ -2728,6 +2728,34 @@ em {
2728
2728
 
2729
2729
  /* Label styling moved to patterns.css (.dndev-interactive-label) */
2730
2730
 
2731
+ /* Loading state */
2732
+
2733
+ [data-loading] {
2734
+ cursor: wait;
2735
+ pointer-events: none;
2736
+ }
2737
+
2738
+ /* Button spinner - inherits size from button font-size */
2739
+
2740
+ .dndev-button-spinner {
2741
+ flex-shrink: 0;
2742
+ }
2743
+
2744
+ /* Progress ring for upload percentage */
2745
+
2746
+ .dndev-button-progress {
2747
+ display: inline-flex;
2748
+ align-items: center;
2749
+ justify-content: center;
2750
+ flex-shrink: 0;
2751
+ }
2752
+
2753
+ .dndev-progress-ring {
2754
+ width: 1em;
2755
+ height: 1em;
2756
+ transform: rotate(-90deg);
2757
+ }
2758
+
2731
2759
  /* packages/components/src/atomic/Calendar/Calendar.css */
2732
2760
 
2733
2761
  /**
@@ -4616,49 +4644,81 @@ em {
4616
4644
  margin-inline-start: var(--gap-sm);
4617
4645
  }
4618
4646
 
4619
- /* Floating Label - positioned absolutely at top of input fields */
4647
+ /* Floating Fieldset - native border-cutting via legend */
4620
4648
 
4621
- .dndev-floating-label {
4622
- position: absolute;
4623
- inset-inline-start: var(--gap-md);
4624
- top: calc(-1 * var(--font-size-xs) / 2 - 1px);
4625
- font-size: var(--font-size-xs);
4626
- font-weight: 500;
4627
- pointer-events: none;
4628
- z-index: 1;
4629
- background-color: var(--background);
4630
- padding: 0 var(--gap-sm);
4631
- line-height: 1;
4632
- color: var(--foreground);
4649
+ .dndev-floating-fieldset {
4650
+ position: relative;
4651
+ border: var(--border-hairline) solid var(--line-2);
4652
+ border-radius: var(--radius-interactive);
4653
+ margin: 0;
4654
+ padding: 0;
4655
+ background-color: transparent;
4656
+ transition: all var(--dur-normal) var(--ease-in-out);
4657
+ text-align: start;
4633
4658
  }
4634
4659
 
4635
- /* Inherit background when inside floating containers (dropdowns, menus, popovers) */
4660
+ .dndev-floating-fieldset:hover {
4661
+ border-color: var(--ring);
4662
+ }
4636
4663
 
4637
- .dndev-floating .dndev-floating-label,
4638
- .dndev-menu-content .dndev-floating-label,
4639
- [class*='dndev-dropdown'] .dndev-floating-label,
4640
- [class*='dndev-navigation'] .dndev-floating-label {
4641
- background-color: var(--popover);
4642
- color: var(--popover-foreground);
4664
+ .dndev-floating-fieldset:focus-within {
4665
+ border-color: var(--ring);
4666
+ box-shadow: 0 0 0 2px var(--ring);
4667
+ }
4668
+
4669
+ .dndev-floating-fieldset[data-disabled='true'] {
4670
+ opacity: var(--opacity-muted);
4671
+ cursor: not-allowed;
4643
4672
  }
4644
4673
 
4645
- /* When floating container has blank glow, use solid popover background */
4674
+ /* Legend sits on border - browser natively cuts border */
4646
4675
 
4647
- .dndev-floating[data-glow='blank'] .dndev-floating-label {
4648
- background-color: var(--popover);
4676
+ .dndev-floating-legend {
4677
+ margin-inline-start: var(--gap-sm);
4678
+ padding: 0 var(--gap-sm);
4679
+ font-size: var(--font-size-xs);
4680
+ font-weight: 500;
4681
+ line-height: 1;
4682
+ color: var(--foreground);
4683
+ }
4684
+
4685
+ .dndev-floating-legend label {
4686
+ cursor: default;
4687
+ display: inline-flex;
4688
+ align-items: center;
4689
+ gap: var(--gap-tight);
4649
4690
  }
4650
4691
 
4651
- .dndev-floating-label[data-disabled='true'] {
4692
+ .dndev-floating-fieldset[data-disabled='true'] .dndev-floating-legend {
4652
4693
  color: var(--muted-foreground);
4653
4694
  }
4654
4695
 
4655
- .dndev-floating-label[data-truncate='true'] {
4696
+ .dndev-floating-legend[data-truncate='true'] {
4656
4697
  max-width: calc(100% - var(--gap-md) * 2);
4657
4698
  overflow: hidden;
4658
4699
  text-overflow: ellipsis;
4659
4700
  white-space: nowrap;
4660
4701
  }
4661
4702
 
4703
+ /* Remove border from inner input since fieldset has it */
4704
+
4705
+ .dndev-floating-fieldset .dndev-input {
4706
+ border: none;
4707
+ border-radius: var(--radius-interactive);
4708
+ box-shadow: none;
4709
+ }
4710
+
4711
+ .dndev-floating-fieldset .dndev-input:hover {
4712
+ border-color: transparent;
4713
+ }
4714
+
4715
+ .dndev-floating-fieldset .dndev-input:focus,
4716
+ .dndev-floating-fieldset .dndev-input:focus-visible {
4717
+ border-color: transparent;
4718
+ box-shadow: none;
4719
+ outline: none;
4720
+ }
4721
+
4662
4722
  /* packages/components/src/atomic/List/List.css */
4663
4723
 
4664
4724
  .dndev-list {
@@ -5646,50 +5706,210 @@ em {
5646
5706
  display: flex;
5647
5707
  flex-direction: column;
5648
5708
  z-index: var(--z-modal);
5649
- border-radius: var(--radius-floating); /* Square like floating panels */
5709
+ background: var(--card);
5710
+ /* Ensure background is opaque */
5711
+ color: var(--card-foreground);
5712
+ box-shadow: var(--shadow-xl);
5713
+ /* Focus Tunnel: Deep elevation */
5714
+ overflow: hidden;
5715
+ /* Scroll Trap: Container clips overflow */
5716
+
5717
+ /* Motion Physics: Base state */
5718
+ will-change: transform, opacity;
5650
5719
 
5651
- /* Sheet positioning by side */
5720
+ /* Open state animation - "Heavy" ease for premium feel */
5652
5721
  }
5653
5722
 
5723
+ .dndev-sheet-content[data-state='open'] {
5724
+ animation: sheet-slide-in var(--dur-heavy) var(--ease-heavy);
5725
+ }
5726
+
5727
+ /* Closed state animation */
5728
+
5729
+ .dndev-sheet-content[data-state='closed'] {
5730
+ animation: sheet-slide-out var(--dur-normal) var(--ease-in-out);
5731
+ }
5732
+
5733
+ /* Sheet positioning by side - SPATIAL METAPHOR */
5734
+
5735
+ /* RIGHT / LEFT (Desktop Panels) */
5736
+
5654
5737
  .dndev-sheet-content[data-side='right'],.dndev-sheet-content[data-side='left'] {
5655
5738
  top: 0;
5656
5739
  bottom: 0;
5657
5740
  width: 80%;
5658
5741
  max-width: 56rem;
5742
+ /* Standard panel width */
5743
+ height: 100%;
5744
+ /* Full height */
5745
+ border-radius: 0;
5746
+ /* Square edges for panel metaphor */
5659
5747
  }
5660
5748
 
5661
5749
  .dndev-sheet-content[data-side='right'] {
5750
+ /* Physical positioning: right edge */
5662
5751
  right: 0;
5752
+ left: auto;
5753
+ /* Border on logical start (left in LTR, right in RTL) */
5754
+ border-inline-start: var(--border-hairline) solid var(--line-1);
5663
5755
  }
5664
5756
 
5665
5757
  .dndev-sheet-content[data-side='left'] {
5758
+ /* Physical positioning: left edge */
5666
5759
  left: 0;
5760
+ right: auto;
5761
+ /* Border on logical end (right in LTR, left in RTL) */
5762
+ border-inline-end: var(--border-hairline) solid var(--line-1);
5667
5763
  }
5668
5764
 
5765
+ /* TOP / BOTTOM (Mobile Cards) */
5766
+
5669
5767
  .dndev-sheet-content[data-side='top'],.dndev-sheet-content[data-side='bottom'] {
5670
5768
  left: 0;
5671
5769
  right: 0;
5672
- height: 80%;
5673
- max-height: 56rem;
5674
- overflow: hidden;
5770
+ /* Card metaphor: Detached from opposite edge */
5771
+ height: auto;
5772
+ max-height: 92dvh;
5773
+ /* Never touch top edge */
5774
+ width: 100%;
5775
+ margin-left: auto;
5776
+ margin-right: auto;
5777
+
5778
+ /* On larger screens, constrain width */
5675
5779
  }
5676
5780
 
5781
+ @media (width >=768px) {
5782
+
5783
+ .dndev-sheet-content[data-side='top'],.dndev-sheet-content[data-side='bottom'] {
5784
+ max-width: 56rem;
5785
+ width: 90%;
5786
+ border-radius: var(--radius-lg);
5787
+ /* Fully rounded card on desktop */
5788
+ }
5789
+ }
5790
+
5677
5791
  .dndev-sheet-content[data-side='top'] {
5678
5792
  top: 0;
5793
+ border-bottom: var(--border-hairline) solid var(--line-1);
5794
+ /* Rounded bottom corners only */
5795
+ border-bottom-left-radius: var(--radius-lg);
5796
+ border-bottom-right-radius: var(--radius-lg);
5679
5797
  }
5680
5798
 
5681
5799
  .dndev-sheet-content[data-side='bottom'] {
5682
5800
  bottom: 0;
5801
+ border-top: var(--border-hairline) solid var(--line-1);
5802
+ /* Rounded top corners only */
5803
+ border-top-left-radius: var(--radius-lg);
5804
+ border-top-right-radius: var(--radius-lg);
5683
5805
  }
5684
5806
 
5807
+ /* DRAG HANDLE PILL - Visual affordance for draggable sheets */
5808
+
5809
+ .dndev-sheet-drag-handle {
5810
+ width: 2.5rem;
5811
+ height: 0.25rem;
5812
+ background: var(--line-2);
5813
+ border-radius: var(--radius-full);
5814
+ margin: var(--gap-sm) auto 0;
5815
+ flex-shrink: 0;
5816
+ cursor: grab;
5817
+ transition: background-color var(--dur-fast) var(--ease-in-out);
5818
+ }
5819
+
5820
+ .dndev-sheet-drag-handle:active {
5821
+ cursor: grabbing;
5822
+ }
5823
+
5824
+ /* Positioning for bottom sheets */
5825
+
5826
+ .dndev-sheet-content[data-side='bottom'] > .dndev-sheet-drag-handle {
5827
+ margin-top: var(--gap-sm);
5828
+ margin-bottom: 0;
5829
+ }
5830
+
5831
+ /* Positioning for top sheets */
5832
+
5833
+ .dndev-sheet-content[data-side='top'] > .dndev-sheet-drag-handle {
5834
+ margin-top: max(var(--gap-sm), env(safe-area-inset-top));
5835
+ margin-bottom: 0;
5836
+ }
5837
+
5838
+ /* HEADER - Pinned, No Padding (Tight Layout) */
5839
+
5840
+ /* Industry standard: Title always on start, X always on end (consistent across all sides) */
5841
+
5685
5842
  .dndev-sheet-header {
5686
5843
  display: flex;
5687
5844
  align-items: center;
5688
5845
  justify-content: space-between;
5689
5846
  gap: var(--gap-md);
5690
5847
  flex-shrink: 0;
5848
+ /* Never shrink */
5691
5849
  min-height: var(--touch-target);
5692
- margin-bottom: var(--gap-md);
5850
+ /* No padding - tight layout: [ Title X ] */
5851
+ padding-block: 0;
5852
+ /* RTL-aware: padding on logical start only */
5853
+ padding-inline-start: var(--gap-md);
5854
+ padding-inline-end: 0; /* X button has its own spacing */
5855
+ border-bottom: var(--border-hairline) solid var(--line-1);
5856
+ /* Separator */
5857
+
5858
+ /* Thumb Ergonomics: Top Safe Area (only for top sheets) */
5859
+ }
5860
+
5861
+ .dndev-sheet-content[data-side='top'] .dndev-sheet-header {
5862
+ padding-top: max(0, env(safe-area-inset-top));
5863
+ }
5864
+
5865
+ /* Adjust header padding when drag handle is present (sibling selector) */
5866
+
5867
+ .dndev-sheet-content[data-side='bottom'] .dndev-sheet-drag-handle ~ .dndev-sheet-header,
5868
+ .dndev-sheet-content[data-side='top'] .dndev-sheet-drag-handle ~ .dndev-sheet-header {
5869
+ padding-top: 0;
5870
+ }
5871
+
5872
+ /* BODY - Scrollable */
5873
+
5874
+ .dndev-sheet-body {
5875
+ flex: 1;
5876
+ /* Consumes available space */
5877
+ overflow-y: auto;
5878
+ /* Independent scroll */
5879
+ overflow-x: hidden;
5880
+ padding: var(--gap-md);
5881
+ overscroll-behavior: contain;
5882
+ /* Prevent body scroll chaining */
5883
+ }
5884
+
5885
+ /* FOOTER - Pinned */
5886
+
5887
+ .dndev-sheet-footer {
5888
+ flex-shrink: 0;
5889
+ /* Never shrink */
5890
+ padding: var(--gap-md);
5891
+ border-top: var(--border-hairline) solid var(--line-1);
5892
+ /* Separator */
5893
+ display: flex;
5894
+ flex-direction: column-reverse;
5895
+ /* Mobile-first stacking */
5896
+ gap: var(--gap-sm);
5897
+
5898
+ /* Desktop: Row layout */
5899
+ }
5900
+
5901
+ @media (width >=640px) {
5902
+
5903
+ .dndev-sheet-footer {
5904
+ flex-direction: row;
5905
+ justify-content: flex-end;
5906
+ }
5907
+ }
5908
+
5909
+ .dndev-sheet-footer {
5910
+
5911
+ /* Thumb Ergonomics: Bottom Safe Area (Home Indicator) */
5912
+ padding-bottom: max(var(--gap-md), env(safe-area-inset-bottom));
5693
5913
  }
5694
5914
 
5695
5915
  .dndev-sheet-title {
@@ -5699,19 +5919,72 @@ em {
5699
5919
  }
5700
5920
 
5701
5921
  .dndev-sheet-close {
5702
- position: absolute;
5703
- top: var(--gap-md);
5704
- inset-inline-end: var(--gap-md);
5922
+ /* Position relative - flex handles alignment */
5923
+ position: relative;
5924
+ margin-inline-start: auto;
5925
+ /* Push to end (RTL-aware: end = right in LTR, left in RTL) */
5705
5926
  opacity: var(--opacity-muted);
5927
+ /* No padding - tight spacing */
5928
+ padding: 0;
5929
+ /* RTL-aware: padding on logical end only */
5930
+ padding-inline-end: var(--gap-md);
5931
+ padding-inline-start: 0;
5706
5932
  }
5707
5933
 
5708
5934
  .dndev-sheet-close:hover {
5709
5935
  opacity: 1;
5710
5936
  }
5711
5937
 
5712
- .dndev-sheet-footer {
5713
- flex-shrink: 0;
5714
- margin-top: var(--gap-md);
5938
+ /* ===========================
5939
+ ANIMATIONS (Motion Physics)
5940
+ =========================== */
5941
+
5942
+ /* Slide In/Out Keyframes - Context Aware */
5943
+
5944
+ @keyframes sheet-slide-in {
5945
+ from {
5946
+ opacity: 0;
5947
+ transform: var(--slide-enter-transform);
5948
+ }
5949
+
5950
+ to {
5951
+ opacity: 1;
5952
+ transform: translate(0, 0);
5953
+ }
5954
+ }
5955
+
5956
+ @keyframes sheet-slide-out {
5957
+ from {
5958
+ opacity: 1;
5959
+ transform: translate(0, 0);
5960
+ }
5961
+
5962
+ to {
5963
+ opacity: 0;
5964
+ transform: var(--slide-exit-transform);
5965
+ }
5966
+ }
5967
+
5968
+ /* Define Transforms based on Side */
5969
+
5970
+ .dndev-sheet-content[data-side='right'] {
5971
+ --slide-enter-transform: translateX(100%);
5972
+ --slide-exit-transform: translateX(100%);
5973
+ }
5974
+
5975
+ .dndev-sheet-content[data-side='left'] {
5976
+ --slide-enter-transform: translateX(-100%);
5977
+ --slide-exit-transform: translateX(-100%);
5978
+ }
5979
+
5980
+ .dndev-sheet-content[data-side='bottom'] {
5981
+ --slide-enter-transform: translateY(100%);
5982
+ --slide-exit-transform: translateY(100%);
5983
+ }
5984
+
5985
+ .dndev-sheet-content[data-side='top'] {
5986
+ --slide-enter-transform: translateY(-100%);
5987
+ --slide-exit-transform: translateY(-100%);
5715
5988
  }
5716
5989
 
5717
5990
  /* packages/components/src/atomic/Skeleton/Skeleton.css */
@@ -6384,7 +6657,8 @@ em {
6384
6657
 
6385
6658
  .dndev-switch-label {
6386
6659
  font-size: var(--font-size-sm);
6387
- transition: color var(--dur-normal) var(--ease-in-out),
6660
+ transition:
6661
+ color var(--dur-normal) var(--ease-in-out),
6388
6662
  font-weight var(--dur-normal) var(--ease-in-out);
6389
6663
  white-space: nowrap;
6390
6664
  }
@@ -6393,16 +6667,14 @@ em {
6393
6667
 
6394
6668
  .dndev-switch-with-labels:not(:has(.dndev-switch[data-state='checked']))
6395
6669
  .dndev-switch-label-unchecked,
6396
- .dndev-switch-with-labels[data-checked='false']
6397
- .dndev-switch-label-unchecked {
6670
+ .dndev-switch-with-labels[data-checked='false'] .dndev-switch-label-unchecked {
6398
6671
  color: var(--foreground);
6399
6672
  font-weight: var(--font-weight-medium);
6400
6673
  }
6401
6674
 
6402
6675
  .dndev-switch-with-labels:has(.dndev-switch[data-state='checked'])
6403
6676
  .dndev-switch-label-unchecked,
6404
- .dndev-switch-with-labels[data-checked='true']
6405
- .dndev-switch-label-unchecked {
6677
+ .dndev-switch-with-labels[data-checked='true'] .dndev-switch-label-unchecked {
6406
6678
  color: var(--muted-foreground);
6407
6679
  font-weight: var(--font-weight-normal);
6408
6680
  }
@@ -6411,16 +6683,14 @@ em {
6411
6683
 
6412
6684
  .dndev-switch-with-labels:has(.dndev-switch[data-state='checked'])
6413
6685
  .dndev-switch-label-checked,
6414
- .dndev-switch-with-labels[data-checked='true']
6415
- .dndev-switch-label-checked {
6686
+ .dndev-switch-with-labels[data-checked='true'] .dndev-switch-label-checked {
6416
6687
  color: var(--foreground);
6417
6688
  font-weight: var(--font-weight-medium);
6418
6689
  }
6419
6690
 
6420
6691
  .dndev-switch-with-labels:not(:has(.dndev-switch[data-state='checked']))
6421
6692
  .dndev-switch-label-checked,
6422
- .dndev-switch-with-labels[data-checked='false']
6423
- .dndev-switch-label-checked {
6693
+ .dndev-switch-with-labels[data-checked='false'] .dndev-switch-label-checked {
6424
6694
  color: var(--muted-foreground);
6425
6695
  font-weight: var(--font-weight-normal);
6426
6696
  }
@@ -6461,6 +6731,12 @@ em {
6461
6731
  background-color: color-mix(in oklab, var(--accent) 15%, transparent);
6462
6732
  }
6463
6733
 
6734
+ /* Cursor pointer for clickable rows */
6735
+
6736
+ .dndev-table-row.dndev-cursor-pointer {
6737
+ cursor: pointer;
6738
+ }
6739
+
6464
6740
  /* Zebra striping for data tables */
6465
6741
 
6466
6742
  .dndev-table-body .dndev-table-row:nth-child(even) {
@@ -6555,8 +6831,8 @@ em {
6555
6831
  /* Input components inside grid cells should be borderless and fit snugly */
6556
6832
 
6557
6833
  .dndev-table-grid .dndev-table-cell .dndev-input,
6558
- .dndev-table-grid .dndev-table-cell input[type="text"],
6559
- .dndev-table-grid .dndev-table-cell input[type="number"] {
6834
+ .dndev-table-grid .dndev-table-cell input[type='text'],
6835
+ .dndev-table-grid .dndev-table-cell input[type='number'] {
6560
6836
  border: none;
6561
6837
  background: transparent;
6562
6838
  width: 100%;
@@ -8159,6 +8435,10 @@ h4[data-variant='code'] {
8159
8435
  pointer-events: auto;
8160
8436
  }
8161
8437
 
8438
+ .dndev-cursor-pointer {
8439
+ cursor: pointer;
8440
+ }
8441
+
8162
8442
  .dndev-aspect-video {
8163
8443
  aspect-ratio: 16 / 9;
8164
8444
  }
@@ -8725,10 +9005,7 @@ main[role='main'][data-routing-animation='none'] {
8725
9005
  max-height: 100dvh;
8726
9006
  overflow: hidden;
8727
9007
  display: grid;
8728
- /* ONE DRY grid structure: 3 rows, 2 columns */
8729
- /* Footer starts at sidebar edge (column 2) - when sidebar-width is 0px, footer starts at left edge */
8730
- /* Footer grows with content wrapping. For pixel-perfect calc() accuracy when footer wraps,
8731
- implement ResizeObserver to update --footer-height dynamically. */
9008
+ /* Grid structure: 3 rows, 2 columns */
8732
9009
  grid-template-areas:
8733
9010
  'header header'
8734
9011
  'sidebar main'
@@ -8739,15 +9016,61 @@ main[role='main'][data-routing-animation='none'] {
8739
9016
  );
8740
9017
  grid-template-columns: var(--sidebar-width) 1fr;
8741
9018
 
8742
- /* Game layout: Grid rows adjust based on breakpoint (footer hidden on tablet/mobile) */
9019
+ /* Mobile: No footer grid row - footer is inside main */
9020
+ /* When mergedBar is shown, header is hidden but grid still needs space for mergedBar */
8743
9021
  }
8744
9022
 
8745
- [data-layout='game']:root .dndev-layout {
8746
- grid-template-rows: var(--header-height) 1fr minmax(
8747
- var(--footer-height),
8748
- auto
8749
- );
9023
+ @media (width <= 1023px) {
9024
+
9025
+ .dndev-layout {
9026
+ grid-template-areas:
9027
+ 'header header'
9028
+ 'sidebar main';
9029
+ grid-template-rows: var(--header-height) 1fr;
9030
+
9031
+ /* Presets with mergedBar: header is hidden, but grid still allocates space for mergedBar */
9032
+ /* No extra padding needed - grid spacing is sufficient */
9033
+ }
9034
+ .dndev-layout[data-layout='admin'],.dndev-layout[data-layout='moolti'],.dndev-layout[data-layout='game'],.dndev-layout[data-layout='docs'] {
9035
+ /* Grid already accounts for header-height, mergedBar is fixed and doesn't need extra padding */
9036
+ }
9037
+ }
9038
+
9039
+ /* Footer containers: show/hide based on breakpoint */
9040
+
9041
+ .footer-mobile {
9042
+ display: none;
9043
+ /* No margin-top: auto - footer scrolls with content on mobile */
9044
+ /* No flex-shrink: 0 - footer is in normal flow, not stuck at bottom */
9045
+ }
9046
+
9047
+ .footer-desktop {
9048
+ display: contents; /* Children (footer element) participate in grid */
9049
+ }
9050
+
9051
+ @media (width <= 1023px) {
9052
+ .footer-mobile {
9053
+ display: block;
9054
+ }
9055
+
9056
+ .footer-desktop {
9057
+ display: none;
9058
+ }
9059
+
9060
+ /* Game: No mobile footer - navigation in MergedBar */
9061
+ [data-layout='game'] .footer-mobile {
9062
+ display: none;
8750
9063
  }
9064
+ }
9065
+
9066
+ /* Presets with no footer at all */
9067
+
9068
+ [data-layout='moolti'] .footer-mobile,
9069
+ [data-layout='moolti'] .footer-desktop,
9070
+ [data-layout='plain'] .footer-mobile,
9071
+ [data-layout='plain'] .footer-desktop {
9072
+ display: none;
9073
+ }
8751
9074
 
8752
9075
  /* ===========================
8753
9076
  LAYOUT ZONE POSITIONING RULES
@@ -8762,6 +9085,8 @@ header[role='banner'] {
8762
9085
  grid-area: header;
8763
9086
  box-sizing: border-box;
8764
9087
  height: var(--header-height);
9088
+ min-height: var(--header-height);
9089
+ max-height: var(--header-height);
8765
9090
  position: relative;
8766
9091
  z-index: var(--z-header);
8767
9092
  contain: layout style;
@@ -8788,7 +9113,9 @@ header[role='banner'] {
8788
9113
  align-items: center;
8789
9114
  flex-shrink: 0;
8790
9115
  height: 100%;
9116
+ max-height: 100%;
8791
9117
  gap: var(--gap-sm);
9118
+ overflow: hidden;
8792
9119
  }
8793
9120
 
8794
9121
  .header-end {
@@ -8796,8 +9123,11 @@ header[role='banner'] {
8796
9123
  align-items: center;
8797
9124
  justify-content: flex-end;
8798
9125
  flex-shrink: 0;
9126
+ height: 100%;
9127
+ max-height: 100%;
8799
9128
  margin-inline-start: auto;
8800
9129
  gap: var(--gap-sm);
9130
+ overflow: hidden;
8801
9131
  }
8802
9132
 
8803
9133
  /* Viewport-centered center content - absolutely positioned overlay */
@@ -9089,11 +9419,17 @@ main[role='main'] > *:not(.breadcrumbs-container):first-of-type,main[role='main'
9089
9419
  /* Page content grows */
9090
9420
  }
9091
9421
 
9092
- main[role='main'] > *:last-child {
9093
- flex-shrink: 0;
9094
- /* Footer stays at bottom */
9422
+ /* Desktop: Footer stays at bottom of viewport */
9423
+
9424
+ @media (width > 1023px) {
9425
+ main[role='main'] > *:last-child {
9426
+ flex-shrink: 0;
9427
+ /* Footer stays at bottom */
9428
+ }
9095
9429
  }
9096
9430
 
9431
+ /* Mobile: Footer scrolls with content (no flex-shrink needed) */
9432
+
9097
9433
  /* Footer: Full width by default, app presets start after sidebar */
9098
9434
 
9099
9435
  /* box-sizing: border-box ensures borders are included in height */
@@ -9126,26 +9462,6 @@ footer[role='contentinfo'] > * {
9126
9462
  padding-inline-end: var(--content-padding);
9127
9463
  }
9128
9464
 
9129
- /* Game: Hide footer on tablet/mobile - merged into GameMergedBar */
9130
-
9131
- @media (width <= 1023px) {
9132
- [data-layout='game']:root footer[role='contentinfo'] {
9133
- display: none;
9134
- }
9135
- }
9136
-
9137
- /* Moolti: No footer (built into sidebar) */
9138
-
9139
- [data-layout='moolti']:root footer[role='contentinfo'] {
9140
- display: none;
9141
- }
9142
-
9143
- /* Plain: No footer (full-screen apps) */
9144
-
9145
- [data-layout='plain']:root footer[role='contentinfo'] {
9146
- display: none;
9147
- }
9148
-
9149
9465
  /* Footer text styles */
9150
9466
 
9151
9467
  footer[role='contentinfo'] .footer-copyright {
@@ -9190,7 +9506,7 @@ footer[role='contentinfo'] a:not(.dndev-interactive):hover {
9190
9506
 
9191
9507
  .merged-bar[data-position='top'] {
9192
9508
  top: 0;
9193
- height: 64px;
9509
+ height: var(--header-height);
9194
9510
  border-bottom: 2px solid var(--border);
9195
9511
  padding-top: env(safe-area-inset-top);
9196
9512
  }
@@ -9218,7 +9534,7 @@ footer[role='contentinfo'] a:not(.dndev-interactive):hover {
9218
9534
  min-height: 0;
9219
9535
  }
9220
9536
 
9221
- /* Mobile (<1024px): Show merged-bar, hide zones, add padding */
9537
+ /* Mobile (<1024px): Show merged-bar, hide zones */
9222
9538
 
9223
9539
  @media (width <= 1023px) {
9224
9540
  /* Presets with mergedBar: top (admin, moolti, game, docs) */
@@ -9233,7 +9549,8 @@ footer[role='contentinfo'] a:not(.dndev-interactive):hover {
9233
9549
  [data-layout='moolti'] .dndev-layout,
9234
9550
  [data-layout='game'] .dndev-layout,
9235
9551
  [data-layout='docs'] .dndev-layout {
9236
- padding-top: calc(64px + env(safe-area-inset-top));
9552
+ /* Remove padding-top - grid already accounts for header-height, mergedBar is fixed and doesn't affect grid flow */
9553
+ /* Content won't go under mergedBar because grid positions main after header row */
9237
9554
  }
9238
9555
 
9239
9556
  [data-layout='admin'] header[role='banner'],