create-specra 0.2.2 → 0.2.5

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 (55) hide show
  1. package/README.md +84 -8
  2. package/dist/{api-client-4XZPF7GL.js → api-client-VHQARPDT.js} +3 -3
  3. package/dist/chunk-5765WX4D.js +192 -0
  4. package/dist/chunk-5765WX4D.js.map +1 -0
  5. package/dist/{chunk-CIM73PDF.js → chunk-72RDEJR2.js} +2 -2
  6. package/dist/chunk-SQ2MMFUZ.js +102 -0
  7. package/dist/chunk-SQ2MMFUZ.js.map +1 -0
  8. package/dist/cli.js +7 -7
  9. package/dist/cli.js.map +1 -1
  10. package/dist/{deploy-ETWFNB4Z.js → deploy-V4JO2D6B.js} +32 -6
  11. package/dist/deploy-V4JO2D6B.js.map +1 -0
  12. package/dist/{doctor-IFELWGQB.js → doctor-ICALAJ4N.js} +41 -2
  13. package/dist/doctor-ICALAJ4N.js.map +1 -0
  14. package/dist/index.js +40 -107
  15. package/dist/index.js.map +1 -1
  16. package/dist/{login-DRPP77G4.js → login-UG3WU7DY.js} +17 -11
  17. package/dist/login-UG3WU7DY.js.map +1 -0
  18. package/dist/{logout-UJFYUAQC.js → logout-WJKHJZT6.js} +2 -2
  19. package/dist/{logs-K2CSCKOE.js → logs-BLUJPWNO.js} +3 -3
  20. package/dist/{projects-NORBBC4D.js → projects-LJ57GK3D.js} +3 -3
  21. package/package.json +1 -1
  22. package/templates/book-docs/.env.sample +1 -0
  23. package/templates/book-docs/package.json +2 -2
  24. package/templates/book-docs/src/app.css +80 -1
  25. package/templates/book-docs/src/routes/+layout.server.ts +3 -0
  26. package/templates/book-docs/src/routes/docs/[version]/+layout.server.ts +31 -0
  27. package/templates/book-docs/src/routes/docs/[version]/[...slug]/+page.server.ts +9 -14
  28. package/templates/book-docs/src/routes/docs/[version]/[...slug]/+page.svelte +40 -3
  29. package/templates/book-docs/svelte.config.js +6 -1
  30. package/templates/jbrains-docs/.env.sample +1 -0
  31. package/templates/jbrains-docs/package.json +2 -2
  32. package/templates/jbrains-docs/src/app.css +80 -1
  33. package/templates/jbrains-docs/src/routes/+layout.server.ts +3 -0
  34. package/templates/jbrains-docs/src/routes/docs/[version]/+layout.server.ts +31 -0
  35. package/templates/jbrains-docs/src/routes/docs/[version]/[...slug]/+page.server.ts +9 -14
  36. package/templates/jbrains-docs/src/routes/docs/[version]/[...slug]/+page.svelte +40 -3
  37. package/templates/jbrains-docs/svelte.config.js +6 -1
  38. package/templates/minimal/.env.sample +1 -0
  39. package/templates/minimal/package.json +1 -1
  40. package/templates/minimal/src/app.css +80 -1
  41. package/templates/minimal/src/routes/+layout.server.ts +1 -1
  42. package/templates/minimal/src/routes/docs/[version]/+layout.server.ts +31 -0
  43. package/templates/minimal/src/routes/docs/[version]/[...slug]/+page.server.ts +8 -13
  44. package/templates/minimal/src/routes/docs/[version]/[...slug]/+page.svelte +40 -3
  45. package/templates/minimal/svelte.config.js +1 -1
  46. package/dist/chunk-ATRUBLRX.js +0 -102
  47. package/dist/chunk-ATRUBLRX.js.map +0 -1
  48. package/dist/deploy-ETWFNB4Z.js.map +0 -1
  49. package/dist/doctor-IFELWGQB.js.map +0 -1
  50. package/dist/login-DRPP77G4.js.map +0 -1
  51. /package/dist/{api-client-4XZPF7GL.js.map → api-client-VHQARPDT.js.map} +0 -0
  52. /package/dist/{chunk-CIM73PDF.js.map → chunk-72RDEJR2.js.map} +0 -0
  53. /package/dist/{logout-UJFYUAQC.js.map → logout-WJKHJZT6.js.map} +0 -0
  54. /package/dist/{logs-K2CSCKOE.js.map → logs-BLUJPWNO.js.map} +0 -0
  55. /package/dist/{projects-NORBBC4D.js.map → projects-LJ57GK3D.js.map} +0 -0
