skrypt-ai 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.md +1 -1
  2. package/dist/auth/index.d.ts +0 -1
  3. package/dist/auth/index.js +3 -5
  4. package/dist/autofix/index.js +15 -3
  5. package/dist/cli.js +19 -4
  6. package/dist/commands/check-links.js +164 -174
  7. package/dist/commands/deploy.js +5 -2
  8. package/dist/commands/generate.js +206 -199
  9. package/dist/commands/i18n.js +3 -20
  10. package/dist/commands/init.js +47 -40
  11. package/dist/commands/lint.js +3 -20
  12. package/dist/commands/mcp.js +125 -122
  13. package/dist/commands/monitor.js +125 -108
  14. package/dist/commands/review-pr.js +1 -1
  15. package/dist/commands/sdk.js +1 -1
  16. package/dist/config/loader.js +21 -2
  17. package/dist/generator/organizer.d.ts +3 -0
  18. package/dist/generator/organizer.js +4 -9
  19. package/dist/generator/writer.js +2 -10
  20. package/dist/github/pr-comments.js +21 -8
  21. package/dist/plugins/index.js +1 -0
  22. package/dist/scanner/index.js +8 -2
  23. package/dist/template/docs.json +2 -1
  24. package/dist/template/next.config.mjs +3 -1
  25. package/dist/template/package.json +17 -14
  26. package/dist/template/public/favicon.svg +4 -0
  27. package/dist/template/public/search-index.json +1 -1
  28. package/dist/template/scripts/build-search-index.mjs +120 -25
  29. package/dist/template/src/app/api/chat/route.ts +11 -3
  30. package/dist/template/src/app/docs/README.md +28 -0
  31. package/dist/template/src/app/docs/[...slug]/page.tsx +141 -14
  32. package/dist/template/src/app/docs/auth/page.mdx +589 -0
  33. package/dist/template/src/app/docs/autofix/page.mdx +624 -0
  34. package/dist/template/src/app/docs/cli/page.mdx +217 -0
  35. package/dist/template/src/app/docs/config/page.mdx +428 -0
  36. package/dist/template/src/app/docs/configuration/page.mdx +86 -0
  37. package/dist/template/src/app/docs/deployment/page.mdx +112 -0
  38. package/dist/template/src/app/docs/error.tsx +20 -0
  39. package/dist/template/src/app/docs/generator/generator.md +504 -0
  40. package/dist/template/src/app/docs/generator/organizer.md +779 -0
  41. package/dist/template/src/app/docs/generator/page.mdx +613 -0
  42. package/dist/template/src/app/docs/github/page.mdx +502 -0
  43. package/dist/template/src/app/docs/llm/anthropic-client.md +549 -0
  44. package/dist/template/src/app/docs/llm/index.md +471 -0
  45. package/dist/template/src/app/docs/llm/page.mdx +428 -0
  46. package/dist/template/src/app/docs/llms-full.md +256 -0
  47. package/dist/template/src/app/docs/llms.txt +2971 -0
  48. package/dist/template/src/app/docs/not-found.tsx +23 -0
  49. package/dist/template/src/app/docs/page.mdx +0 -3
  50. package/dist/template/src/app/docs/plugins/page.mdx +1793 -0
  51. package/dist/template/src/app/docs/pro/page.mdx +121 -0
  52. package/dist/template/src/app/docs/quickstart/page.mdx +93 -0
  53. package/dist/template/src/app/docs/scanner/content-type.md +599 -0
  54. package/dist/template/src/app/docs/scanner/index.md +212 -0
  55. package/dist/template/src/app/docs/scanner/page.mdx +307 -0
  56. package/dist/template/src/app/docs/scanner/python.md +469 -0
  57. package/dist/template/src/app/docs/scanner/python_parser.md +1056 -0
  58. package/dist/template/src/app/docs/scanner/rust.md +325 -0
  59. package/dist/template/src/app/docs/scanner/typescript.md +201 -0
  60. package/dist/template/src/app/error.tsx +3 -3
  61. package/dist/template/src/app/icon.tsx +29 -0
  62. package/dist/template/src/app/layout.tsx +57 -7
  63. package/dist/template/src/app/not-found.tsx +35 -0
  64. package/dist/template/src/app/page.tsx +95 -11
  65. package/dist/template/src/components/ai-chat.tsx +26 -21
  66. package/dist/template/src/components/breadcrumbs.tsx +56 -12
  67. package/dist/template/src/components/copy-button.tsx +17 -3
  68. package/dist/template/src/components/docs-layout.tsx +202 -8
  69. package/dist/template/src/components/feedback.tsx +4 -2
  70. package/dist/template/src/components/footer.tsx +42 -0
  71. package/dist/template/src/components/header.tsx +56 -20
  72. package/dist/template/src/components/mdx/accordion.tsx +17 -13
  73. package/dist/template/src/components/mdx/callout.tsx +50 -37
  74. package/dist/template/src/components/mdx/card.tsx +24 -12
  75. package/dist/template/src/components/mdx/code-block.tsx +17 -3
  76. package/dist/template/src/components/mdx/code-group.tsx +78 -18
  77. package/dist/template/src/components/mdx/code-playground.tsx +3 -0
  78. package/dist/template/src/components/mdx/go-playground.tsx +3 -0
  79. package/dist/template/src/components/mdx/highlighted-code.tsx +178 -38
  80. package/dist/template/src/components/mdx/python-playground.tsx +2 -0
  81. package/dist/template/src/components/mdx/steps.tsx +6 -6
  82. package/dist/template/src/components/mdx/tabs.tsx +76 -8
  83. package/dist/template/src/components/page-header.tsx +19 -0
  84. package/dist/template/src/components/scroll-to-top.tsx +33 -0
  85. package/dist/template/src/components/search-dialog.tsx +251 -57
  86. package/dist/template/src/components/sidebar.tsx +137 -77
  87. package/dist/template/src/components/table-of-contents.tsx +29 -13
  88. package/dist/template/src/lib/highlight.ts +90 -31
  89. package/dist/template/src/lib/search.ts +14 -4
  90. package/dist/template/src/lib/theme-utils.ts +140 -0
  91. package/dist/template/src/styles/globals.css +397 -84
  92. package/dist/template/src/types/remark-gfm.d.ts +2 -0
  93. package/dist/utils/files.d.ts +9 -0
  94. package/dist/utils/files.js +33 -0
  95. package/dist/utils/validation.d.ts +4 -0
  96. package/dist/utils/validation.js +38 -0
  97. package/package.json +1 -4
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Theme color derivation utilities.
3
+ * Pure functions — no external dependencies.
4
+ */
5
+
6
+ /**
7
+ * Convert a hex color string to HSL components.
8
+ * Accepts 3-digit (#abc) or 6-digit (#aabbcc) hex, with or without #.
9
+ */
10
+ export function hexToHsl(hex: string): { h: number; s: number; l: number } {
11
+ // Strip # prefix if present
12
+ hex = hex.replace(/^#/, '')
13
+
14
+ // Expand 3-digit shorthand to 6-digit
15
+ if (hex.length === 3) {
16
+ hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]
17
+ }
18
+
19
+ const r = parseInt(hex.substring(0, 2), 16) / 255
20
+ const g = parseInt(hex.substring(2, 4), 16) / 255
21
+ const b = parseInt(hex.substring(4, 6), 16) / 255
22
+
23
+ const max = Math.max(r, g, b)
24
+ const min = Math.min(r, g, b)
25
+ const l = (max + min) / 2
26
+
27
+ if (max === min) {
28
+ // Achromatic
29
+ return { h: 0, s: 0, l }
30
+ }
31
+
32
+ const d = max - min
33
+ const s = l > 0.5 ? d / (2 - max - min) : d / (max + min)
34
+
35
+ let h: number
36
+ switch (max) {
37
+ case r:
38
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6
39
+ break
40
+ case g:
41
+ h = ((b - r) / d + 2) / 6
42
+ break
43
+ default:
44
+ h = ((r - g) / d + 4) / 6
45
+ break
46
+ }
47
+
48
+ return { h: h * 360, s, l }
49
+ }
50
+
51
+ /**
52
+ * Convert HSL components back to a hex color string.
53
+ * h: 0-360, s: 0-1, l: 0-1
54
+ */
55
+ export function hslToHex(h: number, s: number, l: number): string {
56
+ // Clamp values
57
+ h = ((h % 360) + 360) % 360
58
+ s = Math.max(0, Math.min(1, s))
59
+ l = Math.max(0, Math.min(1, l))
60
+
61
+ const c = (1 - Math.abs(2 * l - 1)) * s
62
+ const x = c * (1 - Math.abs(((h / 60) % 2) - 1))
63
+ const m = l - c / 2
64
+
65
+ let r: number, g: number, b: number
66
+
67
+ if (h < 60) {
68
+ ;[r, g, b] = [c, x, 0]
69
+ } else if (h < 120) {
70
+ ;[r, g, b] = [x, c, 0]
71
+ } else if (h < 180) {
72
+ ;[r, g, b] = [0, c, x]
73
+ } else if (h < 240) {
74
+ ;[r, g, b] = [0, x, c]
75
+ } else if (h < 300) {
76
+ ;[r, g, b] = [x, 0, c]
77
+ } else {
78
+ ;[r, g, b] = [c, 0, x]
79
+ }
80
+
81
+ const toHex = (v: number) =>
82
+ Math.round((v + m) * 255)
83
+ .toString(16)
84
+ .padStart(2, '0')
85
+
86
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`
87
+ }
88
+
89
+ /**
90
+ * Derive primary, dark, and light variants from a single hex color.
91
+ * Dark variant: lightness reduced by ~15%
92
+ * Light variant: lightness increased by ~15%
93
+ */
94
+ /**
95
+ * Compute WCAG relative luminance from a hex color.
96
+ * Returns 0 (black) to 1 (white).
97
+ */
98
+ export function relativeLuminance(hex: string): number {
99
+ hex = hex.replace(/^#/, '')
100
+ if (hex.length === 3) {
101
+ hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]
102
+ }
103
+ const r = parseInt(hex.substring(0, 2), 16) / 255
104
+ const g = parseInt(hex.substring(2, 4), 16) / 255
105
+ const b = parseInt(hex.substring(4, 6), 16) / 255
106
+
107
+ const toLinear = (c: number) => (c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4))
108
+ return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b)
109
+ }
110
+
111
+ /**
112
+ * Return the best contrasting foreground color (white or dark) for a given background.
113
+ * Uses WCAG contrast ratio.
114
+ */
115
+ export function contrastForeground(bgHex: string): string {
116
+ const lum = relativeLuminance(bgHex)
117
+ // WCAG contrast ratio: (L1 + 0.05) / (L2 + 0.05)
118
+ // White on bg: (1 + 0.05) / (lum + 0.05)
119
+ // Dark on bg: (lum + 0.05) / (0 + 0.05)
120
+ const contrastWithWhite = (1.05) / (lum + 0.05)
121
+ const contrastWithBlack = (lum + 0.05) / 0.05
122
+ return contrastWithWhite >= contrastWithBlack ? '#ffffff' : '#0f1117'
123
+ }
124
+
125
+ export function derivePrimaryColors(hex: string): {
126
+ primary: string
127
+ primaryDark: string
128
+ primaryLight: string
129
+ primaryForeground: string
130
+ } {
131
+ const { h, s, l } = hexToHsl(hex)
132
+ const normalizedHex = hex.startsWith('#') ? hex : `#${hex}`
133
+
134
+ return {
135
+ primary: normalizedHex,
136
+ primaryDark: hslToHex(h, s, Math.max(0, l - 0.15)),
137
+ primaryLight: hslToHex(h, s, Math.min(1, l + 0.15)),
138
+ primaryForeground: contrastForeground(normalizedHex),
139
+ }
140
+ }
@@ -1,152 +1,465 @@
1
1
  @import "tailwindcss";
