@autono/open-pages 0.1.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 (110) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +108 -0
  3. package/bin.js +2 -0
  4. package/dist/build-TP72kiw7.js +35 -0
  5. package/dist/cli/bin.d.ts +1 -0
  6. package/dist/cli/bin.js +100 -0
  7. package/dist/config-C9or4m4J.d.ts +23 -0
  8. package/dist/config-L0IbktJ0.js +3135 -0
  9. package/dist/design-C13iz9_4.js +35 -0
  10. package/dist/dev-I2IyEh5W.js +97 -0
  11. package/dist/export-B-kBRWB1.js +4 -0
  12. package/dist/export-ic28osQP.js +131 -0
  13. package/dist/index.d.ts +56 -0
  14. package/dist/index.js +3 -0
  15. package/dist/locale/index.d.ts +24 -0
  16. package/dist/locale/index.js +881 -0
  17. package/dist/open-pages-plugin-D_DN_zjh.js +632 -0
  18. package/dist/preview-BrDuvgAN.js +21 -0
  19. package/dist/sync-Be_hxSOF.js +139 -0
  20. package/dist/sync-lKEXyPOh.js +3 -0
  21. package/dist/types-C5NCdDT-.d.ts +219 -0
  22. package/dist/update-CV62NhBT.js +37 -0
  23. package/dist/update-package-Cxt57pz7.js +152 -0
  24. package/dist/version-B6AiiGvT.js +26 -0
  25. package/dist/version-CeffgdfZ.js +3 -0
  26. package/dist/vite/index.d.ts +14 -0
  27. package/dist/vite/index.js +7 -0
  28. package/env.d.ts +59 -0
  29. package/package.json +106 -0
  30. package/skills/apply-comments/SKILL.md +86 -0
  31. package/skills/create-page/SKILL.md +92 -0
  32. package/skills/create-theme/SKILL.md +223 -0
  33. package/skills/current-page/SKILL.md +106 -0
  34. package/skills/page-authoring/SKILL.md +148 -0
  35. package/skills/page-authoring/references/assets-and-fonts.md +85 -0
  36. package/skills/page-authoring/references/html-pages.md +65 -0
  37. package/skills/page-authoring/references/interactivity.md +77 -0
  38. package/skills/page-authoring/references/layout-and-responsive.md +71 -0
  39. package/skills/page-authoring/references/typography-and-color.md +60 -0
  40. package/src/app/app.tsx +45 -0
  41. package/src/app/components/asset-view.tsx +1665 -0
  42. package/src/app/components/command/command-menu.tsx +227 -0
  43. package/src/app/components/command/command.tsx +142 -0
  44. package/src/app/components/command/home-command-menu.tsx +96 -0
  45. package/src/app/components/icon-tooltip.tsx +34 -0
  46. package/src/app/components/language-toggle.tsx +46 -0
  47. package/src/app/components/sidebar/folder-item.tsx +269 -0
  48. package/src/app/components/sidebar/icon-picker.tsx +61 -0
  49. package/src/app/components/sidebar/sidebar-footer.tsx +139 -0
  50. package/src/app/components/sidebar/sidebar.tsx +302 -0
  51. package/src/app/components/theme-toggle.tsx +66 -0
  52. package/src/app/components/themes/theme-detail.tsx +226 -0
  53. package/src/app/components/themes/themes-gallery.tsx +104 -0
  54. package/src/app/components/ui/badge.tsx +48 -0
  55. package/src/app/components/ui/button.tsx +93 -0
  56. package/src/app/components/ui/card.tsx +92 -0
  57. package/src/app/components/ui/context-menu.tsx +247 -0
  58. package/src/app/components/ui/dialog.tsx +155 -0
  59. package/src/app/components/ui/dropdown-menu.tsx +267 -0
  60. package/src/app/components/ui/input.tsx +25 -0
  61. package/src/app/components/ui/label.tsx +21 -0
  62. package/src/app/components/ui/popover.tsx +82 -0
  63. package/src/app/components/ui/progress.tsx +33 -0
  64. package/src/app/components/ui/scroll-area.tsx +53 -0
  65. package/src/app/components/ui/select.tsx +195 -0
  66. package/src/app/components/ui/separator.tsx +26 -0
  67. package/src/app/components/ui/slider.tsx +68 -0
  68. package/src/app/components/ui/sonner.tsx +48 -0
  69. package/src/app/components/ui/tabs.tsx +79 -0
  70. package/src/app/components/ui/textarea.tsx +22 -0
  71. package/src/app/components/ui/toggle-group.tsx +84 -0
  72. package/src/app/components/ui/toggle.tsx +45 -0
  73. package/src/app/components/ui/tooltip.tsx +75 -0
  74. package/src/app/favicon.ico +0 -0
  75. package/src/app/frame/inspect.ts +140 -0
  76. package/src/app/frame/main.tsx +91 -0
  77. package/src/app/frame.html +12 -0
  78. package/src/app/index.html +13 -0
  79. package/src/app/lib/asset-filter.test.ts +176 -0
  80. package/src/app/lib/asset-filter.ts +80 -0
  81. package/src/app/lib/assets.ts +257 -0
  82. package/src/app/lib/design.ts +58 -0
  83. package/src/app/lib/folders.ts +239 -0
  84. package/src/app/lib/frame.ts +38 -0
  85. package/src/app/lib/locale-store.ts +67 -0
  86. package/src/app/lib/page-thumb.tsx +46 -0
  87. package/src/app/lib/pages.ts +28 -0
  88. package/src/app/lib/sdk.ts +43 -0
  89. package/src/app/lib/themes.ts +22 -0
  90. package/src/app/lib/use-locale.ts +8 -0
  91. package/src/app/lib/use-page-module.ts +48 -0
  92. package/src/app/lib/use-page-titles.ts +29 -0
  93. package/src/app/lib/use-restart-server.ts +78 -0
  94. package/src/app/lib/utils.test.ts +25 -0
  95. package/src/app/lib/utils.ts +6 -0
  96. package/src/app/main.tsx +14 -0
  97. package/src/app/routes/assets.tsx +9 -0
  98. package/src/app/routes/home-shell.tsx +252 -0
  99. package/src/app/routes/home.tsx +846 -0
  100. package/src/app/routes/page.tsx +329 -0
  101. package/src/app/routes/themes.tsx +34 -0
  102. package/src/app/styles.css +405 -0
  103. package/src/app/virtual.d.ts +53 -0
  104. package/src/locale/en.ts +218 -0
  105. package/src/locale/format.ts +12 -0
  106. package/src/locale/index.ts +6 -0
  107. package/src/locale/ja.ts +221 -0
  108. package/src/locale/types.ts +215 -0
  109. package/src/locale/zh-cn.ts +218 -0
  110. package/src/locale/zh-tw.ts +218 -0
