@treeseed/core 0.8.8 → 0.8.10

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 (90) hide show
  1. package/dist/components/SiteTitle.astro +2 -2
  2. package/dist/components/content/ContentStatusLegend.astro +4 -4
  3. package/dist/components/docs/BookFontControls.astro +9 -9
  4. package/dist/components/docs/DesktopSidebarToggle.astro +8 -8
  5. package/dist/components/docs/Footer.astro +7 -91
  6. package/dist/components/docs/Header.astro +9 -2
  7. package/dist/components/docs/PageTitle.astro +1 -1
  8. package/dist/components/docs/ThemeSelect.astro +3 -1
  9. package/dist/components/forms/ContactForm.astro +21 -21
  10. package/dist/components/forms/FooterSubscribeForm.astro +9 -9
  11. package/dist/components/site/BookList.astro +7 -7
  12. package/dist/components/site/CTASection.astro +4 -4
  13. package/dist/components/site/ChronicleList.astro +6 -6
  14. package/dist/components/site/Hero.astro +3 -3
  15. package/dist/components/site/PathCard.astro +5 -5
  16. package/dist/components/site/ProfileList.astro +5 -5
  17. package/dist/components/site/RouteNotFound.astro +6 -6
  18. package/dist/components/site/SectionIntro.astro +3 -3
  19. package/dist/components/site/StageBanner.astro +2 -2
  20. package/dist/components/site/TrustCallout.astro +3 -3
  21. package/dist/components/ui/data/ActionList.astro +51 -0
  22. package/dist/components/ui/data/Badge.astro +19 -0
  23. package/dist/components/ui/data/DataTable.astro +51 -0
  24. package/dist/components/ui/data/KeyValueList.astro +28 -0
  25. package/dist/components/ui/data/MetricCard.astro +25 -0
  26. package/dist/components/ui/data/MetricGrid.astro +27 -0
  27. package/dist/components/ui/data/StatusPill.astro +20 -0
  28. package/dist/components/ui/forms/Button.astro +52 -0
  29. package/dist/components/ui/forms/Field.astro +39 -0
  30. package/dist/components/ui/forms/FormActions.astro +12 -0
  31. package/dist/components/ui/forms/PasswordMeter.astro +80 -0
  32. package/dist/components/ui/forms/RadioGroup.astro +55 -0
  33. package/dist/components/ui/forms/Select.astro +44 -0
  34. package/dist/components/ui/forms/TextInput.astro +58 -0
  35. package/dist/components/ui/forms/Textarea.astro +45 -0
  36. package/dist/components/ui/layout/PageHeader.astro +45 -0
  37. package/dist/components/ui/shell/AppShell.astro +112 -0
  38. package/dist/components/ui/shell/BottomNav.astro +35 -0
  39. package/dist/components/ui/shell/ProjectHeader.astro +66 -0
  40. package/dist/components/ui/shell/PublicFooter.astro +39 -0
  41. package/dist/components/ui/shell/PublicShell.astro +179 -0
  42. package/dist/components/ui/shell/RailNav.astro +35 -0
  43. package/dist/components/ui/shell/TopBar.astro +52 -0
  44. package/dist/components/ui/surface/Card.astro +46 -0
  45. package/dist/components/ui/surface/EmptyState.astro +45 -0
  46. package/dist/components/ui/surface/Panel.astro +54 -0
  47. package/dist/components/ui/theme/ThemeMenu.astro +32 -0
  48. package/dist/components/ui/theme/ThemePreviewSwatch.astro +18 -0
  49. package/dist/components/ui/theme/ThemeScript.astro +111 -0
  50. package/dist/components/ui/theme/ThemeSelector.astro +202 -0
  51. package/dist/components/ui/types.js +0 -0
  52. package/dist/dev-watch.d.ts +6 -2
  53. package/dist/dev-watch.js +12 -3
  54. package/dist/dev.d.ts +10 -2
  55. package/dist/dev.js +352 -68
  56. package/dist/layouts/AuthoredEntryLayout.astro +27 -27
  57. package/dist/layouts/BookLayout.astro +10 -10
  58. package/dist/layouts/ContentLayout.astro +4 -4
  59. package/dist/layouts/MainLayout.astro +66 -193
  60. package/dist/layouts/NoteLayout.astro +6 -6
  61. package/dist/layouts/ProfileLayout.astro +17 -17
  62. package/dist/middleware/starlightRouteData.js +20 -14
  63. package/dist/pages/404.astro +8 -8
  64. package/dist/pages/[slug].astro +1 -1
  65. package/dist/pages/books/[slug].astro +5 -5
  66. package/dist/pages/contact.astro +4 -4
  67. package/dist/pages/docs-runtime/[...slug].astro +12 -12
  68. package/dist/pages/docs-runtime/index.astro +13 -13
  69. package/dist/pages/index.astro +28 -28
  70. package/dist/pages/ui/index.astro +216 -0
  71. package/dist/scripts/dev-platform.js +7 -1
  72. package/dist/site.js +53 -5
  73. package/dist/styles/app-shell.css +597 -0
  74. package/dist/styles/forms.css +258 -0
  75. package/dist/styles/global.css +125 -120
  76. package/dist/styles/prose.css +11 -11
  77. package/dist/styles/theme.css +177 -0
  78. package/dist/styles/tokens.css +62 -22
  79. package/dist/styles/ui.css +551 -0
  80. package/dist/utils/color-schemes/cedar.js +53 -0
  81. package/dist/utils/color-schemes/fern.js +53 -0
  82. package/dist/utils/color-schemes/index.js +13 -0
  83. package/dist/utils/color-schemes/lichen.js +53 -0
  84. package/dist/utils/color-schemes/shared.js +33 -0
  85. package/dist/utils/color-schemes/tidepool.js +53 -0
  86. package/dist/utils/content-status.js +5 -5
  87. package/dist/utils/site-config.js +2 -2
  88. package/dist/utils/starlight-nav.js +13 -7
  89. package/dist/utils/theme.js +133 -41
  90. package/package.json +36 -2
