@voidzero-dev/vitepress-theme 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (373) hide show
  1. package/README.md +26 -33
  2. package/package.json +5 -26
  3. package/src/assets/clients/clickup.svg +5 -0
  4. package/src/assets/clients/stripe.svg +3 -0
  5. package/src/{vitepress/components → components}/oss/Footer.vue +4 -21
  6. package/src/{vitepress/components → components}/oss/Header.vue +82 -180
  7. package/src/{vitepress/components → components}/oss/Sponsors.vue +3 -3
  8. package/src/components/oss/TopBanner.vue +111 -0
  9. package/src/{vitepress/components → components}/oss/TrustedBy.vue +1 -1
  10. package/src/{vitepress/components → components}/vite/Community.vue +3 -3
  11. package/src/components/vite/FeatureGrid1.vue +63 -0
  12. package/src/{vitepress/components/vite/FeatureGrid.vue → components/vite/FeatureGrid2.vue} +12 -11
  13. package/src/{vitepress/components → components}/vite/Hero.vue +9 -18
  14. package/src/{vitepress/components → components}/vitepress-default/VPDocOutlineItem.vue +2 -2
  15. package/src/{vitepress/components → components}/vitepress-default/VPFlyout.vue +1 -1
  16. package/src/{vitepress/components → components}/vitepress-default/VPMenuLink.vue +1 -1
  17. package/src/{vitepress/components → components}/vitepress-default/VPNavBarMenuLink.vue +1 -1
  18. package/src/{vitepress/components → components}/vitepress-default/VPSidebarItem.vue +1 -1
  19. package/src/{vitepress/components → components}/vitepress-default/VPSocialLink.vue +1 -2
  20. package/src/fonts/APK-Protocol-Semi-Bold.woff2 +0 -0
  21. package/src/fonts/inter-italic-cyrillic-ext.woff2 +0 -0
  22. package/src/fonts/inter-italic-cyrillic.woff2 +0 -0
  23. package/src/fonts/inter-italic-greek-ext.woff2 +0 -0
  24. package/src/fonts/inter-italic-greek.woff2 +0 -0
  25. package/src/fonts/inter-italic-latin-ext.woff2 +0 -0
  26. package/src/fonts/inter-italic-latin.woff2 +0 -0
  27. package/src/fonts/inter-italic-vietnamese.woff2 +0 -0
  28. package/src/fonts/inter-roman-cyrillic-ext.woff2 +0 -0
  29. package/src/fonts/inter-roman-cyrillic.woff2 +0 -0
  30. package/src/fonts/inter-roman-greek-ext.woff2 +0 -0
  31. package/src/fonts/inter-roman-greek.woff2 +0 -0
  32. package/src/fonts/inter-roman-latin-ext.woff2 +0 -0
  33. package/src/fonts/inter-roman-latin.woff2 +0 -0
  34. package/src/fonts/inter-roman-vietnamese.woff2 +0 -0
  35. package/src/index.ts +103 -2
  36. package/src/{vitepress/layouts → layouts}/VPLayout.vue +2 -17
  37. package/src/styles/tokens.css +321 -0
  38. package/src/{vitepress/styles → styles}/vitepress-default/vars.css +1 -1
  39. package/src/{vitepress/types → types}/theme-config.ts +2 -0
  40. package/src/types/theme-context.ts +33 -0
  41. package/src/vitepress/assets/clients/beehiiv.svg +0 -30
  42. package/src/vitepress/assets/clients/excalidraw.svg +0 -82
  43. package/src/vitepress/assets/clients/get-your-guide.svg +0 -1
  44. package/src/vitepress/assets/clients/posthog.svg +0 -1
  45. package/src/vitepress/assets/clients/ramp.svg +0 -1
  46. package/src/vitepress/assets/clients/shopee.svg +0 -55
  47. package/src/vitepress/components/oss/TopBanner.vue +0 -150
  48. package/src/vitepress/components/vite/FeaturePanel1.vue +0 -41
  49. package/src/vitepress/components/vite/FeaturePanel2.vue +0 -37
  50. package/src/vitepress/components/vite/FeaturePanel3.vue +0 -43
  51. package/src/vitepress/components/vite/FeaturePanel4.vue +0 -46
  52. package/src/vitepress/components/voidzero/Footer.vue +0 -65
  53. package/src/vitepress/components/voidzero/Header.vue +0 -560
  54. package/src/vitepress/components/voidzero/Megamenu.vue +0 -190
  55. package/src/vitepress/components/voidzero/about/CareerCTA.vue +0 -56
  56. package/src/vitepress/components/voidzero/about/Hero.vue +0 -206
  57. package/src/vitepress/components/voidzero/about/Investors.vue +0 -112
  58. package/src/vitepress/components/voidzero/about/TeamGrid.vue +0 -161
  59. package/src/vitepress/components/voidzero/about/TeamSectionHeading.vue +0 -13
  60. package/src/vitepress/components/voidzero/blog/BlogArchive.vue +0 -223
  61. package/src/vitepress/components/voidzero/blog/BlogSingleContent.vue +0 -364
  62. package/src/vitepress/components/voidzero/blog/BlogSingleHero.vue +0 -113
  63. package/src/vitepress/components/voidzero/blog/BlogSingleRelated.vue +0 -92
  64. package/src/vitepress/components/voidzero/blog/FeaturedArticles.vue +0 -146
  65. package/src/vitepress/components/voidzero/blog/types.ts +0 -56
  66. package/src/vitepress/components/voidzero/home/CaseStudySlider.vue +0 -235
  67. package/src/vitepress/components/voidzero/home/CustomersSectionHeading.vue +0 -5
  68. package/src/vitepress/components/voidzero/home/GitHubStats.vue +0 -27
  69. package/src/vitepress/components/voidzero/home/Hero.vue +0 -69
  70. package/src/vitepress/components/voidzero/home/Investors.vue +0 -30
  71. package/src/vitepress/components/voidzero/home/NewsletterCTA.vue +0 -23
  72. package/src/vitepress/components/voidzero/home/OpenSourceSectionHeading.vue +0 -6
  73. package/src/vitepress/components/voidzero/home/OpenSourceSectionProjects.vue +0 -419
  74. package/src/vitepress/components/voidzero/home/Resources.vue +0 -144
  75. package/src/vitepress/components/voidzero/home/Statistics.vue +0 -507
  76. package/src/vitepress/components/voidzero/home/StatisticsSectionHeading.vue +0 -5
  77. package/src/vitepress/components/voidzero/home/TeamCTA.vue +0 -17
  78. package/src/vitepress/components/voidzero/home/TrustedBy.vue +0 -248
  79. package/src/vitepress/components/voidzero/home/VitePlusSectionFeatures.vue +0 -55
  80. package/src/vitepress/components/voidzero/home/VitePlusSectionHeading.vue +0 -17
  81. package/src/vitepress/fonts/KHTeka-Medium.woff2 +0 -0
  82. package/src/vitepress/fonts/KHTeka-Regular.woff2 +0 -0
  83. package/src/vitepress/index.ts +0 -269
  84. package/src/vitepress/layouts/OSSProjectLayout.vue +0 -28
  85. package/src/vitepress/styles/tokens.css +0 -137
  86. /package/src/{vitepress/assets → assets}/checkmark.svg +0 -0
  87. /package/src/{vitepress/assets → assets}/clients/airbnb.svg +0 -0
  88. /package/src/{vitepress/assets → assets}/clients/bolt.svg +0 -0
  89. /package/src/{vitepress/assets → assets}/clients/cloudflare.svg +0 -0
  90. /package/src/{vitepress/assets → assets}/clients/framer.svg +0 -0
  91. /package/src/{vitepress/assets → assets}/clients/hugging-face.svg +0 -0
  92. /package/src/{vitepress/assets → assets}/clients/linear.svg +0 -0
  93. /package/src/{vitepress/assets → assets}/clients/mercedes.svg +0 -0
  94. /package/src/{vitepress/assets → assets}/clients/openai.svg +0 -0
  95. /package/src/{vitepress/assets → assets}/clients/paramount.svg +0 -0
  96. /package/src/{vitepress/assets → assets}/clients/plaid.svg +0 -0
  97. /package/src/{vitepress/assets → assets}/clients/shopify.svg +0 -0
  98. /package/src/{vitepress/assets → assets}/cta-background.jpg +0 -0
  99. /package/src/{vitepress/assets → assets}/icons/oxc-dark.svg +0 -0
  100. /package/src/{vitepress/assets → assets}/icons/oxc-light.svg +0 -0
  101. /package/src/{vitepress/assets → assets}/icons/oxc-mono.svg +0 -0
  102. /package/src/{vitepress/assets → assets}/icons/rolldown-dark.svg +0 -0
  103. /package/src/{vitepress/assets → assets}/icons/rolldown-light.svg +0 -0
  104. /package/src/{vitepress/assets → assets}/icons/rolldown-mono.svg +0 -0
  105. /package/src/{vitepress/assets → assets}/icons/vite-dark.svg +0 -0
  106. /package/src/{vitepress/assets → assets}/icons/vite-light.svg +0 -0
  107. /package/src/{vitepress/assets → assets}/icons/vite-mono.svg +0 -0
  108. /package/src/{vitepress/assets → assets}/icons/viteplus-dark.svg +0 -0
  109. /package/src/{vitepress/assets → assets}/icons/viteplus-light.svg +0 -0
  110. /package/src/{vitepress/assets → assets}/icons/viteplus-mono.svg +0 -0
  111. /package/src/{vitepress/assets → assets}/icons/vitest-dark.svg +0 -0
  112. /package/src/{vitepress/assets → assets}/icons/vitest-light.svg +0 -0
  113. /package/src/{vitepress/assets → assets}/icons/vitest-mono.svg +0 -0
  114. /package/src/{vitepress/assets → assets}/logos/oxc-dark.svg +0 -0
  115. /package/src/{vitepress/assets → assets}/logos/oxc-light.svg +0 -0
  116. /package/src/{vitepress/assets → assets}/logos/rolldown-dark.svg +0 -0
  117. /package/src/{vitepress/assets → assets}/logos/rolldown-light.svg +0 -0
  118. /package/src/{vitepress/assets → assets}/logos/vite-dark.svg +0 -0
  119. /package/src/{vitepress/assets → assets}/logos/vite-light.svg +0 -0
  120. /package/src/{vitepress/assets → assets}/logos/viteplus-dark.svg +0 -0
  121. /package/src/{vitepress/assets → assets}/logos/viteplus-light.svg +0 -0
  122. /package/src/{vitepress/assets → assets}/logos/vitest-dark.svg +0 -0
  123. /package/src/{vitepress/assets → assets}/logos/vitest-light.svg +0 -0
  124. /package/src/{vitepress/assets → assets}/logos/voidzero-dark.svg +0 -0
  125. /package/src/{vitepress/assets → assets}/logos/voidzero-light.svg +0 -0
  126. /package/src/{vitepress/assets → assets}/oxc/animations/560_x_260_minifier.riv +0 -0
  127. /package/src/{vitepress/assets → assets}/oxc/animations/640_x_630_oxc masthead_.riv +0 -0
  128. /package/src/{vitepress/assets → assets}/oxc/footer-background.jpg +0 -0
  129. /package/src/{vitepress/assets → assets}/oxc/oxc-feature-background.jpg +0 -0
  130. /package/src/{vitepress/assets → assets}/oxc/oxc-formatter-terminal.png +0 -0
  131. /package/src/{vitepress/assets → assets}/oxc/oxc-linter-terminal.png +0 -0
  132. /package/src/{vitepress/assets → assets}/oxc/oxc-resolver-terminal.png +0 -0
  133. /package/src/{vitepress/assets → assets}/oxc/oxc-transformer-terminal.png +0 -0
  134. /package/src/{vitepress/assets → assets}/oxc/primary-button-background.jpg +0 -0
  135. /package/src/{vitepress/assets → assets}/primary-button-background.jpg +0 -0
  136. /package/src/{vitepress/assets → assets}/rolldown/animations/640_x_300_design_for_vite.riv +0 -0
  137. /package/src/{vitepress/assets → assets}/rolldown/animations/640_x_300_esbuild.riv +0 -0
  138. /package/src/{vitepress/assets → assets}/rolldown/animations/640_x_520_rolldown_masthead.riv +0 -0
  139. /package/src/{vitepress/assets → assets}/rolldown/footer-background.jpg +0 -0
  140. /package/src/{vitepress/assets → assets}/rolldown/hero-background.jpg +0 -0
  141. /package/src/{vitepress/assets → assets}/rolldown/hero-terminal.svg +0 -0
  142. /package/src/{vitepress/assets → assets}/rolldown/primary-button-background.jpg +0 -0
  143. /package/src/{vitepress/assets → assets}/rolldown/rolldown-esbuild-parity.png +0 -0
  144. /package/src/{vitepress/assets → assets}/rolldown/rolldown-rollup-background.jpg +0 -0
  145. /package/src/{vitepress/assets → assets}/rolldown/rolldown-rollup.png +0 -0
  146. /package/src/{vitepress/assets → assets}/rolldown/rolldown-thumbnail.png +0 -0
  147. /package/src/{vitepress/assets → assets}/social/bluesky-light.svg +0 -0
  148. /package/src/{vitepress/assets → assets}/social/bluesky.svg +0 -0
  149. /package/src/{vitepress/assets → assets}/social/discord-light.svg +0 -0
  150. /package/src/{vitepress/assets → assets}/social/discord.svg +0 -0
  151. /package/src/{vitepress/assets → assets}/social/github-light.svg +0 -0
  152. /package/src/{vitepress/assets → assets}/social/github.svg +0 -0
  153. /package/src/{vitepress/assets → assets}/social/twitter-light.svg +0 -0
  154. /package/src/{vitepress/assets → assets}/social/twitter.svg +0 -0
  155. /package/src/{vitepress/assets → assets}/terminal-background.jpg +0 -0
  156. /package/src/{vitepress/assets → assets}/vite/animations/563_x_420_rich_features.riv +0 -0
  157. /package/src/{vitepress/assets → assets}/vite/animations/640_x_300_flexible_plugin.riv +0 -0
  158. /package/src/{vitepress/assets → assets}/vite/animations/641_x_629_vite_masthead.riv +0 -0
  159. /package/src/{vitepress/assets → assets}/vite/footer-background.jpg +0 -0
  160. /package/src/{vitepress/assets → assets}/vite/primary-button-background.jpg +0 -0
  161. /package/src/{vitepress/assets → assets}/vite/vite-by-voidzero.png +0 -0
  162. /package/src/{vitepress/assets → assets}/vite/vite-ci.svg +0 -0
  163. /package/src/{vitepress/assets → assets}/vite/vite-featurepanel-1-background.jpg +0 -0
  164. /package/src/{vitepress/assets → assets}/vite/vite-featurepanel-1-terminal.svg +0 -0
  165. /package/src/{vitepress/assets → assets}/vite/vite-featurepanel-2-terminal.png +0 -0
  166. /package/src/{vitepress/assets → assets}/vite/vite-featurepanel-4-background.jpg +0 -0
  167. /package/src/{vitepress/assets → assets}/vite/vite-featurepanel-4-terminal.svg +0 -0
  168. /package/src/{vitepress/assets → assets}/vite/vite-frameworks-mobile.png +0 -0
  169. /package/src/{vitepress/assets → assets}/vite/vite-frameworks.png +0 -0
  170. /package/src/{vitepress/assets → assets}/vite/vite-ssr-support.png +0 -0
  171. /package/src/{vitepress/assets → assets}/vite/vite-typed-api.svg +0 -0
  172. /package/src/{vitepress/assets → assets}/viteplus/logo.svg +0 -0
  173. /package/src/{vitepress/assets → assets}/vitest/animations/640_x_300_esm.riv +0 -0
  174. /package/src/{vitepress/assets → assets}/vitest/animations/640_x_560_vitest_masthead.riv +0 -0
  175. /package/src/{vitepress/assets → assets}/vitest/animations/650_x_300_vite_powered.riv +0 -0
  176. /package/src/{vitepress/assets → assets}/vitest/footer-background.jpg +0 -0
  177. /package/src/{vitepress/assets → assets}/vitest/hero-background.jpg +0 -0
  178. /package/src/{vitepress/assets → assets}/vitest/hero-terminal.svg +0 -0
  179. /package/src/{vitepress/assets → assets}/vitest/primary-button-background.jpg +0 -0
  180. /package/src/{vitepress/assets → assets}/vitest/vitest-jest-compatible.png +0 -0
  181. /package/src/{vitepress/assets → assets}/vitest/vitest-watcher-background.jpg +0 -0
  182. /package/src/{vitepress/assets → assets}/vitest/vitest-watcher.png +0 -0
  183. /package/src/{vitepress/assets → assets}/voidzero/animations/1280_x_552_homepage.riv +0 -0
  184. /package/src/{vitepress/assets → assets}/voidzero/animations/343_x_148_homepage_mobile.riv +0 -0
  185. /package/src/{vitepress/assets → assets}/voidzero/animations/480_x_480_build_tool_for_web.riv +0 -0
  186. /package/src/{vitepress/assets → assets}/voidzero/animations/480_x_480_fastest_javascript_bundler.riv +0 -0
  187. /package/src/{vitepress/assets → assets}/voidzero/animations/480_x_480_language_toolchain.riv +0 -0
  188. /package/src/{vitepress/assets → assets}/voidzero/animations/480_x_480_next_generation_runner.riv +0 -0
  189. /package/src/{vitepress/assets → assets}/voidzero/animations/about-mobile.riv +0 -0
  190. /package/src/{vitepress/assets → assets}/voidzero/animations/about.riv +0 -0
  191. /package/src/{vitepress/assets → assets}/voidzero/backgrounds/casestudies.jpg +0 -0
  192. /package/src/{vitepress/assets → assets}/voidzero/backgrounds/oxc.jpg +0 -0
  193. /package/src/{vitepress/assets → assets}/voidzero/backgrounds/rolldown.jpg +0 -0
  194. /package/src/{vitepress/assets → assets}/voidzero/backgrounds/vite.jpg +0 -0
  195. /package/src/{vitepress/assets → assets}/voidzero/backgrounds/vitest.jpg +0 -0
  196. /package/src/{vitepress/assets → assets}/voidzero/career-illustration.jpg +0 -0
  197. /package/src/{vitepress/assets → assets}/voidzero/footer-logo.svg +0 -0
  198. /package/src/{vitepress/assets → assets}/voidzero/footer.jpg +0 -0
  199. /package/src/{vitepress/assets → assets}/voidzero/investors/accel.svg +0 -0
  200. /package/src/{vitepress/assets → assets}/voidzero/investors/amplify.svg +0 -0
  201. /package/src/{vitepress/assets → assets}/voidzero/investors/peakxv.png +0 -0
  202. /package/src/{vitepress/assets → assets}/voidzero/investors/resend.svg +0 -0
  203. /package/src/{vitepress/assets → assets}/voidzero/investors/sentry.svg +0 -0
  204. /package/src/{vitepress/assets → assets}/voidzero/investors/sunflower.png +0 -0
  205. /package/src/{vitepress/assets → assets}/voidzero/logo-light.svg +0 -0
  206. /package/src/{vitepress/assets → assets}/voidzero/logo.svg +0 -0
  207. /package/src/{vitepress/assets → assets}/voidzero/signature.svg +0 -0
  208. /package/src/{vitepress/assets → assets}/voidzero/terminals/rolldown.svg +0 -0
  209. /package/src/{vitepress/assets → assets}/voidzero/terminals/vite.svg +0 -0
  210. /package/src/{vitepress/assets → assets}/voidzero/terminals/vitest.svg +0 -0
  211. /package/src/{vitepress/assets → assets}/voidzero/vite-plus-chip.png +0 -0
  212. /package/src/{vitepress/components → components}/oss/CTAShaderBackground.vue +0 -0
  213. /package/src/{vitepress/components → components}/oss/HeadingSection.vue +0 -0
  214. /package/src/{vitepress/components → components}/oxc/FeatureLinter.vue +0 -0
  215. /package/src/{vitepress/components → components}/oxc/FeatureMinifierFormatter.vue +0 -0
  216. /package/src/{vitepress/components → components}/oxc/FeatureParser.vue +0 -0
  217. /package/src/{vitepress/components → components}/oxc/FeatureResolver.vue +0 -0
  218. /package/src/{vitepress/components → components}/oxc/FeatureToolbar.vue +0 -0
  219. /package/src/{vitepress/components → components}/oxc/FeatureTransformer.vue +0 -0
  220. /package/src/{vitepress/components → components}/oxc/Hero.vue +0 -0
  221. /package/src/{vitepress/components → components}/rolldown/FeatureGrid.vue +0 -0
  222. /package/src/{vitepress/components → components}/rolldown/Hero.vue +0 -0
  223. /package/src/{vitepress/components → components}/shared/CodeGroup.vue +0 -0
  224. /package/src/{vitepress/components → components}/shared/Eyebrow.vue +0 -0
  225. /package/src/{vitepress/components → components}/shared/LogoGrid.vue +0 -0
  226. /package/src/{vitepress/components → components}/shared/NewsletterForm.vue +0 -0
  227. /package/src/{vitepress/components → components}/shared/PerformanceBar.vue +0 -0
  228. /package/src/{vitepress/components → components}/shared/RiveAnimation.vue +0 -0
  229. /package/src/{vitepress/components → components}/shared/ShaderBackground.vue +0 -0
  230. /package/src/{vitepress/components → components}/shared/Spacer.vue +0 -0
  231. /package/src/{vitepress/components → components}/shared/Terminal.vue +0 -0
  232. /package/src/{vitepress/components → components}/shared/icons/VZIconBluesky.vue +0 -0
  233. /package/src/{vitepress/components → components}/shared/icons/VZIconGitHub.vue +0 -0
  234. /package/src/{vitepress/components → components}/shared/icons/VZIconLogo.vue +0 -0
  235. /package/src/{vitepress/components → components}/shared/icons/VZIconTwitter.vue +0 -0
  236. /package/src/{vitepress/components → components}/shared/terminal-animations/TerminalAnimation1.vue +0 -0
  237. /package/src/{vitepress/components → components}/shared/terminal-animations/TerminalAnimation2.vue +0 -0
  238. /package/src/{vitepress/components → components}/shared/terminal-animations/TerminalAnimation3.vue +0 -0
  239. /package/src/{vitepress/components → components}/shared/terminal-animations/TerminalAnimation4.vue +0 -0
  240. /package/src/{vitepress/components → components}/shared/terminal-animations/TerminalAnimation5.vue +0 -0
  241. /package/src/{vitepress/components → components}/shared/terminal-animations/TerminalAnimation6.vue +0 -0
  242. /package/src/{vitepress/components → components}/vite/Frameworks.vue +0 -0
  243. /package/src/{vitepress/components → components}/viteplus/Header.vue +0 -0
  244. /package/src/{vitepress/components → components}/vitepress-default/Layout.vue +0 -0
  245. /package/src/{vitepress/components → components}/vitepress-default/NotFound.vue +0 -0
  246. /package/src/{vitepress/components → components}/vitepress-default/VPAlgoliaSearchBox.vue +0 -0
  247. /package/src/{vitepress/components → components}/vitepress-default/VPBackdrop.vue +0 -0
  248. /package/src/{vitepress/components → components}/vitepress-default/VPBadge.vue +0 -0
  249. /package/src/{vitepress/components → components}/vitepress-default/VPButton.vue +0 -0
  250. /package/src/{vitepress/components → components}/vitepress-default/VPCarbonAds.vue +0 -0
  251. /package/src/{vitepress/components → components}/vitepress-default/VPContent.vue +0 -0
  252. /package/src/{vitepress/components → components}/vitepress-default/VPDoc.vue +0 -0
  253. /package/src/{vitepress/components → components}/vitepress-default/VPDocAside.vue +0 -0
  254. /package/src/{vitepress/components → components}/vitepress-default/VPDocAsideCarbonAds.vue +0 -0
  255. /package/src/{vitepress/components → components}/vitepress-default/VPDocAsideOutline.vue +0 -0
  256. /package/src/{vitepress/components → components}/vitepress-default/VPDocAsideSponsors.vue +0 -0
  257. /package/src/{vitepress/components → components}/vitepress-default/VPDocFooter.vue +0 -0
  258. /package/src/{vitepress/components → components}/vitepress-default/VPDocFooterLastUpdated.vue +0 -0
  259. /package/src/{vitepress/components → components}/vitepress-default/VPFeature.vue +0 -0
  260. /package/src/{vitepress/components → components}/vitepress-default/VPFeatures.vue +0 -0
  261. /package/src/{vitepress/components → components}/vitepress-default/VPFooter.vue +0 -0
  262. /package/src/{vitepress/components → components}/vitepress-default/VPHero.vue +0 -0
  263. /package/src/{vitepress/components → components}/vitepress-default/VPHome.vue +0 -0
  264. /package/src/{vitepress/components → components}/vitepress-default/VPHomeContent.vue +0 -0
  265. /package/src/{vitepress/components → components}/vitepress-default/VPHomeFeatures.vue +0 -0
  266. /package/src/{vitepress/components → components}/vitepress-default/VPHomeHero.vue +0 -0
  267. /package/src/{vitepress/components → components}/vitepress-default/VPHomeSponsors.vue +0 -0
  268. /package/src/{vitepress/components → components}/vitepress-default/VPImage.vue +0 -0
  269. /package/src/{vitepress/components → components}/vitepress-default/VPLink.vue +0 -0
  270. /package/src/{vitepress/components → components}/vitepress-default/VPLocalNav.vue +0 -0
  271. /package/src/{vitepress/components → components}/vitepress-default/VPLocalNavOutlineDropdown.vue +0 -0
  272. /package/src/{vitepress/components → components}/vitepress-default/VPLocalSearchBox.vue +0 -0
  273. /package/src/{vitepress/components → components}/vitepress-default/VPMenu.vue +0 -0
  274. /package/src/{vitepress/components → components}/vitepress-default/VPMenuGroup.vue +0 -0
  275. /package/src/{vitepress/components → components}/vitepress-default/VPNav.vue +0 -0
  276. /package/src/{vitepress/components → components}/vitepress-default/VPNavBar.vue +0 -0
  277. /package/src/{vitepress/components → components}/vitepress-default/VPNavBarAppearance.vue +0 -0
  278. /package/src/{vitepress/components → components}/vitepress-default/VPNavBarExtra.vue +0 -0
  279. /package/src/{vitepress/components → components}/vitepress-default/VPNavBarHamburger.vue +0 -0
  280. /package/src/{vitepress/components → components}/vitepress-default/VPNavBarMenu.vue +0 -0
  281. /package/src/{vitepress/components → components}/vitepress-default/VPNavBarMenuGroup.vue +0 -0
  282. /package/src/{vitepress/components → components}/vitepress-default/VPNavBarSearch.vue +0 -0
  283. /package/src/{vitepress/components → components}/vitepress-default/VPNavBarSearchButton.vue +0 -0
  284. /package/src/{vitepress/components → components}/vitepress-default/VPNavBarSocialLinks.vue +0 -0
  285. /package/src/{vitepress/components → components}/vitepress-default/VPNavBarTitle.vue +0 -0
  286. /package/src/{vitepress/components → components}/vitepress-default/VPNavBarTranslations.vue +0 -0
  287. /package/src/{vitepress/components → components}/vitepress-default/VPNavScreen.vue +0 -0
  288. /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenAppearance.vue +0 -0
  289. /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenMenu.vue +0 -0
  290. /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenMenuGroup.vue +0 -0
  291. /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenMenuGroupLink.vue +0 -0
  292. /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenMenuGroupSection.vue +0 -0
  293. /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenMenuLink.vue +0 -0
  294. /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenSocialLinks.vue +0 -0
  295. /package/src/{vitepress/components → components}/vitepress-default/VPNavScreenTranslations.vue +0 -0
  296. /package/src/{vitepress/components → components}/vitepress-default/VPPage.vue +0 -0
  297. /package/src/{vitepress/components → components}/vitepress-default/VPSearchError.vue +0 -0
  298. /package/src/{vitepress/components → components}/vitepress-default/VPSidebar.vue +0 -0
  299. /package/src/{vitepress/components → components}/vitepress-default/VPSidebarGroup.vue +0 -0
  300. /package/src/{vitepress/components → components}/vitepress-default/VPSkipLink.vue +0 -0
  301. /package/src/{vitepress/components → components}/vitepress-default/VPSocialLinks.vue +0 -0
  302. /package/src/{vitepress/components → components}/vitepress-default/VPSponsors.vue +0 -0
  303. /package/src/{vitepress/components → components}/vitepress-default/VPSponsorsGrid.vue +0 -0
  304. /package/src/{vitepress/components → components}/vitepress-default/VPSwitch.vue +0 -0
  305. /package/src/{vitepress/components → components}/vitepress-default/VPSwitchAppearance.vue +0 -0
  306. /package/src/{vitepress/components → components}/vitepress-default/VPTeamMembers.vue +0 -0
  307. /package/src/{vitepress/components → components}/vitepress-default/VPTeamMembersItem.vue +0 -0
  308. /package/src/{vitepress/components → components}/vitepress-default/VPTeamPage.vue +0 -0
  309. /package/src/{vitepress/components → components}/vitepress-default/VPTeamPageSection.vue +0 -0
  310. /package/src/{vitepress/components → components}/vitepress-default/VPTeamPageTitle.vue +0 -0
  311. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconAlignJustify.vue +0 -0
  312. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconAlignLeft.vue +0 -0
  313. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconAlignRight.vue +0 -0
  314. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconArrowLeft.vue +0 -0
  315. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconArrowRight.vue +0 -0
  316. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconChevronDown.vue +0 -0
  317. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconChevronLeft.vue +0 -0
  318. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconChevronRight.vue +0 -0
  319. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconChevronUp.vue +0 -0
  320. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconEdit.vue +0 -0
  321. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconHeart.vue +0 -0
  322. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconLanguages.vue +0 -0
  323. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconMinus.vue +0 -0
  324. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconMinusSquare.vue +0 -0
  325. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconMoon.vue +0 -0
  326. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconMoreHorizontal.vue +0 -0
  327. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconPlus.vue +0 -0
  328. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconPlusSquare.vue +0 -0
  329. /package/src/{vitepress/components → components}/vitepress-default/icons/VPIconSun.vue +0 -0
  330. /package/src/{vitepress/components → components}/vitest/FeatureGrid.vue +0 -0
  331. /package/src/{vitepress/components → components}/vitest/Hero.vue +0 -0
  332. /package/src/{vitepress/components → components}/vitest/Intro.vue +0 -0
  333. /package/src/{vitepress/composables → composables}/vitepress-default/aside.ts +0 -0
  334. /package/src/{vitepress/composables → composables}/vitepress-default/data.ts +0 -0
  335. /package/src/{vitepress/composables → composables}/vitepress-default/edit-link.ts +0 -0
  336. /package/src/{vitepress/composables → composables}/vitepress-default/flyout.ts +0 -0
  337. /package/src/{vitepress/composables → composables}/vitepress-default/langs.ts +0 -0
  338. /package/src/{vitepress/composables → composables}/vitepress-default/layout.ts +0 -0
  339. /package/src/{vitepress/composables → composables}/vitepress-default/nav.ts +0 -0
  340. /package/src/{vitepress/composables → composables}/vitepress-default/outline.ts +0 -0
  341. /package/src/{vitepress/composables → composables}/vitepress-default/prev-next.ts +0 -0
  342. /package/src/{vitepress/composables → composables}/vitepress-default/sidebar.ts +0 -0
  343. /package/src/{vitepress/composables → composables}/vitepress-default/sponsor-grid.ts +0 -0
  344. /package/src/{vitepress/env.d.ts → env.d.ts} +0 -0
  345. /package/src/{vitepress/fonts → fonts}/APK-Protocol-Medium.woff2 +0 -0
  346. /package/src/{vitepress/fonts → fonts}/KHTekaMono-Medium.woff2 +0 -0
  347. /package/src/{vitepress/fonts → fonts}/KHTekaMono-Regular.woff2 +0 -0
  348. /package/src/{vitepress/styles → styles}/base.css +0 -0
  349. /package/src/{vitepress/styles → styles}/docs.css +0 -0
  350. /package/src/{vitepress/styles → styles}/index.css +0 -0
  351. /package/src/{vitepress/styles → styles}/marketing.css +0 -0
  352. /package/src/{vitepress/styles → styles}/vitepress-default/base-scoped.css +0 -0
  353. /package/src/{vitepress/styles → styles}/vitepress-default/base.css +0 -0
  354. /package/src/{vitepress/styles → styles}/vitepress-default/components/custom-block.css +0 -0
  355. /package/src/{vitepress/styles → styles}/vitepress-default/components/vp-code-group.css +0 -0
  356. /package/src/{vitepress/styles → styles}/vitepress-default/components/vp-code.css +0 -0
  357. /package/src/{vitepress/styles → styles}/vitepress-default/components/vp-doc.css +0 -0
  358. /package/src/{vitepress/styles → styles}/vitepress-default/components/vp-sponsor.css +0 -0
  359. /package/src/{vitepress/styles → styles}/vitepress-default/fonts.css +0 -0
  360. /package/src/{vitepress/styles → styles}/vitepress-default/icons.css +0 -0
  361. /package/src/{vitepress/styles → styles}/vitepress-default/index-scoped.css +0 -0
  362. /package/src/{vitepress/styles → styles}/vitepress-default/index.css +0 -0
  363. /package/src/{vitepress/styles → styles}/vitepress-default/utils.css +0 -0
  364. /package/src/{vitepress/support → support}/vitepress-default/app-utils.ts +0 -0
  365. /package/src/{vitepress/support → support}/vitepress-default/docsearch-loader.ts +0 -0
  366. /package/src/{vitepress/support → support}/vitepress-default/lru.ts +0 -0
  367. /package/src/{vitepress/support → support}/vitepress-default/search-config.ts +0 -0
  368. /package/src/{vitepress/support → support}/vitepress-default/shared-utils.ts +0 -0
  369. /package/src/{vitepress/support → support}/vitepress-default/sidebar.ts +0 -0
  370. /package/src/{vitepress/support → support}/vitepress-default/translation.ts +0 -0
  371. /package/src/{vitepress/support → support}/vitepress-default/utils.ts +0 -0
  372. /package/src/{vitepress/types → types}/docsearch.d.ts +0 -0
  373. /package/src/{vitepress/types → types}/local-search.d.ts +0 -0
