@donotdev/ui 0.0.12 → 0.0.14

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 (159) hide show
  1. package/dist/components/auth/AuthMenu.d.ts.map +1 -1
  2. package/dist/components/auth/AuthMenu.js +19 -20
  3. package/dist/components/common/FeatureCard.d.ts +3 -1
  4. package/dist/components/common/FeatureCard.d.ts.map +1 -1
  5. package/dist/components/common/FeatureCard.js +3 -3
  6. package/dist/components/common/ProgressBar.js +2 -2
  7. package/dist/components/common/RedirectOverlay.js +1 -1
  8. package/dist/components/common/TechBento.d.ts +14 -2
  9. package/dist/components/common/TechBento.d.ts.map +1 -1
  10. package/dist/components/common/TechBento.js +8 -9
  11. package/dist/components/cookie-consent/CookieConsent.d.ts.map +1 -1
  12. package/dist/components/cookie-consent/CookieConsent.js +6 -7
  13. package/dist/components/layout/GameContainer.d.ts +24 -8
  14. package/dist/components/layout/GameContainer.d.ts.map +1 -1
  15. package/dist/components/layout/GameContainer.js +21 -3
  16. package/dist/components/layout/GameFlow.d.ts.map +1 -1
  17. package/dist/components/layout/GameFlow.js +27 -11
  18. package/dist/components/layout/components/DropdownNavigation.d.ts.map +1 -1
  19. package/dist/components/layout/components/DropdownNavigation.js +3 -12
  20. package/dist/components/layout/components/FloatingLanguageSwitcher.js +1 -1
  21. package/dist/components/layout/components/Notifications.d.ts +1 -3
  22. package/dist/components/layout/components/Notifications.d.ts.map +1 -1
  23. package/dist/components/layout/components/Notifications.js +4 -2
  24. package/dist/components/layout/components/header/AppBranding.d.ts.map +1 -1
  25. package/dist/components/layout/components/header/AppBranding.js +2 -1
  26. package/dist/components/layout/components/header/AppIcon.d.ts.map +1 -1
  27. package/dist/components/layout/components/header/AppIcon.js +5 -2
  28. package/dist/components/layout/components/header/CacheSettings.d.ts.map +1 -1
  29. package/dist/components/layout/components/header/CacheSettings.js +4 -2
  30. package/dist/components/layout/components/header/HeaderNavigation.d.ts +6 -0
  31. package/dist/components/layout/components/header/HeaderNavigation.d.ts.map +1 -1
  32. package/dist/components/layout/components/header/HeaderNavigation.js +12 -2
  33. package/dist/components/license/LicenseWatermark.d.ts.map +1 -1
  34. package/dist/components/license/LicenseWatermark.js +3 -1
  35. package/dist/crud/components/CrudCardLink.d.ts +17 -0
  36. package/dist/crud/components/CrudCardLink.d.ts.map +1 -0
  37. package/dist/crud/components/CrudCardLink.js +17 -0
  38. package/dist/crud/components/EntityCardList.d.ts.map +1 -1
  39. package/dist/crud/components/EntityCardList.js +32 -81
  40. package/dist/crud/components/EntityDisplayRenderer.d.ts +1 -1
  41. package/dist/crud/components/EntityDisplayRenderer.d.ts.map +1 -1
  42. package/dist/crud/components/EntityDisplayRenderer.js +8 -4
  43. package/dist/crud/components/EntityFormRenderer.d.ts +1 -1
  44. package/dist/crud/components/EntityFormRenderer.d.ts.map +1 -1
  45. package/dist/crud/components/EntityFormRenderer.js +29 -18
  46. package/dist/crud/components/EntityList.d.ts +1 -1
  47. package/dist/crud/components/EntityList.d.ts.map +1 -1
  48. package/dist/crud/components/EntityList.js +8 -10
  49. package/dist/crud/components/EntityRecommendations.d.ts +28 -0
  50. package/dist/crud/components/EntityRecommendations.d.ts.map +1 -0
  51. package/dist/crud/components/EntityRecommendations.js +31 -0
  52. package/dist/crud/components/Form.js +1 -1
  53. package/dist/crud/components/index.d.ts +2 -1
  54. package/dist/crud/components/index.d.ts.map +1 -1
  55. package/dist/crud/components/index.js +1 -0
  56. package/dist/index.js +4 -4
  57. package/dist/internal/common/RouteErrorFallback.d.ts.map +1 -1
  58. package/dist/internal/common/RouteErrorFallback.js +3 -3
  59. package/dist/internal/devtools/components/AuthDebugButton.js +1 -1
  60. package/dist/internal/devtools/components/ConfigTab.js +1 -1
  61. package/dist/internal/devtools/components/CookieTab.js +1 -1
  62. package/dist/internal/devtools/components/DesignTab.d.ts.map +1 -1
  63. package/dist/internal/devtools/components/DesignTab.js +5 -4
  64. package/dist/internal/devtools/components/LayoutReset.d.ts.map +1 -1
  65. package/dist/internal/devtools/components/LayoutReset.js +2 -0
  66. package/dist/internal/devtools/components/StoresTab.d.ts.map +1 -1
  67. package/dist/internal/devtools/components/StoresTab.js +5 -2
  68. package/dist/internal/devtools/utils/envVarDiscovery.d.ts +1 -0
  69. package/dist/internal/devtools/utils/envVarDiscovery.d.ts.map +1 -1
  70. package/dist/internal/devtools/utils/envVarDiscovery.js +5 -0
  71. package/dist/internal/devtools/utils/virtualModuleInspector.d.ts.map +1 -1
  72. package/dist/internal/devtools/utils/virtualModuleInspector.js +27 -21
  73. package/dist/internal/initializers/BaseStoresInitializer.d.ts.map +1 -1
  74. package/dist/internal/initializers/BaseStoresInitializer.js +30 -6
  75. package/dist/internal/layout/components/AutoMetaTags.d.ts.map +1 -1
  76. package/dist/internal/layout/components/AutoMetaTags.js +10 -8
  77. package/dist/internal/layout/components/FontPreloadLinks.d.ts +16 -0
  78. package/dist/internal/layout/components/FontPreloadLinks.d.ts.map +1 -0
  79. package/dist/internal/layout/components/FontPreloadLinks.js +32 -0
  80. package/dist/internal/layout/components/PerformanceHints.d.ts +7 -12
  81. package/dist/internal/layout/components/PerformanceHints.d.ts.map +1 -1
  82. package/dist/internal/layout/components/PerformanceHints.js +8 -12
  83. package/dist/internal/layout/components/footer/useLegalLinks.d.ts +6 -5
  84. package/dist/internal/layout/components/footer/useLegalLinks.d.ts.map +1 -1
  85. package/dist/internal/layout/components/footer/useLegalLinks.js +6 -2
  86. package/dist/internal/layout/zones/DnDevFooter.d.ts +6 -0
  87. package/dist/internal/layout/zones/DnDevFooter.d.ts.map +1 -1
  88. package/dist/internal/layout/zones/DnDevFooter.js +10 -4
  89. package/dist/internal/layout/zones/DnDevHeader.d.ts +7 -0
  90. package/dist/internal/layout/zones/DnDevHeader.d.ts.map +1 -1
  91. package/dist/internal/layout/zones/DnDevHeader.js +7 -0
  92. package/dist/internal/layout/zones/DnDevMergedBar.d.ts +7 -0
  93. package/dist/internal/layout/zones/DnDevMergedBar.d.ts.map +1 -1
  94. package/dist/internal/layout/zones/DnDevMergedBar.js +10 -1
  95. package/dist/internal/layout/zones/DnDevSidebar.d.ts +4 -0
  96. package/dist/internal/layout/zones/DnDevSidebar.d.ts.map +1 -1
  97. package/dist/internal/layout/zones/DnDevSidebar.js +13 -1
  98. package/dist/next.d.ts +1 -0
  99. package/dist/next.d.ts.map +1 -1
  100. package/dist/next.js +1 -0
  101. package/dist/routing/404.js +3 -3
  102. package/dist/routing/AuthGuard.d.ts +1 -1
  103. package/dist/routing/AuthGuard.d.ts.map +1 -1
  104. package/dist/routing/AuthGuard.js +3 -1
  105. package/dist/routing/AuthGuardFallback.js +2 -2
  106. package/dist/routing/GoTo.d.ts.map +1 -1
  107. package/dist/routing/GoTo.js +3 -1
  108. package/dist/routing/GoToDialog.d.ts.map +1 -1
  109. package/dist/routing/GoToDialog.js +2 -7
  110. package/dist/routing/GoToInput.d.ts +0 -3
  111. package/dist/routing/GoToInput.d.ts.map +1 -1
  112. package/dist/routing/GoToInput.js +4 -2
  113. package/dist/routing/Link.js +1 -1
  114. package/dist/routing/NavigationItem.d.ts +29 -7
  115. package/dist/routing/NavigationItem.d.ts.map +1 -1
  116. package/dist/routing/NavigationItem.js +22 -6
  117. package/dist/routing/hooks/hooks.next.js +1 -1
  118. package/dist/routing/hooks/hooks.vite.js +1 -1
  119. package/dist/routing/hooks/useRedirectGuard.next.d.ts.map +1 -1
  120. package/dist/routing/hooks/useRedirectGuard.next.js +9 -8
  121. package/dist/routing/hooks/useRedirectGuard.vite.d.ts.map +1 -1
  122. package/dist/routing/hooks/useRedirectGuard.vite.js +9 -8
  123. package/dist/routing/hooks/useSearchParams.next.d.ts +18 -1
  124. package/dist/routing/hooks/useSearchParams.next.d.ts.map +1 -1
  125. package/dist/routing/hooks/useSearchParams.next.js +16 -0
  126. package/dist/routing/hooks/useSearchParams.vite.d.ts +16 -0
  127. package/dist/routing/hooks/useSearchParams.vite.d.ts.map +1 -1
  128. package/dist/routing/hooks/useSearchParams.vite.js +17 -1
  129. package/dist/routing/index.d.ts.map +1 -1
  130. package/dist/routing/index.js +2 -0
  131. package/dist/routing/useNavigation.d.ts +30 -0
  132. package/dist/routing/useNavigation.d.ts.map +1 -1
  133. package/dist/routing/useNavigation.js +40 -3
  134. package/dist/routing/useRouteDiscovery.d.ts +2 -2
  135. package/dist/routing/useRouteDiscovery.d.ts.map +1 -1
  136. package/dist/routing/useRouteDiscovery.js +10 -4
  137. package/dist/styles/index.css +366 -120
  138. package/dist/utils/index.d.ts +1 -0
  139. package/dist/utils/index.d.ts.map +1 -1
  140. package/dist/utils/index.js +1 -0
  141. package/dist/utils/sanitizeSvg.d.ts +13 -0
  142. package/dist/utils/sanitizeSvg.d.ts.map +1 -0
  143. package/dist/utils/sanitizeSvg.js +47 -0
  144. package/dist/utils/useBillingVisibility.d.ts.map +1 -1
  145. package/dist/utils/useBillingVisibility.js +0 -7
  146. package/dist/utils/useCrudSafe.d.ts +0 -2
  147. package/dist/utils/useCrudSafe.d.ts.map +1 -1
  148. package/dist/utils/useFormStoreSafe.d.ts +3 -1
  149. package/dist/utils/useFormStoreSafe.d.ts.map +1 -1
  150. package/dist/utils/useFormStoreSafe.js +4 -5
  151. package/dist/vite-routing/AppRoutes.d.ts +19 -8
  152. package/dist/vite-routing/AppRoutes.d.ts.map +1 -1
  153. package/dist/vite-routing/AppRoutes.js +0 -3
  154. package/package.json +15 -11
  155. package/assets/fonts/fonts.css +0 -206
  156. package/dist/dndev.css +0 -10673
  157. package/dist/routing/Navigate.d.ts +0 -10
  158. package/dist/routing/Navigate.d.ts.map +0 -1
  159. package/dist/routing/Navigate.js +0 -10
