@sntlr/registry-shell 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +2 -5
  2. package/dist/adapter/custom.d.ts +1 -1
  3. package/dist/adapter/default.d.ts +3 -3
  4. package/dist/adapter/default.js +3 -3
  5. package/dist/cli/init.js +0 -3
  6. package/dist/cli/init.js.map +1 -1
  7. package/dist/cli/shared.js +0 -5
  8. package/dist/cli/shared.js.map +1 -1
  9. package/dist/config-loader.d.ts +0 -2
  10. package/dist/config-loader.js +0 -1
  11. package/dist/define-config.d.ts +2 -8
  12. package/package.json +1 -1
  13. package/src/adapter/custom.ts +1 -1
  14. package/src/adapter/default.ts +3 -3
  15. package/src/cli/init.ts +0 -3
  16. package/src/cli/shared.ts +0 -4
  17. package/src/config-loader.ts +0 -3
  18. package/src/define-config.ts +2 -9
  19. package/src/next-app/app/globals.css +329 -329
  20. package/src/next-app/app/page.tsx +1 -1
  21. package/src/next-app/components/component-icon.tsx +140 -140
  22. package/src/next-app/components/heading-anchor.tsx +52 -52
  23. package/src/next-app/{fallback → components}/homepage.tsx +2 -3
  24. package/src/next-app/components/navigation-progress.tsx +62 -62
  25. package/src/next-app/components/resizable-preview.tsx +101 -101
  26. package/src/next-app/components/sidebar-provider.tsx +75 -75
  27. package/src/next-app/hooks/use-controls.ts +72 -72
  28. package/src/next-app/lib/i18n.tsx +630 -630
  29. package/src/next-app/lib/registry-adapter.ts +9 -35
  30. package/src/next-app/lib/utils.ts +6 -6
  31. package/src/next-app/next-env.d.ts +6 -6
  32. package/src/next-app/next.config.ts +0 -5
  33. package/src/next-app/postcss.config.mjs +7 -7
  34. package/src/next-app/user-aliases.d.ts +0 -7
  35. package/src/next-app/app/_user-global.css +0 -6
  36. package/src/next-app/app/_user-sources.css +0 -9
