@sonordev/site-kit 5.3.2 → 5.5.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 (411) hide show
  1. package/AGENTS.md +16 -6
  2. package/README.md +26 -7
  3. package/agent-manifest.json +11 -10
  4. package/dist/AnalyticsProvider-KFXAH4GR.mjs +11 -0
  5. package/dist/{AnalyticsProvider-2XK54UZW.mjs.map → AnalyticsProvider-KFXAH4GR.mjs.map} +1 -1
  6. package/dist/AnalyticsProvider-WDDW3IJW.js +32 -0
  7. package/dist/{AnalyticsProvider-PM7SOGOS.js.map → AnalyticsProvider-WDDW3IJW.js.map} +1 -1
  8. package/dist/{BlogViewTracker-3BIUF5TI.js → BlogViewTracker-D4DIEP4Q.js} +6 -6
  9. package/dist/{BlogViewTracker-3BIUF5TI.js.map → BlogViewTracker-D4DIEP4Q.js.map} +1 -1
  10. package/dist/{BlogViewTracker-KFUDRDQK.mjs → BlogViewTracker-ZVEGGH3Y.mjs} +5 -5
  11. package/dist/{BlogViewTracker-KFUDRDQK.mjs.map → BlogViewTracker-ZVEGGH3Y.mjs.map} +1 -1
  12. package/dist/ChatWidget-2ZYPYIMQ.js +22 -0
  13. package/dist/{ChatWidget-7BYSGNO2.js.map → ChatWidget-2ZYPYIMQ.js.map} +1 -1
  14. package/dist/ChatWidget-FYCCLMQE.mjs +13 -0
  15. package/dist/{ChatWidget-4PHZHGG5.mjs.map → ChatWidget-FYCCLMQE.mjs.map} +1 -1
  16. package/dist/EngageWidget-6HUZYOY7.mjs +11 -0
  17. package/dist/{EngageWidget-D6M6QWEC.mjs.map → EngageWidget-6HUZYOY7.mjs.map} +1 -1
  18. package/dist/EngageWidget-MYQTBBW6.js +20 -0
  19. package/dist/{EngageWidget-Q4ITKTMJ.js.map → EngageWidget-MYQTBBW6.js.map} +1 -1
  20. package/dist/{FileField-YBBIJOCK.js → FileField-JK2S24XU.js} +6 -6
  21. package/dist/{FileField-YBBIJOCK.js.map → FileField-JK2S24XU.js.map} +1 -1
  22. package/dist/{FileField-PQQDX4IR.mjs → FileField-OZZHWGPA.mjs} +5 -5
  23. package/dist/{FileField-PQQDX4IR.mjs.map → FileField-OZZHWGPA.mjs.map} +1 -1
  24. package/dist/{FormSpotlight-WUN24F3P.js → FormSpotlight-5AXFQU5M.js} +15 -15
  25. package/dist/{FormSpotlight-WUN24F3P.js.map → FormSpotlight-5AXFQU5M.js.map} +1 -1
  26. package/dist/{FormSpotlight-7TIIWFTP.mjs → FormSpotlight-XV42L72H.mjs} +3 -3
  27. package/dist/{FormSpotlight-7TIIWFTP.mjs.map → FormSpotlight-XV42L72H.mjs.map} +1 -1
  28. package/dist/{FormStage-CM7OVLUT.js → FormStage-HATUHNRV.js} +13 -13
  29. package/dist/{FormStage-CM7OVLUT.js.map → FormStage-HATUHNRV.js.map} +1 -1
  30. package/dist/{FormStage-TFN2GIBO.mjs → FormStage-RUK675HV.mjs} +3 -3
  31. package/dist/{FormStage-TFN2GIBO.mjs.map → FormStage-RUK675HV.mjs.map} +1 -1
  32. package/dist/ManagedForm-JWEXJEXK.js +23 -0
  33. package/dist/{ManagedForm-N63YGVNY.js.map → ManagedForm-JWEXJEXK.js.map} +1 -1
  34. package/dist/ManagedForm-OA3MNGXT.mjs +14 -0
  35. package/dist/{ManagedForm-ZUXLHEQU.mjs.map → ManagedForm-OA3MNGXT.mjs.map} +1 -1
  36. package/dist/{ManagedNewsletterForm-PIVJTU5L.js → ManagedNewsletterForm-AAHH63KT.js} +8 -8
  37. package/dist/{ManagedNewsletterForm-PIVJTU5L.js.map → ManagedNewsletterForm-AAHH63KT.js.map} +1 -1
  38. package/dist/{ManagedNewsletterForm-4AVKTZ2A.mjs → ManagedNewsletterForm-HZKTNWLW.mjs} +7 -7
  39. package/dist/{ManagedNewsletterForm-4AVKTZ2A.mjs.map → ManagedNewsletterForm-HZKTNWLW.mjs.map} +1 -1
  40. package/dist/{SignalCore-LT4NCPOR.mjs → SignalCore-X3GDGBZD.mjs} +5 -5
  41. package/dist/{SignalCore-LT4NCPOR.mjs.map → SignalCore-X3GDGBZD.mjs.map} +1 -1
  42. package/dist/{SignalCore-2M5TISM7.js → SignalCore-YSNZYBKJ.js} +11 -11
  43. package/dist/{SignalCore-2M5TISM7.js.map → SignalCore-YSNZYBKJ.js.map} +1 -1
  44. package/dist/SitemapSync-2PTDBH5E.mjs +9 -0
  45. package/dist/{SitemapSync-G3OLECFI.mjs.map → SitemapSync-2PTDBH5E.mjs.map} +1 -1
  46. package/dist/SitemapSync-3SFAI546.js +18 -0
  47. package/dist/{SitemapSync-7OBOJG2L.js.map → SitemapSync-3SFAI546.js.map} +1 -1
  48. package/dist/analytics/dispatch.d.ts +4 -4
  49. package/dist/analytics/index.js +15 -15
  50. package/dist/analytics/index.mjs +6 -6
  51. package/dist/{api-NTHZ6PAW.mjs → api-D745LGGU.mjs} +3 -3
  52. package/dist/api-D745LGGU.mjs.map +1 -0
  53. package/dist/{api-N5OLQXYN.js → api-XR5APCH3.js} +3 -3
  54. package/dist/api-XR5APCH3.js.map +1 -0
  55. package/dist/blog/AuthorPage.d.ts +1 -1
  56. package/dist/blog/AuthorPage.d.ts.map +1 -1
  57. package/dist/blog/BlogLayout.d.ts +3 -1
  58. package/dist/blog/BlogLayout.d.ts.map +1 -1
  59. package/dist/blog/BlogList.d.ts +3 -1
  60. package/dist/blog/BlogList.d.ts.map +1 -1
  61. package/dist/blog/BlogPost.d.ts +3 -1
  62. package/dist/blog/BlogPost.d.ts.map +1 -1
  63. package/dist/blog/BlogSidebar.d.ts +3 -1
  64. package/dist/blog/BlogSidebar.d.ts.map +1 -1
  65. package/dist/blog/ClusterLandingPage.d.ts +3 -1
  66. package/dist/blog/ClusterLandingPage.d.ts.map +1 -1
  67. package/dist/blog/ClusterNavigation.d.ts +3 -1
  68. package/dist/blog/ClusterNavigation.d.ts.map +1 -1
  69. package/dist/blog/RelatedPosts.d.ts +4 -1
  70. package/dist/blog/RelatedPosts.d.ts.map +1 -1
  71. package/dist/blog/artwork-components.test.d.ts +2 -0
  72. package/dist/blog/artwork-components.test.d.ts.map +1 -0
  73. package/dist/blog/artwork.d.ts +14 -0
  74. package/dist/blog/artwork.d.ts.map +1 -0
  75. package/dist/blog/artwork.test.d.ts +2 -0
  76. package/dist/blog/artwork.test.d.ts.map +1 -0
  77. package/dist/blog/blog-styles.d.ts.map +1 -1
  78. package/dist/blog/blog-tables.d.ts +13 -0
  79. package/dist/blog/blog-tables.d.ts.map +1 -0
  80. package/dist/blog/blog-tables.test.d.ts +2 -0
  81. package/dist/blog/blog-tables.test.d.ts.map +1 -0
  82. package/dist/blog/index.d.ts +3 -0
  83. package/dist/blog/index.d.ts.map +1 -1
  84. package/dist/blog/index.js +52 -30
  85. package/dist/blog/index.js.map +1 -1
  86. package/dist/blog/index.mjs +15 -12
  87. package/dist/blog/index.mjs.map +1 -1
  88. package/dist/blog/publication-render.test.d.ts +2 -0
  89. package/dist/blog/publication-render.test.d.ts.map +1 -0
  90. package/dist/blog/publication-routes.test.d.ts +2 -0
  91. package/dist/blog/publication-routes.test.d.ts.map +1 -0
  92. package/dist/blog/routes.d.ts +40 -0
  93. package/dist/blog/routes.d.ts.map +1 -0
  94. package/dist/blog/server-core.d.ts +28 -21
  95. package/dist/blog/server-core.d.ts.map +1 -1
  96. package/dist/blog/server-ui.d.ts +4 -0
  97. package/dist/blog/server-ui.d.ts.map +1 -1
  98. package/dist/blog/server-ui.js +49 -28
  99. package/dist/blog/server-ui.js.map +1 -1
  100. package/dist/blog/server-ui.mjs +9 -15
  101. package/dist/blog/server-ui.mjs.map +1 -1
  102. package/dist/blog/server.d.ts +28 -21
  103. package/dist/blog/server.d.ts.map +1 -1
  104. package/dist/blog/server.js +71 -42
  105. package/dist/blog/server.mjs +3 -2
  106. package/dist/blog/types.d.ts +8 -1
  107. package/dist/blog/types.d.ts.map +1 -1
  108. package/dist/blog-styles-6EY3BS5Y.js +595 -0
  109. package/dist/blog-styles-6EY3BS5Y.js.map +1 -0
  110. package/dist/blog-styles-7AKRUMV7.mjs +592 -0
  111. package/dist/blog-styles-7AKRUMV7.mjs.map +1 -0
  112. package/dist/blog-tables-DWDEWA3S.js +17 -0
  113. package/dist/blog-tables-DWDEWA3S.js.map +1 -0
  114. package/dist/blog-tables-QGIHOESZ.mjs +4 -0
  115. package/dist/blog-tables-QGIHOESZ.mjs.map +1 -0
  116. package/dist/{chunk-OIJ435IZ.js → chunk-2CMSWJWC.js} +18 -18
  117. package/dist/{chunk-OIJ435IZ.js.map → chunk-2CMSWJWC.js.map} +1 -1
  118. package/dist/{chunk-K37JPEQW.js → chunk-2OU4KBUN.js} +26 -23
  119. package/dist/chunk-2OU4KBUN.js.map +1 -0
  120. package/dist/{chunk-JSLYNYTB.mjs → chunk-3B6CXGAK.mjs} +3 -3
  121. package/dist/{chunk-JSLYNYTB.mjs.map → chunk-3B6CXGAK.mjs.map} +1 -1
  122. package/dist/{chunk-HMFFAUCD.js → chunk-3DWIYCQX.js} +2 -2
  123. package/dist/chunk-3DWIYCQX.js.map +1 -0
  124. package/dist/{chunk-3EPMDPWI.js → chunk-3SDMJMN2.js} +5 -5
  125. package/dist/{chunk-3EPMDPWI.js.map → chunk-3SDMJMN2.js.map} +1 -1
  126. package/dist/chunk-4B4S56WJ.mjs +110 -0
  127. package/dist/chunk-4B4S56WJ.mjs.map +1 -0
  128. package/dist/chunk-4U5NCKQY.mjs +39 -0
  129. package/dist/chunk-4U5NCKQY.mjs.map +1 -0
  130. package/dist/{chunk-CQUA2AUA.mjs → chunk-4XGACM7D.mjs} +3 -3
  131. package/dist/{chunk-CQUA2AUA.mjs.map → chunk-4XGACM7D.mjs.map} +1 -1
  132. package/dist/{chunk-AVM4OZHR.mjs → chunk-5TGAUWNO.mjs} +3 -3
  133. package/dist/{chunk-AVM4OZHR.mjs.map → chunk-5TGAUWNO.mjs.map} +1 -1
  134. package/dist/{chunk-RO55G3OA.mjs → chunk-64BOVMXG.mjs} +3 -3
  135. package/dist/{chunk-RO55G3OA.mjs.map → chunk-64BOVMXG.mjs.map} +1 -1
  136. package/dist/{chunk-JBGRXICL.js → chunk-746RKQHA.js} +75 -70
  137. package/dist/chunk-746RKQHA.js.map +1 -0
  138. package/dist/{chunk-N3C323NY.mjs → chunk-7PPNXORV.mjs} +3 -3
  139. package/dist/{chunk-N3C323NY.mjs.map → chunk-7PPNXORV.mjs.map} +1 -1
  140. package/dist/{chunk-DYKFC7WY.js → chunk-A3F5GRNJ.js} +8 -8
  141. package/dist/{chunk-DYKFC7WY.js.map → chunk-A3F5GRNJ.js.map} +1 -1
  142. package/dist/{chunk-4TU246Q4.mjs → chunk-AEARU24Q.mjs} +40 -26
  143. package/dist/chunk-AEARU24Q.mjs.map +1 -0
  144. package/dist/{chunk-5BZDHZCN.js → chunk-BNOQXDPJ.js} +4 -4
  145. package/dist/{chunk-5BZDHZCN.js.map → chunk-BNOQXDPJ.js.map} +1 -1
  146. package/dist/{chunk-XQZTOWS3.js → chunk-CT5REGAK.js} +15 -15
  147. package/dist/{chunk-XQZTOWS3.js.map → chunk-CT5REGAK.js.map} +1 -1
  148. package/dist/{chunk-KOP3DPIR.mjs → chunk-DRLHQQBH.mjs} +4 -4
  149. package/dist/{chunk-KOP3DPIR.mjs.map → chunk-DRLHQQBH.mjs.map} +1 -1
  150. package/dist/{chunk-Y7SRO7MJ.mjs → chunk-DYULWKDC.mjs} +4 -4
  151. package/dist/{chunk-Y7SRO7MJ.mjs.map → chunk-DYULWKDC.mjs.map} +1 -1
  152. package/dist/{chunk-DHXQBTXE.mjs → chunk-EEQYKMGH.mjs} +75 -70
  153. package/dist/chunk-EEQYKMGH.mjs.map +1 -0
  154. package/dist/chunk-ESP5RMB7.js +42 -0
  155. package/dist/chunk-ESP5RMB7.js.map +1 -0
  156. package/dist/{chunk-4DE2KJ7R.js → chunk-FF5N5D3D.js} +8 -8
  157. package/dist/{chunk-4DE2KJ7R.js.map → chunk-FF5N5D3D.js.map} +1 -1
  158. package/dist/{chunk-757HXAYX.js → chunk-FYVLQ3OU.js} +3 -3
  159. package/dist/{chunk-757HXAYX.js.map → chunk-FYVLQ3OU.js.map} +1 -1
  160. package/dist/{chunk-OC6PU7U2.mjs → chunk-G5HUI4BO.mjs} +3 -3
  161. package/dist/{chunk-OC6PU7U2.mjs.map → chunk-G5HUI4BO.mjs.map} +1 -1
  162. package/dist/chunk-G6WF4G3E.js +43 -0
  163. package/dist/chunk-G6WF4G3E.js.map +1 -0
  164. package/dist/chunk-GHECYDSZ.mjs +134 -0
  165. package/dist/chunk-GHECYDSZ.mjs.map +1 -0
  166. package/dist/{chunk-JTO3K5B7.mjs → chunk-HBI67P7Y.mjs} +4 -4
  167. package/dist/{chunk-JTO3K5B7.mjs.map → chunk-HBI67P7Y.mjs.map} +1 -1
  168. package/dist/{chunk-FFJVQWKO.js → chunk-HFJQMIFM.js} +4 -4
  169. package/dist/{chunk-FFJVQWKO.js.map → chunk-HFJQMIFM.js.map} +1 -1
  170. package/dist/{chunk-A3NNUKFA.js → chunk-HX3BRMOX.js} +96 -644
  171. package/dist/chunk-HX3BRMOX.js.map +1 -0
  172. package/dist/{chunk-3TXX5KIN.js → chunk-JNRHTZL4.js} +2 -2
  173. package/dist/{chunk-3TXX5KIN.js.map → chunk-JNRHTZL4.js.map} +1 -1
  174. package/dist/{chunk-R3LYTIVN.js → chunk-KAUUGRYB.js} +5 -5
  175. package/dist/{chunk-R3LYTIVN.js.map → chunk-KAUUGRYB.js.map} +1 -1
  176. package/dist/{chunk-L2LJQIM3.js → chunk-KPKQKFT4.js} +11 -11
  177. package/dist/chunk-KPKQKFT4.js.map +1 -0
  178. package/dist/chunk-LC7AM4J5.js +118 -0
  179. package/dist/chunk-LC7AM4J5.js.map +1 -0
  180. package/dist/{chunk-GFNXWS3I.js → chunk-MCJF2KJ6.js} +5 -5
  181. package/dist/{chunk-GFNXWS3I.js.map → chunk-MCJF2KJ6.js.map} +1 -1
  182. package/dist/{chunk-Z7K5AMCE.js → chunk-MNYM2XU4.js} +4 -4
  183. package/dist/{chunk-Z7K5AMCE.js.map → chunk-MNYM2XU4.js.map} +1 -1
  184. package/dist/{chunk-6QABCGM6.mjs → chunk-MU7IEPDG.mjs} +4 -4
  185. package/dist/chunk-MU7IEPDG.mjs.map +1 -0
  186. package/dist/chunk-NSWO43XW.mjs +39 -0
  187. package/dist/chunk-NSWO43XW.mjs.map +1 -0
  188. package/dist/{chunk-Z33JXJTJ.js → chunk-NZSFOZJV.js} +40 -26
  189. package/dist/chunk-NZSFOZJV.js.map +1 -0
  190. package/dist/{chunk-ZKR5AJV5.mjs → chunk-OFSA7LUH.mjs} +4 -4
  191. package/dist/{chunk-ZKR5AJV5.mjs.map → chunk-OFSA7LUH.mjs.map} +1 -1
  192. package/dist/{chunk-M7FWXEXC.js → chunk-PIPLBBDH.js} +8 -8
  193. package/dist/{chunk-M7FWXEXC.js.map → chunk-PIPLBBDH.js.map} +1 -1
  194. package/dist/{chunk-FDVE56JS.js → chunk-Q26VZNM2.js} +3 -3
  195. package/dist/{chunk-FDVE56JS.js.map → chunk-Q26VZNM2.js.map} +1 -1
  196. package/dist/{chunk-6AZTRTCG.js → chunk-QEGUI2Q2.js} +15 -15
  197. package/dist/{chunk-6AZTRTCG.js.map → chunk-QEGUI2Q2.js.map} +1 -1
  198. package/dist/{chunk-GPNBBUEN.js → chunk-QFNSM77X.js} +3 -3
  199. package/dist/{chunk-GPNBBUEN.js.map → chunk-QFNSM77X.js.map} +1 -1
  200. package/dist/{chunk-QZ54OCWD.mjs → chunk-R4MX6EOM.mjs} +7 -7
  201. package/dist/{chunk-QZ54OCWD.mjs.map → chunk-R4MX6EOM.mjs.map} +1 -1
  202. package/dist/{chunk-67CHHDBL.mjs → chunk-RMMHWSPP.mjs} +96 -644
  203. package/dist/chunk-RMMHWSPP.mjs.map +1 -0
  204. package/dist/{chunk-B4BFQSSS.mjs → chunk-RU54J2PY.mjs} +4 -4
  205. package/dist/chunk-RU54J2PY.mjs.map +1 -0
  206. package/dist/{chunk-AXAIUCSF.mjs → chunk-RZUZMUTN.mjs} +9 -8
  207. package/dist/chunk-RZUZMUTN.mjs.map +1 -0
  208. package/dist/{chunk-NSLYY62T.mjs → chunk-S6FEC6UT.mjs} +9 -5
  209. package/dist/chunk-S6FEC6UT.mjs.map +1 -0
  210. package/dist/{chunk-3DPXOZAU.mjs → chunk-SHLWA6JY.mjs} +2 -2
  211. package/dist/chunk-SHLWA6JY.mjs.map +1 -0
  212. package/dist/{chunk-E33HJMRP.js → chunk-SQVYLIIN.js} +11 -7
  213. package/dist/chunk-SQVYLIIN.js.map +1 -0
  214. package/dist/chunk-SUZ3ZLB2.js +8 -0
  215. package/dist/{chunk-D37M7MIH.js.map → chunk-SUZ3ZLB2.js.map} +1 -1
  216. package/dist/{chunk-DZDWBQKA.mjs → chunk-TALEV3IH.mjs} +3 -3
  217. package/dist/{chunk-DZDWBQKA.mjs.map → chunk-TALEV3IH.mjs.map} +1 -1
  218. package/dist/{chunk-UOTXSWKZ.mjs → chunk-TP7H6BSK.mjs} +2 -2
  219. package/dist/{chunk-UOTXSWKZ.mjs.map → chunk-TP7H6BSK.mjs.map} +1 -1
  220. package/dist/{chunk-XW5KNCWJ.mjs → chunk-TX2QQ7IX.mjs} +3 -3
  221. package/dist/{chunk-XW5KNCWJ.mjs.map → chunk-TX2QQ7IX.mjs.map} +1 -1
  222. package/dist/{chunk-PEEQMI7U.js → chunk-UNPEMSLK.js} +12 -11
  223. package/dist/chunk-UNPEMSLK.js.map +1 -0
  224. package/dist/{chunk-42F5EK24.mjs → chunk-UZL2QU2V.mjs} +16 -13
  225. package/dist/chunk-UZL2QU2V.mjs.map +1 -0
  226. package/dist/{chunk-6VG65AIA.mjs → chunk-V6NOM7PJ.mjs} +3 -3
  227. package/dist/{chunk-6VG65AIA.mjs.map → chunk-V6NOM7PJ.mjs.map} +1 -1
  228. package/dist/{chunk-W23TMUKB.js → chunk-VAS3LH5W.js} +418 -98
  229. package/dist/chunk-VAS3LH5W.js.map +1 -0
  230. package/dist/{chunk-TS3N3LGZ.mjs → chunk-VYHRAICF.mjs} +4 -4
  231. package/dist/{chunk-TS3N3LGZ.mjs.map → chunk-VYHRAICF.mjs.map} +1 -1
  232. package/dist/{chunk-G3YUSRCL.js → chunk-W5NVW23S.js} +4 -4
  233. package/dist/{chunk-G3YUSRCL.js.map → chunk-W5NVW23S.js.map} +1 -1
  234. package/dist/chunk-WDBCXRTT.mjs +6 -0
  235. package/dist/{chunk-OUERH2T4.mjs.map → chunk-WDBCXRTT.mjs.map} +1 -1
  236. package/dist/{chunk-ZOJ3TLO5.mjs → chunk-WIZRCI6J.mjs} +3 -3
  237. package/dist/{chunk-ZOJ3TLO5.mjs.map → chunk-WIZRCI6J.mjs.map} +1 -1
  238. package/dist/{chunk-HDQTZAGE.mjs → chunk-X2XFLYZ3.mjs} +3 -3
  239. package/dist/{chunk-HDQTZAGE.mjs.map → chunk-X2XFLYZ3.mjs.map} +1 -1
  240. package/dist/{chunk-HVFXFPUJ.mjs → chunk-XQYC4KMH.mjs} +413 -94
  241. package/dist/chunk-XQYC4KMH.mjs.map +1 -0
  242. package/dist/{chunk-KPFPSOYS.js → chunk-YNC5D3FT.js} +12 -12
  243. package/dist/{chunk-KPFPSOYS.js.map → chunk-YNC5D3FT.js.map} +1 -1
  244. package/dist/chunk-YQTE32QK.js +137 -0
  245. package/dist/chunk-YQTE32QK.js.map +1 -0
  246. package/dist/{chunk-PZXKFHPO.js → chunk-YYAFHIY7.js} +15 -15
  247. package/dist/chunk-YYAFHIY7.js.map +1 -0
  248. package/dist/{chunk-MANX6422.js → chunk-Z6S4MWSR.js} +7 -7
  249. package/dist/{chunk-MANX6422.js.map → chunk-Z6S4MWSR.js.map} +1 -1
  250. package/dist/{chunk-DVH3JHZ3.mjs → chunk-ZRQFG3L6.mjs} +5 -5
  251. package/dist/{chunk-DVH3JHZ3.mjs.map → chunk-ZRQFG3L6.mjs.map} +1 -1
  252. package/dist/cli/agent/checks.d.ts.map +1 -1
  253. package/dist/cli/agent/ssr-bailout.d.ts +27 -0
  254. package/dist/cli/agent/ssr-bailout.d.ts.map +1 -0
  255. package/dist/cli/agent/ssr-bailout.test.d.ts +2 -0
  256. package/dist/cli/agent/ssr-bailout.test.d.ts.map +1 -0
  257. package/dist/cli/codemod/transforms.d.ts.map +1 -1
  258. package/dist/cli/index.js +38 -51
  259. package/dist/cli/index.js.map +1 -1
  260. package/dist/cli/index.mjs +36 -49
  261. package/dist/cli/index.mjs.map +1 -1
  262. package/dist/cli/migrator/index.d.ts.map +1 -1
  263. package/dist/client/index.d.ts +1 -0
  264. package/dist/client/index.d.ts.map +1 -1
  265. package/dist/client/index.js +20 -7
  266. package/dist/client/index.js.map +1 -1
  267. package/dist/client/index.mjs +5 -4
  268. package/dist/client/index.mjs.map +1 -1
  269. package/dist/cms/index.js.map +1 -1
  270. package/dist/cms/index.mjs.map +1 -1
  271. package/dist/cms/sanity-image.d.ts +1 -1
  272. package/dist/commerce/index.js +58 -58
  273. package/dist/commerce/index.mjs +7 -7
  274. package/dist/engage/ChatWidget.d.ts.map +1 -1
  275. package/dist/engage/EngageWidget.d.ts +3 -4
  276. package/dist/engage/EngageWidget.d.ts.map +1 -1
  277. package/dist/engage/chat-launcher.test.d.ts +2 -0
  278. package/dist/engage/chat-launcher.test.d.ts.map +1 -0
  279. package/dist/engage/index.js +12 -10
  280. package/dist/engage/index.js.map +1 -1
  281. package/dist/engage/index.mjs +9 -7
  282. package/dist/engage/index.mjs.map +1 -1
  283. package/dist/engage/launcher-placement.d.ts +56 -0
  284. package/dist/engage/launcher-placement.d.ts.map +1 -0
  285. package/dist/engage/launcher-placement.test.d.ts +2 -0
  286. package/dist/engage/launcher-placement.test.d.ts.map +1 -0
  287. package/dist/engage/types.d.ts +41 -7
  288. package/dist/engage/types.d.ts.map +1 -1
  289. package/dist/fleet/index.js +8 -8
  290. package/dist/fleet/index.mjs +4 -4
  291. package/dist/forms/index.js +16 -16
  292. package/dist/forms/index.mjs +9 -9
  293. package/dist/forms/server.js +10 -10
  294. package/dist/forms/server.mjs +8 -8
  295. package/dist/forms/static.js +7 -7
  296. package/dist/forms/static.mjs +6 -6
  297. package/dist/images/ManagedImage.d.ts.map +1 -1
  298. package/dist/images/index.js +11 -11
  299. package/dist/images/index.mjs +4 -4
  300. package/dist/index.js +65 -65
  301. package/dist/index.mjs +11 -11
  302. package/dist/layout/SiteKitClientProviders.d.ts.map +1 -1
  303. package/dist/layout/client.d.ts.map +1 -1
  304. package/dist/layout/client.js +8 -8
  305. package/dist/layout/client.mjs +7 -7
  306. package/dist/layout/index.js +10 -10
  307. package/dist/layout/index.mjs +8 -8
  308. package/dist/layout/types.d.ts +7 -3
  309. package/dist/layout/types.d.ts.map +1 -1
  310. package/dist/llms/generateLLMsTxt.d.ts.map +1 -1
  311. package/dist/llms/index.js +12 -12
  312. package/dist/llms/index.mjs +2 -2
  313. package/dist/llms/types.d.ts +7 -1
  314. package/dist/llms/types.d.ts.map +1 -1
  315. package/dist/maps/index.js +5 -5
  316. package/dist/maps/index.mjs +3 -3
  317. package/dist/mcp/WebMcpTools.d.ts +5 -2
  318. package/dist/mcp/WebMcpTools.d.ts.map +1 -1
  319. package/dist/mcp/client.js.map +1 -1
  320. package/dist/mcp/client.mjs.map +1 -1
  321. package/dist/search/index.js +4 -4
  322. package/dist/search/index.mjs +3 -3
  323. package/dist/seo/LocationPageContent.d.ts +6 -5
  324. package/dist/seo/LocationPageContent.d.ts.map +1 -1
  325. package/dist/seo/api.d.ts +4 -5
  326. package/dist/seo/api.d.ts.map +1 -1
  327. package/dist/seo/client.js +5 -5
  328. package/dist/seo/client.mjs +4 -4
  329. package/dist/seo/index.js +42 -42
  330. package/dist/seo/index.js.map +1 -1
  331. package/dist/seo/index.mjs +8 -8
  332. package/dist/seo/index.mjs.map +1 -1
  333. package/dist/seo/routing.d.ts +9 -23
  334. package/dist/seo/routing.d.ts.map +1 -1
  335. package/dist/seo/server-api.d.ts +11 -5
  336. package/dist/seo/server-api.d.ts.map +1 -1
  337. package/dist/seo/server.js +18 -18
  338. package/dist/seo/server.mjs +2 -2
  339. package/dist/server/index.js +3 -3
  340. package/dist/server/index.mjs +2 -2
  341. package/dist/{server-api-HW4PL2L2.mjs → server-api-RG3ZL3DV.mjs} +3 -3
  342. package/dist/{server-api-HW4PL2L2.mjs.map → server-api-RG3ZL3DV.mjs.map} +1 -1
  343. package/dist/{server-api-DB2SIUP4.js → server-api-RYJQAUGO.js} +21 -21
  344. package/dist/{server-api-DB2SIUP4.js.map → server-api-RYJQAUGO.js.map} +1 -1
  345. package/dist/shared/version.d.ts +1 -1
  346. package/dist/shared/visual-viewport-gap.d.ts +52 -0
  347. package/dist/shared/visual-viewport-gap.d.ts.map +1 -0
  348. package/dist/shared/visual-viewport-gap.test.d.ts +2 -0
  349. package/dist/shared/visual-viewport-gap.test.d.ts.map +1 -0
  350. package/dist/signal/index.js +11 -11
  351. package/dist/signal/index.mjs +2 -2
  352. package/dist/sitemap/index.js +2 -2
  353. package/dist/sitemap/index.mjs +1 -1
  354. package/dist/sync/BookingWidget.d.ts +0 -23
  355. package/dist/sync/BookingWidget.d.ts.map +1 -1
  356. package/dist/sync/MeetingFormatStep.d.ts +13 -0
  357. package/dist/sync/MeetingFormatStep.d.ts.map +1 -0
  358. package/dist/sync/api.d.ts +9 -10
  359. package/dist/sync/api.d.ts.map +1 -1
  360. package/dist/sync/booking-flow.d.ts +7 -0
  361. package/dist/sync/booking-flow.d.ts.map +1 -0
  362. package/dist/sync/booking-flow.test.d.ts +2 -0
  363. package/dist/sync/booking-flow.test.d.ts.map +1 -0
  364. package/dist/sync/index.d.ts +2 -2
  365. package/dist/sync/index.d.ts.map +1 -1
  366. package/dist/sync/index.js +20 -16
  367. package/dist/sync/index.mjs +4 -4
  368. package/dist/sync/types.d.ts +34 -0
  369. package/dist/sync/types.d.ts.map +1 -1
  370. package/dist/types.d.ts +9 -0
  371. package/dist/types.d.ts.map +1 -1
  372. package/package.json +1 -1
  373. package/skills/site-kit/SKILL.md +8 -3
  374. package/dist/AnalyticsProvider-2XK54UZW.mjs +0 -11
  375. package/dist/AnalyticsProvider-PM7SOGOS.js +0 -32
  376. package/dist/ChatWidget-4PHZHGG5.mjs +0 -11
  377. package/dist/ChatWidget-7BYSGNO2.js +0 -20
  378. package/dist/EngageWidget-D6M6QWEC.mjs +0 -9
  379. package/dist/EngageWidget-Q4ITKTMJ.js +0 -18
  380. package/dist/ManagedForm-N63YGVNY.js +0 -23
  381. package/dist/ManagedForm-ZUXLHEQU.mjs +0 -14
  382. package/dist/SitemapSync-7OBOJG2L.js +0 -18
  383. package/dist/SitemapSync-G3OLECFI.mjs +0 -9
  384. package/dist/api-N5OLQXYN.js.map +0 -1
  385. package/dist/api-NTHZ6PAW.mjs.map +0 -1
  386. package/dist/chunk-3DPXOZAU.mjs.map +0 -1
  387. package/dist/chunk-42F5EK24.mjs.map +0 -1
  388. package/dist/chunk-4TU246Q4.mjs.map +0 -1
  389. package/dist/chunk-67CHHDBL.mjs.map +0 -1
  390. package/dist/chunk-6QABCGM6.mjs.map +0 -1
  391. package/dist/chunk-A3NNUKFA.js.map +0 -1
  392. package/dist/chunk-AXAIUCSF.mjs.map +0 -1
  393. package/dist/chunk-B4BFQSSS.mjs.map +0 -1
  394. package/dist/chunk-CGCYZJYX.mjs +0 -41
  395. package/dist/chunk-CGCYZJYX.mjs.map +0 -1
  396. package/dist/chunk-D37M7MIH.js +0 -8
  397. package/dist/chunk-DHXQBTXE.mjs.map +0 -1
  398. package/dist/chunk-E33HJMRP.js.map +0 -1
  399. package/dist/chunk-HMFFAUCD.js.map +0 -1
  400. package/dist/chunk-HVFXFPUJ.mjs.map +0 -1
  401. package/dist/chunk-JBGRXICL.js.map +0 -1
  402. package/dist/chunk-K37JPEQW.js.map +0 -1
  403. package/dist/chunk-L2LJQIM3.js.map +0 -1
  404. package/dist/chunk-NSLYY62T.mjs.map +0 -1
  405. package/dist/chunk-OUERH2T4.mjs +0 -6
  406. package/dist/chunk-PEEQMI7U.js.map +0 -1
  407. package/dist/chunk-PZXKFHPO.js.map +0 -1
  408. package/dist/chunk-TPL2IHFI.js +0 -43
  409. package/dist/chunk-TPL2IHFI.js.map +0 -1
  410. package/dist/chunk-W23TMUKB.js.map +0 -1
  411. package/dist/chunk-Z33JXJTJ.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/blog/ServiceCallout.tsx","../src/blog/ClusterNavigation.tsx","../src/blog/processBlogHtml.ts","../src/blog/reading-time.ts","../src/blog/author-social.ts","../src/blog/blog-styles.ts","../src/blog/BlogPost.tsx","../src/blog/BlogList.tsx","../src/blog/BlogSidebar.tsx","../src/blog/BlogLayout.tsx","../src/blog/RelatedPosts.tsx"],"names":["jsxs","jsx","Fragment","marked","cls","React","fetchCategories","widgetStyle","widgetTitleStyle","fetchRelatedPosts"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAqZnC,IAAA;AAAK,CAAA;AAMA,IAAM,WAAA;AAAA;AAAA,EAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","file":"chunk-A3NNUKFA.js","sourcesContent":["/**\n * @sonordev/site-kit/blog - Service Callout / CTA Component\n *\n * Renders a promotional call-to-action section within blog posts.\n * Automatically generated by Signal AI during blog creation, linking\n * article content to the business's relevant services.\n *\n * Two variants:\n * - 'featured' (default): Full-width gradient banner with button\n * - 'inline': Compact card with icon accent\n *\n * Uses site-kit brand tokens (--sk-primary, --sk-bg, etc.) for theming.\n * Supports full Tailwind override via `styles` prop.\n *\n * @example\n * ```tsx\n * <ServiceCallout\n * title=\"Ready to build your MVP?\"\n * description=\"Our team specializes in lean SaaS builds.\"\n * cta=\"Get Started\"\n * url=\"/services/application-development\"\n * />\n * ```\n */\n\nimport React from 'react'\n\nexport interface ServiceCalloutProps {\n title: string\n description?: string\n cta?: string\n url: string\n variant?: 'featured' | 'inline'\n /** Override default styles with Tailwind classes */\n styles?: {\n wrapper?: string\n title?: string\n description?: string\n button?: string\n }\n /** Strip all default styles (BYO Tailwind) */\n unstyled?: boolean\n}\n\n// Default inline styles using CSS custom properties for brand theming\nconst defaults = {\n featured: {\n wrapper: {\n display: 'flex',\n flexWrap: 'wrap' as const,\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '1.5rem',\n padding: '2rem 2.5rem',\n margin: '3rem 0',\n borderRadius: '1rem',\n background: 'linear-gradient(135deg, color-mix(in srgb, var(--sk-primary, #2563eb) 8%, transparent), color-mix(in srgb, var(--sk-primary, #2563eb) 15%, transparent))',\n border: '1px solid color-mix(in srgb, var(--sk-primary, #2563eb) 25%, transparent)',\n },\n title: {\n fontSize: '1.25rem',\n fontWeight: 700,\n color: 'var(--sk-text-primary, #0f172a)',\n margin: 0,\n },\n description: {\n fontSize: '0.9375rem',\n color: 'var(--sk-text-secondary, #475569)',\n marginTop: '0.5rem',\n maxWidth: '40rem',\n },\n button: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: '0.75rem 1.75rem',\n borderRadius: '0.5rem',\n fontWeight: 600,\n fontSize: '0.9375rem',\n color: '#ffffff',\n background: 'var(--sk-primary, #2563eb)',\n textDecoration: 'none',\n transition: 'transform 0.15s, box-shadow 0.15s',\n whiteSpace: 'nowrap' as const,\n },\n },\n inline: {\n wrapper: {\n display: 'flex',\n gap: '1rem',\n padding: '1.25rem 1.5rem',\n margin: '2rem 0',\n borderRadius: '0.75rem',\n background: 'var(--sk-bg-elevated, #f8fafc)',\n border: '1px solid color-mix(in srgb, var(--sk-primary, #2563eb) 20%, var(--sk-surface-border, #e2e8f0))',\n },\n icon: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '2.5rem',\n height: '2.5rem',\n borderRadius: '0.625rem',\n background: 'var(--sk-primary, #2563eb)',\n color: '#ffffff',\n flexShrink: 0,\n fontSize: '1.125rem',\n },\n title: {\n fontSize: '1rem',\n fontWeight: 600,\n color: 'var(--sk-text-primary, #0f172a)',\n margin: 0,\n },\n description: {\n fontSize: '0.875rem',\n color: 'var(--sk-text-secondary, #475569)',\n marginTop: '0.25rem',\n },\n link: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.25rem',\n marginTop: '0.5rem',\n fontSize: '0.875rem',\n fontWeight: 600,\n color: 'var(--sk-primary, #2563eb)',\n textDecoration: 'none',\n },\n },\n}\n\nexport function ServiceCallout({\n title,\n description,\n cta = 'Learn More',\n url,\n variant = 'featured',\n styles,\n unstyled = false,\n}: ServiceCalloutProps) {\n if (variant === 'inline') {\n return (\n <aside\n className={styles?.wrapper}\n style={unstyled ? undefined : defaults.inline.wrapper}\n role=\"complementary\"\n aria-label=\"Related service\"\n >\n <div style={unstyled ? undefined : defaults.inline.icon}>→</div>\n <div>\n <h4\n className={styles?.title}\n style={unstyled ? undefined : defaults.inline.title}\n >\n {title}\n </h4>\n {description && (\n <p\n className={styles?.description}\n style={unstyled ? undefined : defaults.inline.description}\n >\n {description}\n </p>\n )}\n <a\n href={url}\n className={styles?.button}\n style={unstyled ? undefined : defaults.inline.link}\n >\n {cta} →\n </a>\n </div>\n </aside>\n )\n }\n\n // Featured variant (default)\n return (\n <section\n className={styles?.wrapper}\n style={unstyled ? undefined : defaults.featured.wrapper}\n role=\"complementary\"\n aria-label=\"Call to action\"\n >\n <div>\n <h3\n className={styles?.title}\n style={unstyled ? undefined : defaults.featured.title}\n >\n {title}\n </h3>\n {description && (\n <p\n className={styles?.description}\n style={unstyled ? undefined : defaults.featured.description}\n >\n {description}\n </p>\n )}\n </div>\n <a\n href={url}\n className={styles?.button}\n style={unstyled ? undefined : defaults.featured.button}\n >\n {cta} →\n </a>\n </section>\n )\n}\n\n/**\n * Renders all service callouts for a blog post.\n * First callout uses 'featured' variant, subsequent use 'inline'.\n */\nexport function ServiceCallouts({\n callouts,\n styles,\n unstyled,\n}: {\n callouts: Array<{ title: string; description?: string; cta?: string; url: string }>\n styles?: ServiceCalloutProps['styles']\n unstyled?: boolean\n}) {\n if (!callouts || callouts.length === 0) return null\n\n return (\n <>\n {callouts.map((callout, i) => (\n <ServiceCallout\n key={callout.url + i}\n {...callout}\n variant={i === 0 ? 'featured' : 'inline'}\n styles={styles}\n unstyled={unstyled}\n />\n ))}\n </>\n )\n}\n","/**\n * @sonordev/site-kit/blog - Cluster Navigation Component\n *\n * Renders cluster context on blog post pages:\n * - \"Full Guide\" pillar backlink (on support articles only)\n * - Sibling article list with article_type badges\n *\n * Adapts to light/dark themes automatically using the same --sk-* variables\n * as the rest of site-kit, with currentColor-based fallbacks.\n */\n\nimport React from 'react'\nimport type { ClusterNavigation as ClusterNavigationType } from './types'\n\n// ============================================================================\n// CSS\n// ============================================================================\n\nconst clusterNavCss = `\n.sk-cluster-nav {\n --_cn-primary: var(--sk-primary, currentColor);\n --_cn-bg: var(--sk-bg-elevated, color-mix(in srgb, currentColor 6%, transparent));\n --_cn-border: var(--sk-surface-border, color-mix(in srgb, currentColor 12%, transparent));\n --_cn-text: var(--sk-text-primary, inherit);\n --_cn-text2: var(--sk-text-secondary, color-mix(in srgb, currentColor 70%, transparent));\n --_cn-text3: var(--sk-text-tertiary, color-mix(in srgb, currentColor 45%, transparent));\n\n margin: 2rem 0;\n padding: 1.5rem;\n border-radius: 0.75rem;\n background: var(--_cn-bg);\n border: 1px solid var(--_cn-border);\n color: var(--_cn-text);\n}\n\n.sk-cluster-pillar-link {\n margin-bottom: 1.25rem;\n padding-bottom: 1.25rem;\n border-bottom: 1px solid var(--_cn-border);\n}\n.sk-cluster-pillar-link-label {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--_cn-text3);\n margin: 0 0 0.375rem 0;\n}\n.sk-cluster-pillar-link a {\n font-size: 0.9375rem;\n font-weight: 600;\n color: var(--_cn-primary);\n text-decoration: none;\n transition: opacity 0.15s;\n}\n.sk-cluster-pillar-link a:hover { opacity: 0.8; }\n\n.sk-cluster-siblings-title {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--_cn-text3);\n margin: 0 0 0.75rem 0;\n}\n.sk-cluster-siblings-list {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n.sk-cluster-siblings-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n.sk-cluster-siblings-item a {\n font-size: 0.875rem;\n color: var(--_cn-text2);\n text-decoration: none;\n transition: color 0.15s;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.sk-cluster-siblings-item a:hover { color: var(--_cn-primary); }\n.sk-cluster-type-badge {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n padding: 0.125rem 0.4rem;\n border-radius: 9999px;\n font-size: 0.625rem;\n font-weight: 500;\n text-transform: capitalize;\n background: color-mix(in srgb, var(--_cn-primary) 10%, transparent);\n color: var(--_cn-primary);\n border: 1px solid color-mix(in srgb, var(--_cn-primary) 20%, transparent);\n}\n`\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport interface ClusterNavigationProps {\n /** Cluster navigation data */\n navigation: ClusterNavigationType\n /** Base path for blog URLs (default: /blog) */\n basePath?: string\n /**\n * Fallback category slug for URL building (optional). Each linked article's\n * OWN category takes precedence when present — applying one category to\n * every sibling produced wrong-category URLs (duplicate content / redirect\n * chains) on category-segmented sites whenever a cluster spans categories.\n */\n category?: string\n /** Append a trailing slash to article URLs (only for trailingSlash sites) */\n trailingSlash?: boolean\n /** Disable default styles */\n unstyled?: boolean\n /** Custom class name */\n className?: string\n}\n\nexport function ClusterNavigation({\n navigation,\n basePath = '/blog',\n category,\n trailingSlash = false,\n unstyled = false,\n className,\n}: ClusterNavigationProps) {\n if (!navigation) return null\n\n const siblings = (navigation.siblings || []).filter(\n s => s.article_type !== 'pillar'\n )\n\n const hasPillarLink = !navigation.is_pillar && navigation.pillar\n const hasSiblings = siblings.length > 0\n\n if (!hasPillarLink && !hasSiblings) return null\n\n const articleUrl = (article: { slug: string; category?: string }) => {\n const cat = article.category || category\n const path = cat\n ? `${basePath}/${cat}/${article.slug}`\n : `${basePath}/${article.slug}`\n return trailingSlash ? `${path}/` : path\n }\n\n return (\n <>\n {!unstyled && <style dangerouslySetInnerHTML={{ __html: clusterNavCss }} />}\n\n <nav className={`${unstyled ? '' : 'sk-cluster-nav'} ${className || ''}`}>\n {hasPillarLink && navigation.pillar && (\n <div className={unstyled ? '' : 'sk-cluster-pillar-link'}>\n <p className={unstyled ? '' : 'sk-cluster-pillar-link-label'}>Full Guide</p>\n <a href={articleUrl(navigation.pillar)}>\n {navigation.pillar.title}\n </a>\n </div>\n )}\n\n {hasSiblings && (\n <div>\n <p className={unstyled ? '' : 'sk-cluster-siblings-title'}>\n {navigation.is_pillar ? 'Deep Dives' : 'More in This Series'}\n </p>\n <ul className={unstyled ? '' : 'sk-cluster-siblings-list'}>\n {siblings.map((sibling) => (\n <li key={sibling.slug} className={unstyled ? '' : 'sk-cluster-siblings-item'}>\n <span className={unstyled ? '' : 'sk-cluster-type-badge'}>\n {sibling.article_type}\n </span>\n <a href={articleUrl(sibling)}>{sibling.title}</a>\n </li>\n ))}\n </ul>\n </div>\n )}\n </nav>\n </>\n )\n}\n","/**\n * Post-process Portal/blog HTML for safe, consistent link behavior.\n * Server-safe string transforms only (no DOM).\n */\n\n/** Normalize hostname for same-site detection (strips leading www). */\nexport function normalizeSiteHost(siteUrl: string): string {\n try {\n const base = siteUrl.startsWith('http') ? siteUrl : `https://${siteUrl}`\n const u = new URL(base)\n return u.hostname.replace(/^www\\./i, '').toLowerCase()\n } catch {\n return ''\n }\n}\n\n/**\n * Resolve canonical site URL for link classification.\n * Pass `explicit` from props when env vars are not set (e.g. non-Vercel hosts).\n */\nexport function resolveBlogSiteUrl(explicit?: string): string {\n const fromProp = explicit?.trim()\n if (fromProp) return fromProp\n const next = process.env.NEXT_PUBLIC_SITE_URL?.trim()\n if (next) return next\n const site = process.env.SITE_URL?.trim()\n if (site) return site\n const vercel = process.env.VERCEL_URL?.trim()\n if (vercel) return vercel.startsWith('http') ? vercel : `https://${vercel}`\n return ''\n}\n\n/**\n * Add `target=\"_blank\"` and `rel=\"noopener noreferrer\"` to external http(s) links.\n * Same registrable host (with or without `www`) is treated as internal.\n * Skips anchors that already set `target`.\n */\nexport function addExternalLinkTargets(html: string, siteUrl: string): string {\n if (!html || !siteUrl) return html\n const siteHost = normalizeSiteHost(siteUrl)\n if (!siteHost) return html\n\n return html.replace(/<a\\b([^>]*)>/gi, (_full, attrs: string) => {\n const hrefMatch = attrs.match(/\\bhref\\s*=\\s*([\"'])([^\"']*)\\1/i)\n if (!hrefMatch) return `<a${attrs}>`\n const href = hrefMatch[2].trim()\n if (!/^https?:\\/\\//i.test(href)) return `<a${attrs}>`\n\n try {\n const url = new URL(href)\n const linkHost = url.hostname.replace(/^www\\./i, '').toLowerCase()\n if (linkHost === siteHost) return `<a${attrs}>`\n if (/\\btarget\\s*=/i.test(attrs)) return `<a${attrs}>`\n const trimmed = attrs.trim()\n return `<a ${trimmed} target=\"_blank\" rel=\"noopener noreferrer\">`\n } catch {\n return `<a${attrs}>`\n }\n })\n}\n","import type { BlogPost } from './types'\n\n/**\n * Single source of truth for reading-time display.\n *\n * The DB/API column is `reading_time` (blog_posts) — `reading_time_minutes`\n * never existed server-side and exists on the type only for callers that\n * pre-map their own data. Every \"X min read\" chip resolves through here.\n */\nexport function readingTimeMinutes(\n post: Pick<BlogPost, 'reading_time' | 'reading_time_minutes'>\n): number | null {\n const value = post.reading_time_minutes ?? post.reading_time\n return typeof value === 'number' && value > 0 ? value : null\n}\n","import type { BlogAuthor } from './types'\n\nexport interface AuthorSocialLink {\n label: string\n href: string\n}\n\nconst withPrefix = (value: string, base: string): string =>\n value.startsWith('http') ? value : `${base}${value}`\n\n/**\n * Single source of truth for author social display.\n *\n * The real blog_authors columns are linkedin_url / twitter_url / website_url\n * (E-E-A-T fields); `social_links` / `website` are the legacy shape that no\n * API response ever carried. Real columns win; legacy handles get their host\n * prefixed unless they are already full URLs.\n */\nexport function getAuthorSocialLinks(\n author: Pick<\n BlogAuthor,\n 'linkedin_url' | 'twitter_url' | 'website_url' | 'website' | 'social_links'\n >\n): AuthorSocialLink[] {\n const links: AuthorSocialLink[] = []\n\n const linkedin = author.linkedin_url || author.social_links?.linkedin\n if (linkedin) links.push({ label: 'LinkedIn', href: withPrefix(linkedin, 'https://linkedin.com/in/') })\n\n const twitter = author.twitter_url\n ? author.twitter_url\n : author.social_links?.twitter\n ? withPrefix(author.social_links.twitter, 'https://twitter.com/')\n : null\n if (twitter) links.push({ label: 'Twitter', href: twitter })\n\n const website = author.website_url || author.website\n if (website) links.push({ label: 'Website', href: website })\n\n const github = author.social_links?.github\n if (github) links.push({ label: 'GitHub', href: withPrefix(github, 'https://github.com/') })\n\n return links\n}\n","/**\n * Scoped CSS for BlogPost and BlogList default rendering.\n *\n * Injected via `<style>` in the server component output so consumers\n * get a polished blog with zero configuration.\n *\n * All colours use `--sk-*` CSS custom properties with `color-mix()` fallbacks\n * that adapt to both light and dark host sites. The host can set:\n *\n * --sk-primary Brand accent (links, highlights)\n * --sk-bg Page background\n * --sk-bg-elevated Card / elevated surface background\n * --sk-text-primary Main text\n * --sk-text-secondary Subdued text\n * --sk-text-tertiary Faint text / meta\n * --sk-surface-border Subtle border color\n *\n * If none are set the defaults produce a clean neutral light-mode look.\n */\n\n// ---------------------------------------------------------------------------\n// BlogPost styles\n// ---------------------------------------------------------------------------\n\nexport const blogPostCss = /* css */ `\n/* ===== Layout ===== */\n.sk-blog-article {\n --_sk-primary: var(--sk-primary, #2563eb);\n --_sk-bg: var(--sk-bg, #ffffff);\n --_sk-bg-el: var(--sk-bg-elevated, #f8fafc);\n --_sk-text: var(--sk-text-primary, inherit);\n --_sk-text2: var(--sk-text-secondary, #475569);\n --_sk-text3: var(--sk-text-tertiary, #94a3b8);\n --_sk-border: var(--sk-surface-border, #e2e8f0);\n max-width: 1080px;\n margin: 0 auto;\n padding: 0 1rem;\n color: var(--_sk-text);\n}\n\n/* ===== Header ===== */\n.sk-blog-header { margin-bottom: 2.5rem; }\n\n.sk-blog-breadcrumb {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n margin-bottom: 1.25rem;\n font-size: 0.8125rem;\n color: var(--_sk-text3);\n}\n.sk-blog-breadcrumb a {\n color: var(--_sk-primary);\n text-decoration: none;\n font-weight: 500;\n}\n.sk-blog-breadcrumb a:hover { text-decoration: underline; }\n.sk-blog-breadcrumb-sep { color: var(--_sk-text3); }\n\n.sk-blog-title {\n font-size: 2.5rem;\n font-weight: 800;\n line-height: 1.15;\n letter-spacing: -0.02em;\n text-wrap: balance;\n margin: 0 0 0.75rem;\n color: var(--_sk-text);\n}\n.sk-blog-subtitle {\n font-size: 1.25rem;\n line-height: 1.5;\n color: var(--_sk-text2);\n margin: 0 0 1rem;\n}\n.sk-blog-meta {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 0.5rem;\n font-size: 0.8125rem;\n color: var(--_sk-text3);\n}\n.sk-blog-meta-item { white-space: nowrap; }\n.sk-blog-meta-dot {\n width: 3px; height: 3px;\n border-radius: 50%;\n background: var(--_sk-text3);\n flex-shrink: 0;\n}\n\n/* ===== Featured image ===== */\n.sk-blog-featured-wrap {\n margin: 0 0 2.5rem;\n border-radius: 0.75rem;\n overflow: hidden;\n}\n.sk-blog-featured-img {\n display: block;\n width: 100%;\n max-height: 500px;\n object-fit: cover;\n}\n\n/* ===== Content + TOC grid ===== */\n.sk-blog-layout {\n display: grid;\n grid-template-columns: 1fr;\n gap: 3rem;\n}\n@media (min-width: 1024px) {\n .sk-blog-layout--has-toc {\n grid-template-columns: 1fr 320px;\n }\n}\n\n/* ===== Article body typography ===== */\n.sk-blog-content {\n font-size: 1.125rem;\n line-height: 1.8;\n color: var(--_sk-text);\n overflow-wrap: break-word;\n}\n.sk-blog-content > * + * { margin-top: 1.5em; }\n.sk-blog-content h2,\n.sk-blog-content h3,\n.sk-blog-content h4 {\n scroll-margin-top: 5rem;\n line-height: 1.3;\n font-weight: 700;\n color: var(--_sk-text);\n}\n.sk-blog-content h2 { font-size: 1.5rem; margin-top: 2.5em; margin-bottom: 0.75em; }\n.sk-blog-content h3 { font-size: 1.25rem; margin-top: 2em; margin-bottom: 0.5em; }\n.sk-blog-content h4 { font-size: 1.1rem; margin-top: 1.5em; margin-bottom: 0.5em; }\n.sk-blog-content p { margin: 0 0 1.5em; }\n.sk-blog-content a {\n color: var(--_sk-primary);\n text-decoration: underline;\n text-decoration-color: color-mix(in srgb, var(--_sk-primary) 40%, transparent);\n text-underline-offset: 2px;\n transition: text-decoration-color 0.15s;\n}\n.sk-blog-content a:hover {\n text-decoration-color: var(--_sk-primary);\n}\n.sk-blog-content strong { font-weight: 700; color: var(--_sk-text); }\n.sk-blog-content em { font-style: italic; }\n.sk-blog-content blockquote {\n border-left: 3px solid var(--_sk-primary);\n padding: 0.75em 1.25em;\n margin: 1.5em 0;\n color: var(--_sk-text2);\n font-style: italic;\n background: color-mix(in srgb, var(--_sk-primary) 5%, var(--_sk-bg));\n border-radius: 0 0.5rem 0.5rem 0;\n}\n.sk-blog-content blockquote p:last-child { margin-bottom: 0; }\n.sk-blog-content ul,\n.sk-blog-content ol {\n padding-left: 1.5em;\n margin: 1.25em 0;\n}\n.sk-blog-content li { margin-bottom: 0.5em; }\n.sk-blog-content li::marker { color: var(--_sk-primary); }\n.sk-blog-content code {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 0.875em;\n padding: 0.15em 0.4em;\n border-radius: 0.25rem;\n background: color-mix(in srgb, var(--_sk-text) 8%, var(--_sk-bg));\n}\n.sk-blog-content pre {\n margin: 1.5em 0;\n padding: 1.25em 1.5em;\n border-radius: 0.75rem;\n background: color-mix(in srgb, var(--_sk-text) 6%, var(--_sk-bg));\n overflow-x: auto;\n font-size: 0.875rem;\n line-height: 1.7;\n}\n.sk-blog-content pre code {\n background: none;\n padding: 0;\n font-size: inherit;\n}\n.sk-blog-content img {\n max-width: 100%;\n height: auto;\n border-radius: 0.5rem;\n margin: 1.5em auto;\n display: block;\n}\n.sk-blog-content hr {\n border: none;\n height: 1px;\n background: var(--_sk-border);\n margin: 2.5em 0;\n}\n.sk-blog-content table {\n width: 100%;\n border-collapse: collapse;\n margin: 1.5em 0;\n font-size: 0.95rem;\n}\n.sk-blog-content th,\n.sk-blog-content td {\n text-align: left;\n padding: 0.625rem 0.875rem;\n border-bottom: 1px solid var(--_sk-border);\n}\n.sk-blog-content th {\n font-weight: 600;\n color: var(--_sk-text);\n}\n.sk-blog-content td { color: var(--_sk-text2); }\n\n/* ===== Table of contents ===== */\n.sk-blog-toc {\n position: sticky;\n top: 6rem;\n align-self: start;\n padding: 1.25rem;\n border-radius: 0.75rem;\n background: var(--_sk-bg-el);\n border: 1px solid var(--_sk-border);\n max-height: calc(100vh - 8rem);\n overflow-y: auto;\n scrollbar-width: thin;\n scrollbar-color: var(--_sk-border) transparent;\n}\n.sk-blog-toc::-webkit-scrollbar { width: 5px; }\n.sk-blog-toc::-webkit-scrollbar-track { background: transparent; }\n.sk-blog-toc::-webkit-scrollbar-thumb { background: var(--_sk-border); border-radius: 3px; }\n.sk-blog-toc::-webkit-scrollbar-thumb:hover { background: var(--_sk-text3); }\n.sk-blog-toc-title {\n margin: 0 0 0.75rem;\n font-size: 0.6875rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n color: var(--_sk-text3);\n}\n.sk-blog-toc-list {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n.sk-blog-toc-list li { margin-bottom: 0.4rem; }\n.sk-blog-toc-list a {\n display: block;\n font-size: 0.8125rem;\n line-height: 1.5;\n color: var(--_sk-text2);\n text-decoration: none;\n padding: 0.15rem 0;\n transition: color 0.15s;\n}\n.sk-blog-toc-list a:hover { color: var(--_sk-primary); }\n.sk-blog-toc-indent-3 { padding-left: 0.75rem; }\n.sk-blog-toc-indent-4 { padding-left: 1.5rem; }\n\n@media (max-width: 1023px) {\n .sk-blog-toc { display: none; }\n}\n\n/* ===== Tags ===== */\n.sk-blog-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n margin-top: 2.5rem;\n}\n.sk-blog-tag {\n display: inline-block;\n padding: 0.25rem 0.875rem;\n font-size: 0.8125rem;\n font-weight: 500;\n border-radius: 9999px;\n background: var(--_sk-bg-el);\n border: 1px solid var(--_sk-border);\n color: var(--_sk-text2);\n text-decoration: none;\n transition: color 0.15s, border-color 0.15s;\n}\n.sk-blog-tag:hover {\n color: var(--_sk-primary);\n border-color: color-mix(in srgb, var(--_sk-primary) 40%, transparent);\n}\n\n/* ===== Author card ===== */\n.sk-blog-author {\n margin-top: 3rem;\n padding: 1.5rem;\n border-radius: 0.75rem;\n background: var(--_sk-bg-el);\n border: 1px solid var(--_sk-border);\n display: flex;\n gap: 1.25rem;\n align-items: flex-start;\n}\n.sk-blog-author-avatar {\n width: 72px;\n height: 72px;\n border-radius: 50%;\n object-fit: cover;\n flex-shrink: 0;\n}\n.sk-blog-author-name {\n margin: 0 0 0.125rem;\n font-size: 1.0625rem;\n font-weight: 700;\n color: var(--_sk-text);\n}\n.sk-blog-author-title {\n margin: 0 0 0.25rem;\n font-size: 0.8125rem;\n color: var(--_sk-text3);\n}\n.sk-blog-author-bio {\n margin: 0.5rem 0 0;\n font-size: 0.875rem;\n line-height: 1.6;\n color: var(--_sk-text2);\n}\n.sk-blog-author-links {\n display: flex;\n gap: 1rem;\n margin-top: 0.625rem;\n}\n.sk-blog-author-links a {\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--_sk-primary);\n text-decoration: none;\n}\n.sk-blog-author-links a:hover { text-decoration: underline; }\n\n@media (max-width: 640px) {\n .sk-blog-author { flex-direction: column; align-items: center; text-align: center; }\n .sk-blog-author-links { justify-content: center; }\n}\n\n/* ===== Related posts ===== */\n.sk-blog-related { margin-top: 3.5rem; }\n.sk-blog-related-title {\n font-size: 1.375rem;\n font-weight: 700;\n margin: 0 0 1.5rem;\n color: var(--_sk-text);\n}\n.sk-blog-related-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));\n gap: 1.25rem;\n}\n.sk-blog-related-card {\n border-radius: 0.75rem;\n overflow: hidden;\n background: var(--_sk-bg-el);\n border: 1px solid var(--_sk-border);\n text-decoration: none;\n color: inherit;\n display: flex;\n flex-direction: column;\n transition: transform 0.2s, box-shadow 0.2s;\n}\n.sk-blog-related-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 24px rgba(0,0,0,0.08);\n}\n.sk-blog-related-card img {\n width: 100%;\n height: 160px;\n object-fit: cover;\n}\n.sk-blog-related-card-body { padding: 1rem 1.125rem; }\n.sk-blog-related-card h3 {\n font-size: 0.9375rem;\n font-weight: 650;\n line-height: 1.4;\n margin: 0 0 0.375rem;\n color: var(--_sk-text);\n}\n.sk-blog-related-card p {\n font-size: 0.8125rem;\n line-height: 1.5;\n color: var(--_sk-text2);\n margin: 0;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* ===== Not found ===== */\n.sk-blog-not-found {\n text-align: center;\n padding: 5rem 1rem;\n}\n.sk-blog-not-found h1 {\n font-size: 1.5rem;\n font-weight: 700;\n margin: 0 0 0.75rem;\n color: var(--_sk-text);\n}\n.sk-blog-not-found p {\n color: var(--_sk-text2);\n margin: 0 0 1.5rem;\n}\n.sk-blog-not-found a {\n display: inline-block;\n padding: 0.75rem 1.5rem;\n border-radius: 0.5rem;\n background: var(--_sk-primary);\n color: #fff;\n font-weight: 600;\n font-size: 0.875rem;\n text-decoration: none;\n transition: opacity 0.15s;\n}\n.sk-blog-not-found a:hover { opacity: 0.9; }\n\n/* ===== Responsive ===== */\n@media (max-width: 768px) {\n .sk-blog-title { font-size: 1.75rem; }\n .sk-blog-subtitle { font-size: 1.0625rem; }\n .sk-blog-content { font-size: 1rem; }\n .sk-blog-related-grid { grid-template-columns: 1fr; }\n}\n`.trim()\n\n// ---------------------------------------------------------------------------\n// BlogList styles\n// ---------------------------------------------------------------------------\n\nexport const blogListCss = /* css */ `\n/* ===== BlogList layout ===== */\n.sk-bloglist {\n --_sk-primary: var(--sk-primary, #2563eb);\n --_sk-bg: var(--sk-bg, #ffffff);\n --_sk-bg-el: var(--sk-bg-elevated, #f8fafc);\n --_sk-text: var(--sk-text-primary, inherit);\n --_sk-text2: var(--sk-text-secondary, #475569);\n --_sk-text3: var(--sk-text-tertiary, #94a3b8);\n --_sk-border: var(--sk-surface-border, #e2e8f0);\n}\n\n/* ===== Category filter ===== */\n.sk-bloglist-cats {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n margin-bottom: 2rem;\n}\n.sk-bloglist-cat {\n display: inline-block;\n padding: 0.375rem 1rem;\n border-radius: 9999px;\n font-size: 0.8125rem;\n font-weight: 600;\n text-decoration: none;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n border: 1px solid var(--_sk-border);\n background: var(--_sk-bg-el);\n color: var(--_sk-text2);\n}\n.sk-bloglist-cat:hover {\n border-color: color-mix(in srgb, var(--_sk-primary) 40%, transparent);\n color: var(--_sk-primary);\n}\n.sk-bloglist-cat--active {\n background: var(--_sk-primary);\n color: #fff;\n border-color: var(--_sk-primary);\n}\n.sk-bloglist-cat--active:hover { color: #fff; opacity: 0.9; }\n\n/* ===== Card grid ===== */\n.sk-bloglist-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 1.5rem;\n}\n\n/* ===== Post card ===== */\n.sk-bloglist-card {\n border-radius: 0.75rem;\n overflow: hidden;\n background: var(--_sk-bg-el);\n border: 1px solid var(--_sk-border);\n display: flex;\n flex-direction: column;\n transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;\n}\n.sk-bloglist-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 24px rgba(0,0,0,0.08);\n border-color: color-mix(in srgb, var(--_sk-primary) 30%, var(--_sk-border));\n}\n.sk-bloglist-card-img-link { display: block; overflow: hidden; }\n.sk-bloglist-card-img {\n display: block;\n width: 100%;\n height: 200px;\n object-fit: cover;\n transition: transform 0.4s;\n}\n.sk-bloglist-card:hover .sk-bloglist-card-img { transform: scale(1.03); }\n.sk-bloglist-card-body {\n padding: 1.25rem;\n display: flex;\n flex-direction: column;\n flex: 1;\n}\n.sk-bloglist-card-meta {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n margin-bottom: 0.625rem;\n}\n.sk-bloglist-card-category {\n display: inline-block;\n padding: 0.125rem 0.5rem;\n border-radius: 0.25rem;\n font-size: 0.6875rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n background: color-mix(in srgb, var(--_sk-primary) 12%, transparent);\n color: var(--_sk-primary);\n}\n.sk-bloglist-card-date {\n font-size: 0.8125rem;\n color: var(--_sk-text3);\n}\n.sk-bloglist-card-title {\n font-size: 1.0625rem;\n font-weight: 700;\n line-height: 1.4;\n margin: 0 0 0.5rem;\n}\n.sk-bloglist-card-title a {\n color: var(--_sk-text);\n text-decoration: none;\n transition: color 0.15s;\n}\n.sk-bloglist-card:hover .sk-bloglist-card-title a { color: var(--_sk-primary); }\n.sk-bloglist-card-excerpt {\n font-size: 0.875rem;\n line-height: 1.6;\n color: var(--_sk-text2);\n margin: 0 0 1rem;\n display: -webkit-box;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n overflow: hidden;\n flex: 1;\n}\n.sk-bloglist-card-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-top: 0.75rem;\n border-top: 1px solid var(--_sk-border);\n font-size: 0.8125rem;\n color: var(--_sk-text3);\n}\n\n/* ===== Pagination ===== */\n.sk-bloglist-pagination {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 0.75rem;\n margin-top: 3rem;\n}\n.sk-bloglist-page-link {\n display: inline-block;\n padding: 0.5rem 1.25rem;\n border-radius: 0.5rem;\n background: var(--_sk-primary);\n color: #fff;\n font-size: 0.875rem;\n font-weight: 600;\n text-decoration: none;\n transition: opacity 0.15s;\n}\n.sk-bloglist-page-link:hover { opacity: 0.9; }\n.sk-bloglist-page-info {\n font-size: 0.8125rem;\n color: var(--_sk-text3);\n}\n\n/* ===== Empty state ===== */\n.sk-bloglist-empty {\n text-align: center;\n padding: 3rem 1rem;\n color: var(--_sk-text2);\n}\n\n/* ===== Responsive ===== */\n@media (max-width: 640px) {\n .sk-bloglist-grid { grid-template-columns: 1fr; }\n}\n`.trim()\n","/**\n * @sonordev/site-kit/blog - Blog Post Component\n *\n * Fetches and displays a single blog post with full content, table of contents,\n * author info, related posts, and SEO metadata support.\n *\n * Ships with world-class default styling via scoped `.sk-blog-*` classes.\n * No configuration needed — just `<BlogPost slug={slug} />`.\n *\n * Override with `styles` prop (per-element class names) or `unstyled` for\n * complete control. The `children` render prop gives full data access.\n */\n\nimport React from 'react'\nimport { marked } from 'marked'\nimport type { BlogPost as BlogPostType, TocItem, BlogAuthor, ClusterNavigation as ClusterNavigationType } from './types'\nimport { ServiceCallouts } from './ServiceCallout'\nimport { readingTimeMinutes } from './reading-time'\nimport { getAuthorSocialLinks } from './author-social'\nimport { ClusterNavigation } from './ClusterNavigation'\nimport { addExternalLinkTargets, resolveBlogSiteUrl } from './processBlogHtml'\nimport { blogPostCss } from './blog-styles'\n\n/**\n * Extract cluster navigation from a post's cluster fields (pure function, no\n * API calls). Mirrored copy: server-core.ts getClusterNavigation is\n * identical. Keep the two in sync — they CANNOT be consolidated because\n * blog/index is a CLIENT_ENTRY that must never import blog/server-core (see\n * build-entries.ts and client-entry-boundary.test.ts).\n */\nfunction getClusterNav(post: Record<string, any>): ClusterNavigationType | null {\n if (!post.cluster_id && !post.cluster_slug) return null\n const isPillar = post.article_type === 'pillar'\n return {\n cluster_name: post.cluster_name || '',\n cluster_slug: post.cluster_slug || '',\n pillar: isPillar ? null\n : post.parent_pillar_slug\n ? {\n slug: post.parent_pillar_slug,\n title: post.parent_pillar_title || '',\n category: post.parent_pillar_category || undefined,\n }\n : null,\n siblings: post.sibling_articles || [],\n is_pillar: isPillar,\n }\n}\n\n// ============================================================================\n// Markdown helpers\n// ============================================================================\n\nfunction looksLikeMarkdown(text: string): boolean {\n if (text.trimStart().startsWith('<')) return false\n const markers = [/^#{1,6}\\s/m, /\\*\\*[^*]+\\*\\*/, /\\[([^\\]]+)\\]\\([^)]+\\)/, /^[-*]\\s/m, /^>\\s/m]\n let hits = 0\n for (const re of markers) if (re.test(text)) hits++\n return hits >= 2\n}\n\nfunction slugify(text: string): string {\n return text.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '')\n}\n\n/** Convert markdown to HTML if needed, and inject IDs into headings for TOC anchors. */\nfunction ensureHtml(raw: string): string {\n if (!raw) return raw\n let html = raw\n if (looksLikeMarkdown(html)) {\n html = marked.parse(html, { gfm: true, breaks: false, async: false }) as string\n }\n html = injectHeadingIds(html)\n return html\n}\n\n/** Add `id` attributes to h2-h4 that lack them so TOC anchor links work. */\nfunction injectHeadingIds(html: string): string {\n return html.replace(/<h([2-4])([^>]*)>(.*?)<\\/h[2-4]>/gi, (_full, level, attrs: string, inner: string) => {\n if (/\\bid\\s*=/i.test(attrs)) return _full\n const text = inner.replace(/<[^>]*>/g, '')\n const id = slugify(text)\n return `<h${level}${attrs} id=\"${id}\">${inner}</h${level}>`\n })\n}\n\n// ============================================================================\n// STYLE TYPES\n// ============================================================================\n\nexport interface BlogPostStyles {\n article?: string\n header?: string\n breadcrumb?: string\n breadcrumbLink?: string\n title?: string\n subtitle?: string\n meta?: string\n metaItem?: string\n featuredImageWrapper?: string\n featuredImage?: string\n contentLayout?: string\n content?: string\n tocSidebar?: string\n tocTitle?: string\n tocList?: string\n tocItem?: string\n tocLink?: string\n tags?: string\n tag?: string\n faqSection?: string\n faqTitle?: string\n faqItem?: string\n faqQuestion?: string\n faqAnswer?: string\n authorCard?: string\n relatedSection?: string\n relatedTitle?: string\n relatedGrid?: string\n relatedCard?: string\n notFound?: string\n}\n\n// ============================================================================\n// DATA FETCHING\n// ============================================================================\n\nasync function fetchBlogPost(apiUrl: string, apiKey: string, slug: string): Promise<BlogPostType | null> {\n try {\n const response = await fetch(`${apiUrl}/public/blog/posts/${slug}`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 60 },\n })\n if (!response.ok) {\n if (response.status === 404) return null\n console.error('[Blog] Failed to fetch post:', response.statusText)\n return null\n }\n const data = await response.json()\n return data.post\n } catch (error) {\n console.error('[Blog] Error fetching post:', error)\n return null\n }\n}\n\nasync function fetchRelatedPosts(apiUrl: string, apiKey: string, postId: string, limit: number = 3): Promise<BlogPostType[]> {\n try {\n const response = await fetch(`${apiUrl}/public/blog/related`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n body: JSON.stringify({ current_post_id: postId, limit }),\n next: { revalidate: 300 },\n })\n if (!response.ok) return []\n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('[Blog] Error fetching related posts:', error)\n return []\n }\n}\n\n// ============================================================================\n// TOC GENERATION\n// ============================================================================\n\nfunction generateTableOfContents(html: string): TocItem[] {\n const headingRegex = /<h([2-4])[^>]*(?:id=\"([^\"]*)\")?[^>]*>(.*?)<\\/h[2-4]>/gi\n const items: TocItem[] = []\n let match\n while ((match = headingRegex.exec(html)) !== null) {\n const level = parseInt(match[1])\n const existingId = match[2]\n const text = match[3].replace(/<[^>]*>/g, '')\n const id = existingId || slugify(text)\n items.push({ id, text, level })\n }\n return items\n}\n\n// ============================================================================\n// COMPONENT PROPS\n// ============================================================================\n\nexport interface BlogPostServerProps {\n apiUrl?: string\n apiKey?: string\n slug: string\n showToc?: boolean\n showRelated?: boolean\n relatedCount?: number\n showAuthor?: boolean\n basePath?: string\n className?: string\n styles?: BlogPostStyles\n unstyled?: boolean\n siteUrl?: string\n children?: (props: {\n post: BlogPostType\n tableOfContents: TocItem[]\n relatedPosts: BlogPostType[]\n }) => React.ReactNode\n}\n\n// ============================================================================\n// CLASS HELPER — pick custom `styles` class or default `.sk-blog-*` class\n// ============================================================================\n\nfunction cls(unstyled: boolean, styles: BlogPostStyles, key: keyof BlogPostStyles, defaultClass: string, extra?: string): string | undefined {\n if (unstyled) return styles[key] || undefined\n const base = styles[key] || defaultClass\n return extra ? `${base} ${extra}` : base\n}\n\n// ============================================================================\n// BLOG POST COMPONENT\n// ============================================================================\n\nexport async function BlogPost({\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n apiKey = process.env.SONOR_API_KEY || '',\n slug,\n showToc = true,\n showRelated = true,\n relatedCount = 3,\n showAuthor = true,\n basePath = '/blog',\n className,\n styles = {},\n unstyled = false,\n siteUrl,\n children,\n}: BlogPostServerProps) {\n if (!apiKey) {\n console.warn('[Blog] No API key configured')\n return null\n }\n\n const post = await fetchBlogPost(apiUrl, apiKey, slug)\n\n // ---------- NOT FOUND ----------\n if (!post) {\n return (\n <>\n {!unstyled && <style dangerouslySetInnerHTML={{ __html: blogPostCss }} />}\n <div className={cls(unstyled, styles, 'notFound', 'sk-blog-not-found', className)}>\n <h1>Post Not Found</h1>\n <p>The blog post you&rsquo;re looking for doesn&rsquo;t exist or has been removed.</p>\n <a href={basePath}>&larr; Back to Blog</a>\n </div>\n </>\n )\n }\n\n // ---------- PREPARE DATA ----------\n const rawContent = post.content_html || post.content || ''\n const content = ensureHtml(rawContent)\n const siteUrlResolved = resolveBlogSiteUrl(siteUrl)\n const contentWithExternalTargets = addExternalLinkTargets(content, siteUrlResolved)\n const tableOfContents = showToc ? generateTableOfContents(content) : []\n const relatedPosts = showRelated ? await fetchRelatedPosts(apiUrl, apiKey, post.id, relatedCount) : []\n\n const faqRaw = (post.faq_items ?? (post as { faqItems?: unknown }).faqItems) as Array<{ question: string; answer: string }> | undefined\n const faqItemsProcessed = faqRaw?.map((item) => ({\n ...item,\n answer: addExternalLinkTargets(item.answer || '', siteUrlResolved),\n })) ?? faqRaw\n\n // Client islands, dynamically imported so tsup splits + 'use client'-stamps\n // their chunks (same pattern for both).\n const { BlogViewTracker } = await import('./BlogViewTracker')\n\n // ---------- CUSTOM RENDER ----------\n if (children) {\n return (\n <>\n <BlogViewTracker slug={post.slug} />\n {children({ post, tableOfContents, relatedPosts })}\n </>\n )\n }\n\n const { BlogPostFaqSection } = await import('./BlogPostFaqSection')\n\n const date = post.published_at\n ? new Date(post.published_at).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })\n : null\n\n const hasToc = showToc && tableOfContents.length > 0\n\n return (\n <>\n {!unstyled && <style dangerouslySetInnerHTML={{ __html: blogPostCss }} />}\n <BlogViewTracker slug={post.slug} />\n\n <article className={cls(unstyled, styles, 'article', 'sk-blog-article', className)}>\n {/* ===== Header ===== */}\n <header className={cls(unstyled, styles, 'header', 'sk-blog-header')}>\n <nav className={cls(unstyled, styles, 'breadcrumb', 'sk-blog-breadcrumb')}>\n <a href={basePath} className={styles.breadcrumbLink || undefined}>Blog</a>\n {post.category && (\n <>\n <span className=\"sk-blog-breadcrumb-sep\">/</span>\n <a\n href={`${basePath}?category=${post.category}`}\n className={styles.breadcrumbLink || undefined}\n >\n {typeof post.category === 'string' ? post.category : (post.category as any)?.name || 'Uncategorized'}\n </a>\n </>\n )}\n </nav>\n\n <h1 className={cls(unstyled, styles, 'title', 'sk-blog-title')}>{post.title}</h1>\n\n {post.subtitle && (\n <p className={cls(unstyled, styles, 'subtitle', 'sk-blog-subtitle')}>{post.subtitle}</p>\n )}\n\n <div className={cls(unstyled, styles, 'meta', 'sk-blog-meta')}>\n {post.author && (\n <span className={cls(unstyled, styles, 'metaItem', 'sk-blog-meta-item')}>\n By {typeof post.author === 'string' ? post.author : post.author.name}\n </span>\n )}\n {post.author && date && <span className=\"sk-blog-meta-dot\" />}\n {date && (\n <span className={cls(unstyled, styles, 'metaItem', 'sk-blog-meta-item')}>{date}</span>\n )}\n {date && readingTimeMinutes(post) && <span className=\"sk-blog-meta-dot\" />}\n {readingTimeMinutes(post) && (\n <span className={cls(unstyled, styles, 'metaItem', 'sk-blog-meta-item')}>\n {readingTimeMinutes(post)} min read\n </span>\n )}\n </div>\n </header>\n\n {/* ===== Featured Image ===== */}\n {post.featured_image && (\n <figure className={cls(unstyled, styles, 'featuredImageWrapper', 'sk-blog-featured-wrap')}>\n <img\n src={post.featured_image}\n alt={post.featured_image_alt || post.title}\n className={cls(unstyled, styles, 'featuredImage', 'sk-blog-featured-img')}\n />\n </figure>\n )}\n\n {/* ===== Content + TOC ===== */}\n <div className={cls(unstyled, styles, 'contentLayout', hasToc ? 'sk-blog-layout sk-blog-layout--has-toc' : 'sk-blog-layout')}>\n <div\n className={cls(unstyled, styles, 'content', 'sk-blog-content')}\n dangerouslySetInnerHTML={{ __html: contentWithExternalTargets }}\n />\n\n {hasToc && (\n <aside className={cls(unstyled, styles, 'tocSidebar', 'sk-blog-toc')}>\n <h4 className={cls(unstyled, styles, 'tocTitle', 'sk-blog-toc-title')}>On This Page</h4>\n <ul className={cls(unstyled, styles, 'tocList', 'sk-blog-toc-list')}>\n {tableOfContents.map((item) => (\n <li\n key={item.id}\n className={cls(unstyled, styles, 'tocItem', item.level > 2 ? `sk-blog-toc-indent-${item.level}` : '')}\n >\n <a href={`#${item.id}`} className={styles.tocLink || undefined}>{item.text}</a>\n </li>\n ))}\n </ul>\n </aside>\n )}\n </div>\n\n {/* ===== Tags ===== */}\n {post.tags && post.tags.length > 0 && (\n <div className={cls(unstyled, styles, 'tags', 'sk-blog-tags')}>\n {post.tags.map((tag, index) => {\n const tagName = typeof tag === 'string' ? tag : tag?.name || ''\n return (\n <a key={`${tagName}-${index}`} href={`${basePath}?tag=${encodeURIComponent(tagName)}`} className={cls(unstyled, styles, 'tag', 'sk-blog-tag')}>\n #{tagName}\n </a>\n )\n })}\n </div>\n )}\n\n {/* ===== Service Callouts ===== */}\n <ServiceCallouts\n callouts={(post as any).service_callouts ?? (post as any).serviceCallouts ?? []}\n unstyled={unstyled}\n />\n\n {/* ===== FAQ ===== */}\n <BlogPostFaqSection\n items={(faqItemsProcessed ?? []) as any[]}\n unstyled={unstyled}\n styles={unstyled ? {\n section: styles.faqSection,\n title: styles.faqTitle,\n item: styles.faqItem,\n question: styles.faqQuestion,\n answerInner: styles.faqAnswer,\n } : undefined}\n />\n\n {/* ===== Author ===== */}\n {showAuthor && post.author && typeof post.author === 'object' && (\n <AuthorSection author={normalizeAuthorForDisplay(post.author)} className={styles.authorCard} unstyled={unstyled} />\n )}\n\n {/* ===== Cluster Navigation ===== */}\n {(() => {\n const clusterNav = getClusterNav(post as any)\n if (!clusterNav) return null\n return (\n <ClusterNavigation\n navigation={clusterNav}\n basePath={basePath}\n unstyled={unstyled}\n />\n )\n })()}\n\n {/* ===== Related Posts ===== */}\n {showRelated && relatedPosts.length > 0 && (\n <section className={cls(unstyled, styles, 'relatedSection', 'sk-blog-related')}>\n <h2 className={cls(unstyled, styles, 'relatedTitle', 'sk-blog-related-title')}>Related Posts</h2>\n <div className={cls(unstyled, styles, 'relatedGrid', 'sk-blog-related-grid')}>\n {relatedPosts.map((rp) => (\n <a key={rp.id} href={`${basePath}/${rp.slug}`} className={cls(unstyled, styles, 'relatedCard', 'sk-blog-related-card')}>\n {rp.featured_image && <img src={rp.featured_image} alt={rp.title} />}\n <div className=\"sk-blog-related-card-body\">\n <h3>{rp.title}</h3>\n {rp.excerpt && <p>{rp.excerpt.slice(0, 120)}...</p>}\n </div>\n </a>\n ))}\n </div>\n </section>\n )}\n </article>\n </>\n )\n}\n\n// ============================================================================\n// AUTHOR HELPERS\n// ============================================================================\n\nfunction normalizeAuthorForDisplay(author: Record<string, unknown> | BlogAuthor): BlogAuthor & { sameAs?: string[]; title?: string } {\n const a = author as Record<string, unknown>\n return {\n id: (a.id as string) ?? 'author',\n project_id: (a.project_id as string) ?? '',\n name: (a.name as string) ?? 'Author',\n slug: (a.slug as string) ?? 'author',\n bio: (a.bio as string) ?? undefined,\n avatar_url: (a.avatar_url as string) ?? (a.image as string) ?? (a.image_url as string) ?? undefined,\n website: (a.website as string) ?? (a.url as string) ?? undefined,\n social_links: a.social_links as BlogAuthor['social_links'] | undefined,\n // Real API columns (blog_authors) — previously dropped here, so\n // AuthorSection could never render socials from a live author row.\n linkedin_url: (a.linkedin_url as string) ?? undefined,\n twitter_url: (a.twitter_url as string) ?? undefined,\n website_url: (a.website_url as string) ?? undefined,\n same_as: (a.same_as as string[]) ?? undefined,\n is_active: (a.is_active as boolean) ?? true,\n ...(normalizeSocialProfiles(a.socialProfiles).length\n ? { sameAs: normalizeSocialProfiles(a.socialProfiles) }\n : {}),\n ...(a.title ? { title: a.title as string } : {}),\n } as BlogAuthor & { sameAs?: string[]; title?: string }\n}\n\n/**\n * socialProfiles arrives as either string[] (site config) or the\n * {linkedin, twitter} object sonor-api emits — accept both into sameAs.\n */\nfunction normalizeSocialProfiles(value: unknown): string[] {\n if (Array.isArray(value)) return value.filter((v): v is string => typeof v === 'string' && !!v)\n if (value && typeof value === 'object') {\n return Object.values(value as Record<string, unknown>).filter(\n (v): v is string => typeof v === 'string' && !!v\n )\n }\n return []\n}\n\nfunction AuthorSection({ author, className, unstyled = false }: { author: BlogAuthor & { sameAs?: string[]; title?: string }; className?: string; unstyled?: boolean }) {\n const base = unstyled ? className : (className || 'sk-blog-author')\n const socialLinks = getAuthorSocialLinks(author)\n return (\n <section className={base || undefined}>\n {author.avatar_url && <img src={author.avatar_url} alt={author.name} className={unstyled ? undefined : 'sk-blog-author-avatar'} />}\n <div>\n <h3 className={unstyled ? undefined : 'sk-blog-author-name'}>{author.name}</h3>\n {'title' in author && author.title && <p className={unstyled ? undefined : 'sk-blog-author-title'}>{author.title}</p>}\n {author.bio && <p className={unstyled ? undefined : 'sk-blog-author-bio'}>{author.bio}</p>}\n {socialLinks.length > 0 && (\n <div className={unstyled ? undefined : 'sk-blog-author-links'}>\n {socialLinks.map((link) => <a key={link.label} href={link.href} target=\"_blank\" rel=\"noopener noreferrer\">{link.label}</a>)}\n </div>\n )}\n {'sameAs' in author && author.sameAs && author.sameAs.length > 0 && socialLinks.length === 0 && (\n <div className={unstyled ? undefined : 'sk-blog-author-links'}>\n {author.sameAs.map((url, i) => <a key={i} href={url} target=\"_blank\" rel=\"noopener noreferrer\">Profile</a>)}\n </div>\n )}\n </div>\n </section>\n )\n}\n","/**\n * @sonordev/site-kit/blog - Blog List Component\n *\n * Fetches and displays a list of blog posts with pagination, filtering, and sorting.\n *\n * Ships with world-class default styling via scoped `.sk-bloglist-*` classes.\n * No configuration needed — just `<BlogList basePath=\"/blog\" />`.\n *\n * Override with `styles` prop (per-element class names) or `unstyled` for\n * complete control. The `children` render prop gives full data access.\n */\n\nimport React from 'react'\nimport type { BlogListResult, BlogPost, BlogCategory } from './types'\nimport { blogListCss } from './blog-styles'\nimport { readingTimeMinutes } from './reading-time'\n\n// ============================================================================\n// STYLE TYPES\n// ============================================================================\n\nexport interface BlogListStyles {\n container?: string\n categoryNav?: string\n categoryLink?: string\n categoryLinkActive?: string\n categoryLinkInactive?: string\n grid?: string\n card?: string\n cardImageWrapper?: string\n cardImage?: string\n cardBody?: string\n cardMeta?: string\n cardCategory?: string\n cardDate?: string\n cardTitle?: string\n cardTitleLink?: string\n cardExcerpt?: string\n cardFooter?: string\n cardAuthor?: string\n cardReadingTime?: string\n cardReadMore?: string\n pagination?: string\n paginationLink?: string\n paginationInfo?: string\n emptyState?: string\n}\n\n// ============================================================================\n// DATA FETCHING\n// ============================================================================\n\ninterface FetchBlogListParams {\n apiUrl: string\n apiKey: string\n category?: string\n tag?: string\n author?: string\n featured?: boolean\n search?: string\n /** Topic cluster slug — the server resolves it to cluster_id */\n cluster?: string\n page?: number\n perPage?: number\n orderBy?: 'published_at' | 'title' | 'view_count'\n order?: 'asc' | 'desc'\n}\n\nasync function fetchBlogList(params: FetchBlogListParams): Promise<BlogListResult> {\n const {\n apiUrl,\n apiKey,\n category,\n tag,\n author,\n featured,\n search,\n cluster,\n page = 1,\n perPage = 12,\n orderBy = 'published_at',\n order = 'desc',\n } = params\n\n const queryParams = new URLSearchParams()\n if (category) queryParams.set('category', category)\n if (tag) queryParams.set('tag', tag)\n if (author) queryParams.set('author', author)\n if (featured) queryParams.set('featured', 'true')\n if (search) queryParams.set('search', search)\n if (cluster) queryParams.set('cluster', cluster)\n queryParams.set('page', String(page))\n queryParams.set('per_page', String(perPage))\n queryParams.set('order_by', orderBy)\n queryParams.set('order', order)\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/posts?${queryParams}`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 60 },\n })\n\n if (!response.ok) {\n console.error('[Blog] Failed to fetch posts:', response.statusText)\n return emptyResult()\n }\n\n const data = await response.json()\n return {\n posts: data.posts || [],\n pagination: {\n page: data.pagination?.page || 1,\n perPage: data.pagination?.per_page || 12,\n total: data.pagination?.total || 0,\n totalPages: data.pagination?.total_pages || 0,\n hasNext: data.pagination?.has_next || false,\n hasPrev: data.pagination?.has_prev || false,\n },\n }\n } catch (error) {\n console.error('[Blog] Error fetching posts:', error)\n return emptyResult()\n }\n}\n\nfunction emptyResult(): BlogListResult {\n return { posts: [], pagination: { page: 1, perPage: 12, total: 0, totalPages: 0, hasNext: false, hasPrev: false } }\n}\n\nasync function fetchCategories(apiUrl: string, apiKey: string): Promise<BlogCategory[]> {\n try {\n const response = await fetch(`${apiUrl}/public/blog/categories`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n if (!response.ok) return []\n const data = await response.json()\n return data.categories || []\n } catch (error) {\n console.error('[Blog] Error fetching categories:', error)\n return []\n }\n}\n\n// ============================================================================\n// CLASS HELPER\n// ============================================================================\n\nfunction cls(unstyled: boolean, styles: BlogListStyles, key: keyof BlogListStyles, defaultClass: string, extra?: string): string | undefined {\n if (unstyled) return styles[key] || undefined\n const base = styles[key] || defaultClass\n return extra ? `${base} ${extra}` : base\n}\n\n// ============================================================================\n// BLOG LIST COMPONENT\n// ============================================================================\n\nexport interface BlogListServerProps {\n apiUrl?: string\n apiKey?: string\n category?: string\n tag?: string\n /** Author slug (preferred) or display name; slug filtering requires the current Sonor API */\n author?: string\n featured?: boolean\n search?: string\n /**\n * Topic cluster slug — pairs with getTopicCluster. Note: an unknown slug\n * yields an UNfiltered list (pre-existing API behavior).\n */\n cluster?: string\n page?: number\n perPage?: number\n orderBy?: 'published_at' | 'title' | 'view_count'\n order?: 'asc' | 'desc'\n showCategoryFilter?: boolean\n showPagination?: boolean\n className?: string\n basePath?: string\n styles?: BlogListStyles\n unstyled?: boolean\n renderPost?: (post: BlogPost) => React.ReactNode\n children?: (props: {\n posts: BlogPost[]\n pagination: BlogListResult['pagination']\n categories: BlogCategory[]\n }) => React.ReactNode\n}\n\nexport async function BlogList({\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n apiKey = process.env.SONOR_API_KEY || '',\n category,\n tag,\n author,\n featured,\n search,\n cluster,\n page = 1,\n perPage = 12,\n orderBy = 'published_at',\n order = 'desc',\n showCategoryFilter = false,\n showPagination = true,\n className,\n basePath = '/blog',\n styles = {},\n unstyled = false,\n renderPost,\n children,\n}: BlogListServerProps) {\n if (!apiKey) {\n console.warn('[Blog] No API key configured')\n return null\n }\n\n const [blogData, categories] = await Promise.all([\n fetchBlogList({ apiUrl, apiKey, category, tag, author, featured, search, cluster, page, perPage, orderBy, order }),\n showCategoryFilter ? fetchCategories(apiUrl, apiKey) : Promise.resolve([]),\n ])\n\n if (children) {\n return children({ posts: blogData.posts, pagination: blogData.pagination, categories })\n }\n\n const { posts, pagination } = blogData\n\n // ---------- EMPTY STATE ----------\n if (posts.length === 0) {\n return (\n <>\n {!unstyled && <style dangerouslySetInnerHTML={{ __html: blogListCss }} />}\n <div className={cls(unstyled, styles, 'emptyState', 'sk-bloglist sk-bloglist-empty', className)}>\n <p>No posts found.</p>\n </div>\n </>\n )\n }\n\n return (\n <>\n {!unstyled && <style dangerouslySetInnerHTML={{ __html: blogListCss }} />}\n\n <div className={cls(unstyled, styles, 'container', 'sk-bloglist', className)}>\n {/* Category Filter */}\n {showCategoryFilter && categories.length > 0 && (\n <nav className={cls(unstyled, styles, 'categoryNav', 'sk-bloglist-cats')}>\n <a\n href={basePath}\n className={cls(unstyled, styles, 'categoryLink', !category ? 'sk-bloglist-cat sk-bloglist-cat--active' : 'sk-bloglist-cat')}\n >\n All\n </a>\n {categories.map((cat) => (\n <a\n key={cat.slug}\n href={`${basePath}?category=${cat.slug}`}\n className={cls(unstyled, styles, 'categoryLink', category === cat.slug ? 'sk-bloglist-cat sk-bloglist-cat--active' : 'sk-bloglist-cat')}\n >\n {cat.name} ({cat.post_count})\n </a>\n ))}\n </nav>\n )}\n\n {/* Blog Grid */}\n <div className={cls(unstyled, styles, 'grid', 'sk-bloglist-grid')}>\n {posts.map((post) =>\n renderPost ? (\n <React.Fragment key={post.id}>{renderPost(post)}</React.Fragment>\n ) : (\n <BlogPostCard key={post.id} post={post} basePath={basePath} styles={styles} unstyled={unstyled} />\n )\n )}\n </div>\n\n {/* Pagination */}\n {showPagination && pagination.totalPages > 1 && (\n <nav className={cls(unstyled, styles, 'pagination', 'sk-bloglist-pagination')}>\n {pagination.hasPrev && (\n <a href={buildPaginationUrl(basePath, page - 1, category)} className={cls(unstyled, styles, 'paginationLink', 'sk-bloglist-page-link')}>\n &larr; Previous\n </a>\n )}\n <span className={cls(unstyled, styles, 'paginationInfo', 'sk-bloglist-page-info')}>\n Page {pagination.page} of {pagination.totalPages}\n </span>\n {pagination.hasNext && (\n <a href={buildPaginationUrl(basePath, page + 1, category)} className={cls(unstyled, styles, 'paginationLink', 'sk-bloglist-page-link')}>\n Next &rarr;\n </a>\n )}\n </nav>\n )}\n </div>\n </>\n )\n}\n\n// ============================================================================\n// BLOG POST CARD (Default rendering)\n// ============================================================================\n\ninterface BlogPostCardProps {\n post: BlogPost\n basePath: string\n styles?: BlogListStyles\n unstyled?: boolean\n}\n\nfunction BlogPostCard({ post, basePath, styles = {}, unstyled = false }: BlogPostCardProps) {\n const date = post.published_at\n ? new Date(post.published_at).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })\n : null\n\n return (\n <article className={cls(unstyled, styles, 'card', 'sk-bloglist-card')}>\n {post.featured_image && (\n <a href={`${basePath}/${post.slug}`} className={cls(unstyled, styles, 'cardImageWrapper', 'sk-bloglist-card-img-link')}>\n <img\n src={post.featured_image}\n alt={post.featured_image_alt || post.title}\n className={cls(unstyled, styles, 'cardImage', 'sk-bloglist-card-img')}\n />\n </a>\n )}\n\n <div className={cls(unstyled, styles, 'cardBody', 'sk-bloglist-card-body')}>\n {/* Meta */}\n <div className={cls(unstyled, styles, 'cardMeta', 'sk-bloglist-card-meta')}>\n {post.category && (\n <span className={cls(unstyled, styles, 'cardCategory', 'sk-bloglist-card-category')}>\n {typeof post.category === 'string' ? post.category : post.category?.name || 'Uncategorized'}\n </span>\n )}\n {(post as any).article_type && (\n <span className=\"sk-bloglist-card-article-type\" style={{\n display: 'inline-flex', alignItems: 'center',\n padding: '0.0625rem 0.375rem', borderRadius: '9999px',\n fontSize: '0.6875rem', fontWeight: 500,\n background: (post as any).article_type === 'pillar' ? 'rgba(99,102,241,0.1)' : 'rgba(99,102,241,0.05)',\n color: '#6366f1', border: '1px solid rgba(99,102,241,0.15)',\n textTransform: 'capitalize',\n }}>\n {(post as any).article_type}\n </span>\n )}\n {date && <span className={cls(unstyled, styles, 'cardDate', 'sk-bloglist-card-date')}>{date}</span>}\n </div>\n\n {/* Title */}\n <h3 className={cls(unstyled, styles, 'cardTitle', 'sk-bloglist-card-title')}>\n <a href={`${basePath}/${post.slug}`} className={styles.cardTitleLink || undefined}>\n {post.title}\n </a>\n </h3>\n\n {/* Excerpt */}\n {post.excerpt && (\n <p className={cls(unstyled, styles, 'cardExcerpt', 'sk-bloglist-card-excerpt')}>\n {post.excerpt}\n </p>\n )}\n\n {/* Footer */}\n <div className={cls(unstyled, styles, 'cardFooter', 'sk-bloglist-card-footer')}>\n {post.author && (\n <span className={cls(unstyled, styles, 'cardAuthor', '')}>\n By {typeof post.author === 'string' ? post.author : post.author.name}\n </span>\n )}\n {readingTimeMinutes(post) && (\n <span className={cls(unstyled, styles, 'cardReadingTime', '')}>\n {readingTimeMinutes(post)} min read\n </span>\n )}\n </div>\n </div>\n </article>\n )\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\nfunction buildPaginationUrl(basePath: string, page: number, category?: string): string {\n const params = new URLSearchParams()\n params.set('page', String(page))\n if (category) params.set('category', category)\n return `${basePath}?${params}`\n}\n","/**\n * @sonordev/site-kit/blog - Blog Sidebar Component\n * \n * A reusable sidebar for blog pages with categories, recent posts,\n * tags, newsletter signup, and custom widgets.\n */\n\nimport React from 'react'\nimport type { BlogPost, BlogCategory, BlogTag } from './types'\nimport { widgetStyle, widgetTitleStyle } from './widget-styles'\n\n// ============================================================================\n// DATA FETCHING\n// ============================================================================\n\nasync function fetchRecentPosts(\n apiUrl: string,\n apiKey: string,\n limit: number = 5\n): Promise<BlogPost[]> {\n try {\n const response = await fetch(`${apiUrl}/public/blog/recent?limit=${limit}`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('[Blog] Error fetching recent posts:', error)\n return []\n }\n}\n\nasync function fetchCategories(apiUrl: string, apiKey: string): Promise<BlogCategory[]> {\n try {\n const response = await fetch(`${apiUrl}/public/blog/categories`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.categories || []\n } catch (error) {\n console.error('[Blog] Error fetching categories:', error)\n return []\n }\n}\n\nasync function fetchTags(apiUrl: string, apiKey: string): Promise<BlogTag[]> {\n try {\n const response = await fetch(`${apiUrl}/public/blog/tags`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.tags || []\n } catch (error) {\n console.error('[Blog] Error fetching tags:', error)\n return []\n }\n}\n\n// ============================================================================\n// BLOG SIDEBAR COMPONENT\n// ============================================================================\n\nexport interface BlogSidebarProps {\n /** Portal API URL */\n apiUrl?: string\n /** Project API key */\n apiKey?: string\n /** Show categories widget */\n showCategories?: boolean\n /** Show recent posts widget */\n showRecentPosts?: boolean\n /** Number of recent posts to show */\n recentPostsCount?: number\n /** Show tags widget */\n showTags?: boolean\n /** Show search widget */\n showSearch?: boolean\n /** Base URL for blog links */\n basePath?: string\n /** Custom class name */\n className?: string\n /** Current category filter (for highlighting) */\n currentCategory?: string\n /** Additional widgets to render */\n children?: React.ReactNode\n}\n\nexport async function BlogSidebar({\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n apiKey = process.env.SONOR_API_KEY || '',\n showCategories = true,\n showRecentPosts = true,\n recentPostsCount = 5,\n showTags = true,\n showSearch = true,\n basePath = '/blog',\n className,\n currentCategory,\n children,\n}: BlogSidebarProps) {\n if (!apiKey) {\n console.warn('[Blog] No API key configured for sidebar')\n return null\n }\n\n // Fetch data in parallel\n const [categories, recentPosts, tags] = await Promise.all([\n showCategories ? fetchCategories(apiUrl, apiKey) : Promise.resolve([]),\n showRecentPosts ? fetchRecentPosts(apiUrl, apiKey, recentPostsCount) : Promise.resolve([]),\n showTags ? fetchTags(apiUrl, apiKey) : Promise.resolve([]),\n ])\n\n return (\n <aside className={className} style={{ display: 'flex', flexDirection: 'column', gap: 32 }}>\n {/* Search Widget */}\n {showSearch && <SearchWidget basePath={basePath} />}\n\n {/* Categories Widget */}\n {showCategories && categories.length > 0 && (\n <CategoriesWidget\n categories={categories}\n basePath={basePath}\n currentCategory={currentCategory}\n />\n )}\n\n {/* Recent Posts Widget */}\n {showRecentPosts && recentPosts.length > 0 && (\n <RecentPostsWidget posts={recentPosts} basePath={basePath} />\n )}\n\n {/* Tags Widget */}\n {showTags && tags.length > 0 && (\n <TagsWidget tags={tags} basePath={basePath} />\n )}\n\n {/* Custom Widgets */}\n {children}\n </aside>\n )\n}\n\n// ============================================================================\n// WIDGET COMPONENTS\n// ============================================================================\n\nfunction SearchWidget({ basePath }: { basePath: string }) {\n return (\n <div style={widgetStyle}>\n <h4 style={widgetTitleStyle}>Search</h4>\n <form action={basePath} method=\"get\">\n <input\n type=\"search\"\n name=\"search\"\n placeholder=\"Search posts...\"\n style={{\n width: '100%',\n padding: '10px 12px',\n border: '1px solid var(--sk-border)',\n borderRadius: 8,\n fontSize: 14,\n }}\n />\n </form>\n </div>\n )\n}\n\nfunction CategoriesWidget({\n categories,\n basePath,\n currentCategory,\n}: {\n categories: BlogCategory[]\n basePath: string\n currentCategory?: string\n}) {\n return (\n <div style={widgetStyle}>\n <h4 style={widgetTitleStyle}>Categories</h4>\n <ul style={{ listStyle: 'none', margin: 0, padding: 0 }}>\n <li style={{ marginBottom: 8 }}>\n <a\n href={basePath}\n style={{\n ...categoryLinkStyle,\n fontWeight: !currentCategory ? 600 : 400,\n color: !currentCategory ? 'var(--sk-primary)' : 'var(--sk-text-primary)',\n }}\n >\n All Posts\n </a>\n </li>\n {categories.map((cat) => (\n <li key={cat.slug} style={{ marginBottom: 8 }}>\n <a\n href={`${basePath}?category=${cat.slug}`}\n style={{\n ...categoryLinkStyle,\n fontWeight: currentCategory === cat.slug ? 600 : 400,\n color: currentCategory === cat.slug ? 'var(--sk-primary)' : 'var(--sk-text-primary)',\n }}\n >\n {cat.name}\n <span style={{ color: 'var(--sk-text-tertiary)', marginLeft: 8 }}>({cat.post_count})</span>\n </a>\n </li>\n ))}\n </ul>\n </div>\n )\n}\n\nfunction RecentPostsWidget({\n posts,\n basePath,\n}: {\n posts: BlogPost[]\n basePath: string\n}) {\n return (\n <div style={widgetStyle}>\n <h4 style={widgetTitleStyle}>Recent Posts</h4>\n <ul style={{ listStyle: 'none', margin: 0, padding: 0 }}>\n {posts.map((post) => {\n const date = post.published_at\n ? new Date(post.published_at).toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n })\n : null\n\n return (\n <li\n key={post.id}\n style={{\n marginBottom: 16,\n paddingBottom: 16,\n borderBottom: '1px solid var(--sk-border)',\n }}\n >\n <div style={{ display: 'flex', gap: 12 }}>\n {post.featured_image && (\n <a href={`${basePath}/${post.slug}`}>\n <img\n src={post.featured_image}\n alt=\"\"\n style={{\n width: 64,\n height: 48,\n objectFit: 'cover',\n borderRadius: 6,\n flexShrink: 0,\n }}\n />\n </a>\n )}\n <div style={{ flex: 1, minWidth: 0 }}>\n <a\n href={`${basePath}/${post.slug}`}\n style={{\n fontSize: 14,\n fontWeight: 500,\n color: 'var(--sk-text-primary)',\n textDecoration: 'none',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {post.title}\n </a>\n {date && (\n <span style={{ fontSize: 12, color: 'var(--sk-text-tertiary)', display: 'block', marginTop: 4 }}>\n {date}\n </span>\n )}\n </div>\n </div>\n </li>\n )\n })}\n </ul>\n </div>\n )\n}\n\nfunction TagsWidget({\n tags,\n basePath,\n}: {\n tags: BlogTag[]\n basePath: string\n}) {\n return (\n <div style={widgetStyle}>\n <h4 style={widgetTitleStyle}>Popular Tags</h4>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>\n {tags.slice(0, 15).map((tag) => (\n <a\n key={tag.slug}\n href={`${basePath}?tag=${encodeURIComponent(tag.name)}`}\n style={{\n padding: '4px 10px',\n backgroundColor: 'var(--sk-bg-elevated)',\n borderRadius: 9999,\n fontSize: 12,\n color: 'var(--sk-text-primary)',\n textDecoration: 'none',\n transition: 'background-color 0.2s',\n }}\n >\n {tag.name}\n </a>\n ))}\n </div>\n </div>\n )\n}\n\n// ============================================================================\n// STYLES\n// ============================================================================\n\n\nconst categoryLinkStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n fontSize: 14,\n textDecoration: 'none',\n}\n","/**\n * @sonordev/site-kit/blog - Blog Layout Component\n * \n * A complete blog layout with sidebar, responsive design, and optional hero.\n * Use this to wrap your blog pages for consistent styling.\n */\n\nimport React from 'react'\nimport { BlogSidebar, BlogSidebarProps } from './BlogSidebar'\n\n// ============================================================================\n// BLOG LAYOUT COMPONENT\n// ============================================================================\n\nexport interface BlogLayoutProps {\n /** Portal API URL */\n apiUrl?: string\n /** Project API key */\n apiKey?: string\n /** Layout style: 'sidebar-right', 'sidebar-left', 'full-width' */\n layout?: 'sidebar-right' | 'sidebar-left' | 'full-width'\n /** Show sidebar */\n showSidebar?: boolean\n /** Sidebar props */\n sidebarProps?: Partial<BlogSidebarProps>\n /** Hero section config */\n hero?: {\n title?: string\n subtitle?: string\n backgroundImage?: string\n backgroundColor?: string\n }\n /** Max width for content */\n maxWidth?: number\n /** Base URL for blog links */\n basePath?: string\n /** Custom class name */\n className?: string\n /** Current category (for sidebar highlighting) */\n currentCategory?: string\n /** Main content */\n children: React.ReactNode\n}\n\nexport async function BlogLayout({\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n apiKey = process.env.SONOR_API_KEY || '',\n layout = 'sidebar-right',\n showSidebar = true,\n sidebarProps = {},\n hero,\n maxWidth = 1280,\n basePath = '/blog',\n className,\n currentCategory,\n children,\n}: BlogLayoutProps) {\n const hasSidebar = showSidebar && layout !== 'full-width'\n\n return (\n <div className={className}>\n {/* Hero Section */}\n {hero && (\n <section\n style={{\n padding: '60px 20px',\n backgroundColor: hero.backgroundColor || 'var(--sk-primary)',\n backgroundImage: hero.backgroundImage ? `url(${hero.backgroundImage})` : undefined,\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n color: 'var(--sk-bg)',\n textAlign: 'center',\n }}\n >\n <div style={{ maxWidth, margin: '0 auto' }}>\n {hero.title && (\n <h1\n style={{\n fontSize: 'clamp(32px, 5vw, 48px)',\n fontWeight: 700,\n marginBottom: 16,\n }}\n >\n {hero.title}\n </h1>\n )}\n {hero.subtitle && (\n <p\n style={{\n fontSize: 'clamp(16px, 2vw, 20px)',\n opacity: 0.9,\n maxWidth: 600,\n margin: '0 auto',\n }}\n >\n {hero.subtitle}\n </p>\n )}\n </div>\n </section>\n )}\n\n {/* Main Content Area */}\n <div\n style={{\n maxWidth,\n margin: '0 auto',\n padding: '40px 20px',\n }}\n >\n <div\n style={{\n display: hasSidebar ? 'grid' : 'block',\n gridTemplateColumns: hasSidebar\n ? layout === 'sidebar-left'\n ? '300px 1fr'\n : '1fr 300px'\n : undefined,\n gap: 48,\n }}\n >\n {/* Sidebar (Left Position) */}\n {hasSidebar && layout === 'sidebar-left' && (\n <BlogSidebar\n apiUrl={apiUrl}\n apiKey={apiKey}\n basePath={basePath}\n currentCategory={currentCategory}\n {...sidebarProps}\n />\n )}\n\n {/* Main Content */}\n <main style={{ minWidth: 0 }}>{children}</main>\n\n {/* Sidebar (Right Position) */}\n {hasSidebar && layout === 'sidebar-right' && (\n <BlogSidebar\n apiUrl={apiUrl}\n apiKey={apiKey}\n basePath={basePath}\n currentCategory={currentCategory}\n {...sidebarProps}\n />\n )}\n </div>\n </div>\n </div>\n )\n}\n\n// ============================================================================\n// BLOG PAGE WRAPPER\n// ============================================================================\n\n/**\n * Convenience wrapper for a complete blog index page\n */\nexport interface BlogPageProps extends Omit<BlogLayoutProps, 'children'> {\n /** List component to render */\n listComponent: React.ReactNode\n}\n\nexport async function BlogPage({ listComponent, ...layoutProps }: BlogPageProps) {\n return <BlogLayout {...layoutProps}>{listComponent}</BlogLayout>\n}\n\n/**\n * Convenience wrapper for a single blog post page\n */\nexport interface BlogPostPageProps extends Omit<BlogLayoutProps, 'children'> {\n /** Post component to render */\n postComponent: React.ReactNode\n}\n\nexport async function BlogPostPage({ postComponent, ...layoutProps }: BlogPostPageProps) {\n return (\n <BlogLayout {...layoutProps} showSidebar={false} layout=\"full-width\">\n <div style={{ maxWidth: 800, margin: '0 auto' }}>{postComponent}</div>\n </BlogLayout>\n )\n}\n\n// ============================================================================\n// CATEGORY PAGE WRAPPER\n// ============================================================================\n\nexport interface CategoryPageProps extends BlogLayoutProps {\n /** Category slug being viewed */\n category: string\n /** Category display name */\n categoryName?: string\n /** List component */\n listComponent: React.ReactNode\n}\n\nexport async function CategoryPage({\n category,\n categoryName,\n listComponent,\n hero,\n ...layoutProps\n}: CategoryPageProps) {\n const categoryHero = hero || {\n title: categoryName || category,\n subtitle: `Browse all posts in ${categoryName || category}`,\n backgroundColor: 'var(--sk-primary)',\n }\n\n return (\n <BlogLayout {...layoutProps} hero={categoryHero} currentCategory={category}>\n {listComponent}\n </BlogLayout>\n )\n}\n","/**\n * @sonordev/site-kit/blog - Related Posts Component\n * \n * Fetches and displays related blog posts via Portal API\n */\n\nimport React from 'react'\nimport type { RelatedPostsProps, BlogPost } from './types'\n\nasync function fetchRelatedPosts(\n apiUrl: string,\n apiKey: string,\n currentPostId: string,\n limit: number\n): Promise<BlogPost[]> {\n try {\n // `/public/blog/*`, not `/api/public/blog/*`. public-blog.controller is\n // one of only two public controllers whose @Controller() omits the `api/`\n // segment (public-images is the other); every other blog call in this\n // module already uses the short form. This one did not, so related posts\n // 404'd and silently rendered as none.\n const response = await fetch(`${apiUrl}/public/blog/related`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n // The controller reads snake_case `current_post_id` and looks the post\n // up by id. camelCase here meant the id arrived as undefined, the\n // lookup matched nothing, and this rendered \"no related posts\" as a\n // clean 200 — the silent sibling of the 404 path bug fixed above.\n body: JSON.stringify({\n current_post_id: currentPostId,\n limit,\n }),\n })\n \n if (!response.ok) {\n console.error('Failed to fetch related posts:', response.statusText)\n return []\n }\n \n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('Failed to fetch related posts:', error)\n return []\n }\n}\n\ninterface RelatedPostsServerProps {\n apiUrl?: string\n apiKey?: string\n currentPostId: string\n limit?: number\n className?: string\n renderItem?: (post: BlogPost) => React.ReactNode\n}\n\nexport async function RelatedPosts({\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n apiKey = process.env.SONOR_API_KEY || '',\n currentPostId,\n limit = 3,\n className,\n renderItem,\n}: RelatedPostsServerProps) {\n if (!apiKey) {\n console.warn('[Blog] No API key configured for RelatedPosts')\n return null\n }\n \n const posts = await fetchRelatedPosts(apiUrl, apiKey, currentPostId, limit)\n\n if (posts.length === 0) return null\n\n return (\n <section className={className}>\n <h3 style={{ marginBottom: 16 }}>Related Posts</h3>\n <div style={{ display: 'grid', gap: 16 }}>\n {posts.map((post) =>\n renderItem ? (\n renderItem(post)\n ) : (\n <article key={post.id} style={{ borderBottom: '1px solid var(--sk-border)', paddingBottom: 16 }}>\n {post.featured_image && (\n <img\n src={post.featured_image}\n alt={post.title}\n style={{\n width: '100%',\n height: 120,\n objectFit: 'cover',\n borderRadius: 8,\n marginBottom: 8,\n }}\n />\n )}\n <a href={`/blog/${post.slug}`} style={{ textDecoration: 'none' }}>\n <h4 style={{ margin: 0, color: 'inherit' }}>{post.title}</h4>\n </a>\n {post.excerpt && (\n <p style={{ margin: '4px 0 0', fontSize: 14, color: 'var(--sk-text-secondary)' }}>\n {post.excerpt}\n </p>\n )}\n </article>\n )\n )}\n </div>\n </section>\n )\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/layout/SiteKitClientProviders.tsx"],"names":[],"mappings":"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","file":"chunk-AXAIUCSF.mjs","sourcesContent":["'use client'\n\n/**\n * SiteKitClientProviders — Client Island\n *\n * This is the 'use client' boundary for SiteKitLayout.\n * It composes the client-only providers (Analytics, Engage, Signal, SitemapSync)\n * that require React context or browser APIs.\n *\n * All modules are lazy-loaded via next/dynamic so their JS is only downloaded\n * when the feature is enabled — keeping the initial bundle lightweight.\n *\n * All modules share a unified identity (visitor ID + session ID) read from\n * the storage-backed singleton (shared/identity), ensuring consistent\n * tracking across Analytics, Signal, and Engage.\n *\n * 4.0 INVARIANT — CHILDREN ARE NEVER WRAPPED. Every module here renders as a\n * childless sibling AFTER {children}; nothing provides context around page\n * content. That makes the prerender-bailout / remount-flash class of bug\n * structurally impossible. Do not reintroduce a wrapper.\n *\n * Props are passed down from the server-side SiteKitLayout component,\n * which reads env vars at render time.\n */\n\nimport React, { Suspense, useCallback, useRef, useState, type ReactNode } from 'react'\nimport dynamic from 'next/dynamic'\nimport {\n getOrCreateVisitorId,\n getOrCreateSessionId,\n} from '../shared/identity'\n// Defer non-critical module mounting until the page is quiet: the lazy\n// modules below are dynamic(ssr:false) and never render on the server, but\n// rendering them during hydration still kicks off their chunk downloads +\n// mount effects inside the critical startup window. useDeferredActivation\n// holds them until window.load + idle or first interaction — the same\n// strategy as the hand-rolled per-site deferrals this replaces (upforge\n// `deferred-analytics.tsx`, TPS `DeferredAnalytics.tsx`). The hook is public\n// (`@sonordev/site-kit/client`) so sites can reuse it for their own scripts.\nimport { useDeferredActivation } from '../shared/defer'\n// Single source of truth for seeding the token manager + the __SITE_KIT_*\n// globals — shared with the public `SiteKitCredential` component that\n// non-core layouts (agency-site-kit) use. Do not re-inline it here.\nimport { publishSiteCredential, resolveSiteHost } from '../shared/publishCredential'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\n// Lazy-load feature modules — JS only downloaded when feature is enabled\nconst LazyAnalyticsProvider = dynamic(\n () => import('../analytics/AnalyticsProvider').then(m => ({ default: m.AnalyticsProvider })),\n { ssr: false },\n)\nconst LazyEngageWidget = dynamic(\n () => import('../engage/EngageWidget').then(m => ({ default: m.EngageWidget })),\n { ssr: false },\n)\nconst LazySitemapSync = dynamic(\n () => import('../SitemapSync').then(m => ({ default: m.SitemapSync })),\n { ssr: false },\n)\n// SignalBridge is imported STATICALLY, not via dynamic(ssr:false): it is a\n// tiny SSR-safe context shell that renders children immediately and\n// lazy-loads its machinery (SignalCore) as a childless sibling internally.\n// Wrapping children in a dynamic(ssr:false) component was the old SSR-bailout\n// failure mode — do not reintroduce it.\nimport { SignalBridge } from '../signal/SignalBridge'\n// Fleet heartbeat: a deferred, CHILDLESS SIBLING (like Analytics/Engage) that\n// reports this site's kit version + active modules once per session, so the\n// platform can see version drift across the fleet. Tiny and SSR-safe — renders\n// null until the shared idle gate fires; never wraps page content.\nimport { FleetHeartbeat } from '../fleet/FleetHeartbeat'\nimport type { FleetModule } from '../fleet/contract'\n\nexport interface SiteKitClientProvidersProps {\n children: ReactNode\n apiKey: string\n apiUrl: string\n projectId?: string\n analytics?: boolean | AnalyticsConfig\n engage?: boolean | EngageConfig\n signal?: boolean | SignalConfig\n /**\n * Runtime SitemapSync from the visitor's browser. Default FALSE — sitemap\n * registration belongs to build time and to sonor-api's nightly reconciler,\n * not to whoever happens to load the page. See SiteKitLayout for the full\n * reasoning; in short, its guards live in session/localStorage, so every new\n * visitor missed them and re-POSTed the whole sitemap.\n */\n sitemapSync?: boolean\n /**\n * Fleet heartbeat — reports kit version + active modules to Sonor once per\n * session so the platform can track version drift and key state across every\n * site. Default true. Deferred exactly like Analytics; never in the hydration\n * path, carries no visitor data.\n */\n fleet?: boolean\n /**\n * Defer Analytics / Engage / SitemapSync until window load + idle or first\n * interaction (default true). Pass false to restore legacy eager mounting\n * on hydration. SignalBridge is never deferred — it must apply experiment\n * variants as early as possible.\n */\n defer?: boolean\n debug?: boolean\n /** Browser-safe Google Maps key, resolved server-side by SiteKitLayout. */\n mapsBrowserKey?: string\n}\n\nexport function SiteKitClientProviders({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = false,\n fleet = true,\n defer = true,\n debug = false,\n mapsBrowserKey,\n}: SiteKitClientProvidersProps) {\n // One shared activation gate for all deferred siblings, so they mount in a\n // single commit instead of staggered re-renders.\n const modulesReady = useDeferredActivation(defer)\n // Hoist analytics config so the `site` dimension is resolvable up here.\n const analyticsConfig: AnalyticsConfig =\n typeof analytics === 'object' ? analytics : {}\n\n // Resolve the sub-site identifier — the dimension that lets one Sonor project\n // host many sites (e.g. truepowersystems.com + ohiopowerstudies.com under one\n // TPS project). Precedence lives in resolveSiteHost (shared contract):\n // explicit `analytics.site` > NEXT_PUBLIC_SITE_URL host > window.location.host.\n // Needed as a local too — SignalBridge and the analytics config read it below.\n const site = resolveSiteHost(analyticsConfig.site)\n\n // Seed the token manager + publish the window globals modules read from.\n // No-op on the server; runs during render so it lands before child effects.\n publishSiteCredential({ apiKey, apiUrl, site, debug, mapsBrowserKey })\n\n // Unified identity — single source of truth for all modules\n const [visitorId] = useState(() => getOrCreateVisitorId())\n const [sessionId] = useState(() => getOrCreateSessionId())\n\n // Page metadata bridge: Analytics writes, Signal reads\n const pageMetadataRef = useRef<Record<string, unknown> | null>(null)\n const onPageMetadata = useCallback((metadata: Record<string, unknown>) => {\n pageMetadataRef.current = metadata\n }, [])\n\n // Children render FIRST and are never re-parented. Siblings accumulate after.\n const siblings: ReactNode[] = []\n\n // SignalBridge — childless sibling (4.0: useSignal reads the module store,\n // so it no longer needs to wrap anything). Not gated on modulesReady:\n // experiment variants must apply as early as possible.\n if (signal) {\n const signalConfig: SignalConfig =\n typeof signal === 'object' ? signal : {}\n siblings.push(\n <SignalBridge\n key=\"sk-signal\"\n enabled\n realtime={signalConfig.realtime !== false}\n experiments={signalConfig.experiments !== false}\n behaviorTracking={signalConfig.behaviorTracking !== false}\n visitorId={visitorId}\n sessionId={sessionId}\n pageMetadataRef={pageMetadataRef}\n />,\n )\n }\n\n // Add Analytics if enabled (renders alongside, doesn't wrap).\n //\n // CRITICAL: LazyAnalyticsProvider is dynamic(..., { ssr: false }). Wrapping\n // {content} inside an ssr:false component makes the entire page tree skip\n // server rendering — the route de-opts to 100% client rendering and the\n // hero / LCP element only paints after hydration (mobile LCP ~4s, Lighthouse\n // ~85). Analytics tracks via effects + a metadata ref, so it never needs to\n // wrap page content — mount it as a childless sibling, exactly like Engage.\n // Each deferred sibling is appended as `{modulesReady && <Module/>}` so the\n // children slot never moves in the tree — flipping ready only mounts the\n // sibling, it never remounts page content.\n if (analytics) {\n siblings.push(\n <React.Fragment key=\"sk-analytics\">\n {modulesReady && (\n <Suspense fallback={null}>\n <LazyAnalyticsProvider\n apiUrl={apiUrl}\n apiKey={apiKey}\n site={site}\n trackPageViews={analyticsConfig.trackPageViews !== false}\n trackWebVitals={analyticsConfig.trackWebVitals !== false}\n trackScrollDepth={analyticsConfig.trackScrollDepth !== false}\n trackClicks={analyticsConfig.trackClicks !== false}\n sessionTimeout={analyticsConfig.sessionDuration}\n excludePaths={analyticsConfig.excludePaths}\n // Off by default: a cross-origin embed of this site reports\n // nothing (see analytics/send-gate.ts). Opt in per site.\n allowInFrame={analyticsConfig.allowInFrame === true}\n debug={debug}\n externalVisitorId={visitorId}\n externalSessionId={sessionId}\n onPageMetadata={onPageMetadata}\n />\n </Suspense>\n )}\n </React.Fragment>,\n )\n }\n\n // Engage widget — childless sibling\n if (engage) {\n const engageConfig: EngageConfig =\n typeof engage === 'object' ? engage : {}\n siblings.push(\n <React.Fragment key=\"sk-engage\">\n {modulesReady && (\n <LazyEngageWidget\n apiUrl={apiUrl}\n apiKey={apiKey}\n projectId={projectId}\n position={engageConfig.position || 'bottom-right'}\n zIndex={engageConfig.zIndex}\n chatEnabled={engageConfig.chatEnabled !== false}\n />\n )}\n </React.Fragment>,\n )\n }\n\n // SitemapSync — childless sibling\n if (sitemapSync) {\n siblings.push(\n <React.Fragment key=\"sk-sitemap\">\n {modulesReady && <LazySitemapSync debug={debug} />}\n </React.Fragment>,\n )\n }\n\n // Fleet heartbeat — childless sibling on the same modulesReady idle gate.\n // Reports the modules actually enabled on THIS layout (honest client-observable\n // set) so the platform can answer \"which version / modules is each site\n // running\". defer={false}: the modulesReady gate already handled deferral, so\n // the heartbeat fires on mount (still bounded to once per session internally).\n if (fleet) {\n const activeModules: FleetModule[] = []\n if (analytics) activeModules.push('analytics')\n if (engage) activeModules.push('engage')\n if (signal) activeModules.push('signal')\n if (sitemapSync) activeModules.push('sitemapSync')\n siblings.push(\n <React.Fragment key=\"sk-fleet\">\n {modulesReady && (\n <FleetHeartbeat\n apiUrl={apiUrl}\n apiKey={apiKey}\n site={site}\n modules={activeModules}\n defer={false}\n debug={debug}\n />\n )}\n </React.Fragment>,\n )\n }\n\n return (\n <>\n {children}\n {siblings}\n </>\n )\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/seo/getManagedMetadata.ts","../src/seo/routing.ts"],"names":[],"mappings":"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","file":"chunk-B4BFQSSS.mjs","sourcesContent":["import type { Metadata } from 'next'\nimport { getSEOPageData, getABTest, recordABImpression, ensureMetadata } from './server-api'\nimport type { \n GetManagedMetadataOptions, \n ManagedMetadataResult,\n GetABVariantOptions,\n ABTestResult \n} from './types'\n\n/**\n * Get managed metadata for a page\n * \n * Use in generateMetadata() to fetch Portal-managed SEO data\n * \n * @example\n * ```tsx\n * export async function generateMetadata({ params }) {\n * return getManagedMetadata({\n * path: `/services/${params.slug}`,\n * fallback: {\n * title: 'Our Services',\n * description: 'Learn about our services'\n * }\n * })\n * }\n * ```\n */\nexport async function getManagedMetadata(\n options: GetManagedMetadataOptions\n): Promise<ManagedMetadataResult> {\n const { path, fallback = {}, overrides = {}, favicon: faviconMode = 'metadata' } = options\n const omitIcons = faviconMode === 'component'\n\n const result = await getSEOPageData(path)\n const pageData = result?.page\n const projectData = result?.project\n\n // If no managed data, return fallback (still include favicon from project if available, unless using component)\n if (!pageData) {\n const fallbackMeta: ManagedMetadataResult = {\n ...fallback,\n ...overrides,\n _managed: false,\n _source: 'fallback',\n } as ManagedMetadataResult\n\n if (!omitIcons && projectData?.logo_url) {\n fallbackMeta.icons = {\n icon: projectData.logo_url,\n apple: projectData.logo_url,\n }\n }\n\n return fallbackMeta\n }\n\n // Build metadata from managed values, falling back to provided fallbacks\n const metadata: ManagedMetadataResult = {\n _managed: true,\n _source: 'database',\n }\n\n if (!omitIcons && projectData?.logo_url) {\n metadata.icons = {\n icon: projectData.logo_url,\n apple: projectData.logo_url,\n }\n }\n\n // Signal fallback — when page exists but both title & description are empty,\n // trigger Signal AI to generate them (fire-and-forget so it never blocks TTFB;\n // the generated data will be available on the next request)\n if (!pageData.managed_title && !pageData.managed_meta_description && !pageData.managed_description) {\n ensureMetadata(path).catch(() => {})\n }\n\n // Title\n if (pageData.managed_title) {\n metadata.title = pageData.managed_title\n } else if (fallback.title) {\n metadata.title = fallback.title\n }\n\n // Description\n if (pageData.managed_meta_description || pageData.managed_description) {\n metadata.description = pageData.managed_meta_description || pageData.managed_description\n } else if (fallback.description) {\n metadata.description = fallback.description\n }\n\n // Keywords\n if (pageData.managed_keywords?.length) {\n metadata.keywords = pageData.managed_keywords\n } else if (fallback.keywords) {\n metadata.keywords = fallback.keywords\n }\n\n // Robots\n if (pageData.managed_robots) {\n metadata.robots = pageData.managed_robots\n }\n\n // Canonical\n if (pageData.managed_canonical) {\n metadata.alternates = {\n ...metadata.alternates,\n canonical: pageData.managed_canonical,\n }\n }\n\n // Optional hreflang map from Portal (expansion / multilingual sites)\n const langAlts = pageData.language_alternates\n if (langAlts && typeof langAlts === 'object' && !Array.isArray(langAlts)) {\n metadata.alternates = {\n ...metadata.alternates,\n languages: langAlts as Record<string, string>,\n }\n }\n\n // Open Graph\n const ogTitle = pageData.managed_og_title || pageData.managed_title\n const ogDescription = pageData.managed_og_description || pageData.managed_meta_description || pageData.managed_description\n const ogImage = pageData.managed_og_image\n\n if (ogTitle || ogDescription || ogImage) {\n metadata.openGraph = {\n ...(ogTitle && { title: ogTitle }),\n ...(ogDescription && { description: ogDescription }),\n ...(ogImage && { images: [{ url: ogImage }] }),\n }\n }\n\n // Twitter (use OG values as fallback)\n if (ogTitle || ogDescription || ogImage) {\n metadata.twitter = {\n card: 'summary_large_image',\n ...(ogTitle && { title: ogTitle }),\n ...(ogDescription && { description: ogDescription }),\n ...(ogImage && { images: [ogImage] }),\n }\n }\n\n // Apply overrides last\n return {\n ...metadata,\n ...overrides,\n _managed: true,\n _source: 'database',\n }\n}\n\n/**\n * Get A/B test variant for a field\n * \n * @example\n * ```tsx\n * const variant = await getABVariant({\n * path: '/pricing',\n * field: 'title',\n * sessionId: cookies().get('session_id')?.value\n * })\n * \n * if (variant) {\n * // Use variant.value instead of default\n * }\n * ```\n */\nexport async function getABVariant(\n options: GetABVariantOptions\n): Promise<ABTestResult | null> {\n const { path, field, sessionId } = options\n\n const test = await getABTest(path, field)\n\n if (!test) {\n return null\n }\n\n // Determine variant based on session ID or random\n let variant: 'a' | 'b'\n \n if (sessionId) {\n // Consistent variant for same session\n const hash = sessionId.split('').reduce((acc, char) => {\n return ((acc << 5) - acc) + char.charCodeAt(0)\n }, 0)\n variant = (Math.abs(hash) % 100) < (test.traffic_split * 100) ? 'a' : 'b'\n } else {\n // Random variant\n variant = Math.random() < test.traffic_split ? 'a' : 'b'\n }\n\n // Record impression (fire and forget)\n recordABImpression(test.id, variant, sessionId).catch(() => {\n // Silently fail - don't block rendering\n })\n\n return {\n testId: test.id,\n variant,\n value: variant === 'a' ? test.variant_a : test.variant_b,\n }\n}\n\n/**\n * Get managed metadata with A/B test support\n * \n * Automatically applies running A/B test variants to metadata\n */\nexport async function getManagedMetadataWithAB(\n options: GetManagedMetadataOptions & { sessionId?: string }\n): Promise<ManagedMetadataResult> {\n const { sessionId, ...metadataOptions } = options\n \n // Get base metadata\n const metadata = await getManagedMetadata(metadataOptions)\n\n // Check for title A/B test\n const titleTest = await getABVariant({\n path: options.path,\n field: 'title',\n sessionId,\n })\n\n if (titleTest) {\n metadata.title = titleTest.value\n }\n\n // Check for description A/B test\n const descTest = await getABVariant({\n path: options.path,\n field: 'description',\n sessionId,\n })\n\n if (descTest) {\n metadata.description = descTest.value\n }\n\n return metadata\n}\n","import { getRedirectData, getRobotsData, getSitemapEntries } from './server-api'\nimport type { \n GetRedirectOptions, \n RedirectResult, \n GetRobotsOptions, \n RobotsDirective,\n GetSitemapEntriesOptions,\n SitemapEntry \n} from './types'\n\n/**\n * Get redirect for a path if one exists\n * \n * Use in Next.js middleware to handle managed redirects\n * \n * @example\n * ```tsx\n * // proxy.ts\n * import { getRedirect } from '@sonordev/site-kit/seo'\n * \n * export default async function proxy(request) {\n * const redirect = await getRedirect({\n * projectId: process.env.SONOR_PROJECT_ID!,\n * path: request.nextUrl.pathname\n * })\n * \n * if (redirect) {\n * return NextResponse.redirect(redirect.destination, redirect.statusCode)\n * }\n * }\n * ```\n */\nexport async function getRedirect(\n options: GetRedirectOptions\n): Promise<RedirectResult | null> {\n const { path } = options\n\n const redirect = await getRedirectData(path)\n\n if (!redirect) {\n return null\n }\n\n // Check if expired\n if (redirect.expires_at && new Date(redirect.expires_at) < new Date()) {\n return null\n }\n\n // Determine destination\n const destination = redirect.destination_url || redirect.destination_path\n const isExternal = destination.startsWith('http://') || destination.startsWith('https://')\n\n return {\n destination,\n statusCode: redirect.status_code,\n isExternal,\n }\n}\n\n/**\n * Parse robots directive string into structured object\n */\nfunction parseRobotsString(robots: string): RobotsDirective {\n const directive: RobotsDirective = {\n index: true,\n follow: true,\n }\n\n const parts = robots.toLowerCase().split(',').map(p => p.trim())\n\n for (const part of parts) {\n if (part === 'noindex') directive.index = false\n if (part === 'nofollow') directive.follow = false\n if (part === 'noarchive') directive.noarchive = true\n if (part === 'nosnippet') directive.nosnippet = true\n if (part === 'noimageindex') directive.noimageindex = true\n if (part.startsWith('max-snippet:')) {\n directive.max_snippet = parseInt(part.split(':')[1], 10)\n }\n if (part.startsWith('max-image-preview:')) {\n const value = part.split(':')[1] as 'none' | 'standard' | 'large'\n directive.max_image_preview = value\n }\n if (part.startsWith('max-video-preview:')) {\n directive.max_video_preview = parseInt(part.split(':')[1], 10)\n }\n }\n\n return directive\n}\n\n/**\n * Get robots directive for a page\n * \n * @example\n * ```tsx\n * const robots = await getRobotsDirective({\n * projectId: process.env.SONOR_PROJECT_ID!,\n * path: '/private-page'\n * })\n * \n * if (!robots.index) {\n * // Page should not be indexed\n * }\n * ```\n */\nexport async function getRobotsDirective(\n options: GetRobotsOptions\n): Promise<RobotsDirective> {\n const { path } = options\n\n const robotsString = await getRobotsData(path)\n\n if (!robotsString) {\n // Default: index and follow\n return { index: true, follow: true }\n }\n\n return parseRobotsString(robotsString)\n}\n\n/**\n * Get sitemap entries for a project\n * \n * Use in sitemap.ts to generate dynamic sitemap\n * \n * @example\n * ```tsx\n * // app/sitemap.ts\n * import { generateSitemap } from '@sonordev/seo'\n * \n * export default async function sitemap() {\n * return generateSitemap({\n * projectId: process.env.SONOR_PROJECT_ID!,\n * baseUrl: 'https://example.com',\n * publishedOnly: true\n * })\n * }\n * ```\n */\nexport async function generateSitemap(\n options: GetSitemapEntriesOptions\n): Promise<SitemapEntry[]> {\n const { baseUrl, publishedOnly = true } = options\n\n const pages = await getSitemapEntries({ publishedOnly })\n\n const normalizedBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n\n return pages.map((page: { path: string; lastmod?: string; changefreq?: string; priority?: number }) => ({\n path: page.path,\n url: `${normalizedBase}${page.path}`,\n lastmod: page.lastmod,\n changefreq: (page.changefreq || 'weekly') as SitemapEntry['changefreq'],\n priority: page.priority ?? 0.5,\n }))\n}\n\n/**\n * Register local sitemap entries with Sonor\n * \n * Call this at build time to sync your local routes to seo_pages.\n * This ensures analytics only tracks real pages.\n * \n * After registration, Signal AI will generate optimized meta titles\n * and descriptions for pages that don't have managed meta yet.\n * \n * @example\n * ```ts\n * // scripts/register-sitemap.ts\n * import { registerLocalSitemap } from '@sonordev/seo'\n * \n * // Option 1: Provide entries directly\n * await registerLocalSitemap({\n * entries: [\n * { path: '/', title: 'Home', priority: 1.0 },\n * { path: '/about', title: 'About Us', priority: 0.8 },\n * ]\n * })\n * \n * // Option 2: Auto-discover from Next.js app directory\n * await registerLocalSitemap({ autoDiscover: true })\n * \n * // Option 3: Skip Signal AI meta optimization\n * await registerLocalSitemap({ autoDiscover: true, optimize_meta: false })\n * ```\n */\nexport async function registerLocalSitemap(options: {\n entries?: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n }>\n autoDiscover?: boolean\n /** Trigger Signal AI to generate optimized meta titles/descriptions (default: true) */\n optimize_meta?: boolean\n /**\n * Sync mode. Defaults to 'additive' for explicit entries (a partial list must\n * never delete the rest of the site's pages) and 'full-replace' for\n * autoDiscover (which enumerates the complete route set).\n */\n mode?: 'additive' | 'full-replace'\n}): Promise<{\n success: boolean\n created: number\n updated: number\n removed?: number\n meta_optimization?: {\n triggered: boolean\n pages_queued: number\n } | null\n}> {\n const { registerSitemap } = await import('./server-api')\n\n let entries = options.entries || []\n\n // Auto-discover from the Next.js app directory if requested. Lazy-import the\n // fs-backed discovery module so `fs` never enters this file's STATIC graph —\n // getRedirect/isIndexable below are imported by edge middleware, which has no\n // fs. Discovery only runs at build time, in Node, so a dynamic import is fine.\n if (options.autoDiscover && entries.length === 0) {\n try {\n const { discoverNextJsRoutes, findAppDirForDiscovery } = await import('../sitemap/discover')\n const appDir = findAppDirForDiscovery()\n if (appDir) {\n entries = discoverNextJsRoutes(appDir)\n console.log(`[Sonor] Auto-discovered ${entries.length} routes from app directory`)\n }\n } catch (error) {\n console.error('[Sonor] Auto-discovery failed:', error)\n }\n }\n\n if (entries.length === 0) {\n console.warn('[Sonor] No sitemap entries to register')\n return { success: true, created: 0, updated: 0 }\n }\n\n // A route set discovered from the filesystem is structurally incomplete (it\n // can't enumerate dynamic routes and ignores sitemap excludes), and an\n // explicit entry list is often partial — either way a full-replace would\n // silently delete real pages. Default everything to additive; a caller that\n // truly holds the complete page set opts in with mode: 'full-replace'. The\n // recommended `sonor-register-sitemap` postbuild additionally self-skips when\n // an app/sitemap route already owns the sync.\n const mode = options.mode ?? 'additive'\n\n console.log(`[Sonor] Registering ${entries.length} sitemap entries (${mode})...`)\n const result = await registerSitemap(entries, { mode })\n \n if (result.success) {\n console.log(`[Sonor] Sitemap registered: ${result.created} new, ${result.updated} updated`)\n }\n \n return result\n}\n\n/**\n * Check if a path should be indexed\n * \n * Quick helper to check indexability without full directive parsing\n */\nexport async function isIndexable(\n projectId: string,\n path: string\n): Promise<boolean> {\n const directive = await getRobotsDirective({ projectId, path })\n return directive.index\n}\n"]}