@@ -121,6 +121,15 @@
121
121
  --popover: var(--card);
122
122
  --popover-foreground: var(--card-foreground);
123
123
 
124
+ /*
125
+ * Root card snapshot — computed once on :root from --card/--card-foreground,
126
+ * then inherited unchanged. Variant blocks (e.g. primary) override --card but
127
+ * never touch these, so data-variant='default' can reset --card back to the
128
+ * root value even when nested inside another variant.
129
+ */
130
+ --card-base: var(--card);
131
+ --card-foreground-base: var(--card-foreground);
132
+
124
133
  /* ===========================
125
134
  BORDER RADIUS - 3 VALUES ONLY
126
135
  =========================== */
@@ -216,6 +225,16 @@
216
225
  -6px 12px 24px -6px var(--shadow-color),
217
226
  -3px 6px 12px -3px var(--shadow-color-light);
218
227
 
228
+ /* Root shadow snapshots — same principle as --card-base (see above) */
229
+ --shadow-md-base: var(--shadow-md);
230
+ --shadow-xl-base: var(--shadow-xl);
231
+
232
+ /* Per-variant shadows — essences override these with different colors/shapes */
233
+ --shadow-primary: var(--shadow-md);
234
+ --shadow-primary-xl: var(--shadow-xl);
235
+ --shadow-secondary: var(--shadow-md);
236
+ --shadow-secondary-xl: var(--shadow-xl);
237
+
219
238
  /* Interactive shadows */
220
239
  --shadow-interactive: 0 0 0 3px
221
240
  color-mix(in oklab, var(--ring) 20%, transparent);