@@ -0,0 +1,33 @@
1
+ function completeTokens(tokens, mode) {
2
+ return {
3
+ ...tokens,
4
+ surfaceOverlay: mode === "dark" ? "rgba(7, 12, 8, 0.72)" : "rgba(255, 255, 255, 0.88)",
5
+ textSubtle: tokens.textMuted,
6
+ textInverse: mode === "dark" ? "#11170f" : "#ffffff",
7
+ link: tokens.info,
8
+ linkHover: tokens.accentHover,
9
+ borderMuted: tokens.border,
10
+ focus: tokens.info,
11
+ accentText: mode === "dark" ? "#10170f" : "#ffffff",
12
+ infoSoft: mode === "dark" ? colorMix(tokens.info, tokens.canvas, 22) : colorMix(tokens.info, tokens.surface, 18),
13
+ infoText: tokens.info,
14
+ infoBorder: colorMix(tokens.info, tokens.border, mode === "dark" ? 48 : 42),
15
+ successSoft: mode === "dark" ? colorMix(tokens.success, tokens.canvas, 24) : colorMix(tokens.success, tokens.surface, 18),
16
+ successText: tokens.success,
17
+ successBorder: colorMix(tokens.success, tokens.border, mode === "dark" ? 48 : 42),
18
+ warningSoft: mode === "dark" ? colorMix(tokens.warning, tokens.canvas, 24) : colorMix(tokens.warning, tokens.surface, 18),
19
+ warningText: tokens.warning,
20
+ warningBorder: colorMix(tokens.warning, tokens.border, mode === "dark" ? 48 : 42),
21
+ dangerSoft: mode === "dark" ? colorMix(tokens.danger, tokens.canvas, 24) : colorMix(tokens.danger, tokens.surface, 16),
22
+ dangerText: tokens.danger,
23
+ dangerBorder: colorMix(tokens.danger, tokens.border, mode === "dark" ? 48 : 42),
24
+ shadow: mode === "dark" ? "0 16px 36px rgba(0, 0, 0, 0.28)" : "0 1px 2px rgba(31, 35, 40, 0.08)",
25
+ grid: mode === "dark" ? "rgba(160, 180, 150, 0.12)" : "rgba(80, 100, 74, 0.12)"
26
+ };
27
+ }
28
+ function colorMix(first, second, firstPercent) {
29
+ return `color-mix(in srgb, ${first} ${firstPercent}%, ${second})`;
30
+ }
31
+ export {
32
+ completeTokens
33
+ };
@@ -0,0 +1,53 @@
1
+ import { completeTokens } from "./shared.js";
2
+ const tidepoolScheme = {
3
+ id: "tidepool",
4
+ name: "Tidepool Dusk",
5
+ swatches: ["#3f8582", "#286462", "#ffffff", "#1d2928"],
6
+ modeSwatches: {
7
+ light: ["#3f8582", "#286462", "#ffffff", "#1d2928"],
8
+ dark: ["#73c5bd", "#b8eee8", "#162123", "#e2eeee"]
9
+ },
10
+ tokens: {
11
+ light: completeTokens({
12
+ canvas: "#eff7f5",
13
+ canvasSubtle: "#dfecea",
14
+ surface: "#ffffff",
15
+ surfaceMuted: "#dfecea",
16
+ surfaceRaised: "#f7fbfa",
17
+ text: "#1d2928",
18
+ textMuted: "#4f615f",
19
+ border: "#c9d9d7",
20
+ borderStrong: "#a9bfbc",
21
+ accent: "#3f8582",
22
+ accentHover: "#32726f",
23
+ accentStrong: "#286462",
24
+ accentSoft: "#d5ece9",
25
+ info: "#4c7899",
26
+ success: "#3d7b62",
27
+ warning: "#8b6e2f",
28
+ danger: "#a6453d"
29
+ }, "light"),
30
+ dark: completeTokens({
31
+ canvas: "#0f1718",
32
+ canvasSubtle: "#162123",
33
+ surface: "#162123",
34
+ surfaceMuted: "#1c2b2d",
35
+ surfaceRaised: "#223235",
36
+ text: "#e2eeee",
37
+ textMuted: "#9fb6b6",
38
+ border: "#304649",
39
+ borderStrong: "#496265",
40
+ accent: "#73c5bd",
41
+ accentHover: "#a2e1d9",
42
+ accentStrong: "#b8eee8",
43
+ accentSoft: "#1c3838",
44
+ info: "#8bbce5",
45
+ success: "#7cc6a1",
46
+ warning: "#d3b66a",
47
+ danger: "#e28074"
48
+ }, "dark")
49
+ }
50
+ };
51
+ export {
52
+ tidepoolScheme
53
+ };
@@ -4,27 +4,27 @@ const CONTENT_STATUS_META = {
4
4
  live: {
5
5
  label: "Live",
6
6
  description: "Materially exists and is maintained.",
7
- tone: "border-[color:var(--site-accent)]/35 bg-[color:var(--site-accent-soft)] text-[color:var(--site-accent-strong)]"
7
+ tone: "border-[color:var(--ts-color-accent)]/35 bg-[color:var(--ts-color-accent-soft)] text-[color:var(--ts-color-accent-strong)]"
8
8
  },
9
9
  "in progress": {
10
10
  label: "In Progress",
11
11
  description: "Actively being built or hardened.",
12
- tone: "border-[color:var(--site-warm)]/40 bg-[color:rgba(215,176,123,0.18)] text-[color:var(--site-warm-strong)]"
12
+ tone: "border-[color:var(--ts-color-warning-border)] bg-[color:var(--ts-color-warning-soft)] text-[color:var(--ts-color-warning-text)]"
13
13
  },
14
14
  exploratory: {
15
15
  label: "Exploratory",
16
16
  description: "Directionally important, but still unsettled.",
17
- tone: "border-[color:var(--site-blue)]/40 bg-[color:var(--site-blue-soft)] text-[color:var(--site-blue-strong)]"
17
+ tone: "border-[color:var(--ts-color-info)]/40 bg-[color:var(--ts-color-info-soft)] text-[color:var(--ts-color-info-text)]"
18
18
  },
19
19
  planned: {
20
20
  label: "Planned",
21
21
  description: "Intended, but not started in a meaningful way.",
22
- tone: "border-[color:#9c9277]/35 bg-[color:rgba(156,146,119,0.14)] text-[color:#5f5743]"
22
+ tone: "border-[color:var(--ts-color-border-strong)] bg-[color:var(--ts-color-surface-muted)] text-[color:var(--ts-color-text-muted)]"
23
23
  },
24
24
  speculative: {
25
25
  label: "Speculative",
26
26
  description: "Conceptual or long-range, not a current commitment.",
27
- tone: "border-[color:#a39b8e]/35 bg-[color:rgba(163,155,142,0.14)] text-[color:#4d4638]"
27
+ tone: "border-[color:var(--ts-color-border)] bg-[color:var(--ts-color-surface-muted)] text-[color:var(--ts-color-text-subtle)]"
28
28
  }
29
29
  };