@@ -1,41 +0,0 @@
1
- // src/blog/author-schema.ts
2
- function generateAuthorSchema(author, options = {}) {
3
- const { siteUrl = "", siteName } = options;
4
- const sameAs = [...author.same_as || []];
5
- if (author.linkedin_url) sameAs.push(author.linkedin_url);
6
- if (author.twitter_url) sameAs.push(author.twitter_url);
7
- if (author.website_url) sameAs.push(author.website_url);
8
- if (author.social_links?.twitter) sameAs.push(`https://twitter.com/${author.social_links.twitter}`);
9
- if (author.social_links?.linkedin) sameAs.push(author.social_links.linkedin);
10
- if (author.social_links?.github) sameAs.push(`https://github.com/${author.social_links.github}`);
11
- const uniqueSameAs = [...new Set(sameAs.filter(Boolean))];
12
- const schema = {
13
- "@context": "https://schema.org",
14
- "@type": "Person",
15
- name: author.name,
16
- url: author.author_page_url || `${siteUrl}/blog/author/${author.slug}`
17
- };
18
- if (author.title) schema.jobTitle = author.title;
19
- if (author.company || siteName) {
20
- schema.worksFor = {
21
- "@type": "Organization",
22
- name: author.company || siteName,
23
- ...siteUrl ? { url: siteUrl } : {}
24
- };
25
- }
26
- if (author.bio || author.short_bio) schema.description = author.short_bio || author.bio;
27
- if (author.avatar_url) schema.image = author.avatar_url;
28
- if (uniqueSameAs.length > 0) schema.sameAs = uniqueSameAs;
29
- if (author.knows_about && author.knows_about.length > 0) schema.knowsAbout = author.knows_about;
30
- if (author.credentials && author.credentials.length > 0) {
31
- schema.hasCredential = author.credentials.map((c) => ({
32
- "@type": "EducationalOccupationalCredential",
33
- credentialCategory: c
34
- }));
35
- }
36
- return schema;
37
- }
38
-
39
- export { generateAuthorSchema };
40
- //# sourceMappingURL=chunk-CGCYZJYX.mjs.map
41
- //# sourceMappingURL=chunk-CGCYZJYX.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/blog/author-schema.ts"],"names":[],"mappings":";AAuBO,SAAS,oBAAA,CACd,MAAA,EACA,OAAA,GAAmD,EAAC,EAC5C;AACR,EAAA,MAAM,EAAE,OAAA,GAAU,EAAA,EAAI,QAAA,EAAS,GAAI,OAAA;AAEnC,EAAA,MAAM,SAAmB,CAAC,GAAI,MAAA,CAAO,OAAA,IAAW,EAAG,CAAA;AACnD,EAAA,IAAI,MAAA,CAAO,YAAA,EAAc,MAAA,CAAO,IAAA,CAAK,OAAO,YAAY,CAAA;AACxD,EAAA,IAAI,MAAA,CAAO,WAAA,EAAa,MAAA,CAAO,IAAA,CAAK,OAAO,WAAW,CAAA;AACtD,EAAA,IAAI,MAAA,CAAO,WAAA,EAAa,MAAA,CAAO,IAAA,CAAK,OAAO,WAAW,CAAA;AACtD,EAAA,IAAI,MAAA,CAAO,cAAc,OAAA,EAAS,MAAA,CAAO,KAAK,CAAA,oBAAA,EAAuB,MAAA,CAAO,YAAA,CAAa,OAAO,CAAA,CAAE,CAAA;AAClG,EAAA,IAAI,OAAO,YAAA,EAAc,QAAA,SAAiB,IAAA,CAAK,MAAA,CAAO,aAAa,QAAQ,CAAA;AAC3E,EAAA,IAAI,MAAA,CAAO,cAAc,MAAA,EAAQ,MAAA,CAAO,KAAK,CAAA,mBAAA,EAAsB,MAAA,CAAO,YAAA,CAAa,MAAM,CAAA,CAAE,CAAA;AAG/F,EAAA,MAAM,YAAA,GAAe,CAAC,GAAG,IAAI,IAAI,MAAA,CAAO,MAAA,CAAO,OAAO,CAAC,CAAC,CAAA;AAExD,EAAA,MAAM,MAAA,GAA8B;AAAA,IAClC,UAAA,EAAY,oBAAA;AAAA,IACZ,OAAA,EAAS,QAAA;AAAA,IACT,MAAM,MAAA,CAAO,IAAA;AAAA,IACb,KAAK,MAAA,CAAO,eAAA,IAAmB,GAAG,OAAO,CAAA,aAAA,EAAgB,OAAO,IAAI,CAAA;AAAA,GACtE;AAEA,EAAA,IAAI,MAAA,CAAO,KAAA,EAAO,MAAA,CAAO,QAAA,GAAW,MAAA,CAAO,KAAA;AAC3C,EAAA,IAAI,MAAA,CAAO,WAAW,QAAA,EAAU;AAC9B,IAAA,MAAA,CAAO,QAAA,GAAW;AAAA,MAChB,OAAA,EAAS,cAAA;AAAA,MACT,IAAA,EAAM,OAAO,OAAA,IAAW,QAAA;AAAA,MACxB,GAAI,OAAA,GAAU,EAAE,GAAA,EAAK,OAAA,KAAY;AAAC,KACpC;AAAA,EACF;AACA,EAAA,IAAI,MAAA,CAAO,OAAO,MAAA,CAAO,SAAA,SAAkB,WAAA,GAAc,MAAA,CAAO,aAAa,MAAA,CAAO,GAAA;AACpF,EAAA,IAAI,MAAA,CAAO,UAAA,EAAY,MAAA,CAAO,KAAA,GAAQ,MAAA,CAAO,UAAA;AAC7C,EAAA,IAAI,YAAA,CAAa,MAAA,GAAS,CAAA,EAAG,MAAA,CAAO,MAAA,GAAS,YAAA;AAC7C,EAAA,IAAI,MAAA,CAAO,eAAe,MAAA,CAAO,WAAA,CAAY,SAAS,CAAA,EAAG,MAAA,CAAO,aAAa,MAAA,CAAO,WAAA;AACpF,EAAA,IAAI,MAAA,CAAO,WAAA,IAAe,MAAA,CAAO,WAAA,CAAY,SAAS,CAAA,EAAG;AACvD,IAAA,MAAA,CAAO,aAAA,GAAgB,MAAA,CAAO,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MACpD,OAAA,EAAS,mCAAA;AAAA,MACT,kBAAA,EAAoB;AAAA,KACtB,CAAE,CAAA;AAAA,EACJ;AAEA,EAAA,OAAO,MAAA;AACT","file":"chunk-CGCYZJYX.mjs","sourcesContent":["/**\n * @sonordev/site-kit/blog — Author JSON-LD (pure)\n *\n * Split out of `./server-core` on purpose. `generateAuthorSchema` is a pure\n * function — it maps a `BlogAuthor` to a Person schema object and touches no\n * env, no config, and no network. It only ever lived in `server-core` because\n * the other author helpers there (`getAuthorBySlug`, `getAuthorPosts`) do fetch.\n *\n * `AuthorPage` is exported from the client-stamped `@sonordev/site-kit/blog`\n * barrel (see `./index.ts`), so importing this one function from `server-core`\n * dragged that whole server module — its `x-api-key` fetches included — into\n * the browser bundle. Keeping the pure half here means `AuthorPage` can stay in\n * the barrel without pulling a single line of server code with it.\n *\n * Anything added here must stay pure. If it needs an API key or a fetch, it\n * belongs in `./server-core`, not in this file.\n */\n\nimport type { BlogAuthor } from './types'\n\n/**\n * Generate Person JSON-LD schema for an author page\n */\nexport function generateAuthorSchema(\n author: BlogAuthor,\n options: { siteUrl?: string; siteName?: string } = {}\n): object {\n const { siteUrl = '', siteName } = options\n\n const sameAs: string[] = [...(author.same_as || [])]\n if (author.linkedin_url) sameAs.push(author.linkedin_url)\n if (author.twitter_url) sameAs.push(author.twitter_url)\n if (author.website_url) sameAs.push(author.website_url)\n if (author.social_links?.twitter) sameAs.push(`https://twitter.com/${author.social_links.twitter}`)\n if (author.social_links?.linkedin) sameAs.push(author.social_links.linkedin)\n if (author.social_links?.github) sameAs.push(`https://github.com/${author.social_links.github}`)\n\n // Deduplicate\n const uniqueSameAs = [...new Set(sameAs.filter(Boolean))]\n\n const schema: Record<string, any> = {\n '@context': 'https://schema.org',\n '@type': 'Person',\n name: author.name,\n url: author.author_page_url || `${siteUrl}/blog/author/${author.slug}`,\n }\n\n if (author.title) schema.jobTitle = author.title\n if (author.company || siteName) {\n schema.worksFor = {\n '@type': 'Organization',\n name: author.company || siteName,\n ...(siteUrl ? { url: siteUrl } : {}),\n }\n }\n if (author.bio || author.short_bio) schema.description = author.short_bio || author.bio\n if (author.avatar_url) schema.image = author.avatar_url\n if (uniqueSameAs.length > 0) schema.sameAs = uniqueSameAs\n if (author.knows_about && author.knows_about.length > 0) schema.knowsAbout = author.knows_about\n if (author.credentials && author.credentials.length > 0) {\n schema.hasCredential = author.credentials.map((c) => ({\n '@type': 'EducationalOccupationalCredential',\n credentialCategory: c,\n }))\n }\n\n return schema\n}\n"]}
@@ -1,8 +0,0 @@
1
- 'use strict';
2
-
3
- // src/shared/version.ts
4
- var SITE_KIT_VERSION = "5.3.2";
5
-
6
- exports.SITE_KIT_VERSION = SITE_KIT_VERSION;
7
- //# sourceMappingURL=chunk-D37M7MIH.js.map
8
- //# sourceMappingURL=chunk-D37M7MIH.js.map