diff --git a/.gitignore b/.gitignore index 9508382..24c4cf0 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,7 @@ junit-vitest.xml !.trunk/ +/docs/static/social-cards +docs/static/og-default.png +docs/static/twitter-default.png +mprocs.log diff --git a/.ncuskip b/.ncuskip index 7381a9a..e69de29 100644 --- a/.ncuskip +++ b/.ncuskip @@ -1,4 +0,0 @@ - -# Eslint went thru a major version bump, so we need to skip it -eslint -@eslint/js \ No newline at end of file diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index a6e7da2..ceeae38 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -7,7 +7,7 @@ cli: plugins: sources: - id: trunk - ref: v1.7.4 + ref: v1.7.5 uri: https://github.com/trunk-io/plugins # Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes) runtimes: @@ -17,18 +17,23 @@ runtimes: - python@3.10.8 # This is the section where you manage your linters. (https://docs.trunk.io/check/configuration) lint: + ignore: + - linters: [ALL] + paths: + - '**/worker-configuration.d.ts' + - convex/_generated/** enabled: - shellcheck@0.11.0 - shfmt@3.6.0 - - actionlint@1.7.10 - - checkov@3.2.501 - - eslint@9.39.2 + - actionlint@1.7.11 + - checkov@3.2.506 + - eslint@10.0.2 - git-diff-check - - markdownlint@0.47.0 + - markdownlint@0.48.0 - osv-scanner@2.3.3 - prettier@3.8.1 - - svgo@4.0.0 - - trufflehog@3.93.3 + - svgo@4.0.1 + - trufflehog@3.93.7 - yamllint@1.38.0 actions: disabled: diff --git a/LICENSE b/LICENSE index 1af7168..5da975e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2024-2025 Humanspeak, Inc. +Copyright (c) 2024-2026 Humanspeak, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/docs/.ncuskip b/docs/.ncuskip index 7381a9a..e69de29 100644 --- a/docs/.ncuskip +++ b/docs/.ncuskip @@ -1,4 +0,0 @@ - -# Eslint went thru a major version bump, so we need to skip it -eslint -@eslint/js \ No newline at end of file diff --git a/docs/eslint.config.mjs b/docs/eslint.config.mjs index 9c11a9e..43d651b 100644 --- a/docs/eslint.config.mjs +++ b/docs/eslint.config.mjs @@ -3,10 +3,12 @@ import js from '@eslint/js' import prettier from 'eslint-config-prettier' import svelte from 'eslint-plugin-svelte' import globals from 'globals' +import { dirname } from 'node:path' import { fileURLToPath } from 'node:url' import ts from 'typescript-eslint' const gitignorePath = fileURLToPath(new URL('../.gitignore', import.meta.url)) +const tsconfigRootDir = dirname(fileURLToPath(import.meta.url)) export default [ includeIgnoreFile(gitignorePath), @@ -32,6 +34,9 @@ export default [ globals: { ...globals.browser, ...globals.node + }, + parserOptions: { + tsconfigRootDir } }, rules: { diff --git a/docs/package.json b/docs/package.json index 7ecee51..df8a436 100644 --- a/docs/package.json +++ b/docs/package.json @@ -4,59 +4,63 @@ "private": true, "type": "module", "scripts": { - "build": "vite build", + "build": "tsx ./scripts/fetch-github-stats.ts && node ./scripts/generate-sitemap-manifest.mjs && tsx ./scripts/generate-social-cards.ts && vite build", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "deploy": "npm run build && wrangler pages deploy", "dev": "vite dev", + "generate-social": "tsx ./scripts/generate-social-cards.ts", "sitemap:manifest": "node ./scripts/generate-sitemap-manifest.mjs", "sitemap:watch": "chokidar 'src/routes/**/*.svelte' 'src/routes/**/*.svx' 'src/routes/**/*.md' --ignore 'src/routes/examples/+page.ts' -c 'node ./scripts/generate-sitemap-manifest.mjs' --initial --silent", + "social:watch": "chokidar 'src/lib/components/OG.svelte' 'scripts/generate-social-cards.ts' -c 'tsx ./scripts/generate-social-cards.ts' --initial --silent", "format": "prettier --write .", "lint": "prettier --check . && eslint .", "lint:fix": "npm run format && eslint . --fix", "preview": "vite preview" }, "dependencies": { + "@humanspeak/docs-kit": "github:humanspeak/docs-kit#2026.3.11", "@humanspeak/memory-cache": "workspace:*", "github-slugger": "^2.0.0", "runed": "^0.37.1" }, "devDependencies": { - "@cloudflare/workers-types": "^4.20260217.0", + "@cloudflare/workers-types": "^4.20260301.1", "@eslint/compat": "^2.0.2", - "@eslint/js": "^9.39.2", - "@humanspeak/svelte-motion": "^0.1.21", - "@sveltejs/adapter-cloudflare": "^7.2.7", - "@sveltejs/kit": "^2.52.0", + "@eslint/js": "^10.0.1", + "@humanspeak/svelte-motion": "^0.1.31", + "@sveltejs/adapter-cloudflare": "^7.2.8", + "@sveltejs/kit": "^2.53.4", "@sveltejs/vite-plugin-svelte": "^6.2.4", - "@tailwindcss/postcss": "^4.1.18", + "@tailwindcss/postcss": "^4.2.1", "@tailwindcss/typography": "^0.5.19", - "@tailwindcss/vite": "^4.1.18", - "@typescript-eslint/eslint-plugin": "^8.56.0", - "@typescript-eslint/parser": "^8.56.0", - "autoprefixer": "^10.4.24", + "@tailwindcss/vite": "^4.2.1", + "@typescript-eslint/eslint-plugin": "^8.56.1", + "@typescript-eslint/parser": "^8.56.1", + "autoprefixer": "^10.4.27", "chokidar-cli": "^3.0.0", - "eslint": "^9.39.2", + "eslint": "^10.0.2", "eslint-config-prettier": "10.1.8", "eslint-plugin-svelte": "3.15.0", - "globals": "^17.3.0", - "lucide-svelte": "^0.574.0", + "globals": "^17.4.0", + "@lucide/svelte": "^0.577.0", "mdsvex": "^0.12.6", "mode-watcher": "^1.1.0", "prettier": "^3.8.1", "prettier-plugin-organize-imports": "^4.3.0", "prettier-plugin-sort-json": "^4.2.0", - "prettier-plugin-svelte": "^3.4.1", + "prettier-plugin-svelte": "^3.5.1", "prettier-plugin-tailwindcss": "^0.7.2", - "shiki": "^3.22.0", - "svelte": "^5.51.3", - "svelte-check": "^4.4.0", - "tailwind-merge": "^3.4.1", - "tailwindcss": "^4.1.18", + "shiki": "^4.0.1", + "svelte": "^5.53.7", + "svelte-check": "^4.4.4", + "tailwind-merge": "^3.5.0", + "tailwindcss": "^4.2.1", + "tsx": "^4.21.0", "typescript": "^5.9.3", - "typescript-eslint": "^8.56.0", + "typescript-eslint": "^8.56.1", "vite": "^7.3.1", - "wrangler": "^4.66.0" + "wrangler": "^4.70.0" }, "volta": { "node": "24.13.0" diff --git a/docs/scripts/fetch-github-stats.ts b/docs/scripts/fetch-github-stats.ts new file mode 100644 index 0000000..cbb47cc --- /dev/null +++ b/docs/scripts/fetch-github-stats.ts @@ -0,0 +1,12 @@ +import { fetchGitHubStats } from '@humanspeak/docs-kit/scripts/fetch-github-stats' +import path from 'path' +import { fileURLToPath } from 'url' +import { docsConfig } from '../src/lib/docs-config' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) + +await fetchGitHubStats({ + repo: docsConfig.repo, + fallbackStars: docsConfig.fallbackStars, + outputPath: path.resolve(__dirname, '..', 'src', 'lib', 'github-stats.json') +}) diff --git a/docs/scripts/generate-social-cards.ts b/docs/scripts/generate-social-cards.ts new file mode 100644 index 0000000..5c350d7 --- /dev/null +++ b/docs/scripts/generate-social-cards.ts @@ -0,0 +1,16 @@ +import { generateSocialCards } from '@humanspeak/docs-kit/scripts/generate-social-cards' +import path from 'path' +import { fileURLToPath } from 'url' +import { docsConfig } from '../src/lib/docs-config' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const ROOT = path.resolve(__dirname, '..') + +await generateSocialCards({ + npmPackage: docsConfig.npmPackage, + defaultTitle: docsConfig.name, + defaultDescription: docsConfig.description, + defaultFeatures: docsConfig.defaultFeatures, + rootDir: ROOT, + fontsDir: path.join(ROOT, 'node_modules/@humanspeak/docs-kit/dist/fonts') +}) diff --git a/docs/src/app.css b/docs/src/app.css index 5a6c0ee..3108ce4 100644 --- a/docs/src/app.css +++ b/docs/src/app.css @@ -1,301 +1,9 @@ @import 'tailwindcss'; +@source '../node_modules/@humanspeak/docs-kit/dist'; +@import '@humanspeak/docs-kit/styles/base.css'; @plugin '@tailwindcss/typography'; -:root { - /* Brand colors - Humanspeak teal green */ - --color-brand-50: #f0fdfb; - --color-brand-100: #ccf7ed; - --color-brand-200: #99eedb; - --color-brand-300: #66e5c9; - --color-brand-400: #54dbbc; - --color-brand-500: #3dbba0; - --color-brand-600: #2d9984; - --color-brand-700: #247768; - --color-brand-800: #1b5a4e; - --color-brand-900: #134038; - - /* Light mode colors */ - --color-background: #ffffff; - --color-foreground: #0f172a; - --color-muted: #f8fafc; - --color-muted-foreground: #64748b; - - /* Card colors */ - --color-card: #ffffff; - --color-card-foreground: #0f172a; - - /* Border colors */ - --color-border: #e2e8f0; - --color-border-muted: #f1f5f9; - --color-border-mid: #e2e8f0; - - /* Primary colors (using brand) */ - --color-primary: var(--color-brand-500); - --color-primary-foreground: #ffffff; - - /* Secondary colors */ - --color-secondary: #f1f5f9; - --color-secondary-foreground: #0f172a; - - /* Accent colors (blue for links/active states) */ - --color-accent: #3b82f6; - --color-accent-foreground: #ffffff; - --color-accent-muted: #dbeafe; - - /* Text colors for different states */ - --color-text-primary: #0f172a; - --color-text-secondary: #475569; - --color-text-muted: #64748b; - --color-text-inverse: #ffffff; - - /* Sidebar specific colors */ - --color-sidebar-background: #ffffff; - --color-sidebar-foreground: #0f172a; - --color-sidebar-border: #e2e8f0; - --color-sidebar-active: #dbeafe; - --color-sidebar-active-foreground: #1d4ed8; - - /* Code colors (light mode: lighter bg, dark text) */ - --color-code-background: #f8f9f9; /* inline code bg */ - --color-code-foreground: #111827; /* near-black text */ - --color-code-block-background: #f5f6f8; /* very light grey block bg */ - --color-code-block-foreground: #111827; /* black/muted text */ -} - -.dark { - /* Dark mode colors */ - --color-background: #0b1011; - --color-foreground: #f8fafc; - --color-muted: #1e293b; - --color-muted-foreground: #a3b2c4; /* slightly brighter for contrast */ - - /* Card colors */ - --color-card: #1e293b; - --color-card-foreground: #f8fafc; - - /* Border colors */ - --color-border: #334155; - --color-border-muted: rgba(255, 255, 255, 0.1); - --color-border-mid: rgba(255, 255, 255, 0.15); - - /* Primary colors (using brand) */ - --color-primary: var(--color-brand-500); - --color-primary-foreground: #ffffff; - - /* Secondary colors */ - --color-secondary: #1e293b; - --color-secondary-foreground: #f8fafc; - - /* Accent colors */ - --color-accent: #3b82f6; - --color-accent-foreground: #ffffff; - --color-accent-muted: #1e3a8a; - - /* Text colors for different states */ - --color-text-primary: #f8fafc; - --color-text-secondary: #e2e8f0; /* brighter secondary for readability */ - --color-text-muted: #cbd5e1; /* raise contrast of muted */ - --color-text-inverse: #0f172a; - - /* Sidebar specific colors */ - --color-sidebar-background: #0b1011; - --color-sidebar-foreground: #f8fafc; - --color-sidebar-border: #334155; - --color-sidebar-active: rgba(59, 130, 246, 0.1); - --color-sidebar-active-foreground: #60a5fa; - - /* Code block colors */ - --color-code-background: #1e293b; - --color-code-foreground: #f8fafc; - --color-code-block-background: #0f172a; - --color-code-block-foreground: #f1f5f9; -} - -@theme { - /* Map CSS variables to Tailwind colors */ - --color-background: var(--color-background); - --color-foreground: var(--color-foreground); - --color-muted: var(--color-muted); - --color-muted-foreground: var(--color-muted-foreground); - - --color-card: var(--color-card); - --color-card-foreground: var(--color-card-foreground); - - --color-border: var(--color-border); - --color-border-muted: var(--color-border-muted); - --color-border-mid: var(--color-border-mid); - - --color-primary: var(--color-primary); - --color-primary-foreground: var(--color-primary-foreground); - - --color-secondary: var(--color-secondary); - --color-secondary-foreground: var(--color-secondary-foreground); - - --color-accent: var(--color-accent); - --color-accent-foreground: var(--color-accent-foreground); - --color-accent-muted: var(--color-accent-muted); - - /* Text colors */ - --color-text-primary: var(--color-text-primary); - --color-text-secondary: var(--color-text-secondary); - --color-text-muted: var(--color-text-muted); - --color-text-inverse: var(--color-text-inverse); - - /* Sidebar colors */ - --color-sidebar-background: var(--color-sidebar-background); - --color-sidebar-foreground: var(--color-sidebar-foreground); - --color-sidebar-border: var(--color-sidebar-border); - --color-sidebar-active: var(--color-sidebar-active); - --color-sidebar-active-foreground: var(--color-sidebar-active-foreground); - - /* Code colors */ - --color-code-background: var(--color-code-background); - --color-code-foreground: var(--color-code-foreground); - --color-code-block-background: var(--color-code-block-background); - --color-code-block-foreground: var(--color-code-block-foreground); - - /* Brand colors */ - --color-brand-50: var(--color-brand-50); - --color-brand-100: var(--color-brand-100); - --color-brand-200: var(--color-brand-200); - --color-brand-300: var(--color-brand-300); - --color-brand-400: var(--color-brand-400); - --color-brand-500: var(--color-brand-500); - --color-brand-600: var(--color-brand-600); - --color-brand-700: var(--color-brand-700); - --color-brand-800: var(--color-brand-800); - --color-brand-900: var(--color-brand-900); -} - -/* Global base styles */ -@layer base { - * { - @apply border-border; - } - - html { - @apply scroll-smooth; - } - - body { - @apply bg-background text-foreground; - font-feature-settings: - 'rlig' 1, - 'calt' 1; - } - - /* Prose styles for markdown content */ - .prose { - @apply text-text-primary; - } - - /* Ensure headings override typography plugin defaults in light mode */ - .prose :where(h1, h2, h3, h4, h5, h6) { - @apply !text-text-primary font-bold; - } - - /* Ensure heading links inherit heading color/contrast */ - .prose h1 a, - .prose h2 a, - .prose h3 a, - .prose h4 a, - .prose h5 a, - .prose h6 a { - @apply text-text-primary hover:text-text-primary no-underline; - } - - .prose p { - @apply text-text-secondary; - } - - /* Strong emphasis readability in dark mode */ - .prose strong, - .prose b { - @apply text-text-primary! font-bold; - } - - /* ensure link color inside paragraphs and lists has adequate contrast */ - .prose p a, - .prose li a { - @apply text-accent! hover:text-accent/80! underline-offset-2; - } - - .prose code { - @apply bg-code-background! text-code-foreground! rounded px-1.5 py-0.5 font-mono text-sm; - } - - .prose pre { - @apply border-border bg-code-background! text-code-block-foreground! rounded-lg border; - } - - .prose pre code { - @apply text-code-block-foreground bg-transparent p-0; - } - - /* Shiki syntax highlighting support */ - .prose .shiki-container { - @apply border-border overflow-hidden rounded-lg border; - } - - .prose .shiki-container pre { - @apply m-0 rounded-none border-0; - } - - .prose .shiki-container pre.shiki { - @apply bg-transparent! p-4 text-inherit!; - } - - .prose .shiki-container pre.shiki code { - @apply bg-transparent! p-0 text-inherit!; - } - - /* Theme switching for Shiki */ - html:not(.dark) .prose .shiki-dark { - display: none; - } - - html.dark .prose .shiki-light { - display: none; - } - - /* Ensure proper display */ - .prose .shiki-light, - .prose .shiki-dark { - width: 100%; - } - - .prose a { - @apply text-accent hover:text-accent/80 no-underline; - } - - /* Maintain paragraph/list contrast in dark mode */ - .dark .prose p, - .dark .prose li { - @apply text-text-secondary; - } - - .prose blockquote { - @apply border-border text-text-muted border-l-4 pl-4 italic; - } - - /* Improve list readability and marker contrast (light/dark) */ - .prose ul, - .prose ol { - @apply text-text-secondary; - } - - .prose ul > li::marker, - .prose ol > li::marker { - color: var(--color-accent); - } - - .prose code::before, - .prose code::after { - content: '' !important; - } -} - -/* Orb backgrounds using the brand color */ +/* Project-specific: landing page decorative styles */ .orb-a-bg { background: radial-gradient( circle at 30% 30%, diff --git a/docs/src/app.html b/docs/src/app.html index ea1f4b7..637d0ff 100644 --- a/docs/src/app.html +++ b/docs/src/app.html @@ -5,9 +5,7 @@ - - + + diff --git a/docs/src/lib/components/contexts/Breadcrumb/Breadcrumb.context.ts b/docs/src/lib/components/contexts/Breadcrumb/Breadcrumb.context.ts deleted file mode 100644 index 15bf3e6..0000000 --- a/docs/src/lib/components/contexts/Breadcrumb/Breadcrumb.context.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { BreadcrumbContext } from '$lib/components/contexts/Breadcrumb/type' -import { getContext, setContext } from 'svelte' - -export const BreadcrumbContextSymbol = Symbol('breadcrumbs') - -export const getBreadcrumbContext = (): BreadcrumbContext | undefined => { - return getContext(BreadcrumbContextSymbol) -} - -export const setBreadcrumbContext = (context: BreadcrumbContext): void => { - setContext(BreadcrumbContextSymbol, context) -} diff --git a/docs/src/lib/components/contexts/Breadcrumb/BreadcrumbContext.svelte b/docs/src/lib/components/contexts/Breadcrumb/BreadcrumbContext.svelte deleted file mode 100644 index c60a23b..0000000 --- a/docs/src/lib/components/contexts/Breadcrumb/BreadcrumbContext.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - -{@render children?.()} - - - diff --git a/docs/src/lib/components/contexts/Breadcrumb/type.ts b/docs/src/lib/components/contexts/Breadcrumb/type.ts deleted file mode 100644 index b5af585..0000000 --- a/docs/src/lib/components/contexts/Breadcrumb/type.ts +++ /dev/null @@ -1,3 +0,0 @@ -// Breadcrumb type -export type BreadcrumbContext = { breadcrumbs: Breadcrumb[] } -export type Breadcrumb = { title: string; href?: string } diff --git a/docs/src/lib/components/contexts/Seo/Seo.context.ts b/docs/src/lib/components/contexts/Seo/Seo.context.ts deleted file mode 100644 index bc229e7..0000000 --- a/docs/src/lib/components/contexts/Seo/Seo.context.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { SeoContext } from '$lib/components/contexts/Seo/type' -import { getContext, setContext } from 'svelte' - -export const SeoContextSymbol = Symbol('seo') - -export const getSeoContext = (): SeoContext | undefined => { - return getContext(SeoContextSymbol) -} - -export const setSeoContext = (context: SeoContext): void => { - setContext(SeoContextSymbol, context) -} diff --git a/docs/src/lib/components/contexts/Seo/SeoContext.svelte b/docs/src/lib/components/contexts/Seo/SeoContext.svelte deleted file mode 100644 index 20853b8..0000000 --- a/docs/src/lib/components/contexts/Seo/SeoContext.svelte +++ /dev/null @@ -1,16 +0,0 @@ - - -{@render children?.()} diff --git a/docs/src/lib/components/contexts/Seo/type.ts b/docs/src/lib/components/contexts/Seo/type.ts deleted file mode 100644 index d948b53..0000000 --- a/docs/src/lib/components/contexts/Seo/type.ts +++ /dev/null @@ -1,5 +0,0 @@ -// SEO type -export type SeoContext = { - title: string - description: string -} diff --git a/docs/src/lib/components/general/Example.svelte b/docs/src/lib/components/general/Example.svelte index 14cf0a6..b90a80a 100644 --- a/docs/src/lib/components/general/Example.svelte +++ b/docs/src/lib/components/general/Example.svelte @@ -1,4 +1,7 @@ - - - - +