30
30
  const PROJECT_STAGE = {
@@ -1,5 +1,5 @@
1
1
  import { RUNTIME_SITE_CONFIG, RUNTIME_TENANT } from "../tenant/runtime-config.js";
2
- import { buildTenantThemeCss } from "./theme.js";
2
+ import { buildTreeseedThemeCss } from "./theme.js";
3
3
  function requireRuntimeSiteConfig() {
4
4
  if (!RUNTIME_SITE_CONFIG) {
5
5
  throw new Error(
@@ -30,7 +30,7 @@ const SITE_HEADER_MENU = SITE.headerMenu;
30
30
  const SITE_FOOTER_MENU = SITE.footerMenu;
31
31
  const SITE_FORMS = SITE.forms;
32
32
  const SITE_EMAIL_NOTIFICATIONS = SITE.emailNotifications;
33
- const SITE_THEME_CSS = buildTenantThemeCss(SITE.theme);
33
+ const SITE_THEME_CSS = buildTreeseedThemeCss(SITE.theme);
34
34
  const PAGE_MODEL_DEFAULTS = SITE_CONFIG.models.pages.defaults;
35
35
  const NOTE_MODEL_DEFAULTS = SITE_CONFIG.models.notes.defaults;
36
36
  const QUESTION_MODEL_DEFAULTS = SITE_CONFIG.models.questions.defaults;
@@ -1,3 +1,9 @@
1
+ import {
2
+ BOOKS as RUNTIME_BOOKS,
3
+ BOOKS_LINK as RUNTIME_BOOKS_LINK,
4
+ TREESEED_LIBRARY_DOWNLOAD as RUNTIME_TREESEED_LIBRARY_DOWNLOAD,
5
+ TREESEED_LINKS as RUNTIME_TREESEED_LINKS
6
+ } from "@treeseed/sdk/platform/books-data";
1
7
  const normalizeHref = (href) => href.endsWith("/") ? href : `${href}/`;
2
8
  function buildSidebarLink(href, label, currentPath) {
3
9
  return {
@@ -76,20 +82,20 @@ function getDocsDownloadForPathFromRuntime(runtime2, pathname) {
76
82
  downloadTitle: book.downloadTitle
77
83
  };
78
84
  }
79
- const BOOKS = [];
80
- const BOOKS_LINK = {
85
+ const BOOKS = RUNTIME_BOOKS ?? [];
86
+ const BOOKS_LINK = RUNTIME_BOOKS_LINK ?? {
81
87
  label: "Books",
82
- link: "/knowledge/"
88
+ link: "/books/"
83
89
  };
84
- const TREESEED_LIBRARY_DOWNLOAD = {
90
+ const TREESEED_LIBRARY_DOWNLOAD = RUNTIME_TREESEED_LIBRARY_DOWNLOAD ?? {
85
91
  downloadFileName: "treeseed-knowledge.md",
86
92
  downloadHref: "/books/treeseed-knowledge.md",
87
93
  downloadTitle: "TreeSeed Knowledge Library"
88
94
  };
89
- const TREESEED_LINKS = {
90
- home: "/knowledge/"
95
+ const TREESEED_LINKS = RUNTIME_TREESEED_LINKS ?? {
96
+ home: "/books/"
91
97
  };
92
- const runtime = { BOOKS, BOOKS_LINK, TREESEED_LIBRARY_DOWNLOAD, TREESEED_LINKS };
98
+ const runtime = typeof __TREESEED_BOOK_RUNTIME__ !== "undefined" ? __TREESEED_BOOK_RUNTIME__ : { BOOKS, BOOKS_LINK, TREESEED_LIBRARY_DOWNLOAD, TREESEED_LINKS };
93
99
  function buildBookSidebar(bookSlug) {
94
100
  return buildBookSidebarFromRuntime(runtime, bookSlug);
95
101
  }
@@ -1,49 +1,141 @@
1
- const THEME_TOKEN_MAP = {
2
- "surfaces.background": "--site-bg",
3
- "surfaces.backgroundElevated": "--site-bg-elevated",
4
- "surfaces.backgroundSoft": "--site-bg-soft",
5
- "surfaces.panel": "--site-panel",
6
- "surfaces.panelStrong": "--site-panel-strong",
7
- "text.body": "--site-text",
8
- "text.muted": "--site-text-muted",
9
- "text.soft": "--site-text-soft",
10
- "border.base": "--site-border",
11
- "border.strong": "--site-border-strong",
12
- "border.grid": "--site-grid",
13
- "accent.base": "--site-accent",
14
- "accent.strong": "--site-accent-strong",
15
- "accent.soft": "--site-accent-soft",
16
- "info.base": "--site-blue",
17
- "info.strong": "--site-blue-strong",
18
- "info.soft": "--site-blue-soft",
19
- "warm.base": "--site-warm",
20
- "warm.strong": "--site-warm-strong"
21
- };
22
- function getThemeValue(theme, dottedPath) {
23
- if (!theme) return void 0;
24
- return dottedPath.split(".").reduce((value, segment) => {
25
- if (!value || typeof value !== "object") {
26
- return void 0;
1
+ import { BUILT_IN_COLOR_SCHEMES } from "./color-schemes/index.js";
2
+ const DEFAULT_SCHEME = "fern";
3
+ const DEFAULT_MODE = "system";
4
+ const THEME_MODES = /* @__PURE__ */ new Set(["light", "dark", "system"]);
5
+ const BUILT_IN_SCHEME_SUMMARIES = BUILT_IN_COLOR_SCHEMES.map((scheme) => ({
6
+ id: scheme.id,
7
+ name: scheme.name,
8
+ swatches: scheme.swatches,
9
+ modeSwatches: scheme.modeSwatches
10
+ }));
11
+ const BUILT_IN_SCHEMES = Object.fromEntries(
12
+ BUILT_IN_COLOR_SCHEMES.map((scheme) => [scheme.id, scheme.tokens])
13
+ );
14
+ function mergeTokens(base, override) {
15
+ return {
16
+ ...base,
17
+ ...override ?? {}
18
+ };
19
+ }
20
+ function mergeScheme(base, override) {
21
+ return {
22
+ light: mergeTokens(base.light, override?.light),
23
+ dark: mergeTokens(base.dark, override?.dark)
24
+ };
25
+ }
26
+ function normalizeSchemeId(value, fallback) {
27
+ return typeof value === "string" && /^[a-z][a-z0-9-]*$/u.test(value) ? value : fallback;
28
+ }
29
+ function cssVariableName(tokenName) {
30
+ return `--ts-color-${tokenName.replace(/[A-Z]/g, (character) => `-${character.toLowerCase()}`)}`;
31
+ }
32
+ function buildTokenDeclarations(tokens) {
33
+ return Object.entries(tokens).map(([tokenName, value]) => ` ${cssVariableName(tokenName)}: ${value};`).join("\n");
34
+ }
35
+ function schemeSelector(schemeId, mode) {
36
+ return `html[data-ts-scheme="${schemeId}"][data-ts-mode="${mode}"]`;
37
+ }
38
+ function systemSchemeSelector(schemeId) {
39
+ return `html[data-ts-scheme="${schemeId}"][data-ts-mode="system"]`;
40
+ }
41
+ function getBuiltInColorSchemes() {
42
+ return BUILT_IN_SCHEME_SUMMARIES.map((summary) => ({
43
+ ...summary,
44
+ swatches: [...summary.swatches],
45
+ modeSwatches: {
46
+ light: [...summary.modeSwatches.light],
47
+ dark: [...summary.modeSwatches.dark]
27
48
  }
28
- return value[segment];
29
- }, theme);
49
+ }));
30
50
  }
31
- function buildTenantThemeCss(theme) {
32
- if (!theme) {
33
- return "";
34
- }
35
- const declarations = Object.entries(THEME_TOKEN_MAP).map(([themePath, cssVariable]) => {
36
- const value = getThemeValue(theme, themePath);
37
- return typeof value === "string" && value.trim().length > 0 ? ` ${cssVariable}: ${value.trim()};` : null;
38
- }).filter((entry) => Boolean(entry));
39
- if (declarations.length === 0) {
40
- return "";
51
+ function resolveTreeseedThemeConfig(input) {
52
+ const schemes = { ...BUILT_IN_SCHEMES };
53
+ for (const [schemeId, scheme] of Object.entries(input?.schemes ?? {})) {
54
+ const base = schemes[schemeId] ?? schemes[DEFAULT_SCHEME];
55
+ schemes[schemeId] = mergeScheme(base, scheme);
41
56
  }
42
- return `:root {
43
- ${declarations.join("\n")}
57
+ const defaultScheme = normalizeSchemeId(input?.defaultScheme, DEFAULT_SCHEME);
58
+ const resolvedDefaultScheme = schemes[defaultScheme] ? defaultScheme : DEFAULT_SCHEME;
59
+ const defaultMode = input?.defaultMode && THEME_MODES.has(input.defaultMode) ? input.defaultMode : DEFAULT_MODE;
60
+ const customSummaries = Object.keys(input?.schemes ?? {}).filter((schemeId) => !BUILT_IN_SCHEME_SUMMARIES.some((summary) => summary.id === schemeId)).map((schemeId) => ({
61
+ id: schemeId,
62
+ name: schemeId.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" "),
63
+ swatches: [
64
+ schemes[schemeId].light.accent,
65
+ schemes[schemeId].light.accentStrong,
66
+ schemes[schemeId].light.surface,
67
+ schemes[schemeId].light.text
68
+ ],
69
+ modeSwatches: {
70
+ light: [
71
+ schemes[schemeId].light.accent,
72
+ schemes[schemeId].light.accentStrong,
73
+ schemes[schemeId].light.surface,
74
+ schemes[schemeId].light.text
75
+ ],
76
+ dark: [
77
+ schemes[schemeId].dark.accent,
78
+ schemes[schemeId].dark.accentStrong,
79
+ schemes[schemeId].dark.surface,
80
+ schemes[schemeId].dark.text
81
+ ]
82
+ }
83
+ }));
84
+ return {
85
+ defaultScheme: resolvedDefaultScheme,
86
+ defaultMode,
87
+ schemes,
88
+ summaries: [...getBuiltInColorSchemes(), ...customSummaries]
89
+ };
44
90
  }
91
+ function normalizeThemePreference(input) {
92
+ const record = input && typeof input === "object" ? input : {};
93
+ return {
94
+ scheme: normalizeSchemeId(record.scheme ?? record.colorScheme, DEFAULT_SCHEME),
95
+ mode: typeof (record.mode ?? record.themeMode) === "string" && THEME_MODES.has(record.mode ?? record.themeMode) ? record.mode ?? record.themeMode : DEFAULT_MODE
96
+ };
97
+ }
98
+ function buildTreeseedThemeCss(input) {
99
+ const resolved = resolveTreeseedThemeConfig(input);
100
+ const defaultTokens = resolved.schemes[resolved.defaultScheme][resolved.defaultMode === "dark" ? "dark" : "light"];
101
+ const darkDefaultTokens = resolved.schemes[resolved.defaultScheme].dark;
102
+ const blocks = [
103
+ `:root {
104
+ ${buildTokenDeclarations(defaultTokens)}
105
+ color-scheme: ${resolved.defaultMode === "dark" ? "dark" : "light"};
106
+ }`
107
+ ];
108
+ if (resolved.defaultMode === "system") {
109
+ blocks.push(`@media (prefers-color-scheme: dark) {
110
+ :root {
111
+ ${buildTokenDeclarations(darkDefaultTokens).replaceAll("\n", "\n ")}
112
+ color-scheme: dark;
113
+ }
114
+ }`);
115
+ }
116
+ for (const [schemeId, scheme] of Object.entries(resolved.schemes)) {
117
+ blocks.push(`${schemeSelector(schemeId, "light")},
118
+ ${systemSchemeSelector(schemeId)} {
119
+ ${buildTokenDeclarations(scheme.light)}
120
+ color-scheme: light;
121
+ }`);
122
+ blocks.push(`${schemeSelector(schemeId, "dark")} {
123
+ ${buildTokenDeclarations(scheme.dark)}
124
+ color-scheme: dark;
125
+ }`);
126
+ blocks.push(`@media (prefers-color-scheme: dark) {
127
+ ${systemSchemeSelector(schemeId)} {
128
+ ${buildTokenDeclarations(scheme.dark).replaceAll("\n", "\n ")}
129
+ color-scheme: dark;
130
+ }
131
+ }`);
132
+ }
133
+ return `${blocks.join("\n\n")}
45
134
  `;
46
135
  }
47
136
  export {
48
- buildTenantThemeCss
137
+ buildTreeseedThemeCss,
138
+ getBuiltInColorSchemes,
139
+ normalizeThemePreference,
140
+ resolveTreeseedThemeConfig
49
141
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/core",
3
- "version": "0.8.8",
3
+ "version": "0.8.10",
4
4
  "description": "Treeseed web framework package for Astro/Starlight site runtimes.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
@@ -70,7 +70,7 @@
70
70
  "@astrojs/sitemap": "3.7.0",
71
71
  "@astrojs/starlight": "0.37.6",
72
72
  "@tailwindcss/vite": "^4.1.4",
73
- "@treeseed/sdk": "0.8.8",
73
+ "@treeseed/sdk": "0.8.10",
74
74
  "astro": "^5.6.1",
75
75
  "esbuild": "^0.28.0",
76
76
  "katex": "^0.16.22",
@@ -159,6 +159,40 @@
159
159
  "./components/site/PathCard.astro": "./dist/components/site/PathCard.astro",
160
160
  "./components/site/TrustCallout.astro": "./dist/components/site/TrustCallout.astro",
161
161
  "./components/content/ContentStatusLegend.astro": "./dist/components/content/ContentStatusLegend.astro",
162
+ "./components/ui/theme/ThemeScript.astro": "./dist/components/ui/theme/ThemeScript.astro",
163
+ "./components/ui/theme/ThemeSelector.astro": "./dist/components/ui/theme/ThemeSelector.astro",
164
+ "./components/ui/theme/ThemeMenu.astro": "./dist/components/ui/theme/ThemeMenu.astro",
165
+ "./components/ui/theme/ThemePreviewSwatch.astro": "./dist/components/ui/theme/ThemePreviewSwatch.astro",
166
+ "./components/ui/forms/Button.astro": "./dist/components/ui/forms/Button.astro",
167
+ "./components/ui/forms/Field.astro": "./dist/components/ui/forms/Field.astro",
168
+ "./components/ui/forms/TextInput.astro": "./dist/components/ui/forms/TextInput.astro",
169
+ "./components/ui/forms/Select.astro": "./dist/components/ui/forms/Select.astro",
170
+ "./components/ui/forms/Textarea.astro": "./dist/components/ui/forms/Textarea.astro",
171
+ "./components/ui/forms/RadioGroup.astro": "./dist/components/ui/forms/RadioGroup.astro",
172
+ "./components/ui/forms/FormActions.astro": "./dist/components/ui/forms/FormActions.astro",
173
+ "./components/ui/forms/PasswordMeter.astro": "./dist/components/ui/forms/PasswordMeter.astro",
174
+ "./components/ui/surface/Panel.astro": "./dist/components/ui/surface/Panel.astro",
175
+ "./components/ui/surface/Card.astro": "./dist/components/ui/surface/Card.astro",
176
+ "./components/ui/surface/EmptyState.astro": "./dist/components/ui/surface/EmptyState.astro",
177
+ "./components/ui/data/Badge.astro": "./dist/components/ui/data/Badge.astro",
178
+ "./components/ui/data/StatusPill.astro": "./dist/components/ui/data/StatusPill.astro",
179
+ "./components/ui/data/MetricCard.astro": "./dist/components/ui/data/MetricCard.astro",
180
+ "./components/ui/data/MetricGrid.astro": "./dist/components/ui/data/MetricGrid.astro",
181
+ "./components/ui/data/ActionList.astro": "./dist/components/ui/data/ActionList.astro",
182
+ "./components/ui/data/KeyValueList.astro": "./dist/components/ui/data/KeyValueList.astro",
183
+ "./components/ui/data/DataTable.astro": "./dist/components/ui/data/DataTable.astro",
184
+ "./components/ui/layout/PageHeader.astro": "./dist/components/ui/layout/PageHeader.astro",
185
+ "./components/ui/shell/AppShell.astro": "./dist/components/ui/shell/AppShell.astro",
186
+ "./components/ui/shell/PublicShell.astro": "./dist/components/ui/shell/PublicShell.astro",
187
+ "./components/ui/shell/PublicFooter.astro": "./dist/components/ui/shell/PublicFooter.astro",
188
+ "./components/ui/shell/RailNav.astro": "./dist/components/ui/shell/RailNav.astro",
189
+ "./components/ui/shell/BottomNav.astro": "./dist/components/ui/shell/BottomNav.astro",
190
+ "./components/ui/shell/TopBar.astro": "./dist/components/ui/shell/TopBar.astro",
191
+ "./components/ui/shell/ProjectHeader.astro": "./dist/components/ui/shell/ProjectHeader.astro",
192
+ "./styles/theme.css": "./dist/styles/theme.css",
193
+ "./styles/ui.css": "./dist/styles/ui.css",
194
+ "./styles/forms.css": "./dist/styles/forms.css",
195
+ "./styles/app-shell.css": "./dist/styles/app-shell.css",
162
196
  "./components/starlight": {
163
197
  "types": "./dist/components/starlight.d.ts",
164
198
  "default": "./dist/components/starlight.js"