@sonordev/site-kit 3.4.0 → 3.6.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 (227) hide show
  1. package/README.md +2 -2
  2. package/agent-manifest.json +1 -1
  3. package/dist/AnalyticsProvider-GOLL2W6O.mjs +10 -0
  4. package/dist/{AnalyticsProvider-HIGSPNRA.mjs.map → AnalyticsProvider-GOLL2W6O.mjs.map} +1 -1
  5. package/dist/AnalyticsProvider-PK5E4TWJ.js +31 -0
  6. package/dist/{AnalyticsProvider-ARAWVJPX.js.map → AnalyticsProvider-PK5E4TWJ.js.map} +1 -1
  7. package/dist/ChatWidget-5RMDVEJL.js +19 -0
  8. package/dist/{ChatWidget-BDES6WUR.js.map → ChatWidget-5RMDVEJL.js.map} +1 -1
  9. package/dist/ChatWidget-LOZDGIVP.mjs +10 -0
  10. package/dist/{ChatWidget-47KAOFLG.mjs.map → ChatWidget-LOZDGIVP.mjs.map} +1 -1
  11. package/dist/EngageWidget-CYJK6RAJ.js +18 -0
  12. package/dist/{EngageWidget-X3NIWGMZ.js.map → EngageWidget-CYJK6RAJ.js.map} +1 -1
  13. package/dist/EngageWidget-HLJMP7MR.mjs +9 -0
  14. package/dist/{EngageWidget-HPZAI6SU.mjs.map → EngageWidget-HLJMP7MR.mjs.map} +1 -1
  15. package/dist/{SignalCore-K2CTZ52G.js → SignalCore-7SB26IPW.js} +11 -10
  16. package/dist/SignalCore-7SB26IPW.js.map +1 -0
  17. package/dist/{SignalCore-XABEH2GA.mjs → SignalCore-JPQMRYMF.mjs} +5 -4
  18. package/dist/SignalCore-JPQMRYMF.mjs.map +1 -0
  19. package/dist/SitemapSync-4UFM6LWW.mjs +8 -0
  20. package/dist/{SitemapSync-OQPRGBG3.mjs.map → SitemapSync-4UFM6LWW.mjs.map} +1 -1
  21. package/dist/SitemapSync-KIFK3OJO.js +17 -0
  22. package/dist/{SitemapSync-4BALOI4B.js.map → SitemapSync-KIFK3OJO.js.map} +1 -1
  23. package/dist/analytics/index.js +12 -11
  24. package/dist/analytics/index.mjs +5 -4
  25. package/dist/blog/index.d.mts +3 -3
  26. package/dist/blog/index.d.ts +3 -3
  27. package/dist/blog/index.js +11 -15
  28. package/dist/blog/index.js.map +1 -1
  29. package/dist/blog/index.mjs +2 -2
  30. package/dist/blog/index.mjs.map +1 -1
  31. package/dist/blog/server-ui.d.mts +1 -1
  32. package/dist/blog/server-ui.d.ts +1 -1
  33. package/dist/blog/server-ui.js +198 -9
  34. package/dist/blog/server-ui.js.map +1 -1
  35. package/dist/blog/server-ui.mjs +198 -2
  36. package/dist/blog/server-ui.mjs.map +1 -1
  37. package/dist/blog/server.d.mts +27 -8
  38. package/dist/blog/server.d.ts +27 -8
  39. package/dist/blog/server.js +45 -43
  40. package/dist/blog/server.mjs +3 -1
  41. package/dist/{chunk-WVAY4ZWC.mjs → chunk-253MGZYN.mjs} +10 -29
  42. package/dist/chunk-253MGZYN.mjs.map +1 -0
  43. package/dist/{chunk-WN5A3KSY.mjs → chunk-34IUDOBC.mjs} +2 -2
  44. package/dist/{chunk-WN5A3KSY.mjs.map → chunk-34IUDOBC.mjs.map} +1 -1
  45. package/dist/{chunk-56X3IUOL.js → chunk-3XQV5HDW.js} +12 -31
  46. package/dist/chunk-3XQV5HDW.js.map +1 -0
  47. package/dist/chunk-5BC7I3KH.mjs +134 -0
  48. package/dist/chunk-5BC7I3KH.mjs.map +1 -0
  49. package/dist/{chunk-O4RVFKQW.mjs → chunk-5WRJRJSM.mjs} +3 -3
  50. package/dist/{chunk-O4RVFKQW.mjs.map → chunk-5WRJRJSM.mjs.map} +1 -1
  51. package/dist/{chunk-7TX5BKVA.js → chunk-6T4NVCAT.js} +2 -2
  52. package/dist/{chunk-7TX5BKVA.js.map → chunk-6T4NVCAT.js.map} +1 -1
  53. package/dist/{chunk-E4VA4FYW.js → chunk-7F3RT2RX.js} +8 -8
  54. package/dist/{chunk-E4VA4FYW.js.map → chunk-7F3RT2RX.js.map} +1 -1
  55. package/dist/{chunk-C37DFD5F.js → chunk-7J47WT5V.js} +14 -14
  56. package/dist/{chunk-C37DFD5F.js.map → chunk-7J47WT5V.js.map} +1 -1
  57. package/dist/{chunk-MJV6RC7I.js → chunk-7ZY44LI4.js} +3 -3
  58. package/dist/{chunk-MJV6RC7I.js.map → chunk-7ZY44LI4.js.map} +1 -1
  59. package/dist/{chunk-WZHWWOUC.js → chunk-BX6FFL2Y.js} +6 -16
  60. package/dist/chunk-BX6FFL2Y.js.map +1 -0
  61. package/dist/chunk-BYW3MJ36.mjs +139 -0
  62. package/dist/chunk-BYW3MJ36.mjs.map +1 -0
  63. package/dist/{chunk-PYA4BR2N.mjs → chunk-C4JYWTI5.mjs} +3 -3
  64. package/dist/{chunk-PYA4BR2N.mjs.map → chunk-C4JYWTI5.mjs.map} +1 -1
  65. package/dist/{chunk-VE5XLADP.mjs → chunk-C7MKSHRI.mjs} +3 -3
  66. package/dist/{chunk-VE5XLADP.mjs.map → chunk-C7MKSHRI.mjs.map} +1 -1
  67. package/dist/chunk-CGCYZJYX.mjs +41 -0
  68. package/dist/chunk-CGCYZJYX.mjs.map +1 -0
  69. package/dist/{chunk-RMUOY6XB.js → chunk-CPYUZSJN.js} +7 -7
  70. package/dist/{chunk-RMUOY6XB.js.map → chunk-CPYUZSJN.js.map} +1 -1
  71. package/dist/{chunk-5WEADCND.mjs → chunk-DAVE4PEM.mjs} +4 -4
  72. package/dist/{chunk-5WEADCND.mjs.map → chunk-DAVE4PEM.mjs.map} +1 -1
  73. package/dist/{chunk-MCDQM75H.js → chunk-DF3MIQNB.js} +15 -15
  74. package/dist/{chunk-MCDQM75H.js.map → chunk-DF3MIQNB.js.map} +1 -1
  75. package/dist/{chunk-IB34IYMN.js → chunk-DLZEFUKB.js} +9 -9
  76. package/dist/{chunk-IB34IYMN.js.map → chunk-DLZEFUKB.js.map} +1 -1
  77. package/dist/chunk-FMUTOABC.js +129 -0
  78. package/dist/chunk-FMUTOABC.js.map +1 -0
  79. package/dist/{chunk-3SIIYHVE.mjs → chunk-GJSNM2A3.mjs} +4 -4
  80. package/dist/{chunk-3SIIYHVE.mjs.map → chunk-GJSNM2A3.mjs.map} +1 -1
  81. package/dist/{chunk-X4OPM3SK.mjs → chunk-GU5OTUQS.mjs} +5 -14
  82. package/dist/chunk-GU5OTUQS.mjs.map +1 -0
  83. package/dist/{chunk-SH4VZDVX.mjs → chunk-GUXB3QH7.mjs} +38 -67
  84. package/dist/chunk-GUXB3QH7.mjs.map +1 -0
  85. package/dist/{chunk-O7B7IEXY.js → chunk-JBRLJMXM.js} +14 -14
  86. package/dist/{chunk-O7B7IEXY.js.map → chunk-JBRLJMXM.js.map} +1 -1
  87. package/dist/{chunk-5SJKYZID.js → chunk-JZAKTBKV.js} +5 -5
  88. package/dist/{chunk-5SJKYZID.js.map → chunk-JZAKTBKV.js.map} +1 -1
  89. package/dist/chunk-K24NKI35.js +8 -0
  90. package/dist/{chunk-CDETOO5W.js.map → chunk-K24NKI35.js.map} +1 -1
  91. package/dist/{chunk-HV7IYMXK.js → chunk-KIUNFFDD.js} +13 -13
  92. package/dist/{chunk-HV7IYMXK.js.map → chunk-KIUNFFDD.js.map} +1 -1
  93. package/dist/{chunk-7523LJ52.js → chunk-KJD5UJ4C.js} +9 -9
  94. package/dist/{chunk-7523LJ52.js.map → chunk-KJD5UJ4C.js.map} +1 -1
  95. package/dist/chunk-KRZL6VYP.mjs +6 -0
  96. package/dist/{chunk-YCQHE2XT.mjs.map → chunk-KRZL6VYP.mjs.map} +1 -1
  97. package/dist/chunk-KTHQKVGZ.js +147 -0
  98. package/dist/chunk-KTHQKVGZ.js.map +1 -0
  99. package/dist/{chunk-BMKZHXWQ.js → chunk-MMON6EVI.js} +3 -194
  100. package/dist/chunk-MMON6EVI.js.map +1 -0
  101. package/dist/chunk-N5H6ORXN.mjs +35 -0
  102. package/dist/chunk-N5H6ORXN.mjs.map +1 -0
  103. package/dist/chunk-NB4MK2Q5.js +18 -0
  104. package/dist/chunk-NB4MK2Q5.js.map +1 -0
  105. package/dist/chunk-NI7OY4FW.mjs +16 -0
  106. package/dist/chunk-NI7OY4FW.mjs.map +1 -0
  107. package/dist/{chunk-7UYUVHCR.js → chunk-OIAAYRGO.js} +4 -4
  108. package/dist/{chunk-7UYUVHCR.js.map → chunk-OIAAYRGO.js.map} +1 -1
  109. package/dist/{chunk-IURQA3H5.mjs → chunk-QLBNK6WJ.mjs} +3 -3
  110. package/dist/{chunk-IURQA3H5.mjs.map → chunk-QLBNK6WJ.mjs.map} +1 -1
  111. package/dist/{chunk-6Q72JAL2.js → chunk-QO45Q7KW.js} +6 -6
  112. package/dist/{chunk-6Q72JAL2.js.map → chunk-QO45Q7KW.js.map} +1 -1
  113. package/dist/{chunk-VNQFKBKF.mjs → chunk-RHKFINCS.mjs} +3 -3
  114. package/dist/{chunk-VNQFKBKF.mjs.map → chunk-RHKFINCS.mjs.map} +1 -1
  115. package/dist/{chunk-LQHZFUZJ.mjs → chunk-RQV3FO33.mjs} +3 -3
  116. package/dist/{chunk-LQHZFUZJ.mjs.map → chunk-RQV3FO33.mjs.map} +1 -1
  117. package/dist/chunk-S32BEPZM.mjs +126 -0
  118. package/dist/chunk-S32BEPZM.mjs.map +1 -0
  119. package/dist/{chunk-472FTEPP.mjs → chunk-SOPPUXR3.mjs} +4 -4
  120. package/dist/{chunk-472FTEPP.mjs.map → chunk-SOPPUXR3.mjs.map} +1 -1
  121. package/dist/chunk-T3LOHTC6.js +136 -0
  122. package/dist/chunk-T3LOHTC6.js.map +1 -0
  123. package/dist/chunk-TPL2IHFI.js +43 -0
  124. package/dist/chunk-TPL2IHFI.js.map +1 -0
  125. package/dist/{chunk-JRUNONG5.mjs → chunk-V4LF47AS.mjs} +3 -3
  126. package/dist/{chunk-JRUNONG5.mjs.map → chunk-V4LF47AS.mjs.map} +1 -1
  127. package/dist/chunk-VELBKUIM.js +38 -0
  128. package/dist/chunk-VELBKUIM.js.map +1 -0
  129. package/dist/{chunk-G3G4HQT3.mjs → chunk-VN3TGLT3.mjs} +3 -3
  130. package/dist/{chunk-G3G4HQT3.mjs.map → chunk-VN3TGLT3.mjs.map} +1 -1
  131. package/dist/{chunk-AB2VYIYU.mjs → chunk-WTR7QJ32.mjs} +4 -194
  132. package/dist/chunk-WTR7QJ32.mjs.map +1 -0
  133. package/dist/{chunk-IB4FRJDV.js → chunk-XAWB2HFQ.js} +37 -67
  134. package/dist/chunk-XAWB2HFQ.js.map +1 -0
  135. package/dist/{chunk-QE53WRXW.mjs → chunk-ZTEQXVQF.mjs} +4 -4
  136. package/dist/{chunk-QE53WRXW.mjs.map → chunk-ZTEQXVQF.mjs.map} +1 -1
  137. package/dist/cli/index.js +2 -2
  138. package/dist/cli/index.mjs +1 -1
  139. package/dist/client/index.d.mts +15 -1
  140. package/dist/client/index.d.ts +15 -1
  141. package/dist/client/index.js +15 -1
  142. package/dist/client/index.js.map +1 -1
  143. package/dist/client/index.mjs +17 -0
  144. package/dist/client/index.mjs.map +1 -1
  145. package/dist/commerce/index.js +51 -50
  146. package/dist/commerce/index.mjs +6 -5
  147. package/dist/engage/index.js +9 -8
  148. package/dist/engage/index.js.map +1 -1
  149. package/dist/engage/index.mjs +6 -5
  150. package/dist/engage/index.mjs.map +1 -1
  151. package/dist/fleet/index.js +8 -7
  152. package/dist/fleet/index.mjs +4 -3
  153. package/dist/forms/index.js +13 -12
  154. package/dist/forms/index.js.map +1 -1
  155. package/dist/forms/index.mjs +5 -4
  156. package/dist/forms/index.mjs.map +1 -1
  157. package/dist/images/index.js +11 -10
  158. package/dist/images/index.mjs +4 -3
  159. package/dist/index.d.mts +1 -1
  160. package/dist/index.d.ts +1 -1
  161. package/dist/index.js +64 -63
  162. package/dist/index.js.map +1 -1
  163. package/dist/index.mjs +10 -9
  164. package/dist/index.mjs.map +1 -1
  165. package/dist/layout/client.js +9 -7
  166. package/dist/layout/client.mjs +8 -6
  167. package/dist/layout/index.js +11 -53
  168. package/dist/layout/index.js.map +1 -1
  169. package/dist/layout/index.mjs +9 -51
  170. package/dist/layout/index.mjs.map +1 -1
  171. package/dist/llms/index.js +12 -12
  172. package/dist/llms/index.mjs +2 -2
  173. package/dist/maps/index.js +5 -4
  174. package/dist/maps/index.js.map +1 -1
  175. package/dist/maps/index.mjs +3 -2
  176. package/dist/maps/index.mjs.map +1 -1
  177. package/dist/seo/client.js +5 -4
  178. package/dist/seo/client.mjs +4 -3
  179. package/dist/seo/index.js +5 -4
  180. package/dist/seo/index.js.map +1 -1
  181. package/dist/seo/index.mjs +4 -3
  182. package/dist/seo/index.mjs.map +1 -1
  183. package/dist/seo-pages/contract.js +6 -5
  184. package/dist/seo-pages/contract.js.map +1 -1
  185. package/dist/seo-pages/contract.mjs +2 -1
  186. package/dist/seo-pages/contract.mjs.map +1 -1
  187. package/dist/server/index.d.mts +45 -1
  188. package/dist/server/index.d.ts +45 -1
  189. package/dist/server/index.js +6 -0
  190. package/dist/server/index.mjs +2 -0
  191. package/dist/signal/index.js +11 -11
  192. package/dist/signal/index.mjs +2 -2
  193. package/dist/sitemap/index.js +2 -2
  194. package/dist/sitemap/index.mjs +1 -1
  195. package/dist/sites/contract.d.mts +36 -12
  196. package/dist/sites/contract.d.ts +36 -12
  197. package/dist/sites/contract.js +12 -11
  198. package/dist/sites/contract.mjs +2 -1
  199. package/dist/sync/index.js +16 -15
  200. package/dist/sync/index.mjs +4 -3
  201. package/dist/{types-DYOumpUT.d.mts → types-8IcjVMDa.d.mts} +1 -1
  202. package/dist/{types-DYOumpUT.d.ts → types-8IcjVMDa.d.ts} +1 -1
  203. package/package.json +1 -1
  204. package/dist/AnalyticsProvider-ARAWVJPX.js +0 -30
  205. package/dist/AnalyticsProvider-HIGSPNRA.mjs +0 -9
  206. package/dist/ChatWidget-47KAOFLG.mjs +0 -9
  207. package/dist/ChatWidget-BDES6WUR.js +0 -18
  208. package/dist/EngageWidget-HPZAI6SU.mjs +0 -8
  209. package/dist/EngageWidget-X3NIWGMZ.js +0 -17
  210. package/dist/SignalCore-K2CTZ52G.js.map +0 -1
  211. package/dist/SignalCore-XABEH2GA.mjs.map +0 -1
  212. package/dist/SitemapSync-4BALOI4B.js +0 -16
  213. package/dist/SitemapSync-OQPRGBG3.mjs +0 -7
  214. package/dist/chunk-56X3IUOL.js.map +0 -1
  215. package/dist/chunk-AB2VYIYU.mjs.map +0 -1
  216. package/dist/chunk-BMKZHXWQ.js.map +0 -1
  217. package/dist/chunk-CDETOO5W.js +0 -8
  218. package/dist/chunk-IB4FRJDV.js.map +0 -1
  219. package/dist/chunk-SH4VZDVX.mjs.map +0 -1
  220. package/dist/chunk-WS4GNH3F.mjs +0 -259
  221. package/dist/chunk-WS4GNH3F.mjs.map +0 -1
  222. package/dist/chunk-WVAY4ZWC.mjs.map +0 -1
  223. package/dist/chunk-WZHWWOUC.js.map +0 -1
  224. package/dist/chunk-X4OPM3SK.mjs.map +0 -1
  225. package/dist/chunk-XKV73RDH.js +0 -266
  226. package/dist/chunk-XKV73RDH.js.map +0 -1
  227. package/dist/chunk-YCQHE2XT.mjs +0 -6
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/layout/SiteKitClientProviders.tsx"],"names":["dynamic","useDeferredActivation","normalizeSiteHost","configureSiteCredential","currentCredential","useState","getOrCreateVisitorId","getOrCreateSessionId","useRef","useCallback","jsx","SignalBridge","jsxs","Fragment","Suspense","FleetHeartbeat","SiteKitIdentityProvider"],"mappings":"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","file":"chunk-56X3IUOL.js","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) via\n * SiteKitIdentityProvider, ensuring consistent tracking across Analytics,\n * Signal, and Engage.\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 SiteKitIdentityProvider,\n getOrCreateVisitorId,\n getOrCreateSessionId,\n} from '../shared/identity'\nimport { normalizeSiteHost } from '../sites/contract'\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'\nimport { configureSiteCredential, currentCredential } from '../shared/siteToken'\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 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}\n\nexport function SiteKitClientProviders({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = true,\n fleet = true,\n defer = true,\n debug = false,\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: explicit `analytics.site` > NEXT_PUBLIC_SITE_URL\n // host > window.location.host. Always a string (possibly empty).\n const explicitSite = analyticsConfig.site\n const envSiteUrl =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_SITE_URL\n : undefined\n let resolvedSite = explicitSite ?? ''\n if (!resolvedSite && envSiteUrl) {\n try {\n resolvedSite = new URL(envSiteUrl).host\n } catch {\n /* malformed URL — fall through to client-side host */\n }\n }\n if (!resolvedSite && typeof window !== 'undefined') {\n resolvedSite = window.location.host\n }\n // Normalize with the shared site contract (lowercase host, no protocol/path/\n // port) so `__SITE_KIT_SITE__` matches exactly what the Sonor API stores —\n // servers re-normalize with the same rule, so this only makes the client\n // emit the canonical value. Always a string (possibly empty).\n const site = normalizeSiteHost(resolvedSite) ?? ''\n\n // Set window globals for modules that still read from them.\n if (typeof window !== 'undefined') {\n // Seed the client token manager. In 3.2+ `apiKey` is a short-lived minted\n // token that sonorFetch refreshes transparently; the window global is set to\n // the freshest token held (a prior page this session may have refreshed).\n // In raw-key mode (2.x kit or mint-failed fallback) this is a passthrough.\n configureSiteCredential({ credential: apiKey, apiUrl })\n ;(window as any).__SITE_KIT_API_URL__ = apiUrl\n ;(window as any).__SITE_KIT_API_KEY__ = currentCredential(apiKey)\n ;(window as any).__SITE_KIT_DEBUG__ = debug\n ;(window as any).__SITE_KIT_SITE__ = site\n }\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 let content = <>{children}</>\n\n // Wrap with SignalBridge if enabled. Safe to wrap: the shell is SSR-safe\n // and renders children straight through — the heavy machinery mounts as a\n // childless sibling inside it. Not gated on modulesReady: experiment\n // variants must apply as early as possible.\n if (signal) {\n const signalConfig: SignalConfig =\n typeof signal === 'object' ? signal : {}\n content = (\n <SignalBridge\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 {content}\n </SignalBridge>\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 content = (\n <>\n {content}\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 debug={debug}\n externalVisitorId={visitorId}\n externalSessionId={sessionId}\n onPageMetadata={onPageMetadata}\n />\n </Suspense>\n )}\n </>\n )\n }\n\n // Add Engage widget if enabled (renders alongside, doesn't wrap)\n if (engage) {\n const engageConfig: EngageConfig =\n typeof engage === 'object' ? engage : {}\n content = (\n <>\n {content}\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 </>\n )\n }\n\n // Add SitemapSync if enabled\n if (sitemapSync) {\n content = (\n <>\n {content}\n {modulesReady && <LazySitemapSync debug={debug} />}\n </>\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 content = (\n <>\n {content}\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 </>\n )\n }\n\n return (\n <SiteKitIdentityProvider visitorId={visitorId} sessionId={sessionId}>\n {content}\n </SiteKitIdentityProvider>\n )\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/blog/ServiceCallout.tsx","../src/blog/ClusterNavigation.tsx","../src/blog/processBlogHtml.ts","../src/blog/blog-styles.ts","../src/blog/BlogPost.tsx","../src/blog/BlogList.tsx","../src/blog/ClusterLandingPage.tsx"],"names":["jsxs","Fragment","jsx","cls"],"mappings":"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AA;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;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;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","file":"chunk-AB2VYIYU.mjs","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","/**\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 { ClusterNavigation } from './ClusterNavigation'\nimport { addExternalLinkTargets, resolveBlogSiteUrl } from './processBlogHtml'\nimport { blogPostCss } from './blog-styles'\n\n/** Extract cluster navigation from a post's cluster fields (pure function, no API calls). */\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 ? { slug: post.parent_pillar_slug, title: post.parent_pillar_title || '' } : 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 // ---------- CUSTOM RENDER ----------\n if (children) {\n return children({ post, tableOfContents, relatedPosts })\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\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 && post.reading_time_minutes && <span className=\"sk-blog-meta-dot\" />}\n {post.reading_time_minutes && (\n <span className={cls(unstyled, styles, 'metaItem', 'sk-blog-meta-item')}>\n {post.reading_time_minutes} 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=${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 email: (a.email 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 is_active: (a.is_active as boolean) ?? true,\n ...((a.socialProfiles as string[])?.length ? { sameAs: a.socialProfiles as string[] } : {}),\n ...(a.title ? { title: a.title as string } : {}),\n } as BlogAuthor & { sameAs?: string[]; title?: string }\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 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 {author.social_links && (\n <div className={unstyled ? undefined : 'sk-blog-author-links'}>\n {author.social_links.twitter && <a href={`https://twitter.com/${author.social_links.twitter}`} target=\"_blank\" rel=\"noopener noreferrer\">Twitter</a>}\n {author.social_links.linkedin && <a href={author.social_links.linkedin} target=\"_blank\" rel=\"noopener noreferrer\">LinkedIn</a>}\n </div>\n )}\n {'sameAs' in author && author.sameAs && author.sameAs.length > 0 && !author.social_links && (\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'\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 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 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 ((params as any).cluster) queryParams.set('cluster', (params as any).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?: string\n featured?: boolean\n search?: 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 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, 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 {post.reading_time_minutes && (\n <span className={cls(unstyled, styles, 'cardReadingTime', '')}>\n {post.reading_time_minutes} 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 - Cluster Landing Page Component\n *\n * Pre-built page component for `/blog/cluster/[slug]` routes.\n * Renders a topic cluster overview with:\n * - Cluster hero (name, topic, description)\n * - Pillar article (featured, large card)\n * - Support articles (grid, categorized by article_type or funnel_stage)\n *\n * Server component — fetches cluster data from Portal API.\n * Ships with `.sk-cluster-landing-*` scoped styles.\n */\n\nimport React from 'react'\nimport { getTopicCluster } from './server-core'\nimport type { TopicCluster, BlogPost } from './types'\n\n// ============================================================================\n// CSS\n// ============================================================================\n\nconst clusterLandingCss = `\n.sk-cluster-landing { max-width: 72rem; margin: 0 auto; padding: 2rem 1rem; }\n\n.sk-cluster-hero { margin-bottom: 3rem; text-align: center; }\n.sk-cluster-hero-label {\n display: inline-flex; align-items: center; gap: 0.375rem;\n font-size: 0.75rem; font-weight: 600; text-transform: uppercase;\n letter-spacing: 0.05em; color: #6366f1; margin-bottom: 0.75rem;\n}\n.sk-cluster-hero-title {\n font-size: 2.25rem; font-weight: 800; color: #111827;\n line-height: 1.2; margin: 0 0 0.75rem 0;\n}\n.sk-cluster-hero-desc {\n font-size: 1.125rem; color: #6b7280; max-width: 40rem;\n margin: 0 auto; line-height: 1.6;\n}\n.sk-cluster-hero-meta {\n display: flex; justify-content: center; gap: 1.5rem;\n margin-top: 1rem; font-size: 0.875rem; color: #9ca3af;\n}\n\n.sk-cluster-pillar-card {\n display: block; text-decoration: none; color: inherit;\n padding: 2rem; border-radius: 0.75rem;\n background: linear-gradient(135deg, rgba(99,102,241,0.04), rgba(99,102,241,0.01));\n border: 2px solid rgba(99,102,241,0.2);\n margin-bottom: 3rem; transition: border-color 0.2s, box-shadow 0.2s;\n}\n.sk-cluster-pillar-card:hover {\n border-color: rgba(99,102,241,0.4);\n box-shadow: 0 4px 24px rgba(99,102,241,0.08);\n}\n.sk-cluster-pillar-label {\n display: inline-flex; align-items: center; gap: 0.375rem;\n font-size: 0.6875rem; font-weight: 700; text-transform: uppercase;\n letter-spacing: 0.05em; color: #6366f1; margin-bottom: 0.75rem;\n padding: 0.25rem 0.5rem; border-radius: 9999px;\n background: rgba(99,102,241,0.08);\n}\n.sk-cluster-pillar-title {\n font-size: 1.5rem; font-weight: 700; color: #111827;\n margin: 0 0 0.5rem 0; line-height: 1.3;\n}\n.sk-cluster-pillar-excerpt {\n font-size: 1rem; color: #6b7280; line-height: 1.6;\n margin: 0 0 1rem 0;\n}\n.sk-cluster-pillar-meta {\n display: flex; gap: 1rem; font-size: 0.8125rem; color: #9ca3af;\n}\n\n.sk-cluster-supports-section { margin-bottom: 2rem; }\n.sk-cluster-supports-title {\n font-size: 1.25rem; font-weight: 700; color: #111827;\n margin: 0 0 1.25rem 0;\n}\n.sk-cluster-supports-grid {\n display: grid; gap: 1.25rem;\n grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));\n}\n.sk-cluster-support-card {\n display: block; text-decoration: none; color: inherit;\n padding: 1.25rem; border-radius: 0.5rem;\n border: 1px solid #e5e7eb; background: #fff;\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n.sk-cluster-support-card:hover {\n border-color: #c7d2fe;\n box-shadow: 0 2px 12px rgba(0,0,0,0.04);\n}\n.sk-cluster-support-card-header {\n display: flex; align-items: center; gap: 0.5rem;\n margin-bottom: 0.5rem;\n}\n.sk-cluster-support-type {\n display: inline-flex; align-items: center;\n padding: 0.125rem 0.375rem; border-radius: 9999px;\n font-size: 0.6875rem; font-weight: 500;\n background: rgba(99,102,241,0.06); color: #6366f1;\n border: 1px solid rgba(99,102,241,0.12);\n text-transform: capitalize;\n}\n.sk-cluster-support-intent {\n font-size: 0.6875rem; color: #9ca3af;\n text-transform: capitalize;\n}\n.sk-cluster-support-title {\n font-size: 1rem; font-weight: 600; color: #111827;\n margin: 0 0 0.375rem 0; line-height: 1.4;\n}\n.sk-cluster-support-excerpt {\n font-size: 0.875rem; color: #6b7280; line-height: 1.5;\n margin: 0; display: -webkit-box; -webkit-line-clamp: 2;\n -webkit-box-orient: vertical; overflow: hidden;\n}\n.sk-cluster-support-meta {\n display: flex; gap: 0.75rem; margin-top: 0.75rem;\n font-size: 0.75rem; color: #9ca3af;\n}\n`\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport interface ClusterLandingPageProps {\n /** Cluster slug to fetch */\n slug: string\n /** Base path for blog URLs (default: /blog) */\n basePath?: string\n /**\n * Include each article's own category segment in its URL:\n * {basePath}/{category}/{slug}. Enable on sites whose blog routes are\n * category-segmented (e.g. upforge.io /insights/{category}/{slug}) —\n * without it, links point at {basePath}/{slug} and 404 on such sites.\n */\n categoryInPath?: boolean\n /** Disable default styles */\n unstyled?: boolean\n /** Custom class name */\n className?: string\n /** Render prop for full data access */\n children?: (props: { cluster: TopicCluster }) => React.ReactNode\n}\n\n/** Category slug of a post — handles both string and object category shapes. */\nfunction categorySlugOf(post: { category?: unknown } | null | undefined): string | null {\n const c = post?.category as { slug?: string } | string | undefined\n if (!c) return null\n if (typeof c === 'string') return c\n return c.slug || null\n}\n\nexport async function ClusterLandingPage({\n slug,\n basePath = '/blog',\n categoryInPath = false,\n unstyled = false,\n className,\n children,\n}: ClusterLandingPageProps) {\n const cluster = await getTopicCluster(slug)\n\n if (!cluster) {\n return (\n <div style={{ padding: '4rem 1rem', textAlign: 'center', color: '#6b7280' }}>\n <p>Topic cluster not found.</p>\n </div>\n )\n }\n\n // Custom render\n if (children) {\n return children({ cluster })\n }\n\n const pillar = cluster.pillar\n const supports = cluster.supports || []\n\n const articleUrl = (post: { slug: string; category?: unknown }) => {\n const cat = categoryInPath ? categorySlugOf(post) : null\n return cat ? `${basePath}/${cat}/${post.slug}` : `${basePath}/${post.slug}`\n }\n\n return (\n <>\n {!unstyled && <style dangerouslySetInnerHTML={{ __html: clusterLandingCss }} />}\n\n <div className={`${unstyled ? '' : 'sk-cluster-landing'} ${className || ''}`}>\n {/* Hero */}\n <header className={unstyled ? '' : 'sk-cluster-hero'}>\n <p className={unstyled ? '' : 'sk-cluster-hero-label'}>\n Topic Cluster\n </p>\n <h1 className={unstyled ? '' : 'sk-cluster-hero-title'}>\n {cluster.cluster_name}\n </h1>\n <p className={unstyled ? '' : 'sk-cluster-hero-desc'}>\n {cluster.core_topic}\n {cluster.geo_target ? ` in ${cluster.geo_target}` : ''}\n </p>\n <div className={unstyled ? '' : 'sk-cluster-hero-meta'}>\n <span>{cluster.article_count} articles</span>\n {cluster.geo_target && <span>{cluster.geo_target}</span>}\n </div>\n </header>\n\n {/* Pillar article (hero card) */}\n {pillar && (\n <a href={articleUrl(pillar)} className={unstyled ? '' : 'sk-cluster-pillar-card'}>\n <span className={unstyled ? '' : 'sk-cluster-pillar-label'}>\n Pillar Guide\n </span>\n <h2 className={unstyled ? '' : 'sk-cluster-pillar-title'}>\n {pillar.title}\n </h2>\n {pillar.excerpt && (\n <p className={unstyled ? '' : 'sk-cluster-pillar-excerpt'}>\n {pillar.excerpt}\n </p>\n )}\n <div className={unstyled ? '' : 'sk-cluster-pillar-meta'}>\n {pillar.reading_time_minutes && (\n <span>{pillar.reading_time_minutes} min read</span>\n )}\n {pillar.word_count && (\n <span>{pillar.word_count.toLocaleString()} words</span>\n )}\n </div>\n </a>\n )}\n\n {/* Support articles */}\n {supports.length > 0 && (\n <section className={unstyled ? '' : 'sk-cluster-supports-section'}>\n <h2 className={unstyled ? '' : 'sk-cluster-supports-title'}>\n Deep Dives\n </h2>\n <div className={unstyled ? '' : 'sk-cluster-supports-grid'}>\n {supports.map((post) => (\n <a\n key={post.id || post.slug}\n href={articleUrl(post)}\n className={unstyled ? '' : 'sk-cluster-support-card'}\n >\n <div className={unstyled ? '' : 'sk-cluster-support-card-header'}>\n {post.article_type && (\n <span className={unstyled ? '' : 'sk-cluster-support-type'}>\n {post.article_type}\n </span>\n )}\n {post.search_intent && (\n <span className={unstyled ? '' : 'sk-cluster-support-intent'}>\n {post.search_intent}\n </span>\n )}\n </div>\n <h3 className={unstyled ? '' : 'sk-cluster-support-title'}>\n {post.title}\n </h3>\n {post.excerpt && (\n <p className={unstyled ? '' : 'sk-cluster-support-excerpt'}>\n {post.excerpt}\n </p>\n )}\n <div className={unstyled ? '' : 'sk-cluster-support-meta'}>\n {post.reading_time_minutes && (\n <span>{post.reading_time_minutes} min read</span>\n )}\n {post.relationship_to_pillar && (\n <span>{post.relationship_to_pillar}</span>\n )}\n </div>\n </a>\n ))}\n </div>\n </section>\n )}\n </div>\n </>\n )\n}\n"]}