2
2
 
3
+ @custom-variant dark (&:where(.dark, .dark *));
4
+
5
+ /* Skip-to-content link — visible on focus only */
6
+ .skip-to-content {
7
+ position: absolute;
8
+ left: -9999px;
9
+ top: auto;
10
+ width: 1px;
11
+ height: 1px;
12
+ overflow: hidden;
13
+ z-index: 9999;
14
+ }
15
+ .skip-to-content:focus {
16
+ position: fixed;
17
+ top: 0.5rem;
18
+ left: 0.5rem;
19
+ width: auto;
20
+ height: auto;
21
+ overflow: visible;
22
+ padding: 0.5rem 1rem;
23
+ background: var(--color-primary);
24
+ color: var(--color-primary-foreground);
25
+ border-radius: 0.5rem;
26
+ font-size: 0.875rem;
27
+ font-weight: 600;
28
+ text-decoration: none;
29
+ }
30
+
3
31
  @theme {
4
- /* Colors */
32
+ /* Primary — configurable per project via docs.json */
5
33
  --color-primary: #3b82f6;
6
34
  --color-primary-dark: #2563eb;
7
- --color-accent: #8b5cf6;
35
+ --color-primary-light: #60a5fa;
36
+ --color-primary-foreground: #ffffff;
8
37
 
9
- /* Background */
10
- --color-bg: #ffffff;
11
- --color-bg-secondary: #f8fafc;
12
- --color-bg-tertiary: #f1f5f9;
13
-
14
- /* Text */
15
- --color-text: #0f172a;
16
- --color-text-secondary: #475569;
17
- --color-text-tertiary: #94a3b8;
38
+ /* Gray scale (Mintlify-style, subtle warm undertone) */
39
+ --color-gray-50: #f9fafb;
40
+ --color-gray-100: #f3f4f6;
41
+ --color-gray-200: #e5e7eb;
42
+ --color-gray-300: #d1d5db;
43
+ --color-gray-400: #9ca3af;
44
+ --color-gray-500: #6b7280;
45
+ --color-gray-600: #4b5563;
46
+ --color-gray-700: #374151;
47
+ --color-gray-800: #1f2937;
48
+ --color-gray-900: #111827;
49
+ --color-gray-950: #030712;
18
50
 
19
- /* Border */
20
- --color-border: #e2e8f0;
21
- --color-border-strong: #cbd5e1;
51
+ /* Semantic tokens — light mode defaults */
52
+ --color-bg: #ffffff;
53
+ --color-bg-secondary: #f9fafb;
54
+ --color-bg-tertiary: #f3f4f6;
55
+ --color-text: #111827;
56
+ --color-text-secondary: #374151;
57
+ --color-text-tertiary: #9ca3af;
58
+ --color-border: rgba(3, 7, 18, 0.1);
59
+ --color-border-strong: rgba(3, 7, 18, 0.15);
22
60
 
23
61
  /* Code */
24
- --color-code-bg: #1e293b;
25
- --color-code-text: #e2e8f0;
62
+ --color-code-bg: #ffffff;
63
+ --color-code-border: rgba(3, 7, 18, 0.1);
64
+ --color-code-text: #1f2937;
26
65
 
27
- /* Sidebar */
28
- --sidebar-width: 280px;
29
- --toc-width: 240px;
66
+ /* Layout */
67
+ --sidebar-width: 264px;
68
+ --toc-width: 224px;
69
+ --header-height: 56px;
70
+ --content-max-width: 768px;
71
+ --radius: 1rem;
30
72
  }
