@beforesemicolon/builder 1.8.25 → 2.0.1

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 (187) hide show
  1. package/README.md +54 -904
  2. package/dist/cjs/build-browser.js +1 -1
  3. package/dist/cjs/build-modules.js +1 -1
  4. package/dist/cjs/index.js +1 -1
  5. package/dist/esm/build-browser.js +1 -1
  6. package/dist/esm/build-modules.js +1 -1
  7. package/dist/esm/index.js +1 -1
  8. package/dist/types/build-browser.d.ts +5 -3
  9. package/dist/types/build-modules.d.ts +5 -22
  10. package/dist/types/index.d.ts +0 -1
  11. package/package.json +5 -25
  12. package/dist/cjs/.declarations.d.js +0 -1
  13. package/dist/cjs/docs/markdown-layout/index.js +0 -1
  14. package/dist/cjs/docs/markdown-layout/marked-extension.js +0 -1
  15. package/dist/cjs/docs/markdown-layout/parser.js +0 -7
  16. package/dist/cjs/docs/markdown-layout/renderer.js +0 -1
  17. package/dist/cjs/docs/markdown-layout/types.js +0 -1
  18. package/dist/cjs/docs/renderer/code.js +0 -11
  19. package/dist/cjs/docs/renderer/heading.js +0 -1
  20. package/dist/cjs/docs/renderer/index.js +0 -1
  21. package/dist/cjs/docs/renderer/link.js +0 -1
  22. package/dist/cjs/docs/run.js +0 -78
  23. package/dist/cjs/docs/templates/default.template.js +0 -17
  24. package/dist/cjs/docs/templates/fading-citrus/README.md +0 -822
  25. package/dist/cjs/docs/templates/fading-citrus/assets/facebook.svg +0 -8
  26. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/android-chrome-192x192.png +0 -0
  27. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/android-chrome-512x512.png +0 -0
  28. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/apple-touch-icon.png +0 -0
  29. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/favicon-16x16.png +0 -0
  30. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/favicon-32x32.png +0 -0
  31. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/favicon.ico +0 -0
  32. package/dist/cjs/docs/templates/fading-citrus/assets/favicon/site.webmanifest +0 -19
  33. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Black.otf +0 -0
  34. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-BlackItalic.otf +0 -0
  35. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Bold.otf +0 -0
  36. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-BoldItalic.otf +0 -0
  37. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraBold.otf +0 -0
  38. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraBoldItalic.otf +0 -0
  39. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraLight.otf +0 -0
  40. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraLightItalic.otf +0 -0
  41. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Italic.otf +0 -0
  42. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Light.otf +0 -0
  43. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-LightItalic.otf +0 -0
  44. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Medium.otf +0 -0
  45. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-MediumItalic.otf +0 -0
  46. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Regular.otf +0 -0
  47. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-SemiBold.otf +0 -0
  48. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-SemiBoldItalic.otf +0 -0
  49. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Thin.otf +0 -0
  50. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ThinItalic.otf +0 -0
  51. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/exo-2/SIL Open Font License.txt +0 -43
  52. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/Apache License.txt +0 -201
  53. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Bold.ttf +0 -0
  54. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-BoldItalic.ttf +0 -0
  55. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-ExtraBold.ttf +0 -0
  56. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-ExtraBoldItalic.ttf +0 -0
  57. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Italic.ttf +0 -0
  58. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Light.ttf +0 -0
  59. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-LightItalic.ttf +0 -0
  60. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Regular.ttf +0 -0
  61. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Semibold.ttf +0 -0
  62. package/dist/cjs/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-SemiboldItalic.ttf +0 -0
  63. package/dist/cjs/docs/templates/fading-citrus/assets/instagram.svg +0 -28
  64. package/dist/cjs/docs/templates/fading-citrus/assets/logo.dark.svg +0 -8
  65. package/dist/cjs/docs/templates/fading-citrus/assets/logo.light.svg +0 -8
  66. package/dist/cjs/docs/templates/fading-citrus/assets/logo.svg +0 -8
  67. package/dist/cjs/docs/templates/fading-citrus/assets/medium2.svg +0 -18
  68. package/dist/cjs/docs/templates/fading-citrus/assets/reddit.svg +0 -16
  69. package/dist/cjs/docs/templates/fading-citrus/assets/twitter.svg +0 -11
  70. package/dist/cjs/docs/templates/fading-citrus/assets/youtube.svg +0 -10
  71. package/dist/cjs/docs/templates/fading-citrus/layouts/_code-snippet.js +0 -128
  72. package/dist/cjs/docs/templates/fading-citrus/layouts/_footer.js +0 -72
  73. package/dist/cjs/docs/templates/fading-citrus/layouts/_head-meta.js +0 -235
  74. package/dist/cjs/docs/templates/fading-citrus/layouts/_header.js +0 -91
  75. package/dist/cjs/docs/templates/fading-citrus/layouts/_layout-utils.js +0 -109
  76. package/dist/cjs/docs/templates/fading-citrus/layouts/document.js +0 -100
  77. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-cta.js +0 -30
  78. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-ecosystem.js +0 -51
  79. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-features.js +0 -25
  80. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-hero.js +0 -89
  81. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-install.js +0 -116
  82. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-showcase.js +0 -133
  83. package/dist/cjs/docs/templates/fading-citrus/layouts/landing.js +0 -29
  84. package/dist/cjs/docs/templates/fading-citrus/stylesheets/common.css +0 -900
  85. package/dist/cjs/docs/templates/fading-citrus/stylesheets/documentation.css +0 -623
  86. package/dist/cjs/docs/templates/fading-citrus/stylesheets/fonts.css +0 -1
  87. package/dist/cjs/docs/templates/fading-citrus/stylesheets/github-dark.hightlighter.css +0 -107
  88. package/dist/cjs/docs/templates/fading-citrus/stylesheets/github-light.hightlighter.css +0 -107
  89. package/dist/cjs/docs/templates/fading-citrus/stylesheets/hybrid.hightlighter.css +0 -102
  90. package/dist/cjs/docs/templates/fading-citrus/stylesheets/landing.css +0 -1563
  91. package/dist/cjs/docs/templates/fading-citrus/stylesheets/normalize.css +0 -351
  92. package/dist/cjs/docs/templates/fading-citrus/template.config.js +0 -233
  93. package/dist/cjs/docs/types.js +0 -1
  94. package/dist/esm/.declarations.d.js +0 -0
  95. package/dist/esm/docs/markdown-layout/index.js +0 -1
  96. package/dist/esm/docs/markdown-layout/marked-extension.js +0 -1
  97. package/dist/esm/docs/markdown-layout/parser.js +0 -7
  98. package/dist/esm/docs/markdown-layout/renderer.js +0 -1
  99. package/dist/esm/docs/markdown-layout/types.js +0 -0
  100. package/dist/esm/docs/renderer/code.js +0 -11
  101. package/dist/esm/docs/renderer/heading.js +0 -1
  102. package/dist/esm/docs/renderer/index.js +0 -1
  103. package/dist/esm/docs/renderer/link.js +0 -1
  104. package/dist/esm/docs/run.js +0 -78
  105. package/dist/esm/docs/templates/default.template.js +0 -17
  106. package/dist/esm/docs/templates/fading-citrus/README.md +0 -822
  107. package/dist/esm/docs/templates/fading-citrus/assets/facebook.svg +0 -8
  108. package/dist/esm/docs/templates/fading-citrus/assets/favicon/android-chrome-192x192.png +0 -0
  109. package/dist/esm/docs/templates/fading-citrus/assets/favicon/android-chrome-512x512.png +0 -0
  110. package/dist/esm/docs/templates/fading-citrus/assets/favicon/apple-touch-icon.png +0 -0
  111. package/dist/esm/docs/templates/fading-citrus/assets/favicon/favicon-16x16.png +0 -0
  112. package/dist/esm/docs/templates/fading-citrus/assets/favicon/favicon-32x32.png +0 -0
  113. package/dist/esm/docs/templates/fading-citrus/assets/favicon/favicon.ico +0 -0
  114. package/dist/esm/docs/templates/fading-citrus/assets/favicon/site.webmanifest +0 -19
  115. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Black.otf +0 -0
  116. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-BlackItalic.otf +0 -0
  117. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Bold.otf +0 -0
  118. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-BoldItalic.otf +0 -0
  119. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraBold.otf +0 -0
  120. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraBoldItalic.otf +0 -0
  121. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraLight.otf +0 -0
  122. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ExtraLightItalic.otf +0 -0
  123. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Italic.otf +0 -0
  124. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Light.otf +0 -0
  125. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-LightItalic.otf +0 -0
  126. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Medium.otf +0 -0
  127. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-MediumItalic.otf +0 -0
  128. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Regular.otf +0 -0
  129. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-SemiBold.otf +0 -0
  130. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-SemiBoldItalic.otf +0 -0
  131. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-Thin.otf +0 -0
  132. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/Exo2.0-ThinItalic.otf +0 -0
  133. package/dist/esm/docs/templates/fading-citrus/assets/fonts/exo-2/SIL Open Font License.txt +0 -43
  134. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/Apache License.txt +0 -201
  135. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Bold.ttf +0 -0
  136. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-BoldItalic.ttf +0 -0
  137. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-ExtraBold.ttf +0 -0
  138. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-ExtraBoldItalic.ttf +0 -0
  139. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Italic.ttf +0 -0
  140. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Light.ttf +0 -0
  141. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-LightItalic.ttf +0 -0
  142. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Regular.ttf +0 -0
  143. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-Semibold.ttf +0 -0
  144. package/dist/esm/docs/templates/fading-citrus/assets/fonts/open-sans/OpenSans-SemiboldItalic.ttf +0 -0
  145. package/dist/esm/docs/templates/fading-citrus/assets/instagram.svg +0 -28
  146. package/dist/esm/docs/templates/fading-citrus/assets/logo.dark.svg +0 -8
  147. package/dist/esm/docs/templates/fading-citrus/assets/logo.light.svg +0 -8
  148. package/dist/esm/docs/templates/fading-citrus/assets/logo.svg +0 -8
  149. package/dist/esm/docs/templates/fading-citrus/assets/medium2.svg +0 -18
  150. package/dist/esm/docs/templates/fading-citrus/assets/reddit.svg +0 -16
  151. package/dist/esm/docs/templates/fading-citrus/assets/twitter.svg +0 -11
  152. package/dist/esm/docs/templates/fading-citrus/assets/youtube.svg +0 -10
  153. package/dist/esm/docs/templates/fading-citrus/layouts/_code-snippet.js +0 -128
  154. package/dist/esm/docs/templates/fading-citrus/layouts/_footer.js +0 -72
  155. package/dist/esm/docs/templates/fading-citrus/layouts/_head-meta.js +0 -235
  156. package/dist/esm/docs/templates/fading-citrus/layouts/_header.js +0 -91
  157. package/dist/esm/docs/templates/fading-citrus/layouts/_layout-utils.js +0 -109
  158. package/dist/esm/docs/templates/fading-citrus/layouts/document.js +0 -100
  159. package/dist/esm/docs/templates/fading-citrus/layouts/landing-cta.js +0 -30
  160. package/dist/esm/docs/templates/fading-citrus/layouts/landing-ecosystem.js +0 -51
  161. package/dist/esm/docs/templates/fading-citrus/layouts/landing-features.js +0 -25
  162. package/dist/esm/docs/templates/fading-citrus/layouts/landing-hero.js +0 -89
  163. package/dist/esm/docs/templates/fading-citrus/layouts/landing-install.js +0 -116
  164. package/dist/esm/docs/templates/fading-citrus/layouts/landing-showcase.js +0 -133
  165. package/dist/esm/docs/templates/fading-citrus/layouts/landing.js +0 -29
  166. package/dist/esm/docs/templates/fading-citrus/stylesheets/common.css +0 -900
  167. package/dist/esm/docs/templates/fading-citrus/stylesheets/documentation.css +0 -623
  168. package/dist/esm/docs/templates/fading-citrus/stylesheets/fonts.css +0 -1
  169. package/dist/esm/docs/templates/fading-citrus/stylesheets/github-dark.hightlighter.css +0 -107
  170. package/dist/esm/docs/templates/fading-citrus/stylesheets/github-light.hightlighter.css +0 -107
  171. package/dist/esm/docs/templates/fading-citrus/stylesheets/hybrid.hightlighter.css +0 -102
  172. package/dist/esm/docs/templates/fading-citrus/stylesheets/landing.css +0 -1563
  173. package/dist/esm/docs/templates/fading-citrus/stylesheets/normalize.css +0 -351
  174. package/dist/esm/docs/templates/fading-citrus/template.config.js +0 -233
  175. package/dist/esm/docs/types.js +0 -0
  176. package/dist/types/docs/markdown-layout/index.d.ts +0 -4
  177. package/dist/types/docs/markdown-layout/marked-extension.d.ts +0 -9
  178. package/dist/types/docs/markdown-layout/parser.d.ts +0 -12
  179. package/dist/types/docs/markdown-layout/renderer.d.ts +0 -3
  180. package/dist/types/docs/markdown-layout/types.d.ts +0 -36
  181. package/dist/types/docs/renderer/code.d.ts +0 -2
  182. package/dist/types/docs/renderer/heading.d.ts +0 -2
  183. package/dist/types/docs/renderer/index.d.ts +0 -3
  184. package/dist/types/docs/renderer/link.d.ts +0 -2
  185. package/dist/types/docs/run.d.ts +0 -19
  186. package/dist/types/docs/templates/default.template.d.ts +0 -3
  187. package/dist/types/docs/types.d.ts +0 -107