@@ -0,0 +1,405 @@
1
+ @import "tailwindcss";
2
+ @import "tw-animate-css";
3
+ @import "shadcn/tailwind.css";
4
+ @import "@fontsource-variable/geist";
5
+
6
+ @custom-variant dark (&:is(.dark *));
7
+
8
+ @theme inline {
9
+ --font-sans: "Geist Variable", -apple-system, BlinkMacSystemFont, sans-serif;
10
+ --font-heading: "Geist Variable", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
11
+ --font-serif:
12
+ ui-serif, "New York", "Iowan Old Style", "Apple Garamond", "Big Caslon", "Charter", Georgia,
13
+ serif;
14
+ --font-mono: ui-monospace, "JetBrains Mono", "SF Mono", "Menlo", "Cascadia Code", monospace;
15
+
16
+ --color-sidebar-ring: var(--sidebar-ring);
17
+ --color-sidebar-border: var(--sidebar-border);
18
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
19
+ --color-sidebar-accent: var(--sidebar-accent);
20
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
21
+ --color-sidebar-primary: var(--sidebar-primary);
22
+ --color-sidebar-foreground: var(--sidebar-foreground);
23
+ --color-sidebar: var(--sidebar);
24
+ --color-chart-5: var(--chart-5);
25
+ --color-chart-4: var(--chart-4);
26
+ --color-chart-3: var(--chart-3);
27
+ --color-chart-2: var(--chart-2);
28
+ --color-chart-1: var(--chart-1);
29
+ --color-ring: var(--ring);
30
+ --color-input: var(--input);
31
+ --color-border: var(--border);
32
+ --color-hairline: var(--hairline);
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
+ --color-canvas: var(--canvas);
47
+ --color-foreground: var(--foreground);
48
+ --color-background: var(--background);
49
+ --color-brand: var(--brand);
50
+ --color-brand-foreground: var(--brand-foreground);
51
+ --color-brand-soft: var(--brand-soft);
52
+
53
+ --radius-sm: calc(var(--radius) * 0.6);
54
+ --radius-md: calc(var(--radius) * 0.85);
55
+ --radius-lg: var(--radius);
56
+ --radius-xl: calc(var(--radius) * 1.4);
57
+ --radius-2xl: calc(var(--radius) * 1.8);
58
+ --radius-3xl: calc(var(--radius) * 2.2);
59
+ --radius-4xl: calc(var(--radius) * 2.6);
60
+
61
+ --shadow-edge: 0 0 0 0.5px oklch(0 0 0 / 0.06), 0 1px 0 oklch(0 0 0 / 0.025);
62
+ --shadow-floating:
63
+ 0 0 0 0.5px oklch(0 0 0 / 0.08), 0 1px 1px oklch(0 0 0 / 0.04),
64
+ 0 4px 16px -2px oklch(0 0 0 / 0.08);
65
+ --shadow-overlay:
66
+ 0 0 0 0.5px oklch(0 0 0 / 0.1), 0 8px 28px -4px oklch(0 0 0 / 0.18),
67
+ 0 24px 64px -12px oklch(0 0 0 / 0.2);
68
+ }
69
+
70
+ :root {
71
+ /* Pure neutral ramp — zero chroma, flat surfaces, hairline borders.
72
+ Near-white background with white cards floating on a slightly
73
+ recessed canvas. */
74
+ --background: oklch(0.99 0 0);
75
+ --foreground: oklch(0.145 0 0);
76
+ --canvas: oklch(0.975 0 0);
77
+
78
+ --card: oklch(1 0 0);
79
+ --card-foreground: oklch(0.145 0 0);
80
+ --popover: oklch(1 0 0);
81
+ --popover-foreground: oklch(0.145 0 0);
82
+
83
+ --primary: oklch(0.185 0 0);
84
+ --primary-foreground: oklch(0.985 0 0);
85
+ --secondary: oklch(0.96 0 0);
86
+ --secondary-foreground: oklch(0.185 0 0);
87
+ --muted: oklch(0.955 0 0);
88
+ --muted-foreground: oklch(0.5 0 0);
89
+ --accent: oklch(0.945 0 0);
90
+ --accent-foreground: oklch(0.185 0 0);
91
+ --destructive: oklch(0.58 0.22 27);
92
+
93
+ --border: oklch(0.92 0 0);
94
+ --hairline: oklch(0.885 0 0);
95
+ --input: oklch(0.92 0 0);
96
+ --ring: oklch(0.6 0.2 25);
97
+
98
+ /* Vermillion — the single signature accent on an otherwise neutral
99
+ surface; restraint is the point. */
100
+ --brand: oklch(0.6 0.2 25);
101
+ --brand-foreground: oklch(0.985 0 0);
102
+ --brand-soft: oklch(0.6 0.2 25 / 0.1);
103
+
104
+ --chart-1: oklch(0.6 0.2 25);
105
+ --chart-2: oklch(0.55 0.16 250);
106
+ --chart-3: oklch(0.55 0.15 285);
107
+ --chart-4: oklch(0.6 0.13 160);
108
+ --chart-5: oklch(0.5 0 0);
109
+
110
+ /* Tight, considered radius — drops the trendy 10px squish for 6px crisp. */
111
+ --radius: 0.375rem;
112
+
113
+ --sidebar: oklch(0.98 0 0);
114
+ --sidebar-foreground: oklch(0.185 0 0);
115
+ --sidebar-primary: oklch(0.185 0 0);
116
+ --sidebar-primary-foreground: oklch(0.985 0 0);
117
+ --sidebar-accent: oklch(0.94 0 0);
118
+ --sidebar-accent-foreground: oklch(0.185 0 0);
119
+ --sidebar-border: oklch(0.905 0 0);
120
+ --sidebar-ring: oklch(0.6 0.2 25);
121
+ }
122
+
123
+ .dark {
124
+ --background: oklch(0.145 0 0);
125
+ --foreground: oklch(0.93 0 0);
126
+ --canvas: oklch(0.125 0 0);
127
+
128
+ --card: oklch(0.19 0 0);
129
+ --card-foreground: oklch(0.93 0 0);
130
+ --popover: oklch(0.205 0 0);
131
+ --popover-foreground: oklch(0.93 0 0);
132
+
133
+ --primary: oklch(0.925 0 0);
134
+ --primary-foreground: oklch(0.17 0 0);
135
+ --secondary: oklch(0.24 0 0);
136
+ --secondary-foreground: oklch(0.93 0 0);
137
+ --muted: oklch(0.23 0 0);
138
+ --muted-foreground: oklch(0.68 0 0);
139
+ --accent: oklch(0.265 0 0);
140
+ --accent-foreground: oklch(0.93 0 0);
141
+ --destructive: oklch(0.66 0.2 25);
142
+
143
+ --border: oklch(1 0 0 / 0.1);
144
+ --hairline: oklch(1 0 0 / 0.07);
145
+ --input: oklch(1 0 0 / 0.14);
146
+ --ring: oklch(0.63 0.19 25);
147
+
148
+ --brand: oklch(0.63 0.2 25);
149
+ --brand-foreground: oklch(0.985 0 0);
150
+ --brand-soft: oklch(0.63 0.2 25 / 0.16);
151
+
152
+ --chart-1: oklch(0.63 0.2 25);
153
+ --chart-2: oklch(0.65 0.15 250);
154
+ --chart-3: oklch(0.65 0.14 285);
155
+ --chart-4: oklch(0.7 0.13 160);
156
+ --chart-5: oklch(0.65 0 0);
157
+
158
+ --sidebar: oklch(0.17 0 0);
159
+ --sidebar-foreground: oklch(0.93 0 0);
160
+ --sidebar-primary: oklch(0.925 0 0);
161
+ --sidebar-primary-foreground: oklch(0.17 0 0);
162
+ --sidebar-accent: oklch(0.26 0 0);
163
+ --sidebar-accent-foreground: oklch(0.93 0 0);
164
+ --sidebar-border: oklch(1 0 0 / 0.1);
165
+ --sidebar-ring: oklch(0.63 0.19 25);
166
+ }
167
+
168
+ /* Tabular numerics — pages, counts, hex values, slider readouts.
169
+ Declared as a Tailwind v4 `@utility` so it can be `@apply`d (e.g. by
170
+ .folio below) and used as a className token. */
171
+ @utility nums {
172
+ font-feature-settings:
173
+ "tnum" on,
174
+ "cv11" on;
175
+ font-variant-numeric: tabular-nums;
176
+ }
177
+
178
+ @layer base {
179
+ * {
180
+ @apply border-border outline-ring/50;
181
+ }
182
+ html {
183
+ @apply font-sans;
184
+ text-rendering: optimizeLegibility;
185
+ -webkit-font-smoothing: antialiased;
186
+ -moz-osx-font-smoothing: grayscale;
187
+ font-feature-settings:
188
+ "ss01" on,
189
+ "cv11" on,
190
+ "calt" on;
191
+ }
192
+ body {
193
+ @apply bg-background text-foreground;
194
+ font-feature-settings:
195
+ "ss01" on,
196
+ "cv11" on,
197
+ "calt" on,
198
+ "tnum" off;
199
+ letter-spacing: -0.005em;
200
+ }
201
+ ::selection {
202
+ background: var(--brand-soft);
203
+ color: var(--foreground);
204
+ }
205
+ }
206
+
207
+ @layer components {
208
+ /*
209
+ * Eyebrow label — the single typographic gesture used for *every* section
210
+ * label across the app. Tracked-out small caps in muted ink.
211
+ */
212
+ .eyebrow {
213
+ @apply font-sans text-[11px] font-medium uppercase text-muted-foreground;
214
+ letter-spacing: 0.08em;
215
+ }
216
+
217
+ /* Hairline divider — 0.5px on retina, snaps to 1px elsewhere. */
218
+ .hairline {
219
+ background: var(--hairline);
220
+ }
221
+
222
+ /* Numeric folio-style page count. */
223
+ .folio {
224
+ @apply nums font-mono text-[10.5px] tracking-[0.08em] text-muted-foreground;
225
+ }
226
+ }
227
+
228
+ /*
229
+ * Comment input cue — kept from the original design but retoned to match
230
+ * the new palette (warm vermillion + amber instead of the AI-classic
231
+ * blue/violet halo). Plays once on first open, then settles.
232
+ */
233
+ @property --comment-cue-angle {
234
+ syntax: "<angle>";
235
+ initial-value: 0deg;
236
+ inherits: false;
237
+ }
238
+
239
+ .comment-cue {
240
+ position: relative;
241
+ isolation: isolate;
242
+ }
243
+
244
+ .comment-cue::before {
245
+ content: "";
246
+ position: absolute;
247
+ inset: -1px;
248
+ border-radius: calc(var(--radius-md) + 1px);
249
+ padding: 1.25px;
250
+ background: conic-gradient(
251
+ from var(--comment-cue-angle),
252
+ transparent 0deg,
253
+ transparent 250deg,
254
+ oklch(0.78 0.14 60 / 0.55) 295deg,
255
+ oklch(0.62 0.2 28 / 0.85) 325deg,
256
+ oklch(0.78 0.14 60 / 0.55) 350deg,
257
+ transparent 360deg
258
+ );
259
+ -webkit-mask:
260
+ linear-gradient(#000 0 0) content-box,
261
+ linear-gradient(#000 0 0);
262
+ -webkit-mask-composite: xor;
263
+ mask:
264
+ linear-gradient(#000 0 0) content-box,
265
+ linear-gradient(#000 0 0);
266
+ mask-composite: exclude;
267
+ pointer-events: none;
268
+ opacity: 0;
269
+ z-index: 1;
270
+ animation: comment-cue-trace 1500ms cubic-bezier(0.22, 0.61, 0.36, 1) 220ms 1 both;
271
+ }
272
+
273
+ .comment-cue::after {
274
+ content: "";
275
+ position: absolute;
276
+ inset: -10px;
277
+ border-radius: calc(var(--radius-md) + 10px);
278
+ background:
279
+ radial-gradient(80% 60% at 30% 50%, oklch(0.62 0.2 28 / 0.18), transparent 70%),
280
+ radial-gradient(70% 60% at 75% 60%, oklch(0.78 0.14 60 / 0.16), transparent 70%);
281
+ filter: blur(14px);
282
+ opacity: 0;
283
+ z-index: -1;
284
+ pointer-events: none;
285
+ animation: comment-cue-halo 1700ms ease-out 180ms 1 both;
286
+ }
287
+
288
+ @keyframes comment-cue-trace {
289
+ 0% {
290
+ --comment-cue-angle: 0deg;
291
+ opacity: 0;
292
+ }
293
+ 18% {
294
+ opacity: 1;
295
+ }
296
+ 82% {
297
+ opacity: 1;
298
+ }
299
+ 100% {
300
+ --comment-cue-angle: 360deg;
301
+ opacity: 0;
302
+ }
303
+ }
304
+
305
+ @keyframes comment-cue-halo {
306
+ 0% {
307
+ opacity: 0;
308
+ transform: scale(0.97);
309
+ }
310
+ 40% {
311
+ opacity: 1;
312
+ transform: scale(1);
313
+ }
314
+ 100% {
315
+ opacity: 0;
316
+ transform: scale(1.015);
317
+ }
318
+ }
319
+
320
+ @media (prefers-reduced-motion: reduce) {
321
+ .comment-cue::before,
322
+ .comment-cue::after {
323
+ animation: none;
324
+ }
325
+ }
326
+
327
+ /*
328
+ * Indeterminate "line loader" — a hairline track with a short bar that
329
+ * glides back and forth. Used for full-screen loading states in place of
330
+ * a spinner; quieter, more typographic, easier on the eye.
331
+ */
332
+ @keyframes osd-line-loader {
333
+ 0% {
334
+ transform: translateX(0%);
335
+ }
336
+ 50% {
337
+ transform: translateX(300%);
338
+ }
339
+ 100% {
340
+ transform: translateX(0%);
341
+ }
342
+ }
343
+
344
+ .line-loader-bar {
345
+ animation: osd-line-loader 1.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
346
+ }
347
+
348
+ @media (prefers-reduced-motion: reduce) {
349
+ .line-loader-bar {
350
+ animation: none;
351
+ transform: translateX(150%);
352
+ }
353
+ }
354
+
355
+ [data-osd-freeze-motion],
356
+ [data-osd-freeze-motion] *,
357
+ [data-osd-freeze-motion] *::before,
358
+ [data-osd-freeze-motion] *::after {
359
+ /* biome-ignore lint/complexity/noImportantStyles: Thumbnail previews must override arbitrary page-authored motion, including inline styles. */
360
+ animation-duration: 1ms !important;
361
+ /* biome-ignore lint/complexity/noImportantStyles: Thumbnail previews must override arbitrary page-authored motion, including inline styles. */
362
+ animation-delay: 0s !important;
363
+ /* biome-ignore lint/complexity/noImportantStyles: Thumbnail previews must override arbitrary page-authored motion, including inline styles. */
364
+ animation-iteration-count: 1 !important;
365
+ /* biome-ignore lint/complexity/noImportantStyles: Thumbnail previews must override arbitrary page-authored motion, including inline styles. */
366
+ animation-fill-mode: forwards !important;
367
+ /* biome-ignore lint/complexity/noImportantStyles: Thumbnail previews must override arbitrary page-authored motion, including inline styles. */
368
+ transition: none !important;
369
+ /* biome-ignore lint/complexity/noImportantStyles: Thumbnail previews must override arbitrary page-authored motion, including inline styles. */
370
+ scroll-behavior: auto !important;
371
+ /* biome-ignore lint/complexity/noImportantStyles: Thumbnail previews must override arbitrary page-authored motion, including inline styles. */
372
+ view-transition-name: none !important;
373
+ }
374
+
375
+ /*
376
+ * Custom scrollbar — slim, ink-on-paper. Removes the chunky default that
377
+ * fights the calm surfaces.
378
+ */
379
+ @media (pointer: fine) {
380
+ *::-webkit-scrollbar {
381
+ width: 10px;
382
+ height: 10px;
383
+ }
384
+ *::-webkit-scrollbar-track {
385
+ background: transparent;
386
+ }
387
+ *::-webkit-scrollbar-thumb {
388
+ background: oklch(0 0 0 / 0.1);
389
+ border: 3px solid transparent;
390
+ background-clip: content-box;
391
+ border-radius: 999px;
392
+ }
393
+ *::-webkit-scrollbar-thumb:hover {
394
+ background: oklch(0 0 0 / 0.18);
395
+ background-clip: content-box;
396
+ }
397
+ .dark *::-webkit-scrollbar-thumb {
398
+ background: oklch(1 0 0 / 0.1);
399
+ background-clip: content-box;
400
+ }
401
+ .dark *::-webkit-scrollbar-thumb:hover {
402
+ background: oklch(1 0 0 / 0.18);
403
+ background-clip: content-box;
404
+ }
405
+ }
@@ -0,0 +1,53 @@
1
+ declare module 'virtual:open-pages/pages' {
2
+ import type { PageKind, PageModule } from './lib/sdk';
3
+ export const pageIds: string[];
4
+ export const pageKinds: Record<string, PageKind>;
5
+ export const pageThemes: Record<string, string>;
6
+ export const pageCreatedAt: Record<string, number>;
7
+ export function loadPage(id: string): Promise<PageModule>;
8
+ }
9
+
10
+ declare module 'virtual:open-pages/pages.css' {}
11
+
12
+ declare module 'virtual:open-pages/config' {
13
+ import type { Locale } from '../locale/types';
14
+
15
+ const config: {
16
+ base?: string;
17
+ pagesDir?: string;
18
+ port?: number;
19
+ locale?: Locale;
20
+ version: string;
21
+ build: {
22
+ showPageBrowser: boolean;
23
+ showPageUi: boolean;
24
+ };
25
+ };
26
+ export default config;
27
+ }
28
+
29
+ declare module 'virtual:open-pages/folders' {
30
+ import type { FoldersManifest } from './lib/sdk';
31
+
32
+ const manifest: FoldersManifest;
33
+ export default manifest;
34
+ }
35
+
36
+ declare module 'virtual:open-pages/themes' {
37
+ import type { DesignSystem } from './lib/design';
38
+ import type { PageComponent } from './lib/sdk';
39
+
40
+ export type ThemeMeta = {
41
+ id: string;
42
+ name: string;
43
+ description: string;
44
+ body: string;
45
+ hasDemo: boolean;
46
+ };
47
+
48
+ export const themes: ThemeMeta[];
49
+ export function loadThemeDemo(id: string): Promise<{
50
+ default: PageComponent;
51
+ design?: DesignSystem;
52
+ }>;
53
+ }
@@ -0,0 +1,218 @@
1
+ import type { Locale } from './types';
2
+
3
+ export const en: Locale = {
4
+ id: 'en',
5
+ common: {
6
+ cancel: 'Cancel',
7
+ save: 'Save',
8
+ delete: 'Delete',
9
+ rename: 'Rename',
10
+ move: 'Move',
11
+ add: 'Add',
12
+ done: 'Done',
13
+ tryAgain: 'Try again',
14
+ selected: 'Selected',
15
+ },
16
+ notFound: {
17
+ eyebrow: '404 · not found',
18
+ title: 'Page not found',
19
+ },
20
+ home: {
21
+ appTitle: 'open-pages',
22
+ draft: 'Draft',
23
+ duplicate: 'Duplicate',
24
+ themes: 'Themes',
25
+ assets: 'Assets',
26
+ folders: 'Folders',
27
+ pages: 'Pages',
28
+ menu: 'Menu',
29
+ newFolder: 'New folder',
30
+ folderName: 'Folder name',
31
+ updateAvailable: 'open-pages {version} is available',
32
+ updatePackage: 'Update',
33
+ updatingPackage: 'Updating',
34
+ updatePackageDone: 'Updated. Restart the dev server to use the new version.',
35
+ updatePackageFailed: 'Update failed. Check the dev server output.',
36
+ restartServer: 'Restart dev server',
37
+ restartingServer: 'Restarting',
38
+ restartServerFailed: 'Restart failed. Restart the dev server manually.',
39
+ changeIcon: 'Change icon',
40
+ iconEmojiTab: 'Emoji',
41
+ iconColorTab: 'Color',
42
+ folderActions: 'Folder actions',
43
+ searchPlaceholder: 'Search pages',
44
+ clearSearch: 'Clear search',
45
+ sortLabel: 'Sort',
46
+ sortByCreatedDesc: 'Newest',
47
+ sortByCreatedAsc: 'Oldest',
48
+ sortByTitleAsc: 'A–Z',
49
+ sortByTitleDesc: 'Z–A',
50
+ noMatches: 'No matches',
51
+ nothingMatchesPrefix: 'Nothing matches ',
52
+ nothingMatchesSuffix: ' in this folder.',
53
+ noDocsYet: 'No pages yet',
54
+ createDocHintPrefix: 'Run ',
55
+ createDocHintSuffix: ' in your agent to scaffold one.',
56
+ folderEmptyTitle: '{name} is empty',
57
+ folderEmptyHint: 'Drag a page from Draft into this folder in the sidebar.',
58
+ docActions: 'Page actions',
59
+ moveToFolder: 'Move to folder…',
60
+ renameDialogEyebrow: 'Rename',
61
+ renameDialogTitle: 'Rename page',
62
+ renameDialogDescription: 'Give this page a new display name.',
63
+ docNamePlaceholder: 'Page name',
64
+ moveDialogEyebrow: 'Move',
65
+ moveDialogTitle: 'Move page',
66
+ moveDialogDescriptionPrefix: 'Choose a folder for ',
67
+ moveDialogDescriptionSuffix: '.',
68
+ deleteDialogEyebrow: 'Destructive',
69
+ deleteDialogTitle: 'Delete page?',
70
+ deleteDialogDescriptionPrefix: 'This permanently removes ',
71
+ deleteDialogDescriptionMid: ' and its files from disk. ',
72
+ deleteDialogDescriptionSuffix: 'This action cannot be undone.',
73
+ toastFolderCreated: 'Created folder “{name}”',
74
+ toastFolderCreateFailed: 'Failed to create folder',
75
+ toastDocDuplicated: 'Duplicated “{page}” as {newDoc}',
76
+ toastDocDuplicateFailed: 'Could not duplicate page',
77
+ toastDocMoved: 'Moved “{page}” to {folder}',
78
+ toastDocMoveFailed: 'Failed to move page',
79
+ toastFolderDeleted: 'Deleted folder “{name}”',
80
+ toastFolderDeleteFailed: 'Failed to delete folder',
81
+ toastFolderReorderFailed: 'Failed to reorder folders',
82
+ pickIcon: 'Pick icon',
83
+ },
84
+ page: {
85
+ loadingEyebrow: 'Loading',
86
+ },
87
+ asset: {
88
+ devOnlyMessage: 'Asset management is only available in dev mode.',
89
+ sectionAria: 'Page assets',
90
+ eyebrow: 'Assets',
91
+ scopeDoc: 'This page',
92
+ scopeGlobal: 'Global',
93
+ fileCount: {
94
+ one: '{count} file',
95
+ other: '{count} files',
96
+ },
97
+ createdAt: 'Created',
98
+ modifiedAt: 'Modified',
99
+ nameColumn: 'Name',
100
+ typeColumn: 'Type',
101
+ sizeColumn: 'Size',
102
+ statusColumn: 'Status',
103
+ sortAria: 'Sort assets',
104
+ sortByColumn: 'Sort by {column}',
105
+ sortAscending: 'Ascending',
106
+ sortDescending: 'Descending',
107
+ assetSearchPlaceholder: 'Search assets…',
108
+ clearAssetSearch: 'Clear asset search',
109
+ usageFilterAria: 'Filter by usage',
110
+ usageAll: 'All usage',
111
+ usageUsed: 'Used',
112
+ usageUnused: 'Unused',
113
+ typeFilterAria: 'Filter by file type',
114
+ typeAll: 'All types',
115
+ typeImage: 'Images',
116
+ typeFont: 'Fonts',
117
+ typeVideo: 'Videos',
118
+ typeOther: 'Other',
119
+ gridViewAria: 'Grid view',
120
+ listViewAria: 'List view',
121
+ gridColumnsAria: 'Grid columns',
122
+ gridColumnsValue: '{count} columns',
123
+ noMatchingAssets: 'No matching assets',
124
+ noMatchingAssetsHint: 'Try adjusting your search or filters.',
125
+ clearFilters: 'Clear filters',
126
+ searchLogos: 'Search logos',
127
+ upload: 'Upload',
128
+ dropToUpload: 'Drop to upload',
129
+ loading: 'Loading…',
130
+ noAssetsYet: 'No assets yet',
131
+ noAssetsHintPrefix: 'Drop files anywhere here, or use ',
132
+ noAssetsHintSuffix: '.',
133
+ nameAlreadyExists: 'A file with that name already exists.',
134
+ previewAria: 'Preview {name}',
135
+ actionsAria: 'Actions for {name}',
136
+ previewMenuItem: 'Preview',
137
+ renameMenuItem: 'Rename',
138
+ deleteMenuItem: 'Delete',
139
+ conflictTitle: 'File already exists',
140
+ conflictDescription: '{name} is already in the assets folder.',
141
+ conflictReplace: 'Replace',
142
+ conflictRenameCopy: 'Rename copy',
143
+ deleteAssetTitle: 'Delete asset',
144
+ deleteAssetDescription: 'Delete {name}? Imports referencing this file in the page will break.',
145
+ deleteAssetInUseDescription: '{name} is used in {count} place(s) across {pages} page(s).',
146
+ deleteAssetInUseHint: 'Deleting will revert these usages back to image placeholders.',
147
+ deleteAndRevert: 'Delete & revert',
148
+ toastRevertFailed: "Couldn't revert usage in {pageId}",
149
+ toastDeletedWithRevert: 'Deleted {name} and reverted {count} usage(s)',
150
+ noPreview: 'No preview available',
151
+ importHintComment: 'import asset from ',
152
+ importHintSemi: ';',
153
+ logoSearchTitle: 'Search logos',
154
+ logoSearchPoweredByPrefix: 'Powered by ',
155
+ logoSearchPlaceholder: 'Search by brand…',
156
+ logoSearchErrorTitle: "Couldn't reach svgl",
157
+ logoSearchErrorBody: 'Check your connection and try again.',
158
+ logoSearchNoResults: 'No logos for "{query}"',
159
+ logoSearchEmpty: 'No logos available',
160
+ logoSearchEmptyHintPrefix: 'Try a different brand name, or browse the full catalog at ',
161
+ logoSearchEmptyHintSuffix: '.',
162
+ logoVariantLight: 'Light',
163
+ logoVariantDark: 'Dark',
164
+ toastUploadFailed: 'Upload failed ({status})',
165
+ toastReplaced: 'Replaced {name}',
166
+ toastUploadedAs: 'Uploaded as {name}',
167
+ toastUploaded: 'Uploaded {name}',
168
+ toastRenameFailed: 'Rename failed ({status})',
169
+ toastRenamed: 'Renamed to {name}',
170
+ toastDeleteFailed: 'Delete failed ({status})',
171
+ toastDeleted: 'Deleted {name}',
172
+ toastDownloadFailed: 'Failed to download logo',
173
+ toastSearchFailed: 'Search failed',
174
+ },
175
+ commandMenu: {
176
+ trigger: 'Commands',
177
+ triggerAria: 'Open command menu',
178
+ triggerTooltip: 'Search',
179
+ placeholder: 'Search pages or run a command…',
180
+ empty: 'No results.',
181
+ groupDocs: 'Pages',
182
+ groupFolders: 'Folders',
183
+ groupNavigation: 'Go to',
184
+ groupAppearance: 'Appearance',
185
+ groupDeveloper: 'Developer',
186
+ themeItem: 'Theme: {name}',
187
+ languageItem: 'Language: {name}',
188
+ hintNavigate: 'Navigate',
189
+ hintSelect: 'Select',
190
+ hintClose: 'Close',
191
+ },
192
+ themeToggle: {
193
+ toggleAria: 'Toggle theme',
194
+ title: 'Theme',
195
+ light: 'Light',
196
+ dark: 'Dark',
197
+ system: 'System',
198
+ },
199
+ languageToggle: {
200
+ toggleAria: 'Change language',
201
+ title: 'Language',
202
+ },
203
+ themes: {
204
+ title: 'Themes',
205
+ noThemesTitle: 'No themes yet',
206
+ noThemesHintPrefix: 'Run ',
207
+ noThemesHintSuffix: ' to author one — a markdown file under themes/ plus a sibling demo page.',
208
+ noDemoYet: 'No demo yet',
209
+ noDemoHintPrefix: 'Re-run ',
210
+ noDemoHintSuffix: ' for this theme to generate a preview page.',
211
+ backToGallery: 'Back to themes',
212
+ openThemeAria: 'Open theme {name}',
213
+ usedBy: 'Pages using this theme',
214
+ usedByEmpty: 'No pages use this theme yet.',
215
+ expandPromptAria: 'Expand prompt',
216
+ collapsePromptAria: 'Collapse prompt',
217
+ },
218
+ };
@@ -0,0 +1,12 @@
1
+ import type { Plural } from './types';
2
+
3
+ export function format(template: string, vars: Record<string, string | number>): string {
4
+ return template.replace(/\{(\w+)\}/g, (m, key) => {
5
+ const v = vars[key];
6
+ return v === undefined ? m : String(v);
7
+ });
8
+ }
9
+
10
+ export function plural(count: number, forms: Plural): string {
11
+ return count === 1 ? forms.one : forms.other;
12
+ }
@@ -0,0 +1,6 @@
1
+ export { en } from './en';
2
+ export { format, plural } from './format';
3
+ export { ja } from './ja';
4
+ export type { Locale, Plural } from './types';
5
+ export { zhCN } from './zh-cn';
6
+ export { zhTW } from './zh-tw';