31
73
 
32
- /* Dark mode - supports both system preference and manual toggle */
74
+ /* ========================
75
+ Dark Mode
76
+ ======================== */
77
+
33
78
  @media (prefers-color-scheme: dark) {
34
79
  :root:not(.light) {
35
- --color-bg: #0f172a;
36
- --color-bg-secondary: #1e293b;
37
- --color-bg-tertiary: #334155;
38
- --color-text: #f8fafc;
39
- --color-text-secondary: #cbd5e1;
40
- --color-text-tertiary: #64748b;
41
- --color-border: #334155;
42
- --color-border-strong: #475569;
43
- --color-code-bg: #0f172a;
44
- --color-code-text: #e2e8f0;
80
+ --color-bg: #0f1117;
81
+ --color-bg-secondary: #1a1d27;
82
+ --color-bg-tertiary: #252833;
83
+ --color-text: #f3f4f6;
84
+ --color-text-secondary: #d1d5db;
85
+ --color-text-tertiary: #6b7280;
86
+ --color-border: rgba(255, 255, 255, 0.07);
87
+ --color-border-strong: rgba(255, 255, 255, 0.12);
88
+ --color-code-bg: #0b0c0e;
89
+ --color-code-border: rgba(255, 255, 255, 0.1);
90
+ --color-code-text: #f3f4f6;
45
91
  }
46
92
  }
