@rimelight/ui 0.0.33 → 0.0.35

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 (389) hide show
  1. package/README.md +158 -157
  2. package/package.json +100 -105
  3. package/src/components/astro/RLAAccordion.astro +94 -18
  4. package/src/components/astro/RLAAspectRatio.astro +2 -2
  5. package/src/components/astro/RLAAvatar.astro +135 -68
  6. package/src/components/astro/RLABadge.astro +4 -2
  7. package/src/components/astro/RLABanner.astro +138 -23
  8. package/src/components/astro/RLABreadcrumb.astro +13 -0
  9. package/src/components/astro/RLAButton.astro +145 -139
  10. package/src/components/astro/RLACallout.astro +112 -0
  11. package/src/components/astro/RLACard.astro +6 -5
  12. package/src/components/astro/RLACarousel.astro +104 -75
  13. package/src/components/astro/RLAChart.astro +23 -35
  14. package/src/components/astro/RLAChip.astro +11 -5
  15. package/src/components/astro/RLACollapsible.astro +4 -1
  16. package/src/components/astro/RLAColorArea.astro +432 -0
  17. package/src/components/astro/RLAColorField.astro +300 -0
  18. package/src/components/astro/RLAColorSlider.astro +413 -0
  19. package/src/components/astro/RLAConfirm.astro +13 -11
  20. package/src/components/astro/RLACopyMarkdown.astro +78 -0
  21. package/src/components/astro/RLADate.astro +30 -0
  22. package/src/components/astro/RLADrawer.astro +50 -3
  23. package/src/components/astro/RLADropdownMenu.astro +78 -51
  24. package/src/components/astro/RLAFieldGroup.astro +4 -1
  25. package/src/components/astro/RLAFileUpload.astro +114 -100
  26. package/src/components/astro/RLAFooter.astro +2 -1
  27. package/src/components/astro/RLAFormField.astro +10 -6
  28. package/src/components/astro/RLAGrid.astro +31 -39
  29. package/src/components/astro/RLAHead.astro +528 -197
  30. package/src/components/astro/RLAHeader.astro +67 -59
  31. package/src/components/astro/RLAImage.astro +274 -209
  32. package/src/components/astro/RLAInput.astro +14 -9
  33. package/src/components/astro/RLAInputMenu.astro +119 -83
  34. package/src/components/astro/RLAKbd.astro +5 -5
  35. package/src/components/astro/RLALayoutGrid.astro +395 -0
  36. package/src/components/astro/RLALink.astro +44 -23
  37. package/src/components/astro/RLALinkGroup.astro +99 -37
  38. package/src/components/astro/RLALocaleSelector.astro +130 -113
  39. package/src/components/astro/RLALogo.astro +117 -90
  40. package/src/components/astro/RLAMain.astro +8 -3
  41. package/src/components/astro/RLAMarquee.astro +9 -2
  42. package/src/components/astro/RLAModal.astro +48 -18
  43. package/src/components/astro/RLANavigationMenu.astro +381 -137
  44. package/src/components/astro/{RLADocsPackageManagers.astro → RLAPackageManagers.astro} +81 -87
  45. package/src/components/astro/RLAPageSection.astro +4 -2
  46. package/src/components/astro/RLAPagination.astro +2 -4
  47. package/src/components/astro/RLAPopover.astro +4 -3
  48. package/src/components/astro/RLAPost.astro +11 -2
  49. package/src/components/astro/RLAProgress.astro +8 -2
  50. package/src/components/astro/RLAScrollArea.astro +4 -1
  51. package/src/components/astro/RLAScrollToTop.astro +200 -172
  52. package/src/components/astro/RLASearch.astro +282 -0
  53. package/src/components/astro/RLASelect.astro +101 -64
  54. package/src/components/astro/RLASeparator.astro +11 -6
  55. package/src/components/astro/RLAShare.astro +60 -0
  56. package/src/components/astro/RLAShortcuts.astro +429 -0
  57. package/src/components/astro/RLASidebar.astro +158 -212
  58. package/src/components/astro/RLASlideover.astro +99 -4
  59. package/src/components/astro/RLASlider.astro +14 -14
  60. package/src/components/astro/RLASplitter.astro +207 -142
  61. package/src/components/astro/RLASteps.astro +118 -71
  62. package/src/components/astro/RLAStickySurface.astro +9 -2
  63. package/src/components/astro/RLASurround.astro +39 -0
  64. package/src/components/astro/RLATable.astro +4 -1
  65. package/src/components/astro/RLATableOfContents.astro +109 -23
  66. package/src/components/astro/RLATabs.astro +147 -133
  67. package/src/components/astro/RLATextarea.astro +4 -1
  68. package/src/components/astro/RLAThemeSelector.astro +105 -76
  69. package/src/components/astro/RLAToast.astro +35 -21
  70. package/src/components/vue/RLVBanner.vue +230 -0
  71. package/src/components/vue/RLVButton.vue +3 -2
  72. package/src/components/vue/RLVCheckbox.vue +70 -68
  73. package/src/components/vue/RLVFooter.vue +3 -2
  74. package/src/components/vue/RLVForm.vue +44 -44
  75. package/src/components/vue/RLVFormField.vue +58 -58
  76. package/src/components/vue/RLVHeader.vue +3 -2
  77. package/src/components/vue/RLVIcon.vue +4 -2
  78. package/src/components/vue/RLVInput.vue +94 -93
  79. package/src/components/vue/RLVLogo.vue +25 -3
  80. package/src/components/vue/RLVPlaceholder.vue +3 -2
  81. package/src/components/vue/RLVPost.vue +69 -63
  82. package/src/components/vue/RLVPosts.vue +21 -21
  83. package/src/components/vue/RLVProgress.vue +60 -0
  84. package/src/components/vue/RLVScrollToTop.vue +65 -52
  85. package/src/components/vue/RLVSection.vue +14 -13
  86. package/src/components/vue/RLVToast.vue +81 -68
  87. package/src/components/vue/RLVToaster.vue +29 -29
  88. package/src/composables/index.ts +4 -3
  89. package/src/composables/useHeaderStore.ts +14 -14
  90. package/src/composables/useScrollToTop.ts +62 -62
  91. package/src/composables/useShortcuts.ts +11 -0
  92. package/src/composables/useToast.ts +43 -42
  93. package/src/config/index.ts +1 -0
  94. package/src/config/security.ts +227 -0
  95. package/src/config/site.config.ts +1 -0
  96. package/src/docs/components/ApiChangelog.astro +147 -0
  97. package/src/{plugins/starlightDocsApi → docs}/components/ApiEmits.astro +4 -4
  98. package/src/{plugins/starlightDocsApi → docs}/components/ApiProps.astro +4 -4
  99. package/src/{plugins/starlightDocsApi → docs}/components/ApiSlots.astro +4 -4
  100. package/src/docs/components/ApiTheme.astro +100 -0
  101. package/src/docs/extractAll.ts +94 -0
  102. package/src/docs/extractors/extractAstro.ts +69 -0
  103. package/src/docs/extractors/extractTheme.ts +56 -0
  104. package/src/{plugins/starlightDocsApi/extract-vue.ts → docs/extractors/extractVue.ts} +164 -15
  105. package/src/{plugins/starlightDocsApi → docs}/utils.ts +1 -2
  106. package/src/env.d.ts +0 -12
  107. package/src/integrations/ui.ts +215 -199
  108. package/src/middleware/security.ts +145 -29
  109. package/src/presets/defaults.ts +297 -297
  110. package/src/presets/index.ts +508 -637
  111. package/src/styles/index.css +158 -160
  112. package/src/themes/3d-hover.theme.ts +13 -13
  113. package/src/themes/accordion.theme.ts +39 -13
  114. package/src/themes/app.theme.ts +13 -13
  115. package/src/themes/aspect-ratio.theme.ts +1 -1
  116. package/src/themes/audio.theme.ts +13 -13
  117. package/src/themes/avatar-group.theme.ts +1 -1
  118. package/src/themes/avatar.theme.ts +84 -84
  119. package/src/themes/badge.theme.ts +168 -163
  120. package/src/themes/banner.theme.ts +49 -13
  121. package/src/themes/breadcrumb.theme.ts +1 -1
  122. package/src/themes/browser-mockup.theme.ts +13 -13
  123. package/src/themes/button.theme.ts +223 -202
  124. package/src/themes/calendar.theme.ts +13 -13
  125. package/src/themes/{alert.theme.ts → callout.theme.ts} +104 -125
  126. package/src/themes/card.theme.ts +50 -42
  127. package/src/themes/carousel.theme.ts +1 -1
  128. package/src/themes/chart.theme.ts +22 -22
  129. package/src/themes/chat-message.theme.ts +13 -13
  130. package/src/themes/chat-messages.theme.ts +13 -13
  131. package/src/themes/chat-palette.theme.ts +13 -13
  132. package/src/themes/chat-prompt-submit.theme.ts +13 -13
  133. package/src/themes/chat-prompt.theme.ts +13 -13
  134. package/src/themes/chat-reasoning.theme.ts +13 -13
  135. package/src/themes/chat-shimmer.theme.ts +13 -13
  136. package/src/themes/chat-tool.theme.ts +13 -13
  137. package/src/themes/chat.theme.ts +13 -13
  138. package/src/themes/checkbox.theme.ts +49 -50
  139. package/src/themes/chip.theme.ts +73 -74
  140. package/src/themes/color-area.theme.ts +33 -0
  141. package/src/themes/color-field.theme.ts +32 -0
  142. package/src/themes/color-picker.theme.ts +13 -13
  143. package/src/themes/color-slider.theme.ts +34 -0
  144. package/src/themes/command-palette.theme.ts +13 -13
  145. package/src/themes/compare.theme.ts +13 -13
  146. package/src/themes/confirm.theme.ts +48 -48
  147. package/src/themes/container.theme.ts +13 -13
  148. package/src/themes/context-menu.theme.ts +13 -13
  149. package/src/themes/dashboard-group.theme.ts +13 -13
  150. package/src/themes/dashboard-navbar.theme.ts +13 -13
  151. package/src/themes/dashboard-panel.theme.ts +13 -13
  152. package/src/themes/dashboard-resize-handle.theme.ts +13 -13
  153. package/src/themes/dashboard-search-button.theme.ts +13 -13
  154. package/src/themes/dashboard-search.theme.ts +13 -13
  155. package/src/themes/dashboard-sidebar-collapse.theme.ts +13 -13
  156. package/src/themes/dashboard-sidebar-toggle.theme.ts +13 -13
  157. package/src/themes/dashboard-sidebar.theme.ts +13 -13
  158. package/src/themes/dashboard-toolbar.theme.ts +13 -13
  159. package/src/themes/dock.theme.ts +13 -13
  160. package/src/themes/drawer.theme.ts +61 -61
  161. package/src/themes/dropdown-menu.theme.ts +29 -29
  162. package/src/themes/editor.theme.ts +13 -13
  163. package/src/themes/empty.theme.ts +13 -13
  164. package/src/themes/error.theme.ts +13 -13
  165. package/src/themes/field-group.theme.ts +24 -24
  166. package/src/themes/fieldset.theme.ts +13 -13
  167. package/src/themes/floating-action.theme.ts +13 -13
  168. package/src/themes/footer.theme.ts +30 -30
  169. package/src/themes/form.theme.ts +13 -13
  170. package/src/themes/gallery.theme.ts +13 -13
  171. package/src/themes/grid.theme.ts +38 -0
  172. package/src/themes/head.theme.ts +13 -13
  173. package/src/themes/header.theme.ts +46 -46
  174. package/src/themes/hover-card.theme.ts +1 -1
  175. package/src/themes/icon.theme.ts +23 -23
  176. package/src/themes/image.theme.ts +33 -19
  177. package/src/themes/input-date.theme.ts +13 -13
  178. package/src/themes/input-menu.theme.ts +35 -35
  179. package/src/themes/input-number.theme.ts +13 -13
  180. package/src/themes/input-tags.theme.ts +13 -13
  181. package/src/themes/input-time.theme.ts +13 -13
  182. package/src/themes/input.theme.ts +48 -42
  183. package/src/themes/kbd.theme.ts +94 -89
  184. package/src/themes/knob.theme.ts +13 -13
  185. package/src/themes/label.theme.ts +1 -1
  186. package/src/themes/layout-grid.theme.ts +16 -0
  187. package/src/themes/link-group.theme.ts +28 -32
  188. package/src/themes/link.theme.ts +13 -13
  189. package/src/themes/listbox.theme.ts +13 -13
  190. package/src/themes/locale-selector.theme.ts +49 -49
  191. package/src/themes/logo.theme.ts +13 -13
  192. package/src/themes/main.theme.ts +13 -13
  193. package/src/themes/marquee.theme.ts +1 -1
  194. package/src/themes/meter.theme.ts +13 -13
  195. package/src/themes/modal.theme.ts +1 -1
  196. package/src/themes/navigation-menu.theme.ts +44 -27
  197. package/src/themes/page-aside.theme.ts +13 -13
  198. package/src/themes/page-body.theme.ts +13 -13
  199. package/src/themes/page-header.theme.ts +13 -13
  200. package/src/themes/page-section.theme.ts +189 -187
  201. package/src/themes/page.theme.ts +13 -13
  202. package/src/themes/pagination.theme.ts +1 -1
  203. package/src/themes/password.theme.ts +13 -13
  204. package/src/themes/phone-mockup.theme.ts +13 -13
  205. package/src/themes/pin-input.theme.ts +1 -1
  206. package/src/themes/placeholder.theme.ts +15 -15
  207. package/src/themes/popover.theme.ts +1 -1
  208. package/src/themes/post.theme.ts +53 -33
  209. package/src/themes/pricing-plan.theme.ts +13 -13
  210. package/src/themes/pricing-table.theme.ts +13 -13
  211. package/src/themes/progress.theme.ts +37 -38
  212. package/src/themes/prose.theme.ts +13 -13
  213. package/src/themes/qr-code.theme.ts +13 -13
  214. package/src/themes/quote.theme.ts +13 -13
  215. package/src/themes/radio-group.theme.ts +13 -13
  216. package/src/themes/rating.theme.ts +13 -13
  217. package/src/themes/scroll-area.theme.ts +26 -26
  218. package/src/themes/scroll-to-top.theme.ts +51 -52
  219. package/src/themes/search.theme.ts +64 -0
  220. package/src/themes/select.theme.ts +29 -29
  221. package/src/themes/separator.theme.ts +147 -147
  222. package/src/themes/sidebar.theme.ts +38 -38
  223. package/src/themes/skeleton.theme.ts +21 -21
  224. package/src/themes/slideover.theme.ts +5 -5
  225. package/src/themes/slider.theme.ts +35 -36
  226. package/src/themes/speed-dial.theme.ts +13 -13
  227. package/src/themes/spinner.theme.ts +33 -34
  228. package/src/themes/splitter.theme.ts +23 -23
  229. package/src/themes/spoiler.theme.ts +13 -13
  230. package/src/themes/stepper.theme.ts +13 -13
  231. package/src/themes/{megamenu.theme.ts → steps.theme.ts} +13 -13
  232. package/src/themes/sticky-surface.theme.ts +1 -1
  233. package/src/themes/switch.theme.ts +66 -67
  234. package/src/themes/table-of-contents.theme.ts +67 -48
  235. package/src/themes/tabs.theme.ts +52 -52
  236. package/src/themes/textarea.theme.ts +27 -27
  237. package/src/themes/theme-selector.theme.ts +15 -15
  238. package/src/themes/timeline.theme.ts +18 -13
  239. package/src/themes/toast.theme.ts +31 -31
  240. package/src/themes/tooltip.theme.ts +28 -28
  241. package/src/themes/tour.theme.ts +13 -13
  242. package/src/themes/tree.theme.ts +13 -13
  243. package/src/themes/user.theme.ts +13 -13
  244. package/src/themes/video.theme.ts +17 -17
  245. package/src/themes/watermark.theme.ts +13 -13
  246. package/src/themes/window-mockup.theme.ts +13 -13
  247. package/src/types/components/3d-hover.ts +11 -11
  248. package/src/types/components/accordion.ts +35 -2
  249. package/src/types/components/app.ts +11 -11
  250. package/src/types/components/audio.ts +11 -11
  251. package/src/types/components/avatar-group.ts +11 -11
  252. package/src/types/components/avatar.ts +76 -60
  253. package/src/types/components/badge.ts +2 -2
  254. package/src/types/components/banner.ts +53 -11
  255. package/src/types/components/browser-mockup.ts +11 -11
  256. package/src/types/components/button.ts +73 -81
  257. package/src/types/components/calendar.ts +11 -11
  258. package/src/types/components/{alert.ts → callout.ts} +8 -8
  259. package/src/types/components/changelog.ts +11 -11
  260. package/src/types/components/chart.ts +2 -1
  261. package/src/types/components/chat-message.ts +11 -11
  262. package/src/types/components/chat-messages.ts +11 -11
  263. package/src/types/components/chat-palette.ts +11 -11
  264. package/src/types/components/chat-prompt-submit.ts +11 -11
  265. package/src/types/components/chat-prompt.ts +11 -11
  266. package/src/types/components/chat-reasoning.ts +11 -11
  267. package/src/types/components/chat-shimmer.ts +11 -11
  268. package/src/types/components/chat-tool.ts +11 -11
  269. package/src/types/components/chat.ts +11 -11
  270. package/src/types/components/checkbox.ts +2 -2
  271. package/src/types/components/chip.ts +17 -17
  272. package/src/types/components/collapsible.ts +2 -1
  273. package/src/types/components/color-area.ts +19 -0
  274. package/src/types/components/color-field.ts +21 -0
  275. package/src/types/components/color-picker.ts +11 -11
  276. package/src/types/components/color-slider.ts +20 -0
  277. package/src/types/components/command-palette.ts +11 -11
  278. package/src/types/components/compare.ts +11 -11
  279. package/src/types/components/container.ts +17 -17
  280. package/src/types/components/context-menu.ts +11 -11
  281. package/src/types/components/dashboard-group.ts +11 -11
  282. package/src/types/components/dashboard-navbar.ts +11 -11
  283. package/src/types/components/dashboard-panel.ts +11 -11
  284. package/src/types/components/dashboard-resize-handle.ts +11 -11
  285. package/src/types/components/dashboard-search-button.ts +11 -11
  286. package/src/types/components/dashboard-search.ts +11 -11
  287. package/src/types/components/dashboard-sidebar-collapse.ts +11 -11
  288. package/src/types/components/dashboard-sidebar-toggle.ts +11 -11
  289. package/src/types/components/dashboard-sidebar.ts +11 -11
  290. package/src/types/components/dashboard-toolbar.ts +11 -11
  291. package/src/types/components/dock.ts +11 -11
  292. package/src/types/components/dropdown-menu.ts +2 -1
  293. package/src/types/components/editor.ts +11 -11
  294. package/src/types/components/empty.ts +11 -11
  295. package/src/types/components/error.ts +11 -11
  296. package/src/types/components/fieldset.ts +11 -11
  297. package/src/types/components/file-upload.ts +2 -1
  298. package/src/types/components/floating-action.ts +11 -11
  299. package/src/types/components/form.ts +19 -19
  300. package/src/types/components/gallery.ts +11 -11
  301. package/src/types/components/grid.ts +23 -0
  302. package/src/types/components/icon.ts +19 -19
  303. package/src/types/components/image.ts +32 -28
  304. package/src/types/components/input-date.ts +11 -11
  305. package/src/types/components/input-menu.ts +44 -43
  306. package/src/types/components/input-number.ts +11 -11
  307. package/src/types/components/input-pin.ts +36 -35
  308. package/src/types/components/input-tags.ts +11 -11
  309. package/src/types/components/input-time.ts +11 -11
  310. package/src/types/components/input.ts +6 -2
  311. package/src/types/components/knob.ts +11 -11
  312. package/src/types/components/layout-grid.ts +145 -0
  313. package/src/types/components/link-group.ts +47 -23
  314. package/src/types/components/link.ts +19 -0
  315. package/src/types/components/listbox.ts +11 -11
  316. package/src/types/components/locale-selector.ts +33 -33
  317. package/src/types/components/logo.ts +32 -31
  318. package/src/types/components/main.ts +17 -17
  319. package/src/types/components/meter.ts +11 -11
  320. package/src/types/components/modal.ts +39 -39
  321. package/src/types/components/navigation-menu.ts +59 -54
  322. package/src/types/components/page-aside.ts +11 -11
  323. package/src/types/components/page-body.ts +11 -11
  324. package/src/types/components/page-header.ts +11 -11
  325. package/src/types/components/page.ts +11 -11
  326. package/src/types/components/password.ts +11 -11
  327. package/src/types/components/phone-mockup.ts +5 -5
  328. package/src/types/components/pin-input.ts +11 -11
  329. package/src/types/components/popover.ts +23 -23
  330. package/src/types/components/post.ts +47 -35
  331. package/src/types/components/pricing-plan.ts +11 -11
  332. package/src/types/components/pricing-table.ts +11 -11
  333. package/src/types/components/progress.ts +33 -33
  334. package/src/types/components/prose.ts +11 -11
  335. package/src/types/components/qr-code.ts +11 -11
  336. package/src/types/components/radio-group.ts +11 -11
  337. package/src/types/components/rating.ts +11 -11
  338. package/src/types/components/scroll-area.ts +23 -23
  339. package/src/types/components/scroll-to-top.ts +2 -2
  340. package/src/types/components/search.ts +29 -0
  341. package/src/types/components/select.ts +2 -1
  342. package/src/types/components/separator.ts +19 -19
  343. package/src/types/components/sidebar.ts +83 -72
  344. package/src/types/components/slideover.ts +31 -31
  345. package/src/types/components/slider.ts +2 -2
  346. package/src/types/components/speed-dial.ts +11 -11
  347. package/src/types/components/spinner.ts +25 -25
  348. package/src/types/components/splitter.ts +19 -19
  349. package/src/types/components/spoiler.ts +11 -11
  350. package/src/types/components/stepper.ts +11 -11
  351. package/src/types/components/{megamenu.ts → steps.ts} +17 -11
  352. package/src/types/components/sticky-surface.ts +19 -19
  353. package/src/types/components/switch.ts +41 -41
  354. package/src/types/components/table-of-contents.ts +39 -17
  355. package/src/types/components/tabs.ts +2 -1
  356. package/src/types/components/textarea.ts +2 -1
  357. package/src/types/components/theme-selector.ts +15 -15
  358. package/src/types/components/timeline.ts +11 -11
  359. package/src/types/components/toast.ts +6 -1
  360. package/src/types/components/tooltip.ts +23 -23
  361. package/src/types/components/tour.ts +11 -11
  362. package/src/types/components/tree.ts +11 -11
  363. package/src/types/components/user.ts +11 -11
  364. package/src/types/components/watermark.ts +11 -11
  365. package/src/types/components/window-mockup.ts +11 -11
  366. package/src/types/docs.ts +40 -0
  367. package/src/types/index.ts +151 -1
  368. package/src/types/theme.ts +11 -1
  369. package/src/utils/color.ts +165 -0
  370. package/src/utils/docs.ts +365 -189
  371. package/src/utils/headerStack.ts +115 -95
  372. package/src/utils/index.ts +7 -5
  373. package/src/utils/shortcuts.ts +322 -0
  374. package/src/components/TableOfContents.astro +0 -107
  375. package/src/components/astro/RLAAlert.astro +0 -93
  376. package/src/components/astro/RLABlogPost.astro +0 -7
  377. package/src/components/astro/RLABlogPosts.astro +0 -9
  378. package/src/components/astro/RLAChangelog.astro +0 -23
  379. package/src/components/astro/RLAMegamenu.astro +0 -23
  380. package/src/components/astro/RLAPosts.astro +0 -23
  381. package/src/plugins/index.ts +0 -2
  382. package/src/plugins/starlightDocsApi/components/ApiTheme.astro +0 -27
  383. package/src/plugins/starlightDocsApi/index.ts +0 -272
  384. package/src/styles/prism.css +0 -42
  385. package/src/themes/changelog.theme.ts +0 -13
  386. package/src/themes/posts.theme.ts +0 -13
  387. package/src/types/components/index.ts +0 -135
  388. package/src/types/components/posts.ts +0 -11
  389. /package/src/{plugins/starlightDocsApi → docs}/types.ts +0 -0