@@ -1,72 +0,0 @@
1
- import {
2
- escapeAttribute,
3
- escapeHTML,
4
- linkAttrs,
5
- siteConfig,
6
- siteName,
7
- } from './_layout-utils.js'
8
-
9
- const defaultFooterGroups = [
10
- {
11
- title: 'Documentation',
12
- links: [{ label: 'Docs', href: '/documentation' }],
13
- },
14
- ]
15
-
16
- const renderLogo = (name) => `
17
- <span class="site-logo-pair">
18
- <img class="site-logo site-logo-dark" src="/assets/logo.dark.svg" alt="${escapeAttribute(name)} logo" width="100" height="30" />
19
- <img class="site-logo site-logo-light" src="/assets/logo.light.svg" alt="" width="100" height="30" aria-hidden="true" />
20
- </span>`
21
-
22
- const renderFooterGroup = (group) => `
23
- <ul class="footer-links">
24
- <li><h4>${escapeHTML(group.title)}</h4></li>
25
- ${(group.links || [])
26
- .map(
27
- (link) =>
28
- `<li><a href="${escapeAttribute(link.href)}"${linkAttrs(link)}>${escapeHTML(link.label)}</a></li>`
29
- )
30
- .join('')}
31
- </ul>`
32
-
33
- const renderSocialLink = (link) => `
34
- <a href="${escapeAttribute(link.href)}"${linkAttrs(link)} aria-label="${escapeAttribute(link.name)}">
35
- <span class="footer-social-icon" style="--icon: url('${escapeAttribute(link.icon)}')" aria-hidden="true"></span>
36
- </a>`
37
-
38
- export default (props = {}) => {
39
- const site = siteConfig(props)
40
- const name = siteName(props)
41
- const description =
42
- site.footerDescription ||
43
- props.description ||
44
- 'Documentation, guides, and references for this project.'
45
- const footerGroups = site.footerGroups || defaultFooterGroups
46
- const socialLinks = site.socialLinks || []
47
- const copyright =
48
- site.copyright ||
49
- `Copyright &copy; ${new Date().getFullYear()} ${escapeHTML(name)}. All rights reserved.`
50
-
51
- return `
52
- <footer class="site-footer">
53
- <div class="footer-inner wrapper">
54
- <div class="footer-brand">
55
- ${renderLogo(name)}
56
- <p>${escapeHTML(description)}</p>
57
- </div>
58
- ${footerGroups.map(renderFooterGroup).join('')}
59
- ${
60
- socialLinks.length
61
- ? `<div class="footer-social" aria-label="social-media">
62
- ${socialLinks.map(renderSocialLink).join('')}
63
- </div>`
64
- : ''
65
- }
66
- <div class="footer-credit">
67
- <span>${copyright}</span>
68
- </div>
69
- </div>
70
- </footer>
71
- `
72
- }
@@ -1,235 +0,0 @@
1
- const fallbackSiteUrl = 'https://beforesemicolon.com'
2
- const fallbackSiteName = 'Before Semicolon'
3
- const fallbackTitle = 'Before Semicolon Documentation'
4
- const fallbackDescription =
5
- 'Documentation for Before Semicolon projects, libraries, and developer tools.'
6
- const fallbackImage = '/assets/site-image.jpg'
7
- const baseKeywords = [
8
- 'Before Semicolon',
9
- 'documentation',
10
- 'JavaScript',
11
- 'developer tools',
12
- 'web development',
13
- 'frontend development',
14
- 'open source',
15
- ]
16
-
17
- const escapeHTML = (value = '') =>
18
- String(value)
19
- .replace(/&/g, '&amp;')
20
- .replace(/</g, '&lt;')
21
- .replace(/>/g, '&gt;')
22
- .replace(/"/g, '&quot;')
23
- .replace(/'/g, '&#39;')
24
-
25
- const canonicalPath = (path = '/') => {
26
- const cleanPath = path.split('?')[0].split('#')[0] || '/'
27
-
28
- if (cleanPath === '/index.html') return '/'
29
- if (cleanPath.endsWith('/index.html')) {
30
- return cleanPath.replace(/index\.html$/, '')
31
- }
32
-
33
- return cleanPath.replace(/\.html$/, '')
34
- }
35
-
36
- const absoluteUrl = (siteUrl, path = '/') => `${siteUrl}${canonicalPath(path)}`
37
-
38
- const absoluteAssetUrl = (siteUrl, imagePath) => {
39
- if (/^https?:\/\//i.test(imagePath)) return imagePath
40
- return `${siteUrl}${imagePath.startsWith('/') ? imagePath : `/${imagePath}`}`
41
- }
42
-
43
- const compactDescription = (description, defaultDescription) =>
44
- (description || defaultDescription).replace(/\s+/g, ' ').trim()
45
-
46
- const pageKeywords = ({ title, name, keywords } = {}) => {
47
- const values = [
48
- ...baseKeywords,
49
- title?.replace(/ - Before Semicolon Documentation$/, ''),
50
- name,
51
- ...(Array.isArray(keywords)
52
- ? keywords
53
- : String(keywords || '').split(',')),
54
- ]
55
-
56
- return [...new Set(values.map((value) => value?.trim()).filter(Boolean))]
57
- .slice(0, 18)
58
- .join(', ')
59
- }
60
-
61
- const jsonScript = (data) =>
62
- `<script type="application/ld+json">${JSON.stringify(data)
63
- .replace(/</g, '\\u003c')
64
- .replace(/>/g, '\\u003e')
65
- .replace(/&/g, '\\u0026')}</script>`
66
-
67
- const breadcrumbJson = ({ siteUrl, title, path }) => {
68
- const cleanPath = canonicalPath(path)
69
- const parts = cleanPath.split('/').filter(Boolean)
70
- const items = [
71
- {
72
- '@type': 'ListItem',
73
- position: 1,
74
- name: 'Home',
75
- item: siteUrl,
76
- },
77
- ]
78
-
79
- let current = ''
80
- parts.forEach((part, index) => {
81
- current += `/${part}`
82
- items.push({
83
- '@type': 'ListItem',
84
- position: index + 2,
85
- name:
86
- index === parts.length - 1
87
- ? title.replace(/ - Before Semicolon Documentation$/, '')
88
- : part
89
- .split('-')
90
- .map((word) => word[0]?.toUpperCase() + word.slice(1))
91
- .join(' '),
92
- item: `${siteUrl}${current}`,
93
- })
94
- })
95
-
96
- return {
97
- '@context': 'https://schema.org',
98
- '@type': 'BreadcrumbList',
99
- itemListElement: items,
100
- }
101
- }
102
-
103
- const pageJson = ({
104
- siteUrl,
105
- siteName,
106
- defaultImage,
107
- title,
108
- description,
109
- path,
110
- name,
111
- }) => {
112
- const isDocsPage = canonicalPath(path).startsWith('/documentation')
113
- const url = absoluteUrl(siteUrl, path)
114
-
115
- if (isDocsPage) {
116
- return {
117
- '@context': 'https://schema.org',
118
- '@type': 'TechArticle',
119
- headline: title,
120
- name: name || title,
121
- description,
122
- url,
123
- image: defaultImage,
124
- inLanguage: 'en-US',
125
- isPartOf: {
126
- '@type': 'TechArticle',
127
- name: `${siteName} Documentation`,
128
- url: `${siteUrl}/documentation`,
129
- },
130
- about: [
131
- `${siteName} documentation`,
132
- 'JavaScript',
133
- 'Web development',
134
- 'Developer tools',
135
- ],
136
- publisher: {
137
- '@type': 'Organization',
138
- name: 'Before Semicolon',
139
- url: 'https://beforesemicolon.com',
140
- logo: {
141
- '@type': 'ImageObject',
142
- url: `${siteUrl}/assets/logo.svg`,
143
- },
144
- },
145
- mainEntityOfPage: url,
146
- }
147
- }
148
-
149
- return {
150
- '@context': 'https://schema.org',
151
- '@type': 'SoftwareSourceCode',
152
- name: siteName,
153
- description,
154
- url,
155
- image: defaultImage,
156
- programmingLanguage: 'JavaScript',
157
- runtimePlatform: 'Browser and Node.js',
158
- publisher: {
159
- '@type': 'Organization',
160
- name: 'Before Semicolon',
161
- url: 'https://beforesemicolon.com',
162
- },
163
- }
164
- }
165
-
166
- export default (props = {}) => {
167
- const meta = props.templateConfig?.meta || {}
168
- const siteUrl = String(
169
- meta.siteUrl || props.siteUrl || fallbackSiteUrl
170
- ).replace(/\/$/, '')
171
- const siteName = meta.siteName || fallbackSiteName
172
- const defaultTitle = meta.title || fallbackTitle
173
- const defaultDescription = meta.description || fallbackDescription
174
- const defaultImage = absoluteAssetUrl(siteUrl, meta.image || fallbackImage)
175
- const title = props.title || defaultTitle
176
- const description = compactDescription(
177
- props.description,
178
- defaultDescription
179
- )
180
- const url = absoluteUrl(siteUrl, props.path)
181
- const canonical = escapeHTML(url)
182
- const image = props.image || defaultImage
183
- const cacheKey = props.cacheKey ? `?v=${escapeHTML(props.cacheKey)}` : ''
184
- const type = canonicalPath(props.path).startsWith('/documentation')
185
- ? 'article'
186
- : 'website'
187
-
188
- return `
189
- <meta charset="UTF-8" />
190
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
191
- <meta http-equiv="X-UA-Compatible" content="ie=edge" />
192
- <title>${escapeHTML(title)}</title>
193
- <meta name="description" content="${escapeHTML(description)}" />
194
- <meta name="keywords" content="${escapeHTML(pageKeywords(props))}" />
195
- <meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1" />
196
- <meta name="googlebot" content="index, follow" />
197
- <meta name="author" content="Before Semicolon" />
198
- <meta name="publisher" content="Before Semicolon" />
199
- <meta name="application-name" content="${siteName}" />
200
- <meta name="generator" content="@beforesemicolon/builder" />
201
- <meta name="theme-color" content="#080d12" />
202
- <meta name="color-scheme" content="dark light" />
203
- <link rel="canonical" href="${canonical}" />
204
- <link rel="home" href="${siteUrl}/" />
205
- <link rel="sitemap" type="application/xml" href="/sitemap.xml" />
206
- <link rel="alternate" type="text/plain" title="LLMs guide" href="/llms.txt" />
207
- <link rel="alternate" type="text/plain" title="Full LLM documentation export" href="/llms-full.txt" />
208
- <meta property="og:title" content="${escapeHTML(title)}" />
209
- <meta property="og:type" content="${type}" />
210
- <meta property="og:description" content="${escapeHTML(description)}" />
211
- <meta property="og:image" content="${escapeHTML(image)}" />
212
- <meta property="og:image:secure_url" content="${escapeHTML(image)}" />
213
- <meta property="og:image:width" content="1200" />
214
- <meta property="og:image:height" content="630" />
215
- <meta property="og:image:alt" content="${escapeHTML(title)}" />
216
- <meta property="og:url" content="${canonical}" />
217
- <meta property="og:site_name" content="${siteName}" />
218
- <meta property="og:locale" content="en_US" />
219
- <meta name="twitter:card" content="summary_large_image" />
220
- <meta name="twitter:site" content="@BeforeSemicolon" />
221
- <meta name="twitter:creator" content="@BeforeSemicolon" />
222
- <meta name="twitter:title" content="${escapeHTML(title)}" />
223
- <meta name="twitter:image" content="${escapeHTML(image)}" />
224
- <meta name="twitter:description" content="${escapeHTML(description)}" />
225
- <meta name="twitter:image:alt" content="${escapeHTML(title)}" />
226
- <link rel="apple-touch-icon" sizes="180x180" href="/assets/favicon/apple-touch-icon.png" />
227
- <link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon/favicon-32x32.png" />
228
- <link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon/favicon-16x16.png" />
229
- <link rel="manifest" href="/assets/favicon/site.webmanifest" />
230
- <link rel="icon" type="image/x-icon" href="/assets/favicon/favicon.ico" />
231
- <link rel="stylesheet" href="/stylesheets/github-dark.hightlighter.css${cacheKey}">
232
- ${jsonScript(pageJson({ ...props, siteUrl, siteName, defaultImage, title, description }))}
233
- ${jsonScript(breadcrumbJson({ siteUrl, title, path: props.path }))}
234
- `
235
- }
@@ -1,91 +0,0 @@
1
- import {
2
- escapeAttribute,
3
- escapeHTML,
4
- linkAttrs,
5
- siteConfig,
6
- siteName,
7
- } from './_layout-utils.js'
8
-
9
- const githubIcon =
10
- '<svg aria-hidden="true" viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path></svg>'
11
-
12
- const renderLogo = (name, width = 90, height = 27) => `
13
- <span class="site-logo-pair">
14
- <img class="site-logo site-logo-dark" src="/assets/logo.dark.svg" alt="${escapeAttribute(name)} logo" width="${width}" height="${height}" />
15
- <img class="site-logo site-logo-light" src="/assets/logo.light.svg" alt="" width="${width}" height="${height}" aria-hidden="true" />
16
- </span>`
17
-
18
- const defaultNavLinks = [
19
- { label: 'Features', href: '/#features' },
20
- { label: 'Code', href: '/#code' },
21
- { label: 'Install', href: '/#install' },
22
- ]
23
-
24
- const defaultActionLinks = [
25
- {
26
- label: 'Documentation',
27
- href: '/documentation',
28
- className: 'btn-primary',
29
- },
30
- ]
31
-
32
- const renderTextLink = (link) => `
33
- <a href="${escapeAttribute(link.href)}"${linkAttrs(link)}${link.className ? ` class="${escapeAttribute(link.className)}"` : ''}${link.ariaLabel ? ` aria-label="${escapeAttribute(link.ariaLabel)}"` : ''}>${escapeHTML(link.label)}</a>`
34
-
35
- const renderRepositoryLink = (props, docs = false) => {
36
- const site = siteConfig(props)
37
-
38
- if (!site.repositoryUrl) return ''
39
-
40
- const label = site.repositoryLabel || `${siteName(props)} repository`
41
-
42
- if (docs) {
43
- return `
44
- <a href="${escapeAttribute(site.repositoryUrl)}" target="_blank" rel="noopener" aria-label="${escapeAttribute(label)}" class="github-link docs-github-link">
45
- <span>v${escapeHTML(props.projectMeta?.version || '')}</span>
46
- ${githubIcon}
47
- </a>`
48
- }
49
-
50
- return `
51
- <a href="${escapeAttribute(site.repositoryUrl)}" target="_blank" rel="noopener" aria-label="${escapeAttribute(label)}" class="github-link">
52
- ${githubIcon}
53
- </a>`
54
- }
55
-
56
- export default (props = {}) => {
57
- const isDocs = props.path?.startsWith('/documentation')
58
- const name = siteName(props)
59
- const site = siteConfig(props)
60
- const navLinks = site.navLinks || defaultNavLinks
61
- const actionLinks = site.actionLinks || defaultActionLinks
62
-
63
- return `
64
- <header class="site-header">
65
- <div class="header-inner wrapper">
66
- <h1>
67
- <a href="/" aria-label="${escapeAttribute(name)} home">
68
- ${renderLogo(name)}
69
- </a>
70
- </h1>
71
- ${
72
- isDocs
73
- ? `
74
- <nav class="nav-actions docs-actions">
75
- ${renderRepositoryLink(props, true)}
76
- </nav>
77
- `
78
- : `
79
- <nav class="nav-links">
80
- ${navLinks.map(renderTextLink).join('')}
81
- </nav>
82
- <nav class="nav-actions">
83
- ${renderRepositoryLink(props)}
84
- ${actionLinks.map(renderTextLink).join('')}
85
- </nav>
86
- `
87
- }
88
- </div>
89
- </header>
90
- `
91
- }
@@ -1,109 +0,0 @@
1
- export const escapeHTML = (value = '') =>
2
- String(value)
3
- .replace(/&/g, '&amp;')
4
- .replace(/</g, '&lt;')
5
- .replace(/>/g, '&gt;')
6
- .replace(/"/g, '&quot;')
7
- .replace(/'/g, '&#39;')
8
-
9
- export const escapeAttribute = escapeHTML
10
-
11
- export const isExternalHref = (href = '') => /^(https?:)?\/\//.test(href)
12
-
13
- export const linkAttrs = (link = {}) => {
14
- const href = link.href || '#'
15
- const external = link.external ?? isExternalHref(href)
16
-
17
- return external ? ' target="_blank" rel="noopener"' : ''
18
- }
19
-
20
- export const siteConfig = (props = {}) => props.templateConfig?.site || {}
21
-
22
- export const siteName = (props = {}) =>
23
- siteConfig(props).name ||
24
- props.projectMeta?.name ||
25
- props.name ||
26
- props.title ||
27
- 'Documentation'
28
-
29
- export const partByName = (parts, name) =>
30
- parts.find((part) => part.name === name)
31
-
32
- export const option = (value, fallback = '') =>
33
- value === undefined || value === true ? fallback : String(value)
34
-
35
- export const optionText = (value, fallback = '') =>
36
- option(value, fallback).replace(/&quot;/g, '"')
37
-
38
- export const codeFromPart = (part = {}) => {
39
- const match = String(part.body || '').match(
40
- /(?:```|~~~)([^\n]*)\n([\s\S]*?)\n(?:```|~~~)/
41
- )
42
-
43
- if (!match) return ''
44
-
45
- return match[2]
46
- }
47
-
48
- export const withFirstParagraphClass = (html = '', className = '') =>
49
- html.replace(/<p>/, `<p class="${className}">`)
50
-
51
- export const statContent = (html = '') => {
52
- const value = html.match(/<h2[^>]*>([\s\S]*?)<\/h2>/)?.[1] || ''
53
- const label = html.match(/<p[^>]*>([\s\S]*?)<\/p>/)?.[1] || ''
54
-
55
- return `
56
- <span class="stat-value text-gradient-primary">${value}</span>
57
- <span class="stat-label">${label}</span>
58
- `
59
- }
60
-
61
- export const stripHeadingLinks = (html = '') =>
62
- html.replace(
63
- /<h([1-6])([^>]*)><a href="[^"]*">([\s\S]*?)<\/a><\/h\1>/g,
64
- '<h$1$2>$3</h$1>'
65
- )
66
-
67
- export const sectionHeader = (html = '') =>
68
- stripHeadingLinks(html).replace(
69
- /<p><code>([\s\S]*?)<\/code><\/p>/,
70
- '<span class="section-tag font-mono">$1</span>'
71
- )
72
-
73
- export const groupedSectionHeader = (html = '') => {
74
- const normalized = sectionHeader(html)
75
- const match = normalized.match(
76
- /^(\s*<span class="section-tag font-mono">[\s\S]*?<\/span>)(\s*<h2[^>]*>[\s\S]*?<\/h2>)([\s\S]*)$/
77
- )
78
-
79
- if (!match) return normalized
80
-
81
- return `<div>${match[1]}${match[2]}</div>${match[3]}`
82
- }
83
-
84
- export const icon = (name) => {
85
- const icons = {
86
- arrowRight:
87
- '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>',
88
- arrowUpRight:
89
- '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7"/><path d="M7 7h10v10"/></svg>',
90
- book: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>',
91
- terminal:
92
- '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></svg>',
93
- sparkles:
94
- '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="sparkles-icon"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275Z"/><path d="m5 3 1 2.5L8.5 6 6 7 5 9.5 4 7 1.5 6 4 5Z"/><path d="m19 17 1 2.5 2.5.5-2.5 1-1 2.5-1-2.5-2.5-1 2.5-1Z"/></svg>',
95
- webComponents:
96
- '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5.5 8.5 9 12l-3.5 3.5L2 12l3.5-3.5Z"/><path d="m12 2 3.5 3.5L12 9 8.5 5.5 12 2Z"/><path d="M18.5 8.5 22 12l-3.5 3.5L15 12l3.5-3.5Z"/><path d="m12 15 3.5 3.5-3.5 3.5-3.5-3.5 3.5-3.5Z"/></svg>',
97
- router: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="19" r="3"/><circle cx="18" cy="5" r="3"/><path d="M9 19h8.5a3.5 3.5 0 0 0 3.5-3.5V8.5a3.5 3.5 0 0 0-3.5-3.5H9"/></svg>',
98
- reactive:
99
- '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>',
100
- tiny: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.24 12.24a6 6 0 0 0-8.49-8.49L5 10.5V19h8.5z"/><line x1="16" y1="8" x2="2" y2="22"/><line x1="17.5" y1="15" x2="9" y2="15"/></svg>',
101
- standards:
102
- '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8.3 10a3.5 3.5 0 0 1 0-7h7.4a3.5 3.5 0 0 1 0 7H8.3Z"/><path d="M12 14a3 3 0 0 1 3-3h3.5a3 3 0 0 1 3 3v3.5a3 3 0 0 1-3 3H15a3 3 0 0 1-3-3V14Z"/><path d="M2 14.5a3.5 3.5 0 0 1 7 0v2.8a3.5 3.5 0 0 1-7 0v-2.8Z"/></svg>',
103
- plug: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22v-5"/><path d="M9 8V2"/><path d="M15 8V2"/><path d="M18 8H6v5a4 4 0 0 0 4 4h4a4 4 0 0 0 4-4Z"/></svg>',
104
- surgical:
105
- '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 14 4-4"/><path d="M3.34 19a10 10 0 1 1 17.32 0"/></svg>',
106
- }
107
-
108
- return icons[name] || icons.reactive
109
- }
@@ -1,100 +0,0 @@
1
- import meta from './_head-meta.js'
2
- import header from './_header.js'
3
- import footer from './_footer.js'
4
- import { escapeAttribute, siteConfig } from './_layout-utils.js'
5
-
6
- const navCategoryToHTML = (docs, currentPath) =>
7
- Array.from(docs.entries())
8
- .map(([k, v]) => {
9
- if (k.endsWith('.html')) {
10
- const href = v.path.replace(/(index)?\.html/, '')
11
-
12
- return `<li ${
13
- currentPath === v.path ? 'class="active"' : ''
14
- }><a href="${href}">${v.name}</a></li>`
15
- }
16
-
17
- return `<ol><span>${k}</span>${navCategoryToHTML(
18
- v,
19
- currentPath
20
- )}</ol>`
21
- })
22
- .join('')
23
-
24
- export default (props) => {
25
- const docs = props.siteMap.get('documentation')
26
- const isDocsIndex = props.path === '/documentation/index.html'
27
- const cacheKey = props.cacheKey ? `?v=${props.cacheKey}` : ''
28
- const docsEditUrl = siteConfig(props).docsEditUrl?.replace(/\/$/, '')
29
- const docsMenu = `<ul>${navCategoryToHTML(docs, props.path)}</ul>`
30
- const pages = [...docs.values()].flatMap((page) =>
31
- page instanceof Map ? [...page.values()] : [page]
32
- )
33
-
34
- let nextPage, previousPage
35
-
36
- for (let i = 0; i < pages.length; i++) {
37
- if (pages[i].path === props.path) {
38
- nextPage = pages[i + 1]
39
- previousPage = pages[i - 1]
40
- }
41
- }
42
-
43
- return `
44
- <!doctype html>
45
- <html lang="en">
46
- <head>
47
- ${meta(props)}
48
- ${props.headScripts?.join('') || ''}
49
- <link rel="stylesheet" href="/stylesheets/documentation.css${cacheKey}">
50
- ${
51
- props.themeStylesheet
52
- ? `<link rel="stylesheet" href="${props.themeStylesheet}">`
53
- : ''
54
- }
55
- </head>
56
- <body>
57
- ${header(props)}
58
-
59
- <div id="mobile-menu-toggle">
60
- <a href="#docs-nav" role="button" aria-label="toggle mobile menu open"></a>
61
- </div>
62
-
63
- <main id="documentation" class="wrapper${isDocsIndex ? ' docs-index' : ''}">
64
- <nav id="docs-nav">
65
- ${docsMenu}
66
- <a href="${props.path}" class="close-mobile-menu" role="button" aria-label="toggle mobile menu close"></a>
67
- </nav>
68
- <article>
69
- ${props.content}
70
-
71
- <div id="page-navigation">
72
- ${previousPage ? `<a href="${previousPage.path.replace('.html', '')}" id="prev-doc"><span aria-hidden="true">&lt;&lt;</span> ${previousPage.name}</a>` : ''}
73
- ${nextPage ? `<a href="${nextPage.path.replace('.html', '')}" id="next-doc">${nextPage.name} <span aria-hidden="true">&gt;&gt;</span></a>` : ''}
74
- </div>
75
-
76
- ${
77
- docsEditUrl
78
- ? `<a href="${escapeAttribute(`${docsEditUrl}${props.path.replace('.html', '')}.md`)}" id="edit-doc" target="_blank" rel="noopener">edit this doc</a>`
79
- : ''
80
- }
81
- </article>
82
- <aside id="table-of-content">
83
- <h4>Content</h4>
84
- <ul>
85
- ${props.tableOfContent
86
- .map(
87
- (c) => `<li><a href="${c.path}">${c.label}</a></li>`
88
- )
89
- .join('')}
90
- </ul>
91
- </aside>
92
- </main>
93
-
94
- ${footer(props)}
95
- ${props.scripts?.join('') || ''}
96
-
97
- </body>
98
- </html>
99
- `
100
- }
@@ -1,30 +0,0 @@
1
- import { icon, partByName } from './_layout-utils.js'
2
-
3
- export default ({ parts, options }) => {
4
- const copy = partByName(parts, 'copy') || parts[0]
5
- const title = options.title || ''
6
- const title2 = options.title2 || ''
7
-
8
- return `
9
- <section class="cta-section wrapper">
10
- <div class="cta-card">
11
- <div class="cta-glow"></div>
12
- <h2>
13
- <span class="text-gradient">${title}</span>
14
- <span class="text-gradient-primary">${title2}</span>
15
- </h2>
16
- ${copy?.html || ''}
17
- <div class="cta-buttons">
18
- <a href="/documentation/get-started" class="btn-primary">
19
- <span>Get Started</span>
20
- ${icon('arrowRight')}
21
- </a>
22
- <a href="/documentation/index.html?v=20260621exact" class="btn-outline">
23
- ${icon('book')}
24
- <span>Read the Docs</span>
25
- </a>
26
- </div>
27
- </div>
28
- </section>
29
- `
30
- }