@@ -1,364 +0,0 @@
1
- <script setup lang="ts">
2
- import {ref, onMounted, onUnmounted, nextTick, computed} from 'vue'
3
- import {Content, onContentUpdated} from 'vitepress'
4
-
5
- interface OutlineItem {
6
- title: string
7
- link: string
8
- level: number
9
- children?: OutlineItem[]
10
- }
11
-
12
- const headers = ref<OutlineItem[]>([])
13
- const activeId = ref<string | null>(null)
14
- const activeIndex = ref<number>(0)
15
- const contentRef = ref<HTMLElement | null>(null)
16
- const markerRef = ref<HTMLElement | null>(null)
17
- const navRef = ref<HTMLElement | null>(null)
18
-
19
- function getHeaders() {
20
- // Query headers from within the blog content
21
- const headings = document.querySelectorAll('.blog-content h1, .blog-content h2, .blog-content h3, .blog-content h4')
22
-
23
- const items: OutlineItem[] = []
24
- headings.forEach((el) => {
25
- if (el.id && el.textContent) {
26
- items.push({
27
- title: el.textContent.replace(/^#\s*/, '').trim(),
28
- link: `#${el.id}`,
29
- level: parseInt(el.tagName[1])
30
- })
31
- }
32
- })
33
-
34
- return items
35
- }
36
-
37
- function updateActiveHeader() {
38
- const headings = document.querySelectorAll('.blog-content h1, .blog-content h2, .blog-content h3, .blog-content h4')
39
- if (headings.length === 0) return
40
-
41
- const viewportCenter = window.innerHeight / 2
42
- let closestHeading: Element | null = null
43
- let closestDistance = Infinity
44
- let closestIndex = 0
45
-
46
- headings.forEach((heading, index) => {
47
- if (heading.id) {
48
- const rect = heading.getBoundingClientRect()
49
- const headingCenter = rect.top + rect.height / 2
50
- const distance = Math.abs(headingCenter - viewportCenter)
51
-
52
- // Prefer headings that are above or at the center
53
- const adjustedDistance = rect.top <= viewportCenter ? distance : distance + 1000
54
-
55
- if (adjustedDistance < closestDistance) {
56
- closestDistance = adjustedDistance
57
- closestHeading = heading
58
- closestIndex = index
59
- }
60
- }
61
- })
62
-
63
- if (closestHeading) {
64
- activeId.value = closestHeading.id
65
- activeIndex.value = closestIndex
66
- updateMarkerPosition()
67
- }
68
- }
69
-
70
- function scrollToHeader(link: string) {
71
- const id = link.slice(1)
72
- const element = document.getElementById(id)
73
- if (element) {
74
- const top = element.getBoundingClientRect().top + window.scrollY - (window.innerHeight / 2)
75
- window.scrollTo({ top, behavior: 'smooth' })
76
- }
77
- }
78
-
79
- function updateMarkerPosition() {
80
- if (!navRef.value || !markerRef.value) return
81
-
82
- const activeLink = navRef.value.querySelector('.outline-link.active') as HTMLElement
83
- if (activeLink) {
84
- const navRect = navRef.value.getBoundingClientRect()
85
- const linkRect = activeLink.getBoundingClientRect()
86
- const reducedHeight = linkRect.height * 0.6
87
- const topOffset = (linkRect.height - reducedHeight) / 2
88
- markerRef.value.style.top = `${linkRect.top - navRect.top + topOffset}px`
89
- markerRef.value.style.height = `${reducedHeight}px`
90
- markerRef.value.style.opacity = '1'
91
- } else {
92
- markerRef.value.style.opacity = '0'
93
- }
94
- }
95
-
96
- onContentUpdated(() => {
97
- nextTick(() => {
98
- headers.value = getHeaders()
99
- // Set first header as active initially
100
- if (headers.value.length > 0 && !activeId.value) {
101
- activeId.value = headers.value[0].link.slice(1)
102
- activeIndex.value = 0
103
- }
104
- nextTick(updateMarkerPosition)
105
- })
106
- })
107
-
108
- onMounted(() => {
109
- nextTick(() => {
110
- headers.value = getHeaders()
111
- // Set first header as active initially
112
- if (headers.value.length > 0) {
113
- activeId.value = headers.value[0].link.slice(1)
114
- activeIndex.value = 0
115
- }
116
- nextTick(updateMarkerPosition)
117
- })
118
- window.addEventListener('scroll', updateActiveHeader, {passive: true})
119
- })
120
-
121
- onUnmounted(() => {
122
- window.removeEventListener('scroll', updateActiveHeader)
123
- })
124
- </script>
125
-
126
- <template>
127
- <section class="wrapper wrapper--ticks border-t">
128
- <div class="flex flex-col lg:flex-row">
129
- <!-- Left: Table of Contents -->
130
- <div class="hidden lg:block px-6 lg:pl-10 lg:pr-10 py-20 w-full max-w-md flex-shrink-0">
131
- <div class="sticky top-24">
132
- <nav v-if="headers.length > 0" ref="navRef" class="outline-nav">
133
- <div ref="markerRef" class="outline-marker"></div>
134
- <ul class="outline-list">
135
- <li v-for="header in headers" :key="header.link">
136
- <a
137
- href="javascript:void(0)"
138
- class="outline-link"
139
- :class="{
140
- active: activeId === header.link.slice(1),
141
- 'pl-4': header.level === 3,
142
- 'pl-8': header.level === 4
143
- }"
144
- @click="scrollToHeader(header.link)"
145
- >
146
- {{ header.title }}
147
- </a>
148
- </li>
149
- </ul>
150
- </nav>
151
- </div>
152
- </div>
153
-
154
- <!-- Right: Blog Content (matches image width from hero) -->
155
- <div ref="contentRef" class="blog-content relative w-full lg:w-120 xl:w-200 shrink-0 px-6 lg:px-0 lg:pr-30 py-10 lg:py-16" data-theme="light">
156
- <div class="prose prose-lg vp-doc max-w-none lg:-ml-10 lg:-mr-20 lg:pr-10 prose-headings:text-primary prose-headings:font-medium prose-p:text-nickel prose-strong:text-nickel prose-li:text-nickel prose-li:marker:text-ruby prose-th:text-primary prose-td:text-primary">
157
- <Content />
158
- </div>
159
- </div>
160
- </div>
161
- </section>
162
- </template>
163
-
164
- <style scoped>
165
- /* Outline styles */
166
- .outline-nav {
167
- position: relative;
168
- }
169
-
170
- .outline-marker {
171
- position: absolute;
172
- left: -2.5rem;
173
- width: 1px;
174
- background-color: var(--color-primary);
175
- opacity: 0;
176
- transition: top 0.2s ease, height 0.2s ease, opacity 0.2s ease;
177
- }
178
-
179
- .outline-list {
180
- list-style: none;
181
- padding: 0;
182
- margin: 0;
183
- }
184
-
185
- .outline-link {
186
- display: block;
187
- padding: 0.375rem 0;
188
- font-size: 1rem;
189
- font-weight: 400;
190
- color: var(--color-grey);
191
- transition: color 0.2s;
192
- font-family: var(--font-sans);
193
- letter-spacing: -0.02em;
194
- white-space: nowrap;
195
- overflow: hidden;
196
- text-overflow: ellipsis;
197
- max-width: calc(100% - 5rem);
198
- }
199
-
200
- .outline-link:hover {
201
- color: var(--color-primary);
202
- }
203
-
204
- .outline-link.active {
205
- color: var(--color-primary);
206
- font-weight: 500;
207
- }
208
-
209
- /* Content border - offset to the left */
210
- @media (min-width: 1024px) {
211
- .blog-content::before {
212
- content: '';
213
- position: absolute;
214
- left: -7.5rem;
215
- top: 0;
216
- bottom: 0;
217
- width: 1px;
218
- background-color: var(--color-stroke);
219
- }
220
-
221
- /* Images stretch to the border edges */
222
- .blog-content :deep(img) {
223
- margin-left: -5rem;
224
- margin-right: -5rem;
225
- max-width: calc(100% + 10rem);
226
- width: calc(100% + 10rem);
227
- }
228
-
229
- /* Dividers stretch to the border edges */
230
- .blog-content :deep(hr) {
231
- margin-left: -5rem;
232
- margin-right: -5rem;
233
- max-width: calc(100% + 10rem);
234
- width: calc(100% + 10rem);
235
- border-color: var(--color-stroke);
236
- }
237
-
238
- /* Blockquotes - stretch to edges with top/bottom borders */
239
- .blog-content :deep(blockquote) {
240
- margin-left: -5rem;
241
- margin-right: -5rem;
242
- padding: 5rem 5rem;
243
- max-width: calc(100% + 10rem);
244
- width: calc(100% + 10rem);
245
- border-left: none;
246
- border-top: 1px solid var(--color-stroke);
247
- border-bottom: 1px solid var(--color-stroke);
248
- font-style: normal;
249
- quotes: none;
250
- position: relative;
251
- }
252
-
253
- .blog-content :deep(blockquote)::before {
254
- content: '/\A**\A*\A*\A*\A*\A*/';
255
- white-space: pre;
256
- position: absolute;
257
- left: 2rem;
258
- top: 50%;
259
- transform: translateY(-50%);
260
- font-family: var(--font-mono);
261
- font-size: 1.25rem;
262
- line-height: 1.4;
263
- color: var(--color-stroke);
264
- opacity: 0.5;
265
- }
266
-
267
- .blog-content :deep(blockquote p) {
268
- font-size: 1.5rem;
269
- line-height: 1.5;
270
- color: var(--color-primary);
271
- font-weight: 400;
272
- }
273
- }
274
-
275
- /* Prose styles - base variables for colors */
276
- .prose {
277
- --tw-prose-body: var(--vp-c-text-1);
278
- --tw-prose-bold: var(--vp-c-text-1);
279
- --tw-prose-counters: var(--vp-c-text-2);
280
- --tw-prose-bullets: var(--vp-c-text-2);
281
- --tw-prose-hr: var(--vp-c-divider);
282
- --tw-prose-quotes: var(--vp-c-text-2);
283
- --tw-prose-quote-borders: var(--vp-c-divider);
284
- --tw-prose-captions: var(--vp-c-text-2);
285
- --tw-prose-th-borders: var(--vp-c-divider);
286
- --tw-prose-td-borders: var(--vp-c-divider);
287
- }
288
-
289
- /* Reset prose styles for code blocks and code groups - let VitePress handle them */
290
- /* Inline code (e.g., `backticks`) keeps prose styling */
291
- .prose :deep(div[class*='language-']),
292
- .prose :deep(.vp-code-group) {
293
- margin: 16px -1.5rem;
294
- padding: 0;
295
- border-radius: 0;
296
- color: inherit;
297
- font-size: inherit;
298
- }
299
-
300
- /* Code blocks inside code groups - reset their negative margins since parent is already full-bleed */
301
- .prose :deep(.vp-code-group div[class*='language-']) {
302
- margin-left: 0 !important;
303
- margin-right: 0 !important;
304
- }
305
-
306
- /* Add internal padding for full-bleed code blocks on mobile */
307
- .prose :deep(div[class*='language-'] code),
308
- .prose :deep(.vp-code-group div[class*='language-'] code) {
309
- padding-left: 1.5rem !important;
310
- padding-right: 1.5rem !important;
311
- }
312
-
313
- .prose :deep(.vp-code-group .tabs) {
314
- padding-left: 1.5rem;
315
- padding-right: 1.5rem;
316
- margin-left: 0;
317
- margin-right: 0;
318
- }
319
-
320
- @media (min-width: 1024px) {
321
- .prose :deep(div[class*='language-']),
322
- .prose :deep(.vp-code-group) {
323
- margin: 16px 0;
324
- border-radius: 8px;
325
- }
326
-
327
- .prose :deep(div[class*='language-'] code),
328
- .prose :deep(.vp-code-group div[class*='language-'] code) {
329
- padding-left: 24px !important;
330
- padding-right: 24px !important;
331
- }
332
-
333
- .prose :deep(.vp-code-group .tabs) {
334
- padding-left: 12px;
335
- padding-right: 12px;
336
- }
337
- }
338
-
339
- .prose pre {
340
- margin: 0;
341
- padding: 0;
342
- border-radius: 0;
343
- overflow: visible;
344
- color: inherit;
345
- font-size: inherit;
346
- line-height: inherit;
347
- }
348
-
349
- .prose pre code {
350
- padding: 0;
351
- border-radius: 0;
352
- color: inherit;
353
- font-size: inherit;
354
- font-weight: inherit;
355
- line-height: inherit;
356
- border: none;
357
- }
358
-
359
- /* Remove Tailwind Typography backticks around inline code */
360
- .prose :deep(code)::before,
361
- .prose :deep(code)::after {
362
- content: none;
363
- }
364
- </style>
@@ -1,113 +0,0 @@
1
- <script setup lang="ts">
2
- import {computed} from 'vue'
3
- import {useData, withBase} from 'vitepress'
4
- import {type Author, getAuthorImage, formatDateShort} from './types'
5
-
6
- const {frontmatter} = useData()
7
-
8
- const coverUrl = computed(() => {
9
- if (!frontmatter.value.cover) return null
10
- const cover = frontmatter.value.cover
11
- // Ensure path is absolute from root
12
- const path = cover.startsWith('/') ? cover : `/${cover}`
13
- return withBase(path)
14
- })
15
-
16
- const pageUrl = computed(() => {
17
- if (typeof window !== 'undefined') {
18
- return window.location.href
19
- }
20
- return ''
21
- })
22
-
23
- function copyLink() {
24
- if (typeof navigator !== 'undefined') {
25
- navigator.clipboard.writeText(window.location.href)
26
- }
27
- }
28
- </script>
29
-
30
- <template>
31
- <section class="wrapper wrapper--ticks border-t">
32
- <!-- Main hero: two columns -->
33
- <div class="flex flex-col lg:flex-row py-10 pt-20 pb-16">
34
- <!-- Left: Content -->
35
- <div class="flex flex-col justify-between px-6 lg:pl-10 lg:pr-20 flex-1 min-w-0">
36
- <div class="flex flex-col gap-4">
37
- <span class="text-grey text-xs font-medium font-mono uppercase tracking-wide">// {{
38
- frontmatter.category
39
- }}</span>
40
- <h1 class="text-3xl md:text-4xl xl:text-5xl text-pretty text-primary font-normal leading-tight">
41
- {{ frontmatter.title }}
42
- </h1>
43
- </div>
44
- <span class="text-grey text-xs font-medium font-mono uppercase tracking-wide mt-8">{{
45
- formatDateShort(frontmatter.date)
46
- }}</span>
47
- </div>
48
-
49
- <!-- Right: Cover image -->
50
- <div class="w-full lg:w-[30rem] xl:w-[50rem] flex-shrink-0 bg-nickel overflow-hidden lg:mr-10 mt-8 lg:mt-0">
51
- <img
52
- v-if="coverUrl"
53
- :src="coverUrl"
54
- :alt="frontmatter.title"
55
- class="w-full h-full object-cover"
56
- />
57
- </div>
58
- </div>
59
-
60
- <!-- Author bar -->
61
- <div class="border-t border-stroke">
62
- <div class="flex flex-col lg:flex-row py-5">
63
- <!-- Left: Author -->
64
- <div class="flex items-center gap-4 px-6 lg:pl-10 lg:pr-20 flex-1 min-w-0">
65
- <img
66
- v-if="frontmatter.authors?.[0] && getAuthorImage(frontmatter.authors[0] as Author)"
67
- :src="getAuthorImage(frontmatter.authors[0] as Author)!"
68
- :alt="frontmatter.authors[0].name"
69
- class="w-10 h-10 rounded object-cover"
70
- />
71
- <div v-else class="w-10 h-10 rounded bg-grey/20"></div>
72
- <span class="text-sm text-primary font-mono">{{
73
- frontmatter.authors?.[0]?.name || 'Unknown'
74
- }}</span>
75
- </div>
76
-
77
- <!-- Right: Read time + Share (matches image width) -->
78
- <div class="w-full lg:w-[30rem] xl:w-[50rem] flex-shrink-0 lg:mr-10 px-6 lg:px-0 mt-4 lg:mt-0 flex items-center justify-between">
79
- <!-- Read time -->
80
- <div class="flex items-center gap-2 text-grey">
81
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
82
- <circle cx="12" cy="12" r="10" stroke-width="1.5"/>
83
- <path stroke-width="1.5" stroke-linecap="round" d="M12 6v6l4 2"/>
84
- </svg>
85
- <span class="text-xs font-medium font-mono uppercase tracking-wide">{{ frontmatter.readTime || '5 MIN READ' }}</span>
86
- </div>
87
-
88
- <!-- Share -->
89
- <div class="flex items-center gap-4">
90
- <span class="hidden lg:inline text-grey text-xs font-medium font-mono uppercase tracking-wide">Share</span>
91
- <div class="flex items-center gap-3">
92
- <a :href="`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(pageUrl)}`" target="_blank" rel="noopener" class="text-grey hover:text-primary transition-colors">
93
- <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>
94
- </a>
95
- <a :href="`https://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(pageUrl)}`" target="_blank" rel="noopener" class="text-grey hover:text-primary transition-colors">
96
- <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>
97
- </a>
98
- <a :href="`https://x.com/intent/tweet?url=${encodeURIComponent(pageUrl)}`" target="_blank" rel="noopener" class="text-grey hover:text-primary transition-colors">
99
- <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>
100
- </a>
101
- <button @click="copyLink" class="text-grey hover:text-primary transition-colors">
102
- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/></svg>
103
- </button>
104
- </div>
105
- </div>
106
- </div>
107
- </div>
108
- </div>
109
- </section>
110
- </template>
111
-
112
- <style scoped>
113
- </style>
@@ -1,92 +0,0 @@
1
- <script setup lang="ts">
2
- import {computed} from 'vue'
3
- import {useData} from 'vitepress'
4
- import {type Post, formatDateShort} from './types'
5
- import NewsletterForm from '@components/shared/NewsletterForm.vue'
6
-
7
- interface Props {
8
- articles: Post[]
9
- newsletterEndpoint?: string
10
- newsletterFormId?: string
11
- }
12
-
13
- const props = defineProps<Props>()
14
- const {frontmatter, page} = useData()
15
-
16
- // Get up to 2 related posts (same category, excluding current, most recent first)
17
- const relatedPosts = computed(() => {
18
- const currentCategory = frontmatter.value.category
19
- const currentUrl = page.value.relativePath.replace(/\.md$/, '')
20
-
21
- return props.articles
22
- .filter(post => {
23
- // Same category, not current post
24
- const postPath = post.url.replace(/^\//, '').replace(/\/$/, '')
25
- const currentPath = currentUrl.replace(/^\//, '').replace(/\/$/, '')
26
- return post.category === currentCategory && postPath !== currentPath
27
- })
28
- .sort((a, b) => b.date.time - a.date.time)
29
- .slice(0, 2)
30
- })
31
- </script>
32
-
33
- <template>
34
- <section v-if="relatedPosts.length > 0" class="wrapper wrapper--ticks border-t">
35
- <div class="flex flex-col lg:flex-row">
36
- <!-- Left: Newsletter Signup -->
37
- <div class="bg-beige px-6 lg:pl-10 py-10 flex-1 min-w-0 flex flex-col justify-between">
38
- <h2 class="text-2xl md:text-3xl text-primary font-normal leading-tight max-w-xs">
39
- Subscribe to our monthly newsletter
40
- </h2>
41
- <div class="mt-10">
42
- <NewsletterForm :endpoint="newsletterEndpoint" :form-id="newsletterFormId" />
43
- </div>
44
- </div>
45
-
46
- <!-- Right: Related Posts (matches image width from hero) -->
47
- <div class="related-posts relative w-full lg:w-[35rem] xl:w-[55rem] flex-shrink-0 px-6 lg:pl-30 lg:mr-10 py-10 lg:py-16">
48
- <div class="grid grid-cols-1 sm:grid-cols-2 gap-6">
49
- <a
50
- v-for="post in relatedPosts"
51
- :key="post.url"
52
- :href="post.url"
53
- class="group flex flex-col"
54
- >
55
- <!-- Cover Image -->
56
- <div class="w-full aspect-video bg-nickel overflow-hidden">
57
- <img
58
- v-if="post.cover"
59
- :src="post.cover"
60
- :alt="post.title"
61
- class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
62
- />
63
- </div>
64
-
65
- <!-- Content -->
66
- <div class="flex flex-col gap-2 mt-4">
67
- <span class="text-grey text-xs font-medium font-mono uppercase tracking-wide">// {{ post.category }}</span>
68
- <h4 class="text-lg text-pretty text-primary font-normal leading-snug group-hover:text-grey transition-colors">
69
- {{ post.title }}
70
- </h4>
71
- <span class="text-grey text-xs font-medium font-mono uppercase tracking-wide">{{ formatDateShort(post.date.string) }}</span>
72
- </div>
73
- </a>
74
- </div>
75
- </div>
76
- </div>
77
- </section>
78
- </template>
79
-
80
- <style scoped>
81
- @media (min-width: 1024px) {
82
- .related-posts::before {
83
- content: '';
84
- position: absolute;
85
- left: 0;
86
- top: 0;
87
- bottom: 0;
88
- width: 1px;
89
- background-color: var(--color-stroke);
90
- }
91
- }
92
- </style>