@@ -1,7 +1,86 @@
1
1
  @import "specra/styles";
2
2
  @source "./**/*.{js,ts,svelte}";
3
3
 
4
- @theme {
4
+ @theme inline {
5
5
  --font-sans: "Geist", "Geist Fallback", system-ui, sans-serif;
6
6
  --font-mono: "Geist Mono", "Geist Mono Fallback", monospace;
7
7
  }
8
+
9
+ /* =============================================
10
+ THEME OVERRIDES
11
+ Uncomment a :root block for light theme and/or
12
+ a .dark block for dark theme. Mix and match!
13
+ ============================================= */
14
+
15
+ /* ─── Mint Light ─── */
16
+ /* :root {
17
+ --primary: oklch(0.45 0.18 162);
18
+ --primary-foreground: oklch(0.98 0 0);
19
+ --ring: oklch(0.45 0.18 162);
20
+ } */
21
+
22
+ /* ─── Ocean Light ─── */
23
+ /* :root {
24
+ --primary: oklch(0.45 0.18 240);
25
+ --primary-foreground: oklch(0.98 0 0);
26
+ --ring: oklch(0.45 0.18 240);
27
+ } */
28
+
29
+ /* ─── Rose Light ─── */
30
+ /* :root {
31
+ --primary: oklch(0.50 0.20 350);
32
+ --primary-foreground: oklch(0.98 0 0);
33
+ --ring: oklch(0.50 0.20 350);
34
+ } */
35
+
36
+ /* ─── Amber Light ─── */
37
+ /* :root {
38
+ --primary: oklch(0.55 0.16 70);
39
+ --primary-foreground: oklch(0.98 0 0);
40
+ --ring: oklch(0.55 0.16 70);
41
+ } */
42
+
43
+ /* ─── Violet Light ─── */
44
+ /* :root {
45
+ --primary: oklch(0.48 0.22 290);
46
+ --primary-foreground: oklch(0.98 0 0);
47
+ --ring: oklch(0.48 0.22 290);
48
+ } */
49
+
50
+ /* ─── Mint Dark ─── */
51
+ /* .dark {
52
+ --primary: oklch(0.72 0.18 162);
53
+ --primary-foreground: oklch(0.10 0.03 160);
54
+ --ring: oklch(0.72 0.18 162);
55
+ } */
56
+
57
+ /* ─── Ocean Dark ─── */
58
+ /* .dark {
59
+ --primary: oklch(0.68 0.16 240);
60
+ --primary-foreground: oklch(0.98 0 0);
61
+ --ring: oklch(0.68 0.16 240);
62
+ } */
63
+
64
+ /* ─── Rose Dark ─── */
65
+ /* .dark {
66
+ --primary: oklch(0.70 0.18 350);
67
+ --primary-foreground: oklch(0.98 0 0);
68
+ --ring: oklch(0.70 0.18 350);
69
+ } */
70
+
71
+ /* ─── Amber Dark ─── */
72
+ /* .dark {
73
+ --primary: oklch(0.75 0.16 70);
74
+ --primary-foreground: oklch(0.10 0.03 70);
75
+ --ring: oklch(0.75 0.16 70);
76
+ } */
77
+
78
+ /* ─── Violet Dark ─── */
79
+ /* .dark {
80
+ --primary: oklch(0.70 0.20 290);
81
+ --primary-foreground: oklch(0.98 0 0);
82
+ --ring: oklch(0.70 0.20 290);
83
+ } */
84
+
85
+ /* For full theme customization (backgrounds, borders, sidebar, etc.)
86
+ see: https://specra-docs.com/docs/v1.0.0/configuration/theming */
@@ -5,6 +5,9 @@ import type { SpecraConfig } from 'specra';
5
5
 
6
6
  initConfig(specraConfig as unknown as Partial<SpecraConfig>);
7
7
 
8
+ export const prerender = true;
9
+ export const trailingSlash = 'never';
10
+
8
11
  export const load: LayoutServerLoad = async () => {
9
12
  const config = getConfig();
10
13
  return { config };
@@ -0,0 +1,31 @@
1
+ import { getCachedVersions, getCachedAllDocs, getEffectiveConfig, getI18nConfig, getVersionsMeta, loadVersionConfig } from 'specra';
2
+ import { redirect } from '@sveltejs/kit';
3
+ import type { LayoutServerLoad } from './$types';
4
+
5
+ export const load: LayoutServerLoad = async ({ params }) => {
6
+ const { version } = params;
7
+
8
+ const i18nConfig = getI18nConfig();
9
+ const defaultLocale = i18nConfig?.defaultLocale || 'en';
10
+
11
+ // Block access to hidden versions — redirect to active version
12
+ const currentVersionConfig = loadVersionConfig(version);
13
+ if (currentVersionConfig?.hidden) {
14
+ const config = getEffectiveConfig(version);
15
+ const activeVersion = config.site?.activeVersion || 'v1.0.0';
16
+ throw redirect(302, `/docs/${activeVersion}`);
17
+ }
18
+
19
+ const allDocs = await getCachedAllDocs(version, defaultLocale);
20
+ const versions = getCachedVersions();
21
+ const config = getEffectiveConfig(version);
22
+ const versionsMeta = getVersionsMeta(versions);
23
+
24
+ return {
25
+ allDocs,
26
+ versions,
27
+ versionsMeta,
28
+ config,
29
+ versionBanner: currentVersionConfig?.banner,
30
+ };
31
+ };
@@ -2,28 +2,17 @@ import {
2
2
  extractTableOfContents,
3
3
  getAdjacentDocs,
4
4
  isCategoryPage,
5
- getCachedVersions,
6
5
  getCachedAllDocs,
7
6
  getCachedDocBySlug,
8
7
  getI18nConfig,
9
- getConfig,
10
8
  } from 'specra';
11
9
  import type { PageServerLoad } from './$types';
12
10
 
13
- export const load: PageServerLoad = async ({ params }) => {
11
+ export const load: PageServerLoad = async ({ params, parent }) => {
14
12
  const { version, slug: slugArray } = params;
15
- const slug = slugArray;
13
+ const slug = slugArray.replace(/\/$/, '');
14
+ const { allDocs, versions, config, versionsMeta, versionBanner } = await parent();
16
15
 
17
- const i18nConfig = getI18nConfig();
18
- const slugParts = slug.split('/');
19
- let locale: string | undefined;
20
- if (i18nConfig && i18nConfig.locales.includes(slugParts[0])) {
21
- locale = slugParts[0];
22
- }
23
-
24
- const allDocs = await getCachedAllDocs(version, locale);
25
- const versions = getCachedVersions();
26
- const config = getConfig();
27
16
  const isCategory = isCategoryPage(slug, allDocs);
28
17
  const doc = await getCachedDocBySlug(slug, version);
29
18
 
@@ -51,6 +40,8 @@ export const load: PageServerLoad = async ({ params }) => {
51
40
  slug,
52
41
  allDocs,
53
42
  versions,
43
+ versionsMeta,
44
+ versionBanner,
54
45
  config,
55
46
  isCategory: true,
56
47
  isNotFound: false,
@@ -74,6 +65,8 @@ export const load: PageServerLoad = async ({ params }) => {
74
65
  slug,
75
66
  allDocs,
76
67
  versions,
68
+ versionsMeta,
69
+ versionBanner,
77
70
  config,
78
71
  isCategory: false,
79
72
  isNotFound: true,
@@ -102,6 +95,8 @@ export const load: PageServerLoad = async ({ params }) => {
102
95
  slug,
103
96
  allDocs,
104
97
  versions,
98
+ versionsMeta,
99
+ versionBanner,
105
100
  config,
106
101
  isCategory: showCategoryIndex,
107
102
  isNotFound: false,
@@ -2,6 +2,7 @@
2
2
  import {
3
3
  TableOfContents,
4
4
  Header,
5
+ TabGroups,
5
6
  DocLayout,
6
7
  CategoryIndex,
7
8
  HotReloadIndicator,
@@ -44,7 +45,19 @@
44
45
  activeTabGroup={data.categoryTabGroup}
45
46
  >
46
47
  {#snippet header()}
47
- <Header currentVersion={data.version} versions={data.versions} config={data.config} />
48
+ <Header currentVersion={data.version} versions={data.versions} versionsMeta={data.versionsMeta} versionBanner={data.versionBanner} config={data.config}>
49
+ {#snippet subheader()}
50
+ {#if data.config.navigation?.tabGroups && data.config.navigation.tabGroups.length > 0}
51
+ <TabGroups
52
+ tabGroups={data.config.navigation.tabGroups}
53
+ activeTabId={data.categoryTabGroup}
54
+ docs={allDocsCompat}
55
+ version={data.version}
56
+ flush={data.config.navigation?.sidebarStyle === 'flush'}
57
+ />
58
+ {/if}
59
+ {/snippet}
60
+ </Header>
48
61
  {/snippet}
49
62
  <CategoryIndex
50
63
  categoryPath={data.slug}
@@ -65,7 +78,19 @@
65
78
  config={data.config}
66
79
  >
67
80
  {#snippet header()}
68
- <Header currentVersion={data.version} versions={data.versions} config={data.config} />
81
+ <Header currentVersion={data.version} versions={data.versions} versionsMeta={data.versionsMeta} versionBanner={data.versionBanner} config={data.config}>
82
+ {#snippet subheader()}
83
+ {#if data.config.navigation?.tabGroups && data.config.navigation.tabGroups.length > 0}
84
+ <TabGroups
85
+ tabGroups={data.config.navigation.tabGroups}
86
+ activeTabId={data.categoryTabGroup}
87
+ docs={allDocsCompat}
88
+ version={data.version}
89
+ flush={data.config.navigation?.sidebarStyle === 'flush'}
90
+ />
91
+ {/if}
92
+ {/snippet}
93
+ </Header>
69
94
  {/snippet}
70
95
  <NotFoundContent version={data.version} />
71
96
  </MobileDocLayout>
@@ -80,7 +105,19 @@
80
105
  activeTabGroup={data.categoryTabGroup}
81
106
  >
82
107
  {#snippet header()}
83
- <Header currentVersion={data.version} versions={data.versions} config={data.config} />
108
+ <Header currentVersion={data.version} versions={data.versions} versionsMeta={data.versionsMeta} versionBanner={data.versionBanner} config={data.config}>
109
+ {#snippet subheader()}
110
+ {#if data.config.navigation?.tabGroups && data.config.navigation.tabGroups.length > 0}
111
+ <TabGroups
112
+ tabGroups={data.config.navigation.tabGroups}
113
+ activeTabId={data.categoryTabGroup}
114
+ docs={allDocsCompat}
115
+ version={data.version}
116
+ flush={data.config.navigation?.sidebarStyle === 'flush'}
117
+ />
118
+ {/if}
119
+ {/snippet}
120
+ </Header>
84
121
  {/snippet}
85
122
  {#snippet toc()}
86
123
  {#if !data.isCategory}
@@ -1,8 +1,13 @@
1
+ import adapter from '@sveltejs/adapter-static';
1
2
  import { specraConfig } from 'specra/svelte-config';
2
3
  import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
3
4
 
4
5
  const config = specraConfig({
5
- vitePreprocess: { vitePreprocess }
6
+ vitePreprocess: { vitePreprocess },
7
+ kit: {
8
+ adapter: adapter(),
9
+ prerender: { handleHttpError: 'warn', handleMissingId: 'warn' }
10
+ }
6
11
  });
7
12
 
8
13
  export default config;
@@ -0,0 +1 @@
1
+ SPECTRA_TOKEN=sk_xxx...
@@ -10,10 +10,10 @@
10
10
  "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json"
11
11
  },
12
12
  "dependencies": {
13
- "specra": "^0.2.1"
13
+ "specra": "^0.2.4"
14
14
  },
15
15
  "devDependencies": {
16
- "@sveltejs/adapter-auto": "^3.0.0",
16
+ "@sveltejs/adapter-static": "^3.0.0",
17
17
  "@sveltejs/kit": "^2.0.0",
18
18
  "@sveltejs/vite-plugin-svelte": "^6.0.0",
19
19
  "@tailwindcss/postcss": "^4.1.9",
@@ -1,7 +1,86 @@
1
1
  @import "specra/styles";
2
2
  @source "./**/*.{js,ts,svelte}";
3
3
 
4
- @theme {
4
+ @theme inline {
5
5
  --font-sans: "Geist", "Geist Fallback", system-ui, sans-serif;
6
6
  --font-mono: "Geist Mono", "Geist Mono Fallback", monospace;
7
7
  }
8
+
9
+ /* =============================================
10
+ THEME OVERRIDES
11
+ Uncomment a :root block for light theme and/or
12
+ a .dark block for dark theme. Mix and match!
13
+ ============================================= */
14
+
15
+ /* ─── Mint Light ─── */
16
+ /* :root {
17
+ --primary: oklch(0.45 0.18 162);
18
+ --primary-foreground: oklch(0.98 0 0);
19
+ --ring: oklch(0.45 0.18 162);
20
+ } */
21
+
22
+ /* ─── Ocean Light ─── */
23
+ /* :root {
24
+ --primary: oklch(0.45 0.18 240);
25
+ --primary-foreground: oklch(0.98 0 0);
26
+ --ring: oklch(0.45 0.18 240);
27
+ } */
28
+
29
+ /* ─── Rose Light ─── */
30
+ /* :root {
31
+ --primary: oklch(0.50 0.20 350);
32
+ --primary-foreground: oklch(0.98 0 0);
33
+ --ring: oklch(0.50 0.20 350);
34
+ } */
35
+
36
+ /* ─── Amber Light ─── */
37
+ /* :root {
38
+ --primary: oklch(0.55 0.16 70);
39
+ --primary-foreground: oklch(0.98 0 0);
40
+ --ring: oklch(0.55 0.16 70);
41
+ } */
42
+
43
+ /* ─── Violet Light ─── */
44
+ /* :root {
45
+ --primary: oklch(0.48 0.22 290);
46
+ --primary-foreground: oklch(0.98 0 0);
47
+ --ring: oklch(0.48 0.22 290);
48
+ } */
49
+
50
+ /* ─── Mint Dark ─── */
51
+ /* .dark {
52
+ --primary: oklch(0.72 0.18 162);
53
+ --primary-foreground: oklch(0.10 0.03 160);
54
+ --ring: oklch(0.72 0.18 162);
55
+ } */
56
+
57
+ /* ─── Ocean Dark ─── */
58
+ /* .dark {
59
+ --primary: oklch(0.68 0.16 240);
60
+ --primary-foreground: oklch(0.98 0 0);
61
+ --ring: oklch(0.68 0.16 240);
62
+ } */
63
+
64
+ /* ─── Rose Dark ─── */
65
+ /* .dark {
66
+ --primary: oklch(0.70 0.18 350);
67
+ --primary-foreground: oklch(0.98 0 0);
68
+ --ring: oklch(0.70 0.18 350);
69
+ } */
70
+
71
+ /* ─── Amber Dark ─── */
72
+ /* .dark {
73
+ --primary: oklch(0.75 0.16 70);
74
+ --primary-foreground: oklch(0.10 0.03 70);
75
+ --ring: oklch(0.75 0.16 70);
76
+ } */
77
+
78
+ /* ─── Violet Dark ─── */
79
+ /* .dark {
80
+ --primary: oklch(0.70 0.20 290);
81
+ --primary-foreground: oklch(0.98 0 0);
82
+ --ring: oklch(0.70 0.20 290);
83
+ } */
84
+
85
+ /* For full theme customization (backgrounds, borders, sidebar, etc.)
86
+ see: https://specra-docs.com/docs/v1.0.0/configuration/theming */
@@ -5,6 +5,9 @@ import type { SpecraConfig } from 'specra';
5
5
 
6
6
  initConfig(specraConfig as unknown as Partial<SpecraConfig>);
7
7
 
8
+ export const prerender = true;
9
+ export const trailingSlash = 'always';
10
+
8
11
  export const load: LayoutServerLoad = async () => {
9
12
  const config = getConfig();
10
13
  return { config };
@@ -0,0 +1,31 @@
1
+ import { getCachedVersions, getCachedAllDocs, getEffectiveConfig, getI18nConfig, getVersionsMeta, loadVersionConfig } from 'specra';
2
+ import { redirect } from '@sveltejs/kit';
3
+ import type { LayoutServerLoad } from './$types';
4
+
5
+ export const load: LayoutServerLoad = async ({ params }) => {
6
+ const { version } = params;
7
+
8
+ const i18nConfig = getI18nConfig();
9
+ const defaultLocale = i18nConfig?.defaultLocale || 'en';
10
+
11
+ // Block access to hidden versions — redirect to active version
12
+ const currentVersionConfig = loadVersionConfig(version);
13
+ if (currentVersionConfig?.hidden) {
14
+ const config = getEffectiveConfig(version);
15
+ const activeVersion = config.site?.activeVersion || 'v1.0.0';
16
+ throw redirect(302, `/docs/${activeVersion}`);
17
+ }
18
+
19
+ const allDocs = await getCachedAllDocs(version, defaultLocale);
20
+ const versions = getCachedVersions();
21
+ const config = getEffectiveConfig(version);
22
+ const versionsMeta = getVersionsMeta(versions);
23
+
24
+ return {
25
+ allDocs,
26
+ versions,
27
+ versionsMeta,
28
+ config,
29
+ versionBanner: currentVersionConfig?.banner,
30
+ };
31
+ };
@@ -2,28 +2,17 @@ import {
2
2
  extractTableOfContents,
3
3
  getAdjacentDocs,
4
4
  isCategoryPage,
5
- getCachedVersions,
6
5
  getCachedAllDocs,
7
6
  getCachedDocBySlug,
8
7
  getI18nConfig,
9
- getConfig,
10
8
  } from 'specra';
11
9
  import type { PageServerLoad } from './$types';
12
10
 
13
- export const load: PageServerLoad = async ({ params }) => {
11
+ export const load: PageServerLoad = async ({ params, parent }) => {
14
12
  const { version, slug: slugArray } = params;
15
- const slug = slugArray;
13
+ const slug = slugArray.replace(/\/$/, '');
14
+ const { allDocs, versions, config, versionsMeta, versionBanner } = await parent();
16
15
 
17
- const i18nConfig = getI18nConfig();
18
- const slugParts = slug.split('/');
19
- let locale: string | undefined;
20
- if (i18nConfig && i18nConfig.locales.includes(slugParts[0])) {
21
- locale = slugParts[0];
22
- }
23
-
24
- const allDocs = await getCachedAllDocs(version, locale);
25
- const versions = getCachedVersions();
26
- const config = getConfig();
27
16
  const isCategory = isCategoryPage(slug, allDocs);
28
17
  const doc = await getCachedDocBySlug(slug, version);
29
18
 
@@ -51,6 +40,8 @@ export const load: PageServerLoad = async ({ params }) => {
51
40
  slug,
52
41
  allDocs,
53
42
  versions,
43
+ versionsMeta,
44
+ versionBanner,
54
45
  config,
55
46
  isCategory: true,
56
47
  isNotFound: false,
@@ -74,6 +65,8 @@ export const load: PageServerLoad = async ({ params }) => {
74
65
  slug,
75
66
  allDocs,
76
67
  versions,
68
+ versionsMeta,
69
+ versionBanner,
77
70
  config,
78
71
  isCategory: false,
79
72
  isNotFound: true,
@@ -102,6 +95,8 @@ export const load: PageServerLoad = async ({ params }) => {
102
95
  slug,
103
96
  allDocs,
104
97
  versions,
98
+ versionsMeta,
99
+ versionBanner,
105
100
  config,
106
101
  isCategory: showCategoryIndex,
107
102
  isNotFound: false,
@@ -2,6 +2,7 @@
2
2
  import {
3
3
  TableOfContents,
4
4
  Header,
5
+ TabGroups,
5
6
  DocLayout,
6
7
  CategoryIndex,
7
8
  HotReloadIndicator,
@@ -44,7 +45,19 @@
44
45
  activeTabGroup={data.categoryTabGroup}
45
46
  >
46
47
  {#snippet header()}
47
- <Header currentVersion={data.version} versions={data.versions} config={data.config} />
48
+ <Header currentVersion={data.version} versions={data.versions} versionsMeta={data.versionsMeta} versionBanner={data.versionBanner} config={data.config}>
49
+ {#snippet subheader()}
50
+ {#if data.config.navigation?.tabGroups && data.config.navigation.tabGroups.length > 0}
51
+ <TabGroups
52
+ tabGroups={data.config.navigation.tabGroups}
53
+ activeTabId={data.categoryTabGroup}
54
+ docs={allDocsCompat}
55
+ version={data.version}
56
+ flush={data.config.navigation?.sidebarStyle === 'flush'}
57
+ />
58
+ {/if}
59
+ {/snippet}
60
+ </Header>
48
61
  {/snippet}
49
62
  <CategoryIndex
50
63
  categoryPath={data.slug}
@@ -65,7 +78,19 @@
65
78
  config={data.config}
66
79
  >
67
80
  {#snippet header()}
68
- <Header currentVersion={data.version} versions={data.versions} config={data.config} />
81
+ <Header currentVersion={data.version} versions={data.versions} versionsMeta={data.versionsMeta} versionBanner={data.versionBanner} config={data.config}>
82
+ {#snippet subheader()}
83
+ {#if data.config.navigation?.tabGroups && data.config.navigation.tabGroups.length > 0}
84
+ <TabGroups
85
+ tabGroups={data.config.navigation.tabGroups}
86
+ activeTabId={data.categoryTabGroup}
87
+ docs={allDocsCompat}
88
+ version={data.version}
89
+ flush={data.config.navigation?.sidebarStyle === 'flush'}
90
+ />
91
+ {/if}
92
+ {/snippet}
93
+ </Header>
69
94
  {/snippet}
70
95
  <NotFoundContent version={data.version} />
71
96
  </MobileDocLayout>
@@ -80,7 +105,19 @@
80
105
  activeTabGroup={data.categoryTabGroup}
81
106
  >
82
107
  {#snippet header()}
83
- <Header currentVersion={data.version} versions={data.versions} config={data.config} />
108
+ <Header currentVersion={data.version} versions={data.versions} versionsMeta={data.versionsMeta} versionBanner={data.versionBanner} config={data.config}>
109
+ {#snippet subheader()}
110
+ {#if data.config.navigation?.tabGroups && data.config.navigation.tabGroups.length > 0}
111
+ <TabGroups
112
+ tabGroups={data.config.navigation.tabGroups}
113
+ activeTabId={data.categoryTabGroup}
114
+ docs={allDocsCompat}
115
+ version={data.version}
116
+ flush={data.config.navigation?.sidebarStyle === 'flush'}
117
+ />
118
+ {/if}
119
+ {/snippet}
120
+ </Header>
84
121
  {/snippet}
85
122
  {#snippet toc()}
86
123
  {#if !data.isCategory}
@@ -1,8 +1,13 @@
1
+ import adapter from '@sveltejs/adapter-static';
1
2
  import { specraConfig } from 'specra/svelte-config';
2
3
  import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
3
4
 
4
5
  const config = specraConfig({
5
- vitePreprocess: { vitePreprocess }
6
+ vitePreprocess: { vitePreprocess },
7
+ kit: {
8
+ adapter: adapter(),
9
+ prerender: { handleHttpError: 'warn', handleMissingId: 'warn' }
10
+ }
6
11
  });
7
12
 
8
13
  export default config;
@@ -0,0 +1 @@
1
+ SPECTRA_TOKEN=sk_xxx...
@@ -10,7 +10,7 @@
10
10
  "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json"
11
11
  },
12
12
  "dependencies": {
13
- "specra": "^0.2.1"
13
+ "specra": "^0.2.4"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@sveltejs/adapter-static": "^3.0.0",
@@ -1,7 +1,86 @@
1
1
  @import "specra/styles";
2
2
  @source "./**/*.{js,ts,svelte}";
3
3
 
4
- @theme {
4
+ @theme inline {
5
5
  --font-sans: "Geist", "Geist Fallback", system-ui, sans-serif;
6
6
  --font-mono: "Geist Mono", "Geist Mono Fallback", monospace;
7
7
  }
8
+
9
+ /* =============================================
10
+ THEME OVERRIDES
11
+ Uncomment a :root block for light theme and/or
12
+ a .dark block for dark theme. Mix and match!
13
+ ============================================= */
14
+
15
+ /* ─── Mint Light ─── */
16
+ /* :root {
17
+ --primary: oklch(0.45 0.18 162);
18
+ --primary-foreground: oklch(0.98 0 0);
19
+ --ring: oklch(0.45 0.18 162);
20
+ } */
21
+
22
+ /* ─── Ocean Light ─── */
23
+ /* :root {
24
+ --primary: oklch(0.45 0.18 240);
25
+ --primary-foreground: oklch(0.98 0 0);
26
+ --ring: oklch(0.45 0.18 240);
27
+ } */
28
+
29
+ /* ─── Rose Light ─── */
30
+ /* :root {
31
+ --primary: oklch(0.50 0.20 350);
32
+ --primary-foreground: oklch(0.98 0 0);
33
+ --ring: oklch(0.50 0.20 350);
34
+ } */
35
+
36
+ /* ─── Amber Light ─── */
37
+ /* :root {
38
+ --primary: oklch(0.55 0.16 70);
39
+ --primary-foreground: oklch(0.98 0 0);
40
+ --ring: oklch(0.55 0.16 70);
41
+ } */
42
+
43
+ /* ─── Violet Light ─── */
44
+ /* :root {
45
+ --primary: oklch(0.48 0.22 290);
46
+ --primary-foreground: oklch(0.98 0 0);
47
+ --ring: oklch(0.48 0.22 290);
48
+ } */
49
+
50
+ /* ─── Mint Dark ─── */
51
+ /* .dark {
52
+ --primary: oklch(0.72 0.18 162);
53
+ --primary-foreground: oklch(0.10 0.03 160);
54
+ --ring: oklch(0.72 0.18 162);
55
+ } */
56
+
57
+ /* ─── Ocean Dark ─── */
58
+ /* .dark {
59
+ --primary: oklch(0.68 0.16 240);
60
+ --primary-foreground: oklch(0.98 0 0);
61
+ --ring: oklch(0.68 0.16 240);
62
+ } */
63
+
64
+ /* ─── Rose Dark ─── */
65
+ /* .dark {
66
+ --primary: oklch(0.70 0.18 350);
67
+ --primary-foreground: oklch(0.98 0 0);
68
+ --ring: oklch(0.70 0.18 350);
69
+ } */
70
+
71
+ /* ─── Amber Dark ─── */
72
+ /* .dark {
73
+ --primary: oklch(0.75 0.16 70);
74
+ --primary-foreground: oklch(0.10 0.03 70);
75
+ --ring: oklch(0.75 0.16 70);
76
+ } */
77
+
78
+ /* ─── Violet Dark ─── */
79
+ /* .dark {
80
+ --primary: oklch(0.70 0.20 290);
81
+ --primary-foreground: oklch(0.98 0 0);
82
+ --ring: oklch(0.70 0.20 290);
83
+ } */
84
+
85
+ /* For full theme customization (backgrounds, borders, sidebar, etc.)
86
+ see: https://specra-docs.com/docs/v1.0.0/configuration/theming */
@@ -6,7 +6,7 @@ import type { SpecraConfig } from 'specra';
6
6
  initConfig(specraConfig as unknown as Partial<SpecraConfig>);
7
7
 
8
8
  export const prerender = true;
9
- export const trailingSlash = 'always';
9
+ export const trailingSlash = 'never';
10
10
 
11
11
  export const load: LayoutServerLoad = async () => {
12
12
  const config = getConfig();