@@ -1,197 +1,528 @@
1
- ---
2
- import { ClientRouter } from 'astro:transitions';
3
- import type { SiteConfig } from '@/config';
4
-
5
- export interface OGImage {
6
- /** Image URL (relative or absolute) */
7
- src: string;
8
- /** Alt text for the image */
9
- alt: string;
10
- }
11
-
12
- export interface RSSFeed {
13
- /** RSS feed URL */
14
- href: string;
15
- /** Feed title (defaults to "RSS") */
16
- title?: string;
17
- }
18
-
19
- export interface HeadProps {
20
- /** Page title */
21
- title?: string;
22
- /** Page description */
23
- description?: string;
24
- /** Open Graph image with alt text */
25
- ogImage?: OGImage;
26
- /** Open Graph type (e.g., "website", "article") */
27
- ogType?: string;
28
- /** Open Graph locale (defaults to "en_US") */
29
- ogLocale?: string;
30
- /** Whether to prevent indexing */
31
- noindex?: boolean;
32
- /** Whether this is a 404 page */
33
- is404?: boolean;
34
- /** Robots metadata (overrides noindex/is404 logic if provided) */
35
- robots?: string;
36
- /** Canonical URL */
37
- canonical?: string;
38
- /** Language alternates for i18n */
39
- languageAlternates?: Array<{ hreflang: string; href: string }>;
40
- /** Site configuration for defaults */
41
- config?: SiteConfig;
42
- /** Whether to enable View Transitions (ClientRouter) */
43
- transitions?: boolean;
44
- /** Meta charset */
45
- charset?: string;
46
- /** Meta viewport */
47
- viewport?: string;
48
- /** RSS feed configuration */
49
- rssFeed?: RSSFeed;
50
- }
51
-
52
- const {
53
- title,
54
- description,
55
- ogImage,
56
- ogType = 'website',
57
- ogLocale = 'en_US',
58
- noindex = false,
59
- is404 = false,
60
- robots,
61
- canonical,
62
- languageAlternates = [],
63
- config,
64
- transitions = true,
65
- charset = 'utf-8',
66
- viewport = 'width=device-width,initial-scale=1',
67
- rssFeed,
68
- } = Astro.props as HeadProps;
69
-
70
- // Resolve defaults from config if available
71
- const siteName = config?.name || 'Rimelight';
72
- const siteDescription = config?.description || '';
73
- const ogImageFallback = config?.seo?.ogImageFallback || config?.ogImage || '';
74
- const themeColor = config?.branding?.colors?.themeColor;
75
- const favicon = config?.branding?.favicon?.svg || '/favicon.svg';
76
- const twitterHandle = config?.seo?.authorHandle;
77
- const titleTemplate = config?.seo?.titleTemplate || `%s | ${siteName}`;
78
-
79
- // Calculated Values
80
- const displayTitle = is404
81
- ? `404 - Not Found | ${siteName}`
82
- : title
83
- ? titleTemplate.replace('%s', title)
84
- : siteName;
85
-
86
- const finalDescription = description || siteDescription;
87
- const safeDescription = finalDescription && config?.seo?.maxDescriptionLength
88
- ? (finalDescription.length > config.seo.maxDescriptionLength
89
- ? finalDescription.slice(0, config.seo.maxDescriptionLength - 3) + '...'
90
- : finalDescription)
91
- : finalDescription;
92
-
93
- const finalOgImage = ogImage || (ogImageFallback ? { src: ogImageFallback, alt: siteName } : undefined);
94
- const absoluteOgImage = finalOgImage
95
- ? new URL(finalOgImage.src, Astro.site).toString()
96
- : undefined;
97
-
98
- function formatCanonicalURL(url: string | URL) {
99
- const resolved = new URL(url, Astro.site);
100
- const path = resolved.toString();
101
- const hasQueryParams = path.includes('?');
102
- if (hasQueryParams) {
103
- return path.replace(/\/?$/, '');
104
- }
105
- return path.replace(/\/?$/, '/');
106
- }
107
-
108
- const finalCanonical = canonical
109
- ? formatCanonicalURL(canonical)
110
- : (!is404 ? formatCanonicalURL(Astro.url) : undefined);
111
-
112
- const isIndexable = !noindex && !is404;
113
- const defaultRobots = isIndexable ? 'index, follow, max-image-preview:large' : 'noindex, nofollow';
114
- ---
115
-
116
- <!-- Basic Metadata -->
117
- <meta charset={charset} />
118
- <meta name="viewport" content={viewport} />
119
- <meta name="generator" content={Astro.generator} />
120
-
121
- <!-- Sitemap -->
122
- <link rel="sitemap" href="/sitemap-index.xml" />
123
-
124
- <!-- RSS Feed -->
125
- {rssFeed && <link rel="alternate" type="application/rss+xml" href={rssFeed.href} title={rssFeed.title || 'RSS'} />}
126
-
127
- <!-- SEO -->
128
- <title>{displayTitle}</title>
129
- {safeDescription && <meta name="description" content={safeDescription} />}
130
- <meta name="robots" content={robots || defaultRobots} />
131
- {finalCanonical && <link rel="canonical" href={finalCanonical} />}
132
-
133
- <!-- i18n Alternates -->
134
- {languageAlternates.map((alt) => (
135
- <link rel="alternate" hreflang={alt.hreflang} href={alt.href} />
136
- ))}
137
-
138
- <!-- Open Graph / Facebook -->
139
- <meta property="og:type" content={ogType} />
140
- <meta property="og:locale" content={ogLocale} />
141
- <meta property="og:url" content={Astro.url.href} />
142
- <meta property="og:title" content={title || siteName} />
143
- {safeDescription && <meta property="og:description" content={safeDescription} />}
144
- {absoluteOgImage && <meta property="og:image" content={absoluteOgImage} />}
145
- {finalOgImage && <meta property="og:image:alt" content={finalOgImage.alt} />}
146
- <meta property="og:site_name" content={siteName} />
147
-
148
- <!-- Twitter -->
149
- <meta property="twitter:card" content="summary_large_image" />
150
- <meta property="twitter:url" content={Astro.url.href} />
151
- <meta property="twitter:title" content={title || siteName} />
152
- {safeDescription && <meta property="twitter:description" content={safeDescription} />}
153
- {absoluteOgImage && <meta property="twitter:image" content={absoluteOgImage} />}
154
- {finalOgImage && <meta property="twitter:image:alt" content={finalOgImage.alt} />}
155
- {twitterHandle && <meta property="twitter:site" content={twitterHandle} />}
156
- {twitterHandle && <meta property="twitter:creator" content={twitterHandle} />}
157
-
158
- <!-- Icons -->
159
- <link rel="icon" type="image/svg+xml" href={favicon} />
160
-
161
- <!-- Theme -->
162
- {themeColor && <meta name="theme-color" content={themeColor} />}
163
-
164
- <script is:inline>
165
- (function() {
166
- function getThemeClass() {
167
- var stored = localStorage.getItem('theme');
168
- if (stored === 'dark') return 'dark';
169
- if (stored === 'light') return '';
170
- return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : '';
171
- }
172
-
173
- function applyTheme(doc) {
174
- var cls = getThemeClass();
175
- if (cls) {
176
- doc.documentElement.classList.add('dark');
177
- } else {
178
- doc.documentElement.classList.remove('dark');
179
- }
180
- }
181
-
182
- // Apply immediately on initial load
183
- applyTheme(document);
184
-
185
- // Apply to incoming document BEFORE the swap — eliminates the flash
186
- document.addEventListener('astro:before-swap', function(e) {
187
- applyTheme(e.newDocument);
188
- });
189
-
190
- // Safety net: re-apply after swap in case anything overrides it
191
- document.addEventListener('astro:after-swap', function() {
192
- applyTheme(document);
193
- });
194
- })();
195
- </script>
196
-
197
- {transitions && <ClientRouter />}
1
+ ---
2
+ import { ClientRouter } from 'astro:transitions';
3
+ import type { SiteConfig } from '@/config';
4
+
5
+ export interface OGImage {
6
+ /** Image URL (relative or absolute) */
7
+ src: string;
8
+ /** Alt text for the image */
9
+ alt: string;
10
+ }
11
+
12
+ export interface RSSFeed {
13
+ /** RSS feed URL */
14
+ href: string;
15
+ /** Feed title (defaults to "RSS") */
16
+ title?: string;
17
+ }
18
+
19
+ export interface HeadProps {
20
+ /** Page title */
21
+ title?: string;
22
+ /** Page description */
23
+ description?: string;
24
+ /** Open Graph image with alt text */
25
+ ogImage?: OGImage;
26
+ /** Open Graph type (e.g., "website", "article") */
27
+ ogType?: string;
28
+ /** Open Graph locale (defaults to "en_US") */
29
+ ogLocale?: string;
30
+ /** Whether to prevent indexing */
31
+ noindex?: boolean;
32
+ /** Whether this is a 404 page */
33
+ is404?: boolean;
34
+ /** Robots metadata (overrides noindex/is404 logic if provided) */
35
+ robots?: string;
36
+ /** Canonical URL */
37
+ canonical?: string;
38
+ /** Language alternates for i18n */
39
+ languageAlternates?: Array<{ hreflang: string; href: string }>;
40
+ /** Site configuration for defaults */
41
+ config?: SiteConfig;
42
+ /** Whether to enable View Transitions (ClientRouter) */
43
+ transitions?: boolean;
44
+ /** Meta charset */
45
+ charset?: string;
46
+ /** Meta viewport */
47
+ viewport?: string;
48
+ /** RSS feed configuration */
49
+ rssFeed?: RSSFeed;
50
+ }
51
+
52
+ const {
53
+ title,
54
+ description,
55
+ ogImage,
56
+ ogType = 'website',
57
+ ogLocale = 'en_US',
58
+ noindex = false,
59
+ is404 = false,
60
+ robots,
61
+ canonical,
62
+ languageAlternates = [],
63
+ config,
64
+ transitions = true,
65
+ charset = 'utf-8',
66
+ viewport = 'width=device-width, initial-scale=1',
67
+ rssFeed,
68
+ } = Astro.props as HeadProps;
69
+
70
+ // Resolve defaults from config if available
71
+ const siteName = config?.name || 'Rimelight';
72
+ const siteDescription = config?.description || '';
73
+ const ogImageFallback = config?.seo?.ogImageFallback || config?.ogImage || '';
74
+ const themeColor = config?.branding?.colors?.themeColor;
75
+ const favicon = config?.branding?.favicon?.svg || '/favicon.svg';
76
+ const twitterHandle = config?.seo?.authorHandle;
77
+ const titleTemplate = config?.seo?.titleTemplate || `%s | ${siteName}`;
78
+
79
+ // Calculated Values
80
+ const displayTitle = is404
81
+ ? `404 - Not Found | ${siteName}`
82
+ : title
83
+ ? titleTemplate.replace('%s', title)
84
+ : siteName;
85
+
86
+ const finalDescription = description || siteDescription;
87
+ const safeDescription = finalDescription && config?.seo?.maxDescriptionLength
88
+ ? (finalDescription.length > config.seo.maxDescriptionLength
89
+ ? finalDescription.slice(0, config.seo.maxDescriptionLength - 3) + '...'
90
+ : finalDescription)
91
+ : finalDescription;
92
+
93
+ const finalOgImage = ogImage || (ogImageFallback ? { src: ogImageFallback, alt: siteName } : undefined);
94
+ const absoluteOgImage = finalOgImage
95
+ ? new URL(finalOgImage.src, Astro.site).toString()
96
+ : undefined;
97
+
98
+ function formatCanonicalURL(url: string | URL) {
99
+ const resolved = new URL(url, Astro.site);
100
+ const path = resolved.toString();
101
+ const hasQueryParams = path.includes('?');
102
+ if (hasQueryParams) {
103
+ return path.replace(/\/?$/, '');
104
+ }
105
+ return path.replace(/\/?$/, '/');
106
+ }
107
+
108
+ const finalCanonical = canonical
109
+ ? formatCanonicalURL(canonical)
110
+ : (!is404 ? formatCanonicalURL(Astro.url) : undefined);
111
+
112
+ const isIndexable = !noindex && !is404;
113
+ const defaultRobots = isIndexable ? 'index, follow, max-image-preview:large' : 'noindex, nofollow';
114
+ ---
115
+
116
+ <!-- Basic Metadata -->
117
+ <meta charset={charset} />
118
+ <meta name="viewport" content={viewport} />
119
+ <meta name="generator" content={Astro.generator} />
120
+
121
+ <!-- Sitemap -->
122
+ <link rel="sitemap" href="/sitemap-index.xml" />
123
+
124
+ <!-- RSS Feed -->
125
+ {rssFeed && <link rel="alternate" type="application/rss+xml" href={rssFeed.href} title={rssFeed.title || 'RSS'} />}
126
+
127
+ <!-- SEO -->
128
+ <title>{displayTitle}</title>
129
+ {safeDescription && <meta name="description" content={safeDescription} />}
130
+ <meta name="robots" content={robots || defaultRobots} />
131
+ {finalCanonical && <link rel="canonical" href={finalCanonical} />}
132
+
133
+ <!-- i18n Alternates -->
134
+ {languageAlternates.map((alt) => (
135
+ <link rel="alternate" hreflang={alt.hreflang} href={alt.href} />
136
+ ))}
137
+
138
+ <!-- Open Graph / Facebook -->
139
+ <meta property="og:type" content={ogType} />
140
+ <meta property="og:locale" content={ogLocale} />
141
+ <meta property="og:url" content={Astro.url.href} />
142
+ <meta property="og:title" content={title || siteName} />
143
+ {safeDescription && <meta property="og:description" content={safeDescription} />}
144
+ {absoluteOgImage && <meta property="og:image" content={absoluteOgImage} />}
145
+ {finalOgImage && <meta property="og:image:alt" content={finalOgImage.alt} />}
146
+ <meta property="og:site_name" content={siteName} />
147
+
148
+ <!-- Twitter -->
149
+ <meta property="twitter:card" content="summary_large_image" />
150
+ <meta property="twitter:url" content={Astro.url.href} />
151
+ <meta property="twitter:title" content={title || siteName} />
152
+ {safeDescription && <meta property="twitter:description" content={safeDescription} />}
153
+ {absoluteOgImage && <meta property="twitter:image" content={absoluteOgImage} />}
154
+ {finalOgImage && <meta property="twitter:image:alt" content={finalOgImage.alt} />}
155
+ {twitterHandle && <meta property="twitter:site" content={twitterHandle} />}
156
+ {twitterHandle && <meta property="twitter:creator" content={twitterHandle} />}
157
+
158
+ <!-- Icons & Manifest -->
159
+ <link rel="icon" type="image/svg+xml" href={favicon} />
160
+ <link rel="icon" href="/favicon.ico" sizes="32x32" />
161
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
162
+ <link rel="manifest" href="/site.webmanifest" />
163
+
164
+ <!-- Theme -->
165
+ <meta name="color-scheme" content="light dark" />
166
+ <meta name="theme-color" media="(prefers-color-scheme: light)" content={themeColor || "#ffffff"} />
167
+ <meta name="theme-color" media="(prefers-color-scheme: dark)" content="#0a0a0a" />
168
+
169
+ <script is:inline>
170
+ (function() {
171
+ if (window.trustedTypes && trustedTypes.createPolicy) {
172
+ trustedTypes.createPolicy('default', {
173
+ createHTML: function(input) { return input; },
174
+ createScript: function(input) { return input; },
175
+ createScriptURL: function(input) { return input; }
176
+ });
177
+ }
178
+ })();
179
+ </script>
180
+ <script is:inline>
181
+ (function() {
182
+ if (!window.initialCspNonce) {
183
+ window.initialCspNonce = document.querySelector('meta[name="csp-nonce"]')?.getAttribute('content') ||
184
+ Array.from(document.querySelectorAll('script')).find(function(s) { return s.nonce; })?.nonce ||
185
+ document.querySelector('script[nonce]')?.nonce ||
186
+ document.querySelector('style[nonce]')?.nonce;
187
+ }
188
+
189
+ var orig = document.createElement;
190
+ document.createElement = function(tag, opts) {
191
+ var el = orig.call(document, tag, opts);
192
+ var lowTag = tag.toLowerCase();
193
+ if (lowTag === 'script' || lowTag === 'style') {
194
+ var nonce = window.initialCspNonce;
195
+ if (nonce) {
196
+ el.setAttribute('nonce', nonce);
197
+ el.nonce = nonce;
198
+ }
199
+ }
200
+ return el;
201
+ };
202
+
203
+ // Synchronous DOM insertion overrides to catch cloned, imported, or createElementNS tags
204
+ var origAppend = Element.prototype.appendChild;
205
+ Element.prototype.appendChild = function(child) {
206
+ if (child && (child.tagName === 'SCRIPT' || child.tagName === 'STYLE')) {
207
+ var nonce = window.initialCspNonce;
208
+ if (nonce && !child.getAttribute('nonce')) {
209
+ child.setAttribute('nonce', nonce);
210
+ child.nonce = nonce;
211
+ }
212
+ }
213
+ return origAppend.apply(this, arguments);
214
+ };
215
+
216
+ var origInsert = Element.prototype.insertBefore;
217
+ Element.prototype.insertBefore = function(newChild, refChild) {
218
+ if (newChild && (newChild.tagName === 'SCRIPT' || newChild.tagName === 'STYLE')) {
219
+ var nonce = window.initialCspNonce;
220
+ if (nonce && !newChild.getAttribute('nonce')) {
221
+ newChild.setAttribute('nonce', nonce);
222
+ newChild.nonce = nonce;
223
+ }
224
+ }
225
+ return origInsert.apply(this, arguments);
226
+ };
227
+
228
+ var origAppendMethod = Element.prototype.append;
229
+ if (origAppendMethod) {
230
+ Element.prototype.append = function() {
231
+ for (var i = 0; i < arguments.length; i++) {
232
+ var arg = arguments[i];
233
+ if (arg && (arg.tagName === 'SCRIPT' || arg.tagName === 'STYLE')) {
234
+ var nonce = window.initialCspNonce;
235
+ if (nonce && !arg.getAttribute('nonce')) {
236
+ arg.setAttribute('nonce', nonce);
237
+ arg.nonce = nonce;
238
+ }
239
+ }
240
+ }
241
+ return origAppendMethod.apply(this, arguments);
242
+ };
243
+ }
244
+
245
+ var origPrependMethod = Element.prototype.prepend;
246
+ if (origPrependMethod) {
247
+ Element.prototype.prepend = function() {
248
+ for (var i = 0; i < arguments.length; i++) {
249
+ var arg = arguments[i];
250
+ if (arg && (arg.tagName === 'SCRIPT' || arg.tagName === 'STYLE')) {
251
+ var nonce = window.initialCspNonce;
252
+ if (nonce && !arg.getAttribute('nonce')) {
253
+ arg.setAttribute('nonce', nonce);
254
+ arg.nonce = nonce;
255
+ }
256
+ }
257
+ }
258
+ return origPrependMethod.apply(this, arguments);
259
+ };
260
+ }
261
+
262
+ function getThemePreference() {
263
+ var stored = localStorage.getItem('theme');
264
+ if (stored === 'dark' || stored === 'light') return stored;
265
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
266
+ }
267
+
268
+ function applyTheme(doc) {
269
+ var pref = getThemePreference();
270
+ doc.documentElement.classList.toggle('dark', pref === 'dark');
271
+ doc.documentElement.classList.toggle('light', pref === 'light');
272
+ }
273
+
274
+ // Apply immediately on initial load
275
+ applyTheme(document);
276
+
277
+ // Apply to incoming document BEFORE the swap — eliminates the flash
278
+ document.addEventListener('astro:before-swap', function(e) {
279
+ applyTheme(e.newDocument);
280
+ var nonce = window.initialCspNonce;
281
+ if (nonce) {
282
+ e.newDocument.querySelectorAll('script').forEach(function(s) {
283
+ s.setAttribute('nonce', nonce);
284
+ });
285
+ e.newDocument.querySelectorAll('style').forEach(function(s) {
286
+ s.setAttribute('nonce', nonce);
287
+ });
288
+ }
289
+ });
290
+
291
+ // Safety net: re-apply after swap in case anything overrides it
292
+ document.addEventListener('astro:after-swap', function() {
293
+ applyTheme(document);
294
+ });
295
+ })();
296
+ </script>
297
+
298
+ <script is:inline data-astro-rerun>
299
+ (function() {
300
+ 'use strict';
301
+ if (window.rlHeaderObserver) window.rlHeaderObserver.disconnect();
302
+
303
+ if (!window.RLHeaderStack) {
304
+ window.RLHeaderStack = {
305
+ layers: [],
306
+ register: function(id, order, naturalHeight, isVisible, el, type) {
307
+ if (el && !el.isConnected) return;
308
+ if (type === undefined) type = el && el.getAttribute ? (el.getAttribute('data-layer-type') || 'header') : 'header';
309
+ let layer = this.layers.find(function(l) { return l.id === id; });
310
+ if (!layer) {
311
+ layer = { id: id, type: type, order: order, naturalHeight: naturalHeight, isVisible: isVisible, el: el };
312
+ this.layers.push(layer);
313
+ this.sortLayers();
314
+ } else {
315
+ layer.naturalHeight = naturalHeight;
316
+ layer.isVisible = isVisible;
317
+ layer.el = el;
318
+ }
319
+ if (el) {
320
+ el.rlNaturalHeight = naturalHeight;
321
+ el.rlIsVisible = isVisible;
322
+ }
323
+ this.update();
324
+ },
325
+ unregister: function(id) {
326
+ const layer = this.layers.find(function(l) { return l.id === id; });
327
+ if (layer && layer.el) {
328
+ const el = layer.el;
329
+ if (el.rlScrollListener) {
330
+ window.removeEventListener('scroll', el.rlScrollListener);
331
+ }
332
+ if (el.rlResizeObserver) {
333
+ el.rlResizeObserver.disconnect();
334
+ }
335
+ }
336
+ this.layers = this.layers.filter(function(l) { return l.id !== id; });
337
+ this.update();
338
+ },
339
+ sortLayers: function() {
340
+ this.layers.sort(function(a, b) {
341
+ if (a.type !== b.type) return a.type === 'banner' ? -1 : 1;
342
+ return a.order - b.order;
343
+ });
344
+ },
345
+ update: function() {
346
+ let currentTop = 0;
347
+ for (let i = 0; i < this.layers.length; i++) {
348
+ const layer = this.layers[i];
349
+ if (layer.el) {
350
+ const topPx = layer.isVisible ? currentTop + 'px' : '-' + layer.naturalHeight + 'px';
351
+ layer.el.style.top = topPx;
352
+ layer.el.style.opacity = layer.isVisible ? '1' : '0';
353
+ layer.el.style.pointerEvents = layer.isVisible ? 'auto' : 'none';
354
+ layer.el.style.setProperty('--rl-header-bottom', 'calc(' + topPx + ' + ' + layer.naturalHeight + 'px)');
355
+ }
356
+ if (layer.isVisible) currentTop += layer.naturalHeight;
357
+ }
358
+ if (currentTop > 0) {
359
+ document.documentElement.style.setProperty('--rl-total-header-height', currentTop + 'px');
360
+ }
361
+ }
362
+ };
363
+ }
364
+ const RL = window.RLHeaderStack;
365
+ RL.layers = [];
366
+
367
+ function getHeight(el) {
368
+ if (!el) return 64;
369
+ const h = el.offsetHeight;
370
+ return h > 0 ? h : 64;
371
+ }
372
+
373
+ function initLayer(el) {
374
+ const id = el.id;
375
+ const type = el.getAttribute('data-layer-type') || 'header';
376
+ const stackIndex = parseInt(el.getAttribute('data-stack-index') || '0', 10);
377
+ const hideOnScroll = el.getAttribute('data-hide-on-scroll') === 'true';
378
+ const contentEl = el.querySelector('[data-header-content]');
379
+
380
+ if (el.rlManaged) {
381
+ const naturalHeight = el.rlNaturalHeight || getHeight(contentEl);
382
+ const isVisible = el.rlIsVisible !== false;
383
+ RL.register(id, stackIndex, naturalHeight, isVisible, el, type);
384
+ return;
385
+ }
386
+ el.rlManaged = true;
387
+
388
+ let naturalHeight = getHeight(contentEl);
389
+ let isVisible = true;
390
+
391
+ RL.register(id, stackIndex, naturalHeight, isVisible, el, type);
392
+
393
+ if (typeof ResizeObserver !== 'undefined' && contentEl) {
394
+ const ro = new ResizeObserver(function(entries) {
395
+ if (!el.isConnected) {
396
+ ro.disconnect();
397
+ return;
398
+ }
399
+ const h = entries[0] && entries[0].contentRect.height;
400
+ if (h && h > 0) {
401
+ naturalHeight = h;
402
+ RL.register(id, stackIndex, naturalHeight, isVisible, el, type);
403
+ }
404
+ });
405
+ ro.observe(contentEl);
406
+ el.rlResizeObserver = ro;
407
+ }
408
+
409
+ if (hideOnScroll) {
410
+ let lastScrollY = window.scrollY;
411
+ const scrollListener = function() {
412
+ if (!el.isConnected) {
413
+ window.removeEventListener('scroll', scrollListener);
414
+ return;
415
+ }
416
+ const current = window.scrollY;
417
+ const diff = current - lastScrollY;
418
+ if (Math.abs(diff) >= 10) {
419
+ const newVisible = current <= 50 ? true : diff <= 0;
420
+ if (newVisible !== isVisible) {
421
+ isVisible = newVisible;
422
+ RL.register(id, stackIndex, naturalHeight, isVisible, el, type);
423
+ }
424
+ lastScrollY = current;
425
+ }
426
+ };
427
+ el.rlScrollListener = scrollListener;
428
+ window.addEventListener('scroll', scrollListener, { passive: true });
429
+ }
430
+
431
+ (function retry() {
432
+ if (!el.isConnected) return;
433
+ const h = getHeight(contentEl);
434
+ if (h !== naturalHeight) {
435
+ naturalHeight = h;
436
+ RL.register(id, stackIndex, naturalHeight, isVisible, el, type);
437
+ }
438
+ if (h > 0 && h !== 64 && contentEl && contentEl.offsetHeight > 0) return;
439
+ requestAnimationFrame(retry);
440
+ })();
441
+ }
442
+
443
+ function dismissBanner(banner) {
444
+ var key = banner.getAttribute('data-dismiss-key');
445
+ if (key) localStorage.setItem(key, 'true');
446
+ banner.style.display = 'none';
447
+ banner.setAttribute('data-rla-banner', 'false');
448
+ if (window.RLHeaderStack) RL.unregister(banner.id);
449
+ }
450
+
451
+ function checkDismissed() {
452
+ var banners = document.querySelectorAll("[data-rla-banner='true']");
453
+ for (var i = 0; i < banners.length; i++) {
454
+ var b = banners[i];
455
+ var key = b.getAttribute('data-dismiss-key');
456
+ if (key && localStorage.getItem(key) === 'true') {
457
+ b.style.display = 'none';
458
+ b.setAttribute('data-rla-banner', 'false');
459
+ }
460
+ }
461
+ }
462
+
463
+ if (!window.rlBannerInit) {
464
+ window.rlBannerInit = true;
465
+ document.addEventListener('click', function(e) {
466
+ var btn = e.target.closest('[data-banner-close]');
467
+ if (!btn) return;
468
+ var banner = btn.closest('[data-rla-banner]');
469
+ if (!banner) return;
470
+ dismissBanner(banner);
471
+ });
472
+ }
473
+
474
+ function selector() {
475
+ return "[data-rla-header='true'],[data-rla-banner='true']";
476
+ }
477
+
478
+ function startObserver() {
479
+ if (document.body) {
480
+ checkDismissed();
481
+ const layers = document.querySelectorAll(selector());
482
+ for (let i = 0; i < layers.length; i++) initLayer(layers[i]);
483
+
484
+ window.rlHeaderObserver = new MutationObserver(function(mutations) {
485
+ for (let i = 0; i < mutations.length; i++) {
486
+ const added = mutations[i].addedNodes;
487
+ for (let j = 0; j < added.length; j++) {
488
+ const node = added[j];
489
+ if (node.nodeType !== 1) continue;
490
+ if (node.matches && node.matches(selector())) initLayer(node);
491
+ if (node.querySelectorAll) {
492
+ const nested = node.querySelectorAll(selector());
493
+ for (let k = 0; k < nested.length; k++) initLayer(nested[k]);
494
+ }
495
+ }
496
+ const removed = mutations[i].removedNodes;
497
+ for (let j = 0; j < removed.length; j++) {
498
+ const node = removed[j];
499
+ if (node.nodeType !== 1) continue;
500
+ if (node.matches && node.matches(selector())) RL.unregister(node.id);
501
+ if (node.querySelectorAll) {
502
+ const nested = node.querySelectorAll(selector());
503
+ for (let k = 0; k < nested.length; k++) RL.unregister(nested[k].id);
504
+ }
505
+ }
506
+ }
507
+ });
508
+ window.rlHeaderObserver.observe(document.body, { childList: true, subtree: true });
509
+ } else {
510
+ document.addEventListener('DOMContentLoaded', startObserver);
511
+ }
512
+ }
513
+
514
+ startObserver();
515
+ })();
516
+ </script>
517
+
518
+ {transitions && <ClientRouter />}
519
+
520
+ {config && (
521
+ <script type="application/ld+json" is:inline set:html={JSON.stringify({
522
+ "@context": "https://schema.org",
523
+ "@type": "WebSite",
524
+ "name": config.name,
525
+ "url": Astro.site ? Astro.site.toString() : config.url,
526
+ "description": config.description
527
+ })} />
528
+ )}