47
93
 
48
- /* Manual dark mode override */
49
94
  :root.dark {
50
- --color-bg: #0f172a;
51
- --color-bg-secondary: #1e293b;
52
- --color-bg-tertiary: #334155;
53
- --color-text: #f8fafc;
54
- --color-text-secondary: #cbd5e1;
55
- --color-text-tertiary: #64748b;
56
- --color-border: #334155;
57
- --color-border-strong: #475569;
58
- --color-code-bg: #0f172a;
59
- --color-code-text: #e2e8f0;
60
- }
61
-
62
- /* Base styles */
95
+ --color-bg: #0f1117;
96
+ --color-bg-secondary: #1a1d27;
97
+ --color-bg-tertiary: #252833;
98
+ --color-text: #f3f4f6;
99
+ --color-text-secondary: #d1d5db;
100
+ --color-text-tertiary: #6b7280;
101
+ --color-border: rgba(255, 255, 255, 0.07);
102
+ --color-border-strong: rgba(255, 255, 255, 0.12);
103
+ --color-code-bg: #0b0c0e;
104
+ --color-code-border: rgba(255, 255, 255, 0.1);
105
+ --color-code-text: #f3f4f6;
106
+ }
107
+
108
+ /* Error page icon — dark mode overrides (avoids Tailwind dark: variant mismatch) */
109
+ :root.dark .error-icon-bg { background-color: rgba(127, 29, 29, 0.3); }
110
+ :root.dark .error-icon-text { color: #f87171; }
111
+ @media (prefers-color-scheme: dark) {
112
+ :root:not(.light) .error-icon-bg { background-color: rgba(127, 29, 29, 0.3); }
113
+ :root:not(.light) .error-icon-text { color: #f87171; }
114
+ }
115
+
116
+ /* Feedback thumbs — dark mode overrides */
117
+ :root.dark .feedback-positive { background-color: rgba(6, 95, 70, 0.3); color: #34d399; }
118
+ :root.dark .feedback-negative { background-color: rgba(127, 29, 29, 0.3); color: #f87171; }
119
+ @media (prefers-color-scheme: dark) {
120
+ :root:not(.light) .feedback-positive { background-color: rgba(6, 95, 70, 0.3); color: #34d399; }
121
+ :root:not(.light) .feedback-negative { background-color: rgba(127, 29, 29, 0.3); color: #f87171; }
122
+ }
123
+
124
+ /* ========================
125
+ Base — in @layer base so Tailwind utilities can override
126
+ ======================== */
127
+
128
+ @layer base {
129
+
63
130
  html {
64
131
  scroll-behavior: smooth;
132
+ -webkit-font-smoothing: antialiased;
133
+ -moz-osx-font-smoothing: grayscale;
134
+ overscroll-behavior-y: none;
135
+ line-height: 1.5;
65
136
  }
66
137
 
67
138
  body {
68
139
  background-color: var(--color-bg);
69
140
  color: var(--color-text);
141
+ font-family: var(--font-body, "Inter", ui-sans-serif, system-ui, sans-serif);
142
+ font-feature-settings: "cv02", "cv03", "cv04", "cv11";
143
+ font-size: 15px;
144
+ }
145
+
146
+ /* Global transitions — 150ms on interactive elements */
147
+ a, button, input, select, textarea {
148
+ transition: color 150ms, background-color 150ms, border-color 150ms, opacity 150ms;
149
+ }
150
+
151
+ ::selection {
152
+ background-color: var(--color-primary);
153
+ color: white;
154
+ }
155
+
156
+ /* Links — inherit color by default, primary in prose */
157
+ a {
158
+ text-decoration: none;
159
+ color: inherit;
160
+ }
161
+
162
+ /* ========================
163
+ Typography
164
+ ======================== */
165
+
166
+ h1, h2, h3, h4, h5, h6 {
167
+ color: var(--color-text);
168
+ line-height: 1.2;
169
+ letter-spacing: -0.025em;
170
+ }
171
+
172
+ h1 { font-size: 2.25em; font-weight: 800; }
173
+ h2 { font-size: 1.5em; font-weight: 700; margin-top: 2em; margin-bottom: 0.6667em; }
174
+ h3 { font-size: 1.25em; font-weight: 600; margin-top: 2.4em; margin-bottom: 0.6em; }
175
+ h4 { font-size: 1.125em; font-weight: 600; margin-top: 2em; margin-bottom: 0.5em; }
176
+
177
+ @media (max-width: 640px) {
178
+ h1 { font-size: 1.75em; }
179
+ h2 { font-size: 1.25em; }
180
+ h3 { font-size: 1.125em; }
70
181
  }
71
182
 
72
- /* Code blocks */
183
+ /* ========================
184
+ Code
185
+ ======================== */
186
+
73
187
  pre {
74
188
  background-color: var(--color-code-bg) !important;
75
- border-radius: 0.5rem;
76
- padding: 1rem;
189
+ border: 1px solid var(--color-code-border);
190
+ border-radius: 0.75rem;
191
+ padding: 0.875rem 1rem;
77
192
  overflow-x: auto;
193
+ font-size: 0.875em;
194
+ line-height: 1.7142857;
195
+ }
196
+
197
+ /* Prevent FOUC: code blocks get the right bg before Shiki loads */
198
+ .shiki, .shiki pre {
199
+ background-color: var(--color-code-bg) !important;
78
200
  }
79
201
 
80
202
  code {
81
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
82
- font-size: 0.875rem;
203
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
204
+ font-size: 0.875em;
205
+ font-variant-ligatures: none;
83
206
  }
84
207
 
85
- /* Inline code */
208
+ /* Inline code — Mintlify style */
86
209
  :not(pre) > code {
87
- background-color: var(--color-bg-tertiary);
88
- padding: 0.125rem 0.375rem;
89
- border-radius: 0.25rem;
210
+ background-color: var(--color-gray-100);
211
+ padding: 0.125rem 0.5rem;
212
+ border-radius: 0.375rem;
90
213
  font-size: 0.875em;
214
+ line-height: 1.5;
215
+ color: var(--color-gray-600);
216
+ overflow-wrap: break-word;
217
+ word-break: break-word;
91
218
  }
92
219
 
93
- /* Links */
94
- a {
95
- color: var(--color-primary);
96
- text-decoration: none;
220
+ :root.dark :not(pre) > code {
221
+ background-color: rgba(255, 255, 255, 0.05);
222
+ color: var(--color-gray-200);
97
223
  }
98
224
 
99
- a:hover {
100
- text-decoration: underline;
225
+ @media (prefers-color-scheme: dark) {
226
+ :root:not(.light) :not(pre) > code {
227
+ background-color: rgba(255, 255, 255, 0.05);
228
+ color: var(--color-gray-200);
229
+ }
101
230
  }
102
231
 
103
- /* Headings */
104
- h1, h2, h3, h4, h5, h6 {
232
+ /* ========================
233
+ Prose Content
234
+ ======================== */
235
+
236
+ .prose {
237
+ max-width: var(--content-max-width);
238
+ line-height: 1.75;
239
+ color: var(--color-text-secondary);
240
+ }
241
+
242
+ .prose a {
105
243
  color: var(--color-text);
106
244
  font-weight: 600;
107
- line-height: 1.25;
245
+ text-decoration: none;
246
+ border-bottom: 1px solid var(--color-primary);
247
+ transition: border-color 150ms, border-bottom-width 150ms;
108
248
  }
109
249
 
110
- h1 { font-size: 2.25rem; }
111
- h2 { font-size: 1.75rem; margin-top: 2rem; }
112
- h3 { font-size: 1.375rem; margin-top: 1.5rem; }
113
- h4 { font-size: 1.125rem; margin-top: 1.25rem; }
114
-
115
- /* Prose content */
116
- .prose {
117
- max-width: 65ch;
118
- line-height: 1.75;
250
+ .prose a:hover {
251
+ border-bottom-width: 2px;
119
252
  }
120
253
 
121
254
  .prose p {
122
- margin-top: 1.25rem;
123
- margin-bottom: 1.25rem;
255
+ margin-top: 1.25em;
256
+ margin-bottom: 1.25em;
124
257
  }
125
258
 
259
+ /* Page header description is handled by PageHeader component */
260
+
261
+ .prose strong {
262
+ font-weight: 600;
263
+ color: var(--color-text);
264
+ }
265
+
266
+ /* Lists */
126
267
  .prose ul, .prose ol {
127
- margin-top: 1rem;
128
- margin-bottom: 1rem;
268
+ margin-top: 1em;
269
+ margin-bottom: 1em;
129
270
  padding-left: 1.5rem;
130
271
  }
131
272
 
273
+ .prose ul { list-style-type: disc; }
274
+ .prose ol { list-style-type: decimal; }
275
+
132
276
  .prose li {
133
- margin-top: 0.5rem;
134
- margin-bottom: 0.5rem;
277
+ margin-top: 0.5em;
278
+ margin-bottom: 0.5em;
279
+ }
280
+
281
+ .prose li::marker {
282
+ color: var(--color-text-tertiary);
283
+ }
284
+
285
+ /* Headings in prose */
286
+ .prose h1, .prose h2, .prose h3, .prose h4 {
287
+ color: var(--color-text);
135
288
  }
136
289
 
290
+ .prose h2 a, .prose h3 a, .prose h4 a {
291
+ color: inherit;
292
+ border-bottom: none;
293
+ font-weight: inherit;
294
+ }
295
+
296
+ .prose h2 a:hover, .prose h3 a:hover, .prose h4 a:hover {
297
+ border-bottom: none;
298
+ }
299
+
300
+ /* Tables — Mintlify style: clean, minimal */
137
301
  .prose table {
138
302
  width: 100%;
139
303
  border-collapse: collapse;
140
- margin: 1.5rem 0;
304
+ margin: 1.5em 0;
305
+ font-size: 0.875rem;
306
+ line-height: 1.5;
307
+ display: table;
308
+ table-layout: auto;
141
309
  }
142
310
 
143
- .prose th, .prose td {
144
- border: 1px solid var(--color-border);
145
- padding: 0.75rem;
146
- text-align: left;
147
- }
311
+ .prose thead { display: table-header-group; }
312
+ .prose tbody { display: table-row-group; }
313
+ .prose tr { display: table-row; }
148
314
 
149
315
  .prose th {
150
- background-color: var(--color-bg-secondary);
316
+ display: table-cell;
151
317
  font-weight: 600;
318
+ color: var(--color-text);
319
+ vertical-align: bottom;
320
+ padding: 0.625rem 1rem 0.625rem 0;
321
+ text-align: left;
322
+ white-space: nowrap;
323
+ border-bottom: 1px solid var(--color-border-strong);
324
+ }
325
+
326
+ .prose th:last-child { padding-right: 0; }
327
+
328
+ .prose td {
329
+ display: table-cell;
330
+ vertical-align: top;
331
+ color: var(--color-text-secondary);
332
+ padding: 0.75rem 1rem 0.75rem 0;
333
+ }
334
+
335
+ .prose td:last-child { padding-right: 0; }
336
+
337
+ /* Inline code inside table cells should never wrap */
338
+ .prose td code, .prose th code {
339
+ white-space: nowrap;
340
+ word-break: normal;
341
+ overflow-wrap: normal;
342
+ }
343
+
344
+ .prose tbody tr {
345
+ border-bottom: 1px solid var(--color-border);
346
+ }
347
+
348
+ /* Blockquotes */
349
+ .prose blockquote {
350
+ border-left: 3px solid var(--color-border-strong);
351
+ padding: 0.5em 0 0.5em 1.25em;
352
+ margin: 1.5em 0;
353
+ color: var(--color-text-secondary);
354
+ }
355
+
356
+ .prose blockquote p { margin: 0; }
357
+
358
+ /* Horizontal rules */
359
+ .prose hr {
360
+ border: none;
361
+ border-top: 1px solid var(--color-border);
362
+ margin: 3em 0;
363
+ }
364
+
365
+ /* Images */
366
+ .prose img {
367
+ max-width: 100%;
368
+ border-radius: 0.75rem;
369
+ margin: 2em 0;
370
+ }
371
+
372
+ /* ========================
373
+ Scrollbar (Mintlify style — thin, subtle)
374
+ ======================== */
375
+
376
+ * {
377
+ scrollbar-width: thin;
378
+ scrollbar-color: rgba(0, 0, 0, 0.15) transparent;
379
+ }
380
+
381
+ :root.dark * {
382
+ scrollbar-color: rgba(255, 255, 255, 0.2) transparent;
383
+ }
384
+
385
+ @media (prefers-color-scheme: dark) {
386
+ :root:not(.light) * {
387
+ scrollbar-color: rgba(255, 255, 255, 0.2) transparent;
388
+ }
389
+ :root:not(.light) ::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.2); }
390
+ :root:not(.light) ::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.3); }
391
+ }
392
+
393
+ :root.dark ::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.2); }
394
+ :root.dark ::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.3); }
395
+
396
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
397
+ ::-webkit-scrollbar-track { background: transparent; }
398
+ ::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.15); border-radius: 3px; }
399
+ ::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.2); }
400
+
401
+ /* ========================
402
+ Focus indicators
403
+ ======================== */
404
+
405
+ *:focus-visible {
406
+ outline: 2px solid var(--color-primary);
407
+ outline-offset: 2px;
408
+ }
409
+
410
+ input:focus-visible, textarea:focus-visible {
411
+ outline-offset: 0;
412
+ }
413
+
414
+ } /* end @layer base */
415
+
416
+ /* Sidebar scroll shadows — fade content at top/bottom edges */
417
+ .sidebar-scroll-shadow {
418
+ mask-image: linear-gradient(to bottom, transparent, black 1rem, black calc(100% - 1rem), transparent);
419
+ -webkit-mask-image: linear-gradient(to bottom, transparent, black 1rem, black calc(100% - 1rem), transparent);
420
+ }
421
+
422
+ /* Search dialog entrance animation */
423
+ @keyframes dialog-in {
424
+ from { opacity: 0; transform: translate(-50%, -8px) scale(0.98); }
425
+ to { opacity: 1; transform: translate(-50%, 0) scale(1); }
426
+ }
427
+ .dialog-animate-in {
428
+ animation: dialog-in 150ms ease-out;
429
+ }
430
+
431
+ /* ========================
432
+ Terminal-style code blocks
433
+ ======================== */
434
+ .terminal-block pre {
435
+ background-color: #0a0a0a !important;
436
+ border-color: rgba(255, 255, 255, 0.08);
437
+ }
438
+
439
+ /* ========================
440
+ Copy toast animation
441
+ ======================== */
442
+ @keyframes copy-toast-in {
443
+ 0% { opacity: 0; transform: translateX(-50%) translateY(-4px); }
444
+ 15% { opacity: 1; transform: translateX(-50%) translateY(0); }
445
+ 85% { opacity: 1; transform: translateX(-50%) translateY(0); }
446
+ 100% { opacity: 0; transform: translateX(-50%) translateY(-4px); }
447
+ }
448
+ .copy-toast {
449
+ animation: copy-toast-in 1.5s ease-in-out forwards;
450
+ pointer-events: none;
451
+ }
452
+
453
+ /* ========================
454
+ Search skeleton shimmer
455
+ ======================== */
456
+ @keyframes shimmer {
457
+ 0% { background-position: -200% 0; }
458
+ 100% { background-position: 200% 0; }
459
+ }
460
+ .skeleton {
461
+ background: linear-gradient(90deg, var(--color-bg-secondary) 25%, var(--color-bg-tertiary) 50%, var(--color-bg-secondary) 75%);
462
+ background-size: 200% 100%;
463
+ animation: shimmer 1.5s infinite;
464
+ border-radius: 0.25rem;
152
465
  }
@@ -0,0 +1,2 @@
1
+ declare module 'remark-gfm'
2
+ declare module 'remark-frontmatter'
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Recursively find all .md and .mdx files in a directory.
3
+ * Skips hidden directories and node_modules.
4
+ */
5
+ export declare function findMdxFiles(dir: string): string[];
6
+ /**
7
+ * Convert string to URL-safe slug
8
+ */
9
+ export declare function slugify(str: string): string;