@@ -519,7 +538,6 @@ body {
519
538
  /* Reset and base styles */
520
539
 
521
540
  :root {
522
- font-family: var(--font-sans);
523
541
  -webkit-font-smoothing: antialiased;
524
542
  -moz-osx-font-smoothing: grayscale;
525
543
  text-rendering: optimizeLegibility;
@@ -533,9 +551,10 @@ body {
533
551
  box-sizing: border-box;
534
552
  }
535
553
 
536
- /* Set core body defaults */
554
+ /* Set core body defaults — font-family here so theme tokens on :root cascade cleanly */
537
555
 
538
556
  body {
557
+ font-family: var(--font-family, var(--font-sans));
539
558
  min-height: 100dvh;
540
559
  line-height: var(--line-height);
541
560
  text-rendering: optimizeSpeed;
@@ -610,17 +629,21 @@ h6 {
610
629
  color: var(--foreground);
611
630
  background: transparent;
612
631
  text-wrap: balance; /* Equalize line lengths, prevent orphans */
632
+ text-transform: var(--text-transform-heading, none);
633
+ letter-spacing: var(--letter-spacing-heading, normal);
613
634
  }
614
635
 
615
- h1 {
636
+ :is(h1, h2, h3, h4, h5, h6) {
616
637
  font-family: var(--font-headline);
638
+ }
639
+
640
+ h1 {
617
641
  font-size: var(--font-size-3xl);
618
642
  font-weight: var(--font-weight-bold);
619
643
  letter-spacing: -0.02em;
620
644
  }
621
645
 
622
646
  h2 {
623
- font-family: var(--font-headline);
624
647
  font-size: var(--font-size-2xl);
625
648
  font-weight: var(--font-weight-bold);
626
649
  letter-spacing: -0.01em;
@@ -1051,10 +1074,20 @@ em {
1051
1074
  * - accent: Highlighted/active state (--accent colors, sets context for children)
1052
1075
  * - destructive: Error/danger state (--destructive colors)
1053
1076
  *
1054
- * Variants only override --card and --card-foreground.
1077
+ * Variants override --card and --card-foreground.
1078
+ * Primary/secondary also override --shadow-md/--shadow-xl for per-variant shadows.
1079
+ * Default resets --card from --card-base (root snapshot) so nested default cards
1080
+ * inside other variants get the root card color, not the parent's.
1055
1081
  * Surface glow gradient is computed from --theme-is-dark flag and not affected by variants.
1056
1082
  */
1057
1083
 
1084
+ .dndev-surface[data-variant='default'] {
1085
+ --card: var(--card-base);
1086
+ --card-foreground: var(--card-foreground-base);
1087
+ --shadow-md: var(--shadow-md-base);
1088
+ --shadow-xl: var(--shadow-xl-base);
1089
+ }
1090
+
1058
1091
  .dndev-surface[data-variant='muted'] {
1059
1092
  --card: var(--muted);
1060
1093
  --card-foreground: var(--muted-foreground);
@@ -1064,12 +1097,16 @@ em {
1064
1097
  .dndev-surface[data-variant='primary'] {
1065
1098
  --card: var(--primary);
1066
1099
  --card-foreground: var(--primary-foreground);
1100
+ --shadow-md: var(--shadow-primary);
1101
+ --shadow-xl: var(--shadow-primary-xl);
1067
1102
  border-color: var(--primary);
1068
1103
  }
1069
1104
 
1070
1105
  .dndev-surface[data-variant='secondary'] {
1071
1106
  --card: var(--secondary);
1072
1107
  --card-foreground: var(--secondary-foreground);
1108
+ --shadow-md: var(--shadow-secondary);
1109
+ --shadow-xl: var(--shadow-secondary-xl);
1073
1110
  border-color: var(--secondary);
1074
1111
  }
1075
1112
 
@@ -1351,6 +1388,7 @@ em {
1351
1388
  border-radius: var(--radius-interactive);
1352
1389
  font-size: var(--font-size-base);
1353
1390
  font-weight: var(--font-weight-medium);
1391
+ text-transform: var(--text-transform-button, none);
1354
1392
  transition: var(--transition-fast);
1355
1393
  cursor: pointer;
1356
1394
  border: var(--border-hairline) solid transparent;
@@ -1641,6 +1679,7 @@ em {
1641
1679
  overflow: hidden;
1642
1680
  text-overflow: ellipsis;
1643
1681
  white-space: nowrap;
1682
+ text-transform: var(--text-transform-label, none);
1644
1683
  }
1645
1684
 
1646
1685
  /* Compact mode - always hide label */
@@ -1706,7 +1745,8 @@ em {
1706
1745
 
1707
1746
  .dndev-control[data-state='checked'],.dndev-control[data-state='on'],.dndev-control[data-pressed='true'] {
1708
1747
  background-color: var(--control-border);
1709
- color: var(--background);
1748
+ /* --card not --background: inverted text must be opaque (--background can be transparent in some themes) */
1749
+ color: var(--card);
1710
1750
  }
1711
1751
 
1712
1752
  /* CONTROL GROUP - Shared pattern for grouped controls (RadioGroup, Checkbox groups) */
@@ -2012,7 +2052,7 @@ em {
2012
2052
  height: var(--icon-md);
2013
2053
  border: 2px solid currentColor;
2014
2054
  border-radius: var(--radius-full);
2015
- border-right-color: transparent;
2055
+ border-inline-end-color: transparent;
2016
2056
  animation: spin 1s linear infinite;
2017
2057
  }
2018
2058
 
@@ -2352,7 +2392,6 @@ em {
2352
2392
  flex-shrink: 0;
2353
2393
  overflow: hidden;
2354
2394
  border-radius: var(--radius-full);
2355
- border: 1px solid var(--border);
2356
2395
  }
2357
2396
 
2358
2397
  .dndev-avatar-image {
@@ -2809,8 +2848,7 @@ em {
2809
2848
  .dndev-calendar-nav {
2810
2849
  position: absolute;
2811
2850
  top: 0;
2812
- left: 0;
2813
- right: 0;
2851
+ inset-inline: 0;
2814
2852
  height: var(--touch-target);
2815
2853
  pointer-events: none;
2816
2854
  z-index: 1;
@@ -2840,13 +2878,13 @@ em {
2840
2878
  }
2841
2879
 
2842
2880
  .dndev-calendar-nav-previous {
2843
- left: 0;
2881
+ inset-inline-start: 0;
2844
2882
  border-start-start-radius: 0;
2845
2883
  border-end-start-radius: 0;
2846
2884
  }
2847
2885
 
2848
2886
  .dndev-calendar-nav-next {
2849
- right: 0;
2887
+ inset-inline-end: 0;
2850
2888
  border-start-end-radius: 0;
2851
2889
  border-end-end-radius: 0;
2852
2890
  }
@@ -3092,13 +3130,10 @@ em {
3092
3130
  background: var(--muted);
3093
3131
  }
3094
3132
 
3095
- .dndev-cta[data-tone='elevated'] {
3096
- background: var(--background);
3097
- }
3098
-
3099
3133
  .dndev-cta[data-tone='contrast'] {
3100
3134
  background: var(--foreground);
3101
- color: var(--background);
3135
+ /* --card not --background: inverted text must be opaque (--background can be transparent in some themes) */
3136
+ color: var(--card);
3102
3137
  }
3103
3138
 
3104
3139
  .dndev-cta[data-tone='accent'] {
@@ -3143,7 +3178,6 @@ em {
3143
3178
  flex-direction: row;
3144
3179
  gap: var(--gap-md);
3145
3180
  justify-content: center;
3146
-
3147
3181
  }
3148
3182
 
3149
3183
  .dndev-cta-actions .dndev-interactive {
@@ -3154,7 +3188,8 @@ em {
3154
3188
 
3155
3189
  .dndev-cta-actions .dndev-interactive[data-variant='primary'] {
3156
3190
  background: var(--foreground);
3157
- color: var(--background);
3191
+ /* --card not --background: inverted text must be opaque */
3192
+ color: var(--card);
3158
3193
  border-color: var(--foreground);
3159
3194
  }
3160
3195
 
@@ -3172,7 +3207,8 @@ em {
3172
3207
 
3173
3208
  :is(.dndev-cta-actions .dndev-interactive[data-variant='outline']):hover {
3174
3209
  background: var(--foreground);
3175
- color: var(--background);
3210
+ /* --card not --background: inverted text must be opaque */
3211
+ color: var(--card);
3176
3212
  border-color: var(--foreground);
3177
3213
  }
3178
3214
 
@@ -3387,7 +3423,7 @@ em {
3387
3423
  justify-content: space-between;
3388
3424
  align-items: center;
3389
3425
  width: 100%;
3390
- text-align: left;
3426
+ text-align: start;
3391
3427
  }
3392
3428
 
3393
3429
  .dndev-combobox-trigger button {
@@ -3729,8 +3765,9 @@ em {
3729
3765
  }
3730
3766
 
3731
3767
  .dndev-code-line-number {
3732
- line-height: inherit;
3733
- /* Inherit from parent */
3768
+ line-height: 1.5;
3769
+ min-height: 1.5em;
3770
+ font-size: inherit;
3734
3771
  }
3735
3772
 
3736
3773
  .dndev-code-code {
@@ -3750,7 +3787,21 @@ em {
3750
3787
  .dndev-code-code code {
3751
3788
  line-height: inherit;
3752
3789
  font-size: inherit;
3753
- /* Match parent font-size */
3790
+ }
3791
+
3792
+ /* Shiki wraps each line in <span class="line"> — force consistent sizing */
3793
+
3794
+ .dndev-code-code .line {
3795
+ display: block;
3796
+ line-height: 1.5;
3797
+ font-size: inherit;
3798
+ min-height: 1.5em;
3799
+ }
3800
+
3801
+ /* Empty Shiki lines still need height to stay in sync with line numbers */
3802
+
3803
+ .dndev-code-code .line:empty::after {
3804
+ content: '\00a0';
3754
3805
  }
3755
3806
 
3756
3807
  /* packages/components/src/atomic/Command/Command.css */
@@ -3914,7 +3965,7 @@ em {
3914
3965
  order: 3;
3915
3966
  font-size: var(--font-size-xs);
3916
3967
  color: var(--muted-foreground);
3917
- padding-left: calc(var(--icon-md) + var(--gap-sm));
3968
+ padding-inline-start: calc(var(--icon-md) + var(--gap-sm));
3918
3969
  }
3919
3970
 
3920
3971
  .dndev-command-favorite-button {
@@ -4200,6 +4251,54 @@ em {
4200
4251
  }
4201
4252
  }
4202
4253
 
4254
+ /* Responsive templateColumns via custom properties */
4255
+
4256
+ .dndev-grid-component[data-responsive-tpl='true'] {
4257
+ grid-template-columns: var(--grid-tpl-mobile);
4258
+ }
4259
+
4260
+ @media (min-width: 768px) {
4261
+ .dndev-grid-component[data-responsive-tpl='true'] {
4262
+ grid-template-columns: var(--grid-tpl-tablet);
4263
+ }
4264
+ }
4265
+
4266
+ @media (min-width: 1024px) {
4267
+ .dndev-grid-component[data-responsive-tpl='true'] {
4268
+ grid-template-columns: var(--grid-tpl-laptop);
4269
+ }
4270
+ }
4271
+
4272
+ @media (min-width: 1440px) {
4273
+ .dndev-grid-component[data-responsive-tpl='true'] {
4274
+ grid-template-columns: var(--grid-tpl-desktop);
4275
+ }
4276
+ }
4277
+
4278
+ /* Responsive grid areas via custom properties */
4279
+
4280
+ .dndev-grid-component[data-responsive-areas='true'] {
4281
+ grid-template-areas: var(--grid-areas-mobile);
4282
+ }
4283
+
4284
+ @media (min-width: 768px) {
4285
+ .dndev-grid-component[data-responsive-areas='true'] {
4286
+ grid-template-areas: var(--grid-areas-tablet);
4287
+ }
4288
+ }
4289
+
4290
+ @media (min-width: 1024px) {
4291
+ .dndev-grid-component[data-responsive-areas='true'] {
4292
+ grid-template-areas: var(--grid-areas-laptop);
4293
+ }
4294
+ }
4295
+
4296
+ @media (min-width: 1440px) {
4297
+ .dndev-grid-component[data-responsive-areas='true'] {
4298
+ grid-template-areas: var(--grid-areas-desktop);
4299
+ }
4300
+ }
4301
+
4203
4302
  /* Spacing from CSS variables */
4204
4303
 
4205
4304
  .dndev-grid-component[data-gap='none'] {
@@ -4513,7 +4612,8 @@ em {
4513
4612
  height: 44px;
4514
4613
  border: none;
4515
4614
  border-radius: var(--radius-full);
4516
- background-color: var(--background);
4615
+ /* --card not --background: surface must be opaque */
4616
+ background-color: var(--card);
4517
4617
  color: var(--foreground);
4518
4618
  cursor: pointer;
4519
4619
  opacity: 0;
@@ -5080,7 +5180,7 @@ input[type='number'] {
5080
5180
  }
5081
5181
 
5082
5182
  .dndev-nav-menu-content {
5083
- left: 0;
5183
+ inset-inline-start: 0;
5084
5184
  top: 0;
5085
5185
  width: 100%;
5086
5186
  }
@@ -5095,7 +5195,7 @@ input[type='number'] {
5095
5195
 
5096
5196
  .dndev-nav-menu-viewport-wrapper {
5097
5197
  position: absolute;
5098
- left: 0;
5198
+ inset-inline-start: 0;
5099
5199
  top: 100%;
5100
5200
  display: flex;
5101
5201
  justify-content: center;
@@ -5135,7 +5235,7 @@ input[type='number'] {
5135
5235
  height: var(--gap-sm);
5136
5236
  width: var(--gap-sm);
5137
5237
  transform: rotate(45deg);
5138
- border-top-left-radius: 2px;
5238
+ border-start-start-radius: 2px;
5139
5239
  background-color: var(--border);
5140
5240
  box-shadow: var(--shadow-md);
5141
5241
  }
@@ -5306,19 +5406,34 @@ input[type='number'] {
5306
5406
  }
5307
5407
 
5308
5408
  .dndev-pagination-size-label {
5309
- margin-right: var(--gap-sm);
5409
+ margin-inline-end: var(--gap-sm);
5310
5410
  }
5311
5411
 
5312
5412
  .dndev-pagination-nav {
5313
5413
  justify-content: flex-end;
5314
5414
  width: auto;
5315
- margin-left: auto;
5316
- /* Push to right */
5415
+ margin-inline-start: auto;
5416
+ /* Push to end */
5317
5417
  }
5318
5418
  }
5319
5419
 
5320
5420
  /* packages/components/src/atomic/Popover/Popover.css */
5321
5421
 
5422
+ /* Popover content width constraints and wrapping */
5423
+
5424
+ /* Targets Radix UI PopoverContent element */
5425
+
5426
+ [data-radix-popover-content],
5427
+ .dndev-floating[data-radix-popover-content] {
5428
+ max-width: min(90vw, 400px);
5429
+ width: -moz-max-content;
5430
+ width: max-content;
5431
+ min-width: 0;
5432
+ word-wrap: break-word;
5433
+ overflow-wrap: break-word;
5434
+ white-space: normal;
5435
+ }
5436
+
5322
5437
  /* packages/components/src/atomic/Progress/Progress.css */
5323
5438
 
5324
5439
  .dndev-progress {
@@ -5663,9 +5778,10 @@ input[type='number'] {
5663
5778
  /* Content wrapper: constrained + centered + padded */
5664
5779
 
5665
5780
  .dndev-section-content {
5666
- /* Respects PageContainer's --content-width */
5781
+ /* Respects PageContainer's --content-width (passed through breakthrough root) */
5667
5782
  max-width: var(--content-width);
5668
5783
  margin-inline: auto;
5784
+ min-width: 0; /* Allow shrinking so max-width wins when content would force wider */
5669
5785
  /* Padding with section background - responsive to match PageContainer */
5670
5786
  padding-inline: var(--gap-md);
5671
5787
  padding-top: var(--gap-lg);
@@ -5913,6 +6029,9 @@ input[type='number'] {
5913
6029
 
5914
6030
  /* Sheet positioning by side - SPATIAL METAPHOR */
5915
6031
 
6032
+ /* Physical properties intentional: Sheet anchors to viewport edges regardless of text direction.
6033
+ Logical inset-inline would incorrectly swap sides in RTL for left/right sheet variants. */
6034
+
5916
6035
  /* RIGHT / LEFT (Desktop Panels) */
5917
6036
 
5918
6037
  .dndev-sheet-content[data-side='right'],.dndev-sheet-content[data-side='left'] {
@@ -5953,8 +6072,7 @@ input[type='number'] {
5953
6072
  max-height: 92dvh;
5954
6073
  /* Never touch top edge */
5955
6074
  width: 100%;
5956
- margin-left: auto;
5957
- margin-right: auto;
6075
+ margin-inline: auto;
5958
6076
 
5959
6077
  /* On larger screens, constrain width */
5960
6078
  }
@@ -5973,16 +6091,16 @@ input[type='number'] {
5973
6091
  top: 0;
5974
6092
  border-bottom: var(--border-hairline) solid var(--line-1);
5975
6093
  /* Rounded bottom corners only */
5976
- border-bottom-left-radius: var(--radius-lg);
5977
- border-bottom-right-radius: var(--radius-lg);
6094
+ border-end-start-radius: var(--radius-lg);
6095
+ border-end-end-radius: var(--radius-lg);
5978
6096
  }
5979
6097
 
5980
6098
  .dndev-sheet-content[data-side='bottom'] {
5981
6099
  bottom: 0;
5982
6100
  border-top: var(--border-hairline) solid var(--line-1);
5983
6101
  /* Rounded top corners only */
5984
- border-top-left-radius: var(--radius-lg);
5985
- border-top-right-radius: var(--radius-lg);
6102
+ border-start-start-radius: var(--radius-lg);
6103
+ border-start-end-radius: var(--radius-lg);
5986
6104
  }
5987
6105
 
5988
6106
  /* DRAG HANDLE PILL - Visual affordance for draggable sheets */
@@ -6301,7 +6419,8 @@ input[type='number'] {
6301
6419
  min-width: 1.25rem;
6302
6420
  min-height: 1.25rem;
6303
6421
  border-radius: var(--radius-full);
6304
- background-color: var(--background);
6422
+ /* --card not --background: surface must be opaque (--background can be transparent in some themes) */
6423
+ background-color: var(--card);
6305
6424
  border: 2px solid var(--primary);
6306
6425
  box-shadow: var(--shadow-md);
6307
6426
  transition: all var(--dur-fast) var(--ease-in-out);
@@ -6372,7 +6491,8 @@ input[type='number'] {
6372
6491
  font-size: var(--font-size-xs);
6373
6492
  font-weight: var(--font-weight-medium);
6374
6493
  color: var(--foreground);
6375
- background-color: var(--background);
6494
+ /* --card not --background: surface must be opaque */
6495
+ background-color: var(--card);
6376
6496
  padding: 0.125rem 0.375rem;
6377
6497
  border-radius: var(--radius-interactive);
6378
6498
  box-shadow: var(--shadow-sm);
@@ -6396,7 +6516,7 @@ input[type='number'] {
6396
6516
  height: 1em;
6397
6517
  border: 2px solid transparent;
6398
6518
  border-top-color: var(--primary);
6399
- border-right-color: var(--primary);
6519
+ border-inline-end-color: var(--primary);
6400
6520
  border-radius: 50%;
6401
6521
  animation: spin 0.6s linear infinite;
6402
6522
  display: inline-block;
@@ -6406,42 +6526,42 @@ input[type='number'] {
6406
6526
 
6407
6527
  .dndev-spinner[data-variant='default'] {
6408
6528
  border-top-color: var(--foreground);
6409
- border-right-color: var(--foreground);
6529
+ border-inline-end-color: var(--foreground);
6410
6530
  }
6411
6531
 
6412
6532
  .dndev-spinner[data-variant='muted'] {
6413
6533
  border-top-color: var(--muted-foreground);
6414
- border-right-color: var(--muted-foreground);
6534
+ border-inline-end-color: var(--muted-foreground);
6415
6535
  }
6416
6536
 
6417
6537
  .dndev-spinner[data-variant='primary'] {
6418
6538
  border-top-color: var(--primary);
6419
- border-right-color: var(--primary);
6539
+ border-inline-end-color: var(--primary);
6420
6540
  }
6421
6541
 
6422
6542
  .dndev-spinner[data-variant='secondary'] {
6423
6543
  border-top-color: var(--secondary);
6424
- border-right-color: var(--secondary);
6544
+ border-inline-end-color: var(--secondary);
6425
6545
  }
6426
6546
 
6427
6547
  .dndev-spinner[data-variant='accent'] {
6428
6548
  border-top-color: var(--accent);
6429
- border-right-color: var(--accent);
6549
+ border-inline-end-color: var(--accent);
6430
6550
  }
6431
6551
 
6432
6552
  .dndev-spinner[data-variant='success'] {
6433
6553
  border-top-color: var(--success);
6434
- border-right-color: var(--success);
6554
+ border-inline-end-color: var(--success);
6435
6555
  }
6436
6556
 
6437
6557
  .dndev-spinner[data-variant='warning'] {
6438
6558
  border-top-color: var(--warning);
6439
- border-right-color: var(--warning);
6559
+ border-inline-end-color: var(--warning);
6440
6560
  }
6441
6561
 
6442
6562
  .dndev-spinner[data-variant='destructive'] {
6443
6563
  border-top-color: var(--destructive);
6444
- border-right-color: var(--destructive);
6564
+ border-inline-end-color: var(--destructive);
6445
6565
  }
6446
6566
 
6447
6567
  /* Overlay variant - full-page loading */
@@ -6725,6 +6845,8 @@ input[type='number'] {
6725
6845
  display: flex;
6726
6846
  align-items: center;
6727
6847
  justify-content: space-between;
6848
+ gap: var(--gap-md);
6849
+ margin-top: var(--gap-md);
6728
6850
  }
6729
6851
 
6730
6852
  .dndev-stepper-info {
@@ -7164,19 +7286,20 @@ input[type='number'] {
7164
7286
  word-break: break-word;
7165
7287
  border: var(--border-hairline) solid var(--line-2); /* Show clickable area */
7166
7288
 
7167
- /* Fallback (no variant): inactive = primary, active = foreground/background */
7289
+ /* Fallback (no variant): inactive = primary, active = foreground/card */
7168
7290
  background-color: var(--primary);
7169
7291
  color: var(--primary-foreground);
7170
7292
  }
7171
7293
 
7172
7294
  .dndev-interactive[data-role='tab-trigger'][data-state='active'] {
7173
- background-color: var(--background);
7295
+ /* --card not --background: active tab surface must be opaque (--background can be transparent in some themes) */
7296
+ background-color: var(--card);
7174
7297
  color: var(--foreground);
7175
7298
  box-shadow: var(--shadow-sm);
7176
7299
  border-color: var(--primary);
7177
7300
  }
7178
7301
 
7179
- /* Default/Primary variant: inactive = primary, active = foreground/background */
7302
+ /* Default/Primary variant: inactive = primary, active = foreground/card */
7180
7303
 
7181
7304
  .dndev-interactive[data-role='tab-trigger'][data-variant='default'],.dndev-interactive[data-role='tab-trigger'][data-variant='primary'] {
7182
7305
  background-color: var(--primary);
@@ -7184,13 +7307,14 @@ input[type='number'] {
7184
7307
  }
7185
7308
 
7186
7309
  [data-state='active']:is(.dndev-interactive[data-role='tab-trigger'][data-variant='default'],.dndev-interactive[data-role='tab-trigger'][data-variant='primary']) {
7187
- background-color: var(--background);
7310
+ /* --card not --background: active tab surface must be opaque */
7311
+ background-color: var(--card);
7188
7312
  color: var(--foreground);
7189
7313
  box-shadow: var(--shadow-sm);
7190
7314
  border-color: var(--primary);
7191
7315
  }
7192
7316
 
7193
- /* Secondary variant: inactive = secondary, active = foreground/background */
7317
+ /* Secondary variant: inactive = secondary, active = foreground/card */
7194
7318
 
7195
7319
  .dndev-interactive[data-role='tab-trigger'][data-variant='secondary'] {
7196
7320
  background-color: var(--secondary);
@@ -7198,13 +7322,14 @@ input[type='number'] {
7198
7322
  }
7199
7323
 
7200
7324
  .dndev-interactive[data-role='tab-trigger'][data-variant='secondary'][data-state='active'] {
7201
- background-color: var(--background);
7325
+ /* --card not --background: active tab surface must be opaque */
7326
+ background-color: var(--card);
7202
7327
  color: var(--foreground);
7203
7328
  box-shadow: var(--shadow-sm);
7204
7329
  border-color: var(--secondary);
7205
7330
  }
7206
7331
 
7207
- /* Accent variant: inactive = accent, active = foreground/background */
7332
+ /* Accent variant: inactive = accent, active = foreground/card */
7208
7333
 
7209
7334
  .dndev-interactive[data-role='tab-trigger'][data-variant='accent'] {
7210
7335
  background-color: var(--accent);
@@ -7212,7 +7337,8 @@ input[type='number'] {
7212
7337
  }
7213
7338
 
7214
7339
  .dndev-interactive[data-role='tab-trigger'][data-variant='accent'][data-state='active'] {
7215
- background-color: var(--background);
7340
+ /* --card not --background: active tab surface must be opaque */
7341
+ background-color: var(--card);
7216
7342
  color: var(--foreground);
7217
7343
  box-shadow: var(--shadow-sm);
7218
7344
  border-color: var(--accent);
@@ -7232,7 +7358,7 @@ input[type='number'] {
7232
7358
  border-color: var(--primary);
7233
7359
  }
7234
7360
 
7235
- /* Warning variant: inactive = warning, active = foreground/background */
7361
+ /* Warning variant: inactive = warning, active = foreground/card */
7236
7362
 
7237
7363
  .dndev-interactive[data-role='tab-trigger'][data-variant='warning'] {
7238
7364
  background-color: var(--warning);
@@ -7240,13 +7366,14 @@ input[type='number'] {
7240
7366
  }
7241
7367
 
7242
7368
  .dndev-interactive[data-role='tab-trigger'][data-variant='warning'][data-state='active'] {
7243
- background-color: var(--background);
7369
+ /* --card not --background: active tab surface must be opaque */
7370
+ background-color: var(--card);
7244
7371
  color: var(--foreground);
7245
7372
  box-shadow: var(--shadow-sm);
7246
7373
  border-color: var(--warning);
7247
7374
  }
7248
7375
 
7249
- /* Success variant: inactive = success, active = foreground/background */
7376
+ /* Success variant: inactive = success, active = foreground/card */
7250
7377
 
7251
7378
  .dndev-interactive[data-role='tab-trigger'][data-variant='success'] {
7252
7379
  background-color: var(--success);
@@ -7254,13 +7381,14 @@ input[type='number'] {
7254
7381
  }
7255
7382
 
7256
7383
  .dndev-interactive[data-role='tab-trigger'][data-variant='success'][data-state='active'] {
7257
- background-color: var(--background);
7384
+ /* --card not --background: active tab surface must be opaque */
7385
+ background-color: var(--card);
7258
7386
  color: var(--foreground);
7259
7387
  box-shadow: var(--shadow-sm);
7260
7388
  border-color: var(--success);
7261
7389
  }
7262
7390
 
7263
- /* Destructive variant: inactive = destructive, active = foreground/background */
7391
+ /* Destructive variant: inactive = destructive, active = foreground/card */
7264
7392
 
7265
7393
  .dndev-interactive[data-role='tab-trigger'][data-variant='destructive'] {
7266
7394
  background-color: var(--destructive);
@@ -7268,7 +7396,8 @@ input[type='number'] {
7268
7396
  }
7269
7397
 
7270
7398
  .dndev-interactive[data-role='tab-trigger'][data-variant='destructive'][data-state='active'] {
7271
- background-color: var(--background);
7399
+ /* --card not --background: active tab surface must be opaque */
7400
+ background-color: var(--card);
7272
7401
  color: var(--foreground);
7273
7402
  box-shadow: var(--shadow-sm);
7274
7403
  border-color: var(--destructive);
@@ -7315,7 +7444,7 @@ input[type='number'] {
7315
7444
  align-items: center;
7316
7445
  justify-content: center;
7317
7446
  padding: 0;
7318
- margin-left: 2px;
7447
+ margin-inline-start: 2px;
7319
7448
  background: transparent;
7320
7449
  border: none;
7321
7450
  cursor: pointer;
@@ -7478,7 +7607,11 @@ input[type='number'] {
7478
7607
  border-radius: var(--radius-interactive);
7479
7608
  }
7480
7609
 
7481
- /* Level overrides */
7610
+ /* Level overrides — headline font for all heading levels */
7611
+
7612
+ .dndev-text-base[data-level^='h'] {
7613
+ font-family: var(--font-headline);
7614
+ }
7482
7615
 
7483
7616
  .dndev-text-base[data-level='h1'] {
7484
7617
  font-size: var(--font-size-3xl);
@@ -7531,6 +7664,10 @@ input[type='number'] {
7531
7664
  font-weight: var(--font-weight-bold);
7532
7665
  }
7533
7666
 
7667
+ .dndev-text-base[data-italic] {
7668
+ font-style: italic;
7669
+ }
7670
+
7534
7671
  /* packages/components/src/atomic/Toaster/Toaster.css */
7535
7672
 
7536
7673
  .dndev-toast-viewport {
@@ -7730,8 +7867,9 @@ input[type='number'] {
7730
7867
 
7731
7868
  .dndev-toggle-group {
7732
7869
  display: inline-flex;
7870
+ flex-wrap: wrap;
7733
7871
  align-items: center;
7734
- gap: 0;
7872
+ gap: var(--gap-sm);
7735
7873
  padding: 0.125rem;
7736
7874
  border-radius: var(--radius-interactive);
7737
7875
  background-color: var(--muted);
@@ -7823,7 +7961,8 @@ input[type='number'] {
7823
7961
  z-index: var(--z-tooltip);
7824
7962
  /* Inverted colors for high contrast - industry standard (Vercel, GitHub, Stripe) */
7825
7963
  background: var(--foreground);
7826
- color: var(--background);
7964
+ /* --card not --background: inverted text must be opaque (--background can be transparent in some themes) */
7965
+ color: var(--card);
7827
7966
  box-shadow: var(--shadow-lg); /* Stronger shadow for visibility */
7828
7967
  padding: 0.375rem 0.5rem; /* 6px 8px - industry standard */
7829
7968
  font-size: var(--font-size-xs); /* 12px */
@@ -7927,12 +8066,16 @@ input[type='number'] {
7927
8066
 
7928
8067
  .dndev-video-dialog {
7929
8068
  max-width: 90vw;
7930
- max-height: 90vh;
7931
8069
  }
7932
8070
 
7933
8071
  .dndev-video-dialog .dndev-modal-body {
7934
8072
  padding: 0;
8073
+ overflow: hidden;
8074
+ }
8075
+
8076
+ .dndev-video-dialog .dndev-video-frame {
7935
8077
  aspect-ratio: 16/9;
8078
+ max-height: calc(90vh - 5rem);
7936
8079
  }
7937
8080
 
7938
8081
  /* 6. Animation keyframes */
@@ -8459,6 +8602,12 @@ input[type='number'] {
8459
8602
 
8460
8603
  /* Tone backgrounds - apply directly to section element (like CallToAction) */
8461
8604
 
8605
+ /* Ghost (default) - transparent, allows background images to show through */
8606
+
8607
+ .dndev-section-full-width[data-tone='ghost'],.dndev-section-full-width:not([data-tone]) {
8608
+ background: transparent;
8609
+ }
8610
+
8462
8611
  .dndev-section-full-width[data-tone='base'] {
8463
8612
  background: var(--background);
8464
8613
  }
@@ -8467,16 +8616,37 @@ input[type='number'] {
8467
8616
  background: var(--muted);
8468
8617
  }
8469
8618
 
8470
- .dndev-section-full-width[data-tone='elevated'] {
8619
+ .dndev-section-full-width[data-tone='contrast'] {
8471
8620
  background: var(--background);
8621
+ color: var(--foreground);
8472
8622
  }
8473
8623
 
8474
- .dndev-section-full-width[data-tone='contrast'] {
8624
+ .dndev-section-full-width[data-tone='accent'] {
8625
+ background: color-mix(in oklab, var(--accent) 5%, transparent);
8626
+ }
8627
+
8628
+ /* HeroSection tone backgrounds - same system as Section/CallToAction */
8629
+
8630
+ /* Ghost (default) - transparent, allows background images to show through */
8631
+
8632
+ .dndev-hero-section[data-tone='ghost'],.dndev-hero-section:not([data-tone]) {
8633
+ background: transparent;
8634
+ }
8635
+
8636
+ .dndev-hero-section[data-tone='base'] {
8637
+ background: var(--background);
8638
+ }
8639
+
8640
+ .dndev-hero-section[data-tone='muted'] {
8641
+ background: var(--muted);
8642
+ }
8643
+
8644
+ .dndev-hero-section[data-tone='contrast'] {
8475
8645
  background: var(--background);
8476
8646
  color: var(--foreground);
8477
8647
  }
8478
8648
 
8479
- .dndev-section-full-width[data-tone='accent'] {
8649
+ .dndev-hero-section[data-tone='accent'] {
8480
8650
  background: color-mix(in oklab, var(--accent) 5%, transparent);
8481
8651
  }
8482
8652
 
@@ -8689,10 +8859,7 @@ h4[data-variant='code'] {
8689
8859
  }
8690
8860
 
8691
8861
  .dndev-inset-0 {
8692
- top: 0;
8693
- right: 0;
8694
- bottom: 0;
8695
- left: 0;
8862
+ inset: 0;
8696
8863
  }
8697
8864
 
8698
8865
  .dndev-inset-y-0 {
@@ -8700,8 +8867,8 @@ h4[data-variant='code'] {
8700
8867
  bottom: 0;
8701
8868
  }
8702
8869
 
8703
- .dndev-left-0 {
8704
- left: 0;
8870
+ .dndev-inset-inline-start-0 {
8871
+ inset-inline-start: 0;
8705
8872
  }
8706
8873
 
8707
8874
  .dndev-min-h-0 {
@@ -9076,6 +9243,8 @@ h4[data-variant='code'] {
9076
9243
  /* Narrow content (mobile-first PWA, app-like single column) - single source of truth */
9077
9244
  --narrow-content-max: 37.5rem;
9078
9245
  /* 600px */
9246
+ --narrow-form-max: 30rem;
9247
+ /* 480px - inner form/input width within narrow layout */
9079
9248
 
9080
9249
  /* Content Area Calculations */
9081
9250
  /* Header content area (excludes sidebar on some presets) */
@@ -9186,7 +9355,8 @@ main[role='main'][data-routing-animation='fade'] {
9186
9355
  /* Slide animation - keyframes handle opacity 0→1 */
9187
9356
 
9188
9357
  main[role='main'][data-routing-animation='slide'] {
9189
- animation: routeSlideIn var(--routing-default-duration, 300ms) ease-in forwards;
9358
+ animation: routeSlideIn var(--routing-default-duration, 300ms) ease-in
9359
+ forwards;
9190
9360
  }
9191
9361
 
9192
9362
  /* No animation - already visible by default, explicit for clarity */
@@ -9200,11 +9370,15 @@ main[role='main'][data-routing-animation='none'] {
9200
9370
 
9201
9371
  @media (width < 768px) {
9202
9372
  main[role='main'][data-routing-animation='fade'] {
9203
- animation: routeFadeIn var(--routing-mobile-duration, var(--routing-default-duration, 300ms)) ease-in forwards;
9373
+ animation: routeFadeIn
9374
+ var(--routing-mobile-duration, var(--routing-default-duration, 300ms))
9375
+ ease-in forwards;
9204
9376
  }
9205
9377
 
9206
9378
  main[role='main'][data-routing-animation='slide'] {
9207
- animation: routeSlideIn var(--routing-mobile-duration, var(--routing-default-duration, 300ms)) ease-in forwards;
9379
+ animation: routeSlideIn
9380
+ var(--routing-mobile-duration, var(--routing-default-duration, 300ms))
9381
+ ease-in forwards;
9208
9382
  }
9209
9383
  }
9210
9384
 
@@ -9212,11 +9386,15 @@ main[role='main'][data-routing-animation='none'] {
9212
9386
 
9213
9387
  @media (width >=768px) and (width <=1023px) {
9214
9388
  main[role='main'][data-routing-animation='fade'] {
9215
- animation: routeFadeIn var(--routing-tablet-duration, var(--routing-default-duration, 300ms)) ease-in forwards;
9389
+ animation: routeFadeIn
9390
+ var(--routing-tablet-duration, var(--routing-default-duration, 300ms))
9391
+ ease-in forwards;
9216
9392
  }
9217
9393
 
9218
9394
  main[role='main'][data-routing-animation='slide'] {
9219
- animation: routeSlideIn var(--routing-tablet-duration, var(--routing-default-duration, 300ms)) ease-in forwards;
9395
+ animation: routeSlideIn
9396
+ var(--routing-tablet-duration, var(--routing-default-duration, 300ms))
9397
+ ease-in forwards;
9220
9398
  }
9221
9399
  }
9222
9400
 
@@ -9224,11 +9402,15 @@ main[role='main'][data-routing-animation='none'] {
9224
9402
 
9225
9403
  @media (width >=1024px) and (width <=1439px) {
9226
9404
  main[role='main'][data-routing-animation='fade'] {
9227
- animation: routeFadeIn var(--routing-desktop-duration, var(--routing-default-duration, 300ms)) ease-in forwards;
9405
+ animation: routeFadeIn
9406
+ var(--routing-desktop-duration, var(--routing-default-duration, 300ms))
9407
+ ease-in forwards;
9228
9408
  }
9229
9409
 
9230
9410
  main[role='main'][data-routing-animation='slide'] {
9231
- animation: routeSlideIn var(--routing-desktop-duration, var(--routing-default-duration, 300ms)) ease-in forwards;
9411
+ animation: routeSlideIn
9412
+ var(--routing-desktop-duration, var(--routing-default-duration, 300ms))
9413
+ ease-in forwards;
9232
9414
  }
9233
9415
  }
9234
9416
 
@@ -9236,11 +9418,15 @@ main[role='main'][data-routing-animation='none'] {
9236
9418
 
9237
9419
  @media (width >=1440px) {
9238
9420
  main[role='main'][data-routing-animation='fade'] {
9239
- animation: routeFadeIn var(--routing-wide-duration, var(--routing-default-duration, 300ms)) ease-in forwards;
9421
+ animation: routeFadeIn
9422
+ var(--routing-wide-duration, var(--routing-default-duration, 300ms))
9423
+ ease-in forwards;
9240
9424
  }
9241
9425
 
9242
9426
  main[role='main'][data-routing-animation='slide'] {
9243
- animation: routeSlideIn var(--routing-wide-duration, var(--routing-default-duration, 300ms)) ease-in forwards;
9427
+ animation: routeSlideIn
9428
+ var(--routing-wide-duration, var(--routing-default-duration, 300ms))
9429
+ ease-in forwards;
9244
9430
  }
9245
9431
  }
9246
9432
 
@@ -9264,7 +9450,6 @@ main[role='main'][data-routing-animation='none'] {
9264
9450
  /* Mobile/Tablet: Hide sidebars - WCAG & Lighthouse best practices */
9265
9451
 
9266
9452
  @media (width <=1023px) {
9267
-
9268
9453
  .dndev-layout aside[role='navigation'].sidebar,
9269
9454
  aside[role='navigation'].sidebar {
9270
9455
  display: none !important;
@@ -9288,8 +9473,10 @@ main[role='main'][data-routing-animation='none'] {
9288
9473
  'header header'
9289
9474
  'sidebar main'
9290
9475
  'footer footer';
9291
- grid-template-rows: var(--header-height) 1fr minmax(var(--footer-height),
9292
- auto);
9476
+ grid-template-rows: var(--header-height) 1fr minmax(
9477
+ var(--footer-height),
9478
+ auto
9479
+ );
9293
9480
  grid-template-columns: var(--sidebar-width) 1fr;
9294
9481
  }
9295
9482
 
@@ -9303,7 +9490,10 @@ main[role='main'][data-routing-animation='none'] {
9303
9490
  grid-template-rows: var(--header-height) 1fr auto;
9304
9491
  }
9305
9492
 
9306
- .dndev-layout[data-footer-mode='scroll'] header[role='banner'] { position: sticky; top: 0; }
9493
+ .dndev-layout[data-footer-mode='scroll'] header[role='banner'] {
9494
+ position: sticky;
9495
+ top: 0;
9496
+ }
9307
9497
 
9308
9498
  .dndev-layout[data-footer-mode='scroll'] aside.sidebar[role='navigation'] {
9309
9499
  position: sticky;
@@ -9312,14 +9502,21 @@ main[role='main'][data-routing-animation='none'] {
9312
9502
  align-self: start;
9313
9503
  }
9314
9504
 
9315
- .dndev-layout[data-footer-mode='scroll'] main[role='main'] { overflow-y: visible; overflow-x: hidden; }
9505
+ .dndev-layout[data-footer-mode='scroll'] main[role='main'] {
9506
+ overflow-y: visible;
9507
+ overflow-x: hidden;
9508
+ contain: style;
9509
+ }
9316
9510
 
9317
9511
  .dndev-layout[data-footer-mode='scroll'] footer[role='contentinfo'] {
9318
9512
  grid-column: 2 / -1;
9319
9513
  height: auto;
9320
9514
  }
9321
9515
 
9322
- :is(.dndev-layout[data-footer-mode='scroll'] footer[role='contentinfo']) > * { height: auto; min-height: var(--footer-height); }
9516
+ :is(.dndev-layout[data-footer-mode='scroll'] footer[role='contentinfo']) > * {
9517
+ height: auto;
9518
+ min-height: var(--footer-height);
9519
+ }
9323
9520
 
9324
9521
  /* Mobile: footer scroll mode ON by default (same rules) */
9325
9522
 
@@ -9330,15 +9527,25 @@ main[role='main'][data-routing-animation='none'] {
9330
9527
  grid-template-rows: var(--header-height) 1fr auto;
9331
9528
  }
9332
9529
 
9333
- .dndev-layout header[role='banner'] { position: sticky; top: 0; }
9530
+ .dndev-layout header[role='banner'] {
9531
+ position: sticky;
9532
+ top: 0;
9533
+ }
9334
9534
 
9335
- .dndev-layout main[role='main'] { overflow-y: visible; overflow-x: hidden; }
9535
+ .dndev-layout main[role='main'] {
9536
+ overflow-y: visible;
9537
+ overflow-x: hidden;
9538
+ contain: style;
9539
+ }
9336
9540
 
9337
9541
  .dndev-layout footer[role='contentinfo'] {
9338
9542
  height: auto;
9339
9543
  }
9340
9544
 
9341
- :is(.dndev-layout footer[role='contentinfo']) > * { height: auto; min-height: var(--footer-height); }
9545
+ :is(.dndev-layout footer[role='contentinfo']) > * {
9546
+ height: auto;
9547
+ min-height: var(--footer-height);
9548
+ }
9342
9549
  }
9343
9550
 
9344
9551
  /* Presets with no footer at all */
@@ -9366,6 +9573,7 @@ header[role='banner'] {
9366
9573
  position: relative;
9367
9574
  z-index: var(--z-header);
9368
9575
  contain: layout style;
9576
+ overflow: visible; /* Allow absolutely positioned children's shadows to extend beyond bounds */
9369
9577
 
9370
9578
  /* Container queries support for responsive components */
9371
9579
  container-type: inline-size;
@@ -9401,7 +9609,11 @@ header[role='banner'] {
9401
9609
  height: 100%;
9402
9610
  max-height: 100%;
9403
9611
  gap: var(--gap-sm);
9404
- overflow: hidden;
9612
+ overflow: visible; /* Allow shadows to show */
9613
+ /* Theme-controlled padding for shadows that extend beyond bounds (e.g., brutalist hard-offset shadows) */
9614
+ /* Shadows extend rightward, so only end padding needed */
9615
+ /* Defaults to 0 for themes with diffused shadows that don't extend beyond bounds */
9616
+ padding-inline-end: var(--header-shadow-padding, 0);
9405
9617
  }
9406
9618
 
9407
9619
  .header-end {
@@ -9413,7 +9625,11 @@ header[role='banner'] {
9413
9625
  max-height: 100%;
9414
9626
  margin-inline-start: auto;
9415
9627
  gap: var(--gap-sm);
9416
- overflow: hidden;
9628
+ overflow: visible; /* Allow shadows to show */
9629
+ /* Theme-controlled padding for shadows that extend beyond bounds (e.g., brutalist hard-offset shadows) */
9630
+ /* Shadows extend rightward, so only end padding needed */
9631
+ /* Defaults to 0 for themes with diffused shadows that don't extend beyond bounds */
9632
+ padding-inline-end: var(--header-shadow-padding, 0);
9417
9633
  }
9418
9634
 
9419
9635
  /* Viewport-centered center content - absolutely positioned overlay */
@@ -9426,6 +9642,10 @@ header[role='banner'] .header-center {
9426
9642
  width: -moz-fit-content;
9427
9643
  width: fit-content;
9428
9644
  z-index: 1;
9645
+ /* Theme-controlled padding for shadows that extend beyond bounds (e.g., brutalist hard-offset shadows) */
9646
+ /* Shadows extend rightward, so only end padding needed */
9647
+ /* Defaults to 0 for themes with diffused shadows that don't extend beyond bounds */
9648
+ padding-inline-end: var(--header-shadow-padding, 0);
9429
9649
  }
9430
9650
 
9431
9651
  /* ===========================
@@ -9506,7 +9726,8 @@ aside[role='navigation'].sidebar .dndev-sidebar-resize-handle:focus-visible {
9506
9726
 
9507
9727
  /* Active drag state */
9508
9728
 
9509
- aside[role='navigation'].sidebar[data-dragging='true'] .dndev-sidebar-resize-handle {
9729
+ aside[role='navigation'].sidebar[data-dragging='true']
9730
+ .dndev-sidebar-resize-handle {
9510
9731
  background: var(--primary);
9511
9732
  }
9512
9733
 
@@ -9522,7 +9743,10 @@ aside[role='navigation'].sidebar[data-dragging='true'] .dndev-sidebar-resize-han
9522
9743
  /* Landing: AUTO display mode - compact below wide breakpoint (< 1440px) */
9523
9744
 
9524
9745
  @media (width < 1440px) {
9525
- [data-layout='landing'] header[role='banner'] [data-display='auto'] .dndev-interactive-label {
9746
+ [data-layout='landing']
9747
+ header[role='banner']
9748
+ [data-display='auto']
9749
+ .dndev-interactive-label {
9526
9750
  display: none;
9527
9751
  }
9528
9752
  }
@@ -9695,7 +9919,6 @@ main[role='main'] {
9695
9919
  contain: layout style;
9696
9920
 
9697
9921
  /* First child after breadcrumbs grows to fill space */
9698
-
9699
9922
  }
9700
9923
 
9701
9924
  main[role='main'] > *:not(.breadcrumbs-container):first-of-type,main[role='main'] > .breadcrumbs-container + * {
@@ -9776,8 +9999,7 @@ footer[role='contentinfo'] a:not(.dndev-interactive):hover {
9776
9999
 
9777
10000
  .merged-bar {
9778
10001
  position: fixed;
9779
- left: 0;
9780
- right: 0;
10002
+ inset-inline: 0;
9781
10003
  display: none;
9782
10004
  /* Hidden by default - CSS shows on mobile */
9783
10005
  align-items: center;
@@ -9786,8 +10008,8 @@ footer[role='contentinfo'] a:not(.dndev-interactive):hover {
9786
10008
  contain: layout style;
9787
10009
 
9788
10010
  /* Safe area padding for notched devices */
9789
- padding-left: max(var(--content-padding), env(safe-area-inset-left));
9790
- padding-right: max(var(--content-padding), env(safe-area-inset-right));
10011
+ padding-inline-start: max(var(--content-padding), env(safe-area-inset-left));
10012
+ padding-inline-end: max(var(--content-padding), env(safe-area-inset-right));
9791
10013
  }
9792
10014
 
9793
10015
  .merged-bar[data-position='top'] {
@@ -9823,7 +10045,6 @@ footer[role='contentinfo'] a:not(.dndev-interactive):hover {
9823
10045
  /* Mobile (<1024px): Show merged-bar, hide zones */
9824
10046
 
9825
10047
  @media (width <=1023px) {
9826
-
9827
10048
  /* Presets with mergedBar: top (admin, moolti, game, docs) */
9828
10049
  [data-layout='admin'] .merged-bar[data-position='top'],
9829
10050
  [data-layout='moolti'] .merged-bar[data-position='top'],
@@ -10133,6 +10354,7 @@ footer[role='contentinfo'] a:not(.dndev-interactive):hover {
10133
10354
  .dndev-container {
10134
10355
  width: 100%;
10135
10356
  max-width: var(--content-width);
10357
+ min-width: 0; /* Allow shrinking in flex so max-width wins */
10136
10358
  flex: 1 1 auto;
10137
10359
 
10138
10360
  /* First child spacing when enabled */
@@ -10246,10 +10468,9 @@ footer[role='contentinfo'] a:not(.dndev-interactive):hover {
10246
10468
 
10247
10469
  /* Breakthrough pattern: only applies inside PageContainer */
10248
10470
 
10249
- .dndev-container>.dndev-section-full-width,
10250
- .dndev-container>.dndev-cta,
10251
- .dndev-container>.dndev-hero-section,
10252
- .dndev-container>.dndev-tech-bento {
10471
+ .dndev-container > .dndev-section-full-width,
10472
+ .dndev-container > .dndev-cta,
10473
+ .dndev-container > .dndev-tech-bento {
10253
10474
  /* Break out of PageContainer padding and max-width constraint */
10254
10475
  /* Account for sidebar: --sidebar-width is 0px for presets without sidebar */
10255
10476
  width: calc(100dvw - var(--sidebar-width));
@@ -10258,6 +10479,19 @@ footer[role='contentinfo'] a:not(.dndev-interactive):hover {
10258
10479
  /* Eat gap BEFORE section only */
10259
10480
  margin-top: calc(-1 * var(--gap-lg));
10260
10481
  margin-bottom: 0;
10482
+ /* Pass through so inner content (e.g. .dndev-section-content) can use it */
10483
+ --content-width: var(--max-content-width, 100%);
10484
+ }
10485
+
10486
+ /* HeroSection: only breakthrough when it has fullHeight (needs full viewport background) */
10487
+
10488
+ .dndev-container > .dndev-hero-section[style*='height'] {
10489
+ width: calc(100dvw - var(--sidebar-width));
10490
+ max-width: calc(100dvw - var(--sidebar-width));
10491
+ margin-inline: calc((-50dvw + var(--sidebar-width) / 2) + 50%);
10492
+ margin-top: calc(-1 * var(--gap-lg));
10493
+ margin-bottom: 0;
10494
+ --content-width: var(--max-content-width, 100%);
10261
10495
  }
10262
10496
 
10263
10497
  .footer-mobile-button:hover {
@@ -10290,7 +10524,16 @@ footer[role='contentinfo'] a:not(.dndev-interactive):hover {
10290
10524
  width: 100%;
10291
10525
  }
10292
10526
 
10293
- /* ScrollArea wrapper */
10527
+ /* Scroll wrapper - stretches to full width so scrollbar is at viewport edge */
10528
+
10529
+ .dndev-game-container__scroll-wrapper {
10530
+ flex: 1 1 0;
10531
+ min-height: 0;
10532
+ width: 100%;
10533
+ align-self: stretch;
10534
+ }
10535
+
10536
+ /* ScrollArea - fills wrapper */
10294
10537
 
10295
10538
  .dndev-game-container__scroll {
10296
10539
  width: 100%;
@@ -10329,20 +10572,16 @@ footer[role='contentinfo'] a:not(.dndev-interactive):hover {
10329
10572
  justify-content: space-between;
10330
10573
  }
10331
10574
 
10332
- /* Narrow content wrapper - constrained by --narrow-content-max (mobile-first PWA) */
10575
+ /* Narrow content wrapper - constrained by --narrow-content-max, centered inside scroll */
10576
+
10577
+ /* height: 100% fills the scroll viewport so children can use percentage heights.
10578
+ Content taller than viewport still scrolls — overflow propagates to the scroll container. */
10333
10579
 
10334
10580
  .dndev-game-container__content-narrow {
10335
10581
  width: 100%;
10336
10582
  max-width: var(--narrow-content-max);
10337
10583
  margin-inline: auto;
10338
- min-height: 0;
10339
- flex: 1 1 auto;
10340
- display: flex;
10341
- flex-direction: column;
10342
- }
10343
-
10344
- .dndev-game-container__content-narrow .dndev-game-container__scroll {
10345
- width: 100%;
10584
+ height: 100%;
10346
10585
  }
10347
10586
 
10348
10587
  /* CTA Zone - Fixed at bottom; safe area for notched devices */
@@ -10357,6 +10596,13 @@ footer[role='contentinfo'] a:not(.dndev-interactive):hover {
10357
10596
 
10358
10597
  /* CTA Button */
10359
10598
 
10599
+ .dndev-game-container__cta-buttons {
10600
+ display: grid;
10601
+ grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
10602
+ gap: var(--gap-sm);
10603
+ width: 100%;
10604
+ }
10605
+
10360
10606
  .dndev-game-container__cta-button {
10361
10607
  height: var(--touch-target);
10362
10608
  width: 100%;