@@ -1,329 +1,329 @@
1
- @import "tailwindcss";
2
- @import "tw-animate-css";
3
- @plugin "@tailwindcss/typography";
4
-
5
- /* Tailwind content scan for the user's registry files. Generated by the CLI
6
- * from the `paths` declared in sntlr.ui-shell.config.ts — regenerated every
7
- * `ui-shell dev` / `build` boot. Do not edit _user-sources.css by hand. */
8
- @import "./_user-sources.css";
9
-
10
- @custom-variant dark (&:is(.dark *));
11
-
12
- @theme inline {
13
- --color-background: var(--background);
14
- --color-foreground: var(--foreground);
15
- --default-font-family: var(--font-sans);
16
- --default-mono-font-family: var(--font-mono);
17
- --color-sidebar-ring: var(--sidebar-ring);
18
- --color-sidebar-border: var(--sidebar-border);
19
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
20
- --color-sidebar-accent: var(--sidebar-accent);
21
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
22
- --color-sidebar-primary: var(--sidebar-primary);
23
- --color-sidebar-foreground: var(--sidebar-foreground);
24
- --color-sidebar: var(--sidebar);
25
- --color-chart-5: var(--chart-5);
26
- --color-chart-4: var(--chart-4);
27
- --color-chart-3: var(--chart-3);
28
- --color-chart-2: var(--chart-2);
29
- --color-chart-1: var(--chart-1);
30
- --color-ring: var(--ring);
31
- --color-input: var(--input);
32
- --color-border: var(--border);
33
- --color-destructive: var(--destructive);
34
- --color-accent-foreground: var(--accent-foreground);
35
- --color-accent: var(--accent);
36
- --color-muted-foreground: var(--muted-foreground);
37
- --color-muted: var(--muted);
38
- --color-secondary-foreground: var(--secondary-foreground);
39
- --color-secondary: var(--secondary);
40
- --color-primary-foreground: var(--primary-foreground);
41
- --color-primary: var(--primary);
42
- --color-popover-foreground: var(--popover-foreground);
43
- --color-popover: var(--popover);
44
- --color-card-foreground: var(--card-foreground);
45
- --color-card: var(--card);
46
- --radius-sm: calc(var(--radius) - 4px);
47
- --radius-md: calc(var(--radius) - 2px);
48
- --radius-lg: var(--radius);
49
- --radius-xl: calc(var(--radius) + 4px);
50
- }
51
-
52
- :root {
53
- --radius: 0.625rem;
54
- --background: oklch(1 0 0);
55
- --foreground: oklch(0.145 0 0);
56
- --card: oklch(1 0 0);
57
- --card-foreground: oklch(0.145 0 0);
58
- --popover: oklch(1 0 0);
59
- --popover-foreground: oklch(0.145 0 0);
60
- --primary: oklch(0.426 0.094 161.619);
61
- --primary-foreground: oklch(0.985 0 0);
62
- --secondary: oklch(0.97 0 0);
63
- --secondary-foreground: oklch(0.205 0 0);
64
- --muted: oklch(0.97 0 0);
65
- --muted-foreground: oklch(0.525 0 0);
66
- --accent: oklch(0.97 0 0);
67
- --accent-foreground: oklch(0.205 0 0);
68
- --destructive: oklch(0.577 0.245 27.325);
69
- --border: oklch(0.922 0 0);
70
- --input: oklch(0.922 0 0);
71
- --ring: oklch(0.708 0 0);
72
- --chart-1: oklch(0.646 0.222 41.116);
73
- --chart-2: oklch(0.6 0.118 184.714);
74
- --chart-3: oklch(0.398 0.07 227.392);
75
- --chart-4: oklch(0.828 0.189 84.429);
76
- --chart-5: oklch(0.769 0.188 70.08);
77
- --sidebar: oklch(0.985 0 0);
78
- --sidebar-foreground: oklch(0.145 0 0);
79
- --sidebar-primary: oklch(0.426 0.094 161.619);
80
- --sidebar-primary-foreground: oklch(0.985 0 0);
81
- --sidebar-accent: oklch(0.97 0 0);
82
- --sidebar-accent-foreground: oklch(0.205 0 0);
83
- --sidebar-border: oklch(0.922 0 0);
84
- --sidebar-ring: oklch(0.708 0 0);
85
- }
86
-
87
- .dark {
88
- --background: oklch(0.145 0 0);
89
- --foreground: oklch(0.985 0 0);
90
- --card: oklch(0.145 0 0);
91
- --card-foreground: oklch(0.985 0 0);
92
- --popover: oklch(0.145 0 0);
93
- --popover-foreground: oklch(0.985 0 0);
94
- --primary: oklch(0.796 0.125 168.082);
95
- --primary-foreground: oklch(0.145 0 0);
96
- --secondary: oklch(0.269 0 0);
97
- --secondary-foreground: oklch(0.985 0 0);
98
- --muted: oklch(0.269 0 0);
99
- --muted-foreground: oklch(0.708 0 0);
100
- --accent: oklch(0.269 0 0);
101
- --accent-foreground: oklch(0.985 0 0);
102
- --destructive: oklch(0.577 0.245 27.325);
103
- --border: oklch(0.269 0 0);
104
- --input: oklch(0.269 0 0);
105
- --ring: oklch(0.439 0 0);
106
- --chart-1: oklch(0.488 0.243 264.376);
107
- --chart-2: oklch(0.696 0.17 162.48);
108
- --chart-3: oklch(0.769 0.188 70.08);
109
- --chart-4: oklch(0.627 0.265 303.9);
110
- --chart-5: oklch(0.645 0.246 16.439);
111
- --sidebar: oklch(0.205 0 0);
112
- --sidebar-foreground: oklch(0.985 0 0);
113
- --sidebar-primary: oklch(0.796 0.125 168.082);
114
- --sidebar-primary-foreground: oklch(0.145 0 0);
115
- --sidebar-accent: oklch(0.269 0 0);
116
- --sidebar-accent-foreground: oklch(0.985 0 0);
117
- --sidebar-border: oklch(0.269 0 0);
118
- --sidebar-ring: oklch(0.439 0 0);
119
- }
120
-
121
- @layer base {
122
- * {
123
- @apply border-border;
124
- }
125
- html, body {
126
- scrollbar-gutter: stable;
127
- }
128
- body {
129
- @apply bg-background text-foreground font-sans;
130
- }
131
- /* Prevent Radix scroll-lock from causing layout shift */
132
- body[data-scroll-locked] {
133
- margin-right: 0 !important;
134
- scrollbar-gutter: stable;
135
- }
136
- }
137
-
138
- /* Minimal scrollbars */
139
- * {
140
- scrollbar-width: thin;
141
- scrollbar-color: var(--border) transparent;
142
- }
143
-
144
- *::-webkit-scrollbar {
145
- width: 6px;
146
- height: 6px;
147
- }
148
-
149
- *::-webkit-scrollbar-track {
150
- background: transparent;
151
- }
152
-
153
- *::-webkit-scrollbar-thumb {
154
- background: var(--border);
155
- border-radius: 3px;
156
- }
157
-
158
- *::-webkit-scrollbar-thumb:hover {
159
- background: var(--muted-foreground);
160
- }
161
-
162
- .prose pre {
163
- @apply bg-muted text-foreground rounded-lg;
164
- }
165
-
166
- .prose code::before,
167
- .prose code::after {
168
- content: none;
169
- }
170
-
171
- .prose :not(pre) > code {
172
- @apply bg-muted px-1.5 py-0.5 rounded text-xs font-medium;
173
- }
174
-
175
- .prose a {
176
- @apply underline underline-offset-2 decoration-border hover:decoration-foreground transition-colors;
177
- }
178
-
179
- .prose table {
180
- @apply w-full text-sm;
181
- }
182
-
183
- .prose th {
184
- @apply text-left font-medium px-3 py-2 border-b border-border;
185
- }
186
-
187
- .prose td {
188
- @apply px-3 py-2 border-b border-border;
189
- }
190
-
191
- @media (prefers-reduced-motion: reduce) {
192
- *, *::before, *::after {
193
- animation-duration: 0.01ms !important;
194
- animation-iteration-count: 1 !important;
195
- transition-duration: 0.01ms !important;
196
- }
197
- }
198
-
199
- /* Chart line draw-in animation */
200
- @keyframes chart-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
201
- /* Pair with `pathLength="1"` on the path so the animation is length-agnostic. */
202
- .chart-line { stroke-dasharray: 1; animation: chart-draw 1.5s ease-out forwards; }
203
-
204
- /* Bento chart entry animations — line draws, area fades in, dots pop sequentially */
205
- @keyframes chart-area-fade { from { opacity: 0; } to { opacity: 1; } }
206
- @keyframes chart-dot-pop {
207
- 0% { opacity: 0; transform: scale(0); }
208
- 60% { opacity: 1; transform: scale(1.4); }
209
- 100% { opacity: 1; transform: scale(1); }
210
- }
211
- .chart-area-fade { animation: chart-area-fade 1.4s ease-out 0.4s both; }
212
- .chart-dot-pop { transform-box: fill-box; transform-origin: center; animation: chart-dot-pop 0.5s ease-out both; }
213
-
214
- /* Typing cursor blink */
215
- @keyframes cursor-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
216
- .typing-cursor { animation: cursor-blink 0.8s step-end infinite; }
217
-
218
- /* Marquee */
219
- @keyframes marquee-left { from { transform: translateX(0); } to { transform: translateX(-50%); } }
220
- @keyframes marquee-right { from { transform: translateX(-50%); } to { transform: translateX(0); } }
221
- .marquee-track { animation: marquee-left 30s linear infinite; }
222
- .marquee-track-reverse { animation: marquee-right 30s linear infinite; }
223
- .marquee-container:hover .marquee-track,
224
- .marquee-container:hover .marquee-track-reverse { animation-play-state: paused; }
225
-
226
- /* Bounce chevron */
227
- @keyframes bounce-gentle { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(6px); } }
228
- .bounce-gentle { animation: bounce-gentle 2s ease-in-out infinite; }
229
-
230
- /* Hero bento card entrance — pre-animation hidden state.
231
- * The actual animation is driven by the Web Animations API in HeroSection
232
- * (with a module-level guard) so it's guaranteed to fire exactly once per
233
- * page load — even under React strict-mode double-mounts or hydration
234
- * recovery. Cells are kept invisible via this class until the JS effect
235
- * runs and replaces it with the WAAPI-driven keyframes. */
236
- .bento-cell-pending { opacity: 0; }
237
-
238
- /* Prototyping section — file flying along the conveyor */
239
- @keyframes proto-fly {
240
- 0% { left: 0%; opacity: 0; transform: translate(-50%, -50%) scale(0.85); }
241
- 10% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
242
- 85% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
243
- 100% { left: 100%; opacity: 0; transform: translate(-50%, -50%) scale(0.85); }
244
- }
245
- .proto-fly { animation: proto-fly 2.2s ease-in-out forwards; }
246
-
247
- /* Prototyping section — checkmark pop-in for the test list */
248
- @keyframes proto-check-pop {
249
- 0% { opacity: 0; transform: scale(0.4); }
250
- 60% { opacity: 1; transform: scale(1.25); }
251
- 100% { opacity: 1; transform: scale(1); }
252
- }
253
- .proto-check-pop { animation: proto-check-pop 0.45s ease-out both; }
254
-
255
- /* Prototyping section — neural network node pulse */
256
- @keyframes proto-node-pulse {
257
- 0%, 100% { opacity: 0.55; r: 3.5; }
258
- 50% { opacity: 1; r: 5; }
259
- }
260
- .proto-node-pulse { animation: proto-node-pulse 1.6s ease-in-out infinite; }
261
-
262
- /* Prototyping section — synapse trail (used by stroke-dasharray fired links) */
263
- @keyframes proto-synapse {
264
- 0% { stroke-dashoffset: 1; opacity: 0; }
265
- 20% { opacity: 0.9; }
266
- 100% { stroke-dashoffset: 0; opacity: 0; }
267
- }
268
- .proto-synapse { stroke-dasharray: 1; animation: proto-synapse 1.4s ease-out forwards; }
269
-
270
- /* Data-table row flash highlights — appear (primary), update (orange), delete (red→fade out) */
271
- @keyframes row-flash-appear {
272
- 0% { background-color: color-mix(in oklch, var(--color-primary) 28%, transparent); }
273
- 100% { background-color: transparent; }
274
- }
275
- @keyframes row-flash-update {
276
- 0% { background-color: oklch(0.75 0.18 65 / 0.32); }
277
- 100% { background-color: transparent; }
278
- }
279
- @keyframes row-flash-delete {
280
- 0% { background-color: oklch(0.6 0.22 25 / 0.45); opacity: 1; }
281
- 70% { background-color: oklch(0.6 0.22 25 / 0.45); opacity: 1; }
282
- 100% { background-color: oklch(0.6 0.22 25 / 0.45); opacity: 0; }
283
- }
284
- .row-flash-appear { animation: row-flash-appear 3s ease-out forwards; }
285
- .row-flash-update { animation: row-flash-update 3s ease-out forwards; }
286
- .row-flash-delete { animation: row-flash-delete 1.4s ease-out forwards; pointer-events: none; }
287
-
288
- /* Row presence avatar — fades+scales in (and stays visible until removed by JS) */
289
- @keyframes row-presence-pop {
290
- 0% { opacity: 0; transform: translateY(-50%) scale(0.6); }
291
- 60% { opacity: 1; transform: translateY(-50%) scale(1.1); }
292
- 100% { opacity: 1; transform: translateY(-50%) scale(1); }
293
- }
294
- .row-presence-pop { animation: row-presence-pop 0.35s ease-out forwards; }
295
-
296
- /* Gradient text */
297
- .text-gradient-primary {
298
- color: transparent;
299
- background-image: linear-gradient(135deg, var(--color-primary), oklch(0.6 0.15 180));
300
- -webkit-background-clip: text;
301
- background-clip: text;
302
- }
303
-
304
- /* Skip navigation link */
305
- .skip-nav {
306
- @apply sr-only focus:not-sr-only focus:fixed focus:top-2 focus:left-2 focus:z-[100] focus:px-4 focus:py-2 focus:rounded-md focus:bg-background focus:text-foreground focus:border focus:border-border focus:shadow-lg;
307
- }
308
-
309
- /* High contrast mode */
310
- @media (forced-colors: active) {
311
- * { border-color: CanvasText !important; }
312
- button, [role="button"] { border: 1px solid ButtonText !important; }
313
- }
314
-
315
- /* Text scaling safety */
316
- html { font-size: clamp(14px, 1rem, 20px); }
317
-
318
- @media print {
319
- header, aside, .no-print { display: none !important; }
320
- main { width: 100% !important; margin: 0 !important; }
321
- pre { white-space: pre-wrap !important; word-break: break-word !important; }
322
- * { box-shadow: none !important; }
323
- }
324
-
325
- /* User's optional global CSS — `paths.globalCss` in their config.
326
- * Generated by the CLI. Imported LAST so user `:root`/`.dark` token
327
- * overrides cascade-win over the shell's defaults above. Always exists
328
- * (no-op when unconfigured) so this import never 404s. */
329
- @import "./_user-global.css";
1
+ @import "tailwindcss";
2
+ @import "tw-animate-css";
3
+ @plugin "@tailwindcss/typography";
4
+
5
+ /* Tailwind content scan for the user's registry files. Generated by the CLI
6
+ * from the `paths` declared in sntlr.ui-shell.config.ts — regenerated every
7
+ * `ui-shell dev` / `build` boot. Do not edit _user-sources.css by hand. */
8
+ @import "./_user-sources.css";
9
+
10
+ @custom-variant dark (&:is(.dark *));
11
+
12
+ @theme inline {
13
+ --color-background: var(--background);
14
+ --color-foreground: var(--foreground);
15
+ --default-font-family: var(--font-sans);
16
+ --default-mono-font-family: var(--font-mono);
17
+ --color-sidebar-ring: var(--sidebar-ring);
18
+ --color-sidebar-border: var(--sidebar-border);
19
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
20
+ --color-sidebar-accent: var(--sidebar-accent);
21
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
22
+ --color-sidebar-primary: var(--sidebar-primary);
23
+ --color-sidebar-foreground: var(--sidebar-foreground);
24
+ --color-sidebar: var(--sidebar);
25
+ --color-chart-5: var(--chart-5);
26
+ --color-chart-4: var(--chart-4);
27
+ --color-chart-3: var(--chart-3);
28
+ --color-chart-2: var(--chart-2);
29
+ --color-chart-1: var(--chart-1);
30
+ --color-ring: var(--ring);
31
+ --color-input: var(--input);
32
+ --color-border: var(--border);
33
+ --color-destructive: var(--destructive);
34
+ --color-accent-foreground: var(--accent-foreground);
35
+ --color-accent: var(--accent);
36
+ --color-muted-foreground: var(--muted-foreground);
37
+ --color-muted: var(--muted);
38
+ --color-secondary-foreground: var(--secondary-foreground);
39
+ --color-secondary: var(--secondary);
40
+ --color-primary-foreground: var(--primary-foreground);
41
+ --color-primary: var(--primary);
42
+ --color-popover-foreground: var(--popover-foreground);
43
+ --color-popover: var(--popover);
44
+ --color-card-foreground: var(--card-foreground);
45
+ --color-card: var(--card);
46
+ --radius-sm: calc(var(--radius) - 4px);
47
+ --radius-md: calc(var(--radius) - 2px);
48
+ --radius-lg: var(--radius);
49
+ --radius-xl: calc(var(--radius) + 4px);
50
+ }
51
+
52
+ :root {
53
+ --radius: 0.625rem;
54
+ --background: oklch(1 0 0);
55
+ --foreground: oklch(0.145 0 0);
56
+ --card: oklch(1 0 0);
57
+ --card-foreground: oklch(0.145 0 0);
58
+ --popover: oklch(1 0 0);
59
+ --popover-foreground: oklch(0.145 0 0);
60
+ --primary: oklch(0.426 0.094 161.619);
61
+ --primary-foreground: oklch(0.985 0 0);
62
+ --secondary: oklch(0.97 0 0);
63
+ --secondary-foreground: oklch(0.205 0 0);
64
+ --muted: oklch(0.97 0 0);
65
+ --muted-foreground: oklch(0.525 0 0);
66
+ --accent: oklch(0.97 0 0);
67
+ --accent-foreground: oklch(0.205 0 0);
68
+ --destructive: oklch(0.577 0.245 27.325);
69
+ --border: oklch(0.922 0 0);
70
+ --input: oklch(0.922 0 0);
71
+ --ring: oklch(0.708 0 0);
72
+ --chart-1: oklch(0.646 0.222 41.116);
73
+ --chart-2: oklch(0.6 0.118 184.714);
74
+ --chart-3: oklch(0.398 0.07 227.392);
75
+ --chart-4: oklch(0.828 0.189 84.429);
76
+ --chart-5: oklch(0.769 0.188 70.08);
77
+ --sidebar: oklch(0.985 0 0);
78
+ --sidebar-foreground: oklch(0.145 0 0);
79
+ --sidebar-primary: oklch(0.426 0.094 161.619);
80
+ --sidebar-primary-foreground: oklch(0.985 0 0);
81
+ --sidebar-accent: oklch(0.97 0 0);
82
+ --sidebar-accent-foreground: oklch(0.205 0 0);
83
+ --sidebar-border: oklch(0.922 0 0);
84
+ --sidebar-ring: oklch(0.708 0 0);
85
+ }
86
+
87
+ .dark {
88
+ --background: oklch(0.145 0 0);
89
+ --foreground: oklch(0.985 0 0);
90
+ --card: oklch(0.145 0 0);
91
+ --card-foreground: oklch(0.985 0 0);
92
+ --popover: oklch(0.145 0 0);
93
+ --popover-foreground: oklch(0.985 0 0);
94
+ --primary: oklch(0.796 0.125 168.082);
95
+ --primary-foreground: oklch(0.145 0 0);
96
+ --secondary: oklch(0.269 0 0);
97
+ --secondary-foreground: oklch(0.985 0 0);
98
+ --muted: oklch(0.269 0 0);
99
+ --muted-foreground: oklch(0.708 0 0);
100
+ --accent: oklch(0.269 0 0);
101
+ --accent-foreground: oklch(0.985 0 0);
102
+ --destructive: oklch(0.577 0.245 27.325);
103
+ --border: oklch(0.269 0 0);
104
+ --input: oklch(0.269 0 0);
105
+ --ring: oklch(0.439 0 0);
106
+ --chart-1: oklch(0.488 0.243 264.376);
107
+ --chart-2: oklch(0.696 0.17 162.48);
108
+ --chart-3: oklch(0.769 0.188 70.08);
109
+ --chart-4: oklch(0.627 0.265 303.9);
110
+ --chart-5: oklch(0.645 0.246 16.439);
111
+ --sidebar: oklch(0.205 0 0);
112
+ --sidebar-foreground: oklch(0.985 0 0);
113
+ --sidebar-primary: oklch(0.796 0.125 168.082);
114
+ --sidebar-primary-foreground: oklch(0.145 0 0);
115
+ --sidebar-accent: oklch(0.269 0 0);
116
+ --sidebar-accent-foreground: oklch(0.985 0 0);
117
+ --sidebar-border: oklch(0.269 0 0);
118
+ --sidebar-ring: oklch(0.439 0 0);
119
+ }
120
+
121
+ @layer base {
122
+ * {
123
+ @apply border-border;
124
+ }
125
+ html, body {
126
+ scrollbar-gutter: stable;
127
+ }
128
+ body {
129
+ @apply bg-background text-foreground font-sans;
130
+ }
131
+ /* Prevent Radix scroll-lock from causing layout shift */
132
+ body[data-scroll-locked] {
133
+ margin-right: 0 !important;
134
+ scrollbar-gutter: stable;
135
+ }
136
+ }
137
+
138
+ /* Minimal scrollbars */
139
+ * {
140
+ scrollbar-width: thin;
141
+ scrollbar-color: var(--border) transparent;
142
+ }
143
+
144
+ *::-webkit-scrollbar {
145
+ width: 6px;
146
+ height: 6px;
147
+ }
148
+
149
+ *::-webkit-scrollbar-track {
150
+ background: transparent;
151
+ }
152
+
153
+ *::-webkit-scrollbar-thumb {
154
+ background: var(--border);
155
+ border-radius: 3px;
156
+ }
157
+
158
+ *::-webkit-scrollbar-thumb:hover {
159
+ background: var(--muted-foreground);
160
+ }
161
+
162
+ .prose pre {
163
+ @apply bg-muted text-foreground rounded-lg;
164
+ }
165
+
166
+ .prose code::before,
167
+ .prose code::after {
168
+ content: none;
169
+ }
170
+
171
+ .prose :not(pre) > code {
172
+ @apply bg-muted px-1.5 py-0.5 rounded text-xs font-medium;
173
+ }
174
+
175
+ .prose a {
176
+ @apply underline underline-offset-2 decoration-border hover:decoration-foreground transition-colors;
177
+ }
178
+
179
+ .prose table {
180
+ @apply w-full text-sm;
181
+ }
182
+
183
+ .prose th {
184
+ @apply text-left font-medium px-3 py-2 border-b border-border;
185
+ }
186
+
187
+ .prose td {
188
+ @apply px-3 py-2 border-b border-border;
189
+ }
190
+
191
+ @media (prefers-reduced-motion: reduce) {
192
+ *, *::before, *::after {
193
+ animation-duration: 0.01ms !important;
194
+ animation-iteration-count: 1 !important;
195
+ transition-duration: 0.01ms !important;
196
+ }
197
+ }
198
+
199
+ /* Chart line draw-in animation */
200
+ @keyframes chart-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
201
+ /* Pair with `pathLength="1"` on the path so the animation is length-agnostic. */
202
+ .chart-line { stroke-dasharray: 1; animation: chart-draw 1.5s ease-out forwards; }
203
+
204
+ /* Bento chart entry animations — line draws, area fades in, dots pop sequentially */
205
+ @keyframes chart-area-fade { from { opacity: 0; } to { opacity: 1; } }
206
+ @keyframes chart-dot-pop {
207
+ 0% { opacity: 0; transform: scale(0); }
208
+ 60% { opacity: 1; transform: scale(1.4); }
209
+ 100% { opacity: 1; transform: scale(1); }
210
+ }
211
+ .chart-area-fade { animation: chart-area-fade 1.4s ease-out 0.4s both; }
212
+ .chart-dot-pop { transform-box: fill-box; transform-origin: center; animation: chart-dot-pop 0.5s ease-out both; }
213
+
214
+ /* Typing cursor blink */
215
+ @keyframes cursor-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
216
+ .typing-cursor { animation: cursor-blink 0.8s step-end infinite; }
217
+
218
+ /* Marquee */
219
+ @keyframes marquee-left { from { transform: translateX(0); } to { transform: translateX(-50%); } }
220
+ @keyframes marquee-right { from { transform: translateX(-50%); } to { transform: translateX(0); } }
221
+ .marquee-track { animation: marquee-left 30s linear infinite; }
222
+ .marquee-track-reverse { animation: marquee-right 30s linear infinite; }
223
+ .marquee-container:hover .marquee-track,
224
+ .marquee-container:hover .marquee-track-reverse { animation-play-state: paused; }
225
+
226
+ /* Bounce chevron */
227
+ @keyframes bounce-gentle { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(6px); } }
228
+ .bounce-gentle { animation: bounce-gentle 2s ease-in-out infinite; }
229
+
230
+ /* Hero bento card entrance — pre-animation hidden state.
231
+ * The actual animation is driven by the Web Animations API in HeroSection
232
+ * (with a module-level guard) so it's guaranteed to fire exactly once per
233
+ * page load — even under React strict-mode double-mounts or hydration
234
+ * recovery. Cells are kept invisible via this class until the JS effect
235
+ * runs and replaces it with the WAAPI-driven keyframes. */
236
+ .bento-cell-pending { opacity: 0; }
237
+
238
+ /* Prototyping section — file flying along the conveyor */
239
+ @keyframes proto-fly {
240
+ 0% { left: 0%; opacity: 0; transform: translate(-50%, -50%) scale(0.85); }
241
+ 10% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
242
+ 85% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
243
+ 100% { left: 100%; opacity: 0; transform: translate(-50%, -50%) scale(0.85); }
244
+ }
245
+ .proto-fly { animation: proto-fly 2.2s ease-in-out forwards; }
246
+
247
+ /* Prototyping section — checkmark pop-in for the test list */
248
+ @keyframes proto-check-pop {
249
+ 0% { opacity: 0; transform: scale(0.4); }
250
+ 60% { opacity: 1; transform: scale(1.25); }
251
+ 100% { opacity: 1; transform: scale(1); }
252
+ }
253
+ .proto-check-pop { animation: proto-check-pop 0.45s ease-out both; }
254
+
255
+ /* Prototyping section — neural network node pulse */
256
+ @keyframes proto-node-pulse {
257
+ 0%, 100% { opacity: 0.55; r: 3.5; }
258
+ 50% { opacity: 1; r: 5; }
259
+ }
260
+ .proto-node-pulse { animation: proto-node-pulse 1.6s ease-in-out infinite; }
261
+
262
+ /* Prototyping section — synapse trail (used by stroke-dasharray fired links) */
263
+ @keyframes proto-synapse {
264
+ 0% { stroke-dashoffset: 1; opacity: 0; }
265
+ 20% { opacity: 0.9; }
266
+ 100% { stroke-dashoffset: 0; opacity: 0; }
267
+ }
268
+ .proto-synapse { stroke-dasharray: 1; animation: proto-synapse 1.4s ease-out forwards; }
269
+
270
+ /* Data-table row flash highlights — appear (primary), update (orange), delete (red→fade out) */
271
+ @keyframes row-flash-appear {
272
+ 0% { background-color: color-mix(in oklch, var(--color-primary) 28%, transparent); }
273
+ 100% { background-color: transparent; }
274
+ }
275
+ @keyframes row-flash-update {
276
+ 0% { background-color: oklch(0.75 0.18 65 / 0.32); }
277
+ 100% { background-color: transparent; }
278
+ }
279
+ @keyframes row-flash-delete {
280
+ 0% { background-color: oklch(0.6 0.22 25 / 0.45); opacity: 1; }
281
+ 70% { background-color: oklch(0.6 0.22 25 / 0.45); opacity: 1; }
282
+ 100% { background-color: oklch(0.6 0.22 25 / 0.45); opacity: 0; }
283
+ }
284
+ .row-flash-appear { animation: row-flash-appear 3s ease-out forwards; }
285
+ .row-flash-update { animation: row-flash-update 3s ease-out forwards; }
286
+ .row-flash-delete { animation: row-flash-delete 1.4s ease-out forwards; pointer-events: none; }
287
+
288
+ /* Row presence avatar — fades+scales in (and stays visible until removed by JS) */
289
+ @keyframes row-presence-pop {
290
+ 0% { opacity: 0; transform: translateY(-50%) scale(0.6); }
291
+ 60% { opacity: 1; transform: translateY(-50%) scale(1.1); }
292
+ 100% { opacity: 1; transform: translateY(-50%) scale(1); }
293
+ }
294
+ .row-presence-pop { animation: row-presence-pop 0.35s ease-out forwards; }
295
+
296
+ /* Gradient text */
297
+ .text-gradient-primary {
298
+ color: transparent;
299
+ background-image: linear-gradient(135deg, var(--color-primary), oklch(0.6 0.15 180));
300
+ -webkit-background-clip: text;
301
+ background-clip: text;
302
+ }
303
+
304
+ /* Skip navigation link */
305
+ .skip-nav {
306
+ @apply sr-only focus:not-sr-only focus:fixed focus:top-2 focus:left-2 focus:z-[100] focus:px-4 focus:py-2 focus:rounded-md focus:bg-background focus:text-foreground focus:border focus:border-border focus:shadow-lg;
307
+ }
308
+
309
+ /* High contrast mode */
310
+ @media (forced-colors: active) {
311
+ * { border-color: CanvasText !important; }
312
+ button, [role="button"] { border: 1px solid ButtonText !important; }
313
+ }
314
+
315
+ /* Text scaling safety */
316
+ html { font-size: clamp(14px, 1rem, 20px); }
317
+
318
+ @media print {
319
+ header, aside, .no-print { display: none !important; }
320
+ main { width: 100% !important; margin: 0 !important; }
321
+ pre { white-space: pre-wrap !important; word-break: break-word !important; }
322
+ * { box-shadow: none !important; }
323
+ }
324
+
325
+ /* User's optional global CSS — `paths.globalCss` in their config.
326
+ * Generated by the CLI. Imported LAST so user `:root`/`.dark` token
327
+ * overrides cascade-win over the shell's defaults above. Always exists
328
+ * (no-op when unconfigured) so this import never 404s. */
329
+ @import "./_user-global.css";
@@ -1,5 +1,5 @@
1
1
  import { getAllDocs } from "@shell/lib/docs"
2
- import HomePage from "@user/homepage"
2
+ import HomePage from "@shell/components/homepage"
3
3
 
4
4
  export default function Home() {
5
5
  const docs = getAllDocs()