@usequark/quark-create-app 1.23.11

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 (237) hide show
  1. package/README.md +210 -0
  2. package/package.json +56 -0
  3. package/src/dependabot-config.test.js +128 -0
  4. package/src/deploy/adapters/iac.js +203 -0
  5. package/src/deploy/adapters/index.js +27 -0
  6. package/src/deploy/adapters/railway.js +508 -0
  7. package/src/deploy/adapters/railway.test.js +318 -0
  8. package/src/deploy/contract.js +59 -0
  9. package/src/deploy/deploy.integration.test.js +183 -0
  10. package/src/deploy/deploy.js +430 -0
  11. package/src/deploy/deploy.test.js +105 -0
  12. package/src/deploy/discovery.js +115 -0
  13. package/src/deploy/discovery.test.js +141 -0
  14. package/src/deploy/index.js +38 -0
  15. package/src/deploy/inspect.js +130 -0
  16. package/src/index.js +2920 -0
  17. package/src/mobile-template.test.js +232 -0
  18. package/src/prepare-hooks.test.js +535 -0
  19. package/src/scaffold-guards.test.js +140 -0
  20. package/src/scaffold-output.test.js +228 -0
  21. package/src/template-scripts.test.js +160 -0
  22. package/src/utils.js +77 -0
  23. package/src/utils.test.js +95 -0
  24. package/src/worker-dockerfile.test.js +85 -0
  25. package/templates/base-project/.cursor/rules/quark.mdc +172 -0
  26. package/templates/base-project/.dockerignore +14 -0
  27. package/templates/base-project/.env.railway.example +87 -0
  28. package/templates/base-project/.github/copilot-instructions.md +65 -0
  29. package/templates/base-project/.github/dependabot.yml +31 -0
  30. package/templates/base-project/.github/skills/project-context/SKILL.md +109 -0
  31. package/templates/base-project/.github/workflows/ci.yml +116 -0
  32. package/templates/base-project/.github/workflows/dependabot-auto-merge.yml +22 -0
  33. package/templates/base-project/.github/workflows/install-windows.yml +27 -0
  34. package/templates/base-project/.github/workflows/release.yml +67 -0
  35. package/templates/base-project/.railway/railway.ts +40 -0
  36. package/templates/base-project/CLAUDE.md +163 -0
  37. package/templates/base-project/MAIN.md +21 -0
  38. package/templates/base-project/README.md +164 -0
  39. package/templates/base-project/apps/web/.env.example +99 -0
  40. package/templates/base-project/apps/web/Dockerfile +38 -0
  41. package/templates/base-project/apps/web/biome.json +8 -0
  42. package/templates/base-project/apps/web/jsconfig.json +9 -0
  43. package/templates/base-project/apps/web/next.config.js +154 -0
  44. package/templates/base-project/apps/web/package.json +42 -0
  45. package/templates/base-project/apps/web/postcss.config.mjs +7 -0
  46. package/templates/base-project/apps/web/public/.well-known/security.txt +3 -0
  47. package/templates/base-project/apps/web/public/quark.svg +47 -0
  48. package/templates/base-project/apps/web/scripts/prepare-standalone.mjs +71 -0
  49. package/templates/base-project/apps/web/src/app/_components/AsciiPanel.js +103 -0
  50. package/templates/base-project/apps/web/src/app/_components/HealthIndicator.js +85 -0
  51. package/templates/base-project/apps/web/src/app/_components/HomeThemeToggle.js +63 -0
  52. package/templates/base-project/apps/web/src/app/_components/QuarkAnimation.js +168 -0
  53. package/templates/base-project/apps/web/src/app/_components/SyncedPanels.js +212 -0
  54. package/templates/base-project/apps/web/src/app/_components/UmamiReplayRecorder.js +198 -0
  55. package/templates/base-project/apps/web/src/app/_components/UmamiWebVitals.js +39 -0
  56. package/templates/base-project/apps/web/src/app/api/auth/[...nextauth]/route.js +7 -0
  57. package/templates/base-project/apps/web/src/app/api/auth/apple/route.js +82 -0
  58. package/templates/base-project/apps/web/src/app/api/auth/google/route.js +59 -0
  59. package/templates/base-project/apps/web/src/app/api/auth/refresh/route.js +48 -0
  60. package/templates/base-project/apps/web/src/app/api/auth/register/route.js +63 -0
  61. package/templates/base-project/apps/web/src/app/api/auth/token/route.js +44 -0
  62. package/templates/base-project/apps/web/src/app/api/csrf/route.js +40 -0
  63. package/templates/base-project/apps/web/src/app/api/device/register/route.js +57 -0
  64. package/templates/base-project/apps/web/src/app/api/error-handler.js +23 -0
  65. package/templates/base-project/apps/web/src/app/api/files/[id]/route.js +89 -0
  66. package/templates/base-project/apps/web/src/app/api/files/route.js +120 -0
  67. package/templates/base-project/apps/web/src/app/api/health/route.js +160 -0
  68. package/templates/base-project/apps/web/src/app/api/users/[id]/route.js +54 -0
  69. package/templates/base-project/apps/web/src/app/api/users/me/route.js +67 -0
  70. package/templates/base-project/apps/web/src/app/api/users/route.js +45 -0
  71. package/templates/base-project/apps/web/src/app/auth/error/page.js +83 -0
  72. package/templates/base-project/apps/web/src/app/auth/forgot-password/page.js +58 -0
  73. package/templates/base-project/apps/web/src/app/auth/provider-loading.js +25 -0
  74. package/templates/base-project/apps/web/src/app/auth/register/RegisterPageClient.js +340 -0
  75. package/templates/base-project/apps/web/src/app/auth/register/page.js +17 -0
  76. package/templates/base-project/apps/web/src/app/auth/signin/SignInPageClient.js +230 -0
  77. package/templates/base-project/apps/web/src/app/auth/signin/page.js +10 -0
  78. package/templates/base-project/apps/web/src/app/favicon.ico +0 -0
  79. package/templates/base-project/apps/web/src/app/global-error.js +58 -0
  80. package/templates/base-project/apps/web/src/app/globals.css +1166 -0
  81. package/templates/base-project/apps/web/src/app/icon.svg +47 -0
  82. package/templates/base-project/apps/web/src/app/layout.js +57 -0
  83. package/templates/base-project/apps/web/src/app/manifest.js +12 -0
  84. package/templates/base-project/apps/web/src/app/not-found.js +39 -0
  85. package/templates/base-project/apps/web/src/app/page.js +262 -0
  86. package/templates/base-project/apps/web/src/app/robots.js +23 -0
  87. package/templates/base-project/apps/web/src/app/sitemap.js +14 -0
  88. package/templates/base-project/apps/web/src/lib/analytics/umami-before-send.js +29 -0
  89. package/templates/base-project/apps/web/src/lib/analytics/umami-config.js +95 -0
  90. package/templates/base-project/apps/web/src/lib/analytics/umami-csp.js +24 -0
  91. package/templates/base-project/apps/web/src/lib/analytics/umami-marketing.js +131 -0
  92. package/templates/base-project/apps/web/src/lib/analytics/umami-replay.js +204 -0
  93. package/templates/base-project/apps/web/src/lib/analytics/umami-web-vitals.js +237 -0
  94. package/templates/base-project/apps/web/src/lib/analytics/umami.js +57 -0
  95. package/templates/base-project/apps/web/src/lib/auth-middleware.js +82 -0
  96. package/templates/base-project/apps/web/src/lib/auth-signup.js +5 -0
  97. package/templates/base-project/apps/web/src/lib/auth.js +191 -0
  98. package/templates/base-project/apps/web/src/lib/csrf-cookie.js +11 -0
  99. package/templates/base-project/apps/web/src/lib/jwt.js +84 -0
  100. package/templates/base-project/apps/web/src/lib/load-crm-config.js +35 -0
  101. package/templates/base-project/apps/web/src/lib/normalize-auth-request.js +33 -0
  102. package/templates/base-project/apps/web/src/lib/proxy-auth.js +80 -0
  103. package/templates/base-project/apps/web/src/lib/seo/indexing.js +25 -0
  104. package/templates/base-project/apps/web/src/lib/seo/site-metadata.js +74 -0
  105. package/templates/base-project/apps/web/src/lib/sitemap-entries.js +22 -0
  106. package/templates/base-project/apps/web/src/preflight.js +55 -0
  107. package/templates/base-project/apps/web/src/proxy.js +328 -0
  108. package/templates/base-project/biome.json +52 -0
  109. package/templates/base-project/docker-compose.override.yml +17 -0
  110. package/templates/base-project/docker-compose.yml +37 -0
  111. package/templates/base-project/docs/FIRST_FEATURE.md +74 -0
  112. package/templates/base-project/docs/START_HERE.md +70 -0
  113. package/templates/base-project/docs/adr/README.md +42 -0
  114. package/templates/base-project/package.json +58 -0
  115. package/templates/base-project/packages/db/package.json +38 -0
  116. package/templates/base-project/packages/db/prisma/migrations/20260202061128_initial/migration.sql +202 -0
  117. package/templates/base-project/packages/db/prisma/migrations/migration_lock.toml +3 -0
  118. package/templates/base-project/packages/db/prisma/schema.prisma +161 -0
  119. package/templates/base-project/packages/db/prisma/seed.js +152 -0
  120. package/templates/base-project/packages/db/prisma.config.js +27 -0
  121. package/templates/base-project/packages/db/src/client.js +75 -0
  122. package/templates/base-project/packages/db/src/connection.js +44 -0
  123. package/templates/base-project/packages/db/src/context.js +275 -0
  124. package/templates/base-project/packages/db/src/index.js +5 -0
  125. package/templates/base-project/packages/db/src/ping.js +66 -0
  126. package/templates/base-project/packages/db/src/queries.js +292 -0
  127. package/templates/base-project/packages/db/src/schemas.js +30 -0
  128. package/templates/base-project/packages/db/src/umami.js +299 -0
  129. package/templates/base-project/pnpm-workspace.yaml +20 -0
  130. package/templates/base-project/scripts/check-loading.mjs +49 -0
  131. package/templates/base-project/scripts/check-standards.mjs +186 -0
  132. package/templates/base-project/scripts/clean-workspace.mjs +479 -0
  133. package/templates/base-project/scripts/dev-preflight.mjs +48 -0
  134. package/templates/base-project/scripts/doctor.js +408 -0
  135. package/templates/base-project/scripts/prepare.js +490 -0
  136. package/templates/base-project/scripts/run-tests.mjs +71 -0
  137. package/templates/base-project/skills/add-dashboard/SKILL.md +28 -0
  138. package/templates/base-project/skills/add-endpoint/SKILL.md +29 -0
  139. package/templates/base-project/skills/add-model/SKILL.md +28 -0
  140. package/templates/base-project/skills/ecommerce/SKILL.md +224 -0
  141. package/templates/base-project/skills/ecommerce-cart/SKILL.md +193 -0
  142. package/templates/base-project/skills/ecommerce-catalog/SKILL.md +179 -0
  143. package/templates/base-project/skills/ecommerce-checkout/SKILL.md +195 -0
  144. package/templates/base-project/skills/i18n/SKILL.md +211 -0
  145. package/templates/base-project/skills/payment/SKILL.md +280 -0
  146. package/templates/base-project/skills/quark-skills/SKILL.md +37 -0
  147. package/templates/base-project/turbo.json +143 -0
  148. package/templates/config/package.json +20 -0
  149. package/templates/config/src/app-url.js +134 -0
  150. package/templates/config/src/environment.js +284 -0
  151. package/templates/config/src/index.js +16 -0
  152. package/templates/config/src/load-config.js +157 -0
  153. package/templates/config/src/rate-limit.js +136 -0
  154. package/templates/config/src/redis.js +43 -0
  155. package/templates/config/src/validate-env.js +532 -0
  156. package/templates/jobs/README.md +52 -0
  157. package/templates/jobs/package.json +9 -0
  158. package/templates/jobs/src/definitions.js +13 -0
  159. package/templates/jobs/src/index.js +1 -0
  160. package/templates/mobile/.env.example +16 -0
  161. package/templates/mobile/CHECKLIST.md +40 -0
  162. package/templates/mobile/README.md +130 -0
  163. package/templates/mobile/app/(app)/_layout.tsx +83 -0
  164. package/templates/mobile/app/(app)/index.tsx +147 -0
  165. package/templates/mobile/app/(app)/profile.tsx +204 -0
  166. package/templates/mobile/app/(app)/settings.tsx +80 -0
  167. package/templates/mobile/app/(auth)/_layout.tsx +10 -0
  168. package/templates/mobile/app/(auth)/sign-in.tsx +140 -0
  169. package/templates/mobile/app/(auth)/sign-up.tsx +178 -0
  170. package/templates/mobile/app/+not-found.tsx +32 -0
  171. package/templates/mobile/app/_layout.tsx +18 -0
  172. package/templates/mobile/app.json +47 -0
  173. package/templates/mobile/assets/adaptive-icon.png +0 -0
  174. package/templates/mobile/assets/icon.png +0 -0
  175. package/templates/mobile/assets/notification-icon.png +0 -0
  176. package/templates/mobile/assets/splash.png +0 -0
  177. package/templates/mobile/biome.json +27 -0
  178. package/templates/mobile/components/AuthGate.tsx +19 -0
  179. package/templates/mobile/components/ThemeProvider.tsx +23 -0
  180. package/templates/mobile/eas.json +29 -0
  181. package/templates/mobile/hooks/use-auth.ts +127 -0
  182. package/templates/mobile/lib/api-client.ts +138 -0
  183. package/templates/mobile/lib/api.ts +83 -0
  184. package/templates/mobile/lib/auth-providers-google.ts +74 -0
  185. package/templates/mobile/lib/auth-providers.ts +74 -0
  186. package/templates/mobile/lib/auth.ts +100 -0
  187. package/templates/mobile/lib/config.ts +14 -0
  188. package/templates/mobile/lib/errors.ts +46 -0
  189. package/templates/mobile/lib/notifications.ts +77 -0
  190. package/templates/mobile/lib/storage.ts +25 -0
  191. package/templates/mobile/lib/theme-tokens.ts +16 -0
  192. package/templates/mobile/package.json +37 -0
  193. package/templates/mobile/tsconfig.json +10 -0
  194. package/templates/pwa/app/_components/PWARegister.js +15 -0
  195. package/templates/pwa/app/manifest.js +32 -0
  196. package/templates/pwa/public/sw.js +72 -0
  197. package/templates/ui/README.md +44 -0
  198. package/templates/ui/package.json +21 -0
  199. package/templates/ui/src/badge.js +23 -0
  200. package/templates/ui/src/button.js +111 -0
  201. package/templates/ui/src/card.js +128 -0
  202. package/templates/ui/src/checkbox.js +20 -0
  203. package/templates/ui/src/container.js +13 -0
  204. package/templates/ui/src/dialog.js +137 -0
  205. package/templates/ui/src/error-banner.js +15 -0
  206. package/templates/ui/src/footer.js +239 -0
  207. package/templates/ui/src/form-field.integration-test.js +142 -0
  208. package/templates/ui/src/form-field.js +50 -0
  209. package/templates/ui/src/index.js +24 -0
  210. package/templates/ui/src/input.js +11 -0
  211. package/templates/ui/src/label.js +14 -0
  212. package/templates/ui/src/lightbox.integration-test.js +167 -0
  213. package/templates/ui/src/lightbox.js +243 -0
  214. package/templates/ui/src/logo.js +52 -0
  215. package/templates/ui/src/navbar.js +602 -0
  216. package/templates/ui/src/password-input.js +31 -0
  217. package/templates/ui/src/rich-text.js +514 -0
  218. package/templates/ui/src/select.js +317 -0
  219. package/templates/ui/src/skeleton.js +10 -0
  220. package/templates/ui/src/spinner.js +31 -0
  221. package/templates/ui/src/table.js +169 -0
  222. package/templates/ui/src/textarea.js +11 -0
  223. package/templates/ui/src/theme-constants.js +24 -0
  224. package/templates/ui/src/theme.js +196 -0
  225. package/templates/ui/src/toast.js +206 -0
  226. package/templates/worker/Dockerfile +64 -0
  227. package/templates/worker/README.md +56 -0
  228. package/templates/worker/package.json +36 -0
  229. package/templates/worker/src/config/pricing.js +46 -0
  230. package/templates/worker/src/handlers/email-job-validation.js +36 -0
  231. package/templates/worker/src/handlers/email.js +98 -0
  232. package/templates/worker/src/handlers/files.js +59 -0
  233. package/templates/worker/src/handlers/index.js +20 -0
  234. package/templates/worker/src/handlers/push-notification.js +234 -0
  235. package/templates/worker/src/index.js +505 -0
  236. package/templates/worker/src/lib/railway.js +438 -0
  237. package/templates/worker/src/lib/tokens.js +81 -0
@@ -0,0 +1,230 @@
1
+ "use client";
2
+
3
+ import {
4
+ Button,
5
+ ErrorBanner,
6
+ Input,
7
+ Label,
8
+ PasswordInput,
9
+ QuarkLogo,
10
+ } from "@techstream/quark-ui";
11
+ import Link from "next/link";
12
+ import { useSearchParams } from "next/navigation";
13
+ import { signIn } from "next-auth/react";
14
+ import { Suspense, useEffect, useState } from "react";
15
+ import { loadAuthProviders } from "../provider-loading";
16
+
17
+ const ERROR_MESSAGES = {
18
+ CredentialsSignin: "Invalid email or password.",
19
+ CallbackRouteError: "Sign in failed. Check your connection and try again.",
20
+ OAuthAccountNotLinked:
21
+ "This email is already registered with a different provider.",
22
+ OAuthSignin: "Could not start the sign-in flow. Try again.",
23
+ OAuthCallback: "Authentication callback failed. Try again.",
24
+ Default: "An unexpected error occurred. Try again.",
25
+ Unauthorized: "You must sign in to access that page.",
26
+ };
27
+
28
+ export default function SignInPageClient({ allowSignup }) {
29
+ return (
30
+ <Suspense>
31
+ <SignInForm allowSignup={allowSignup} />
32
+ </Suspense>
33
+ );
34
+ }
35
+
36
+ function SignInForm({ allowSignup }) {
37
+ const searchParams = useSearchParams();
38
+ const callbackUrl = searchParams.get("callbackUrl") || "/";
39
+ const errorCode = searchParams.get("error");
40
+
41
+ const [email, setEmail] = useState("");
42
+ const [password, setPassword] = useState("");
43
+ const [loading, setLoading] = useState(false);
44
+ const [providers, setProviders] = useState(null);
45
+ const [providerError, setProviderError] = useState("");
46
+ const [error, setError] = useState(
47
+ errorCode ? (ERROR_MESSAGES[errorCode] ?? ERROR_MESSAGES.Default) : "",
48
+ );
49
+
50
+ useEffect(() => {
51
+ let cancelled = false;
52
+
53
+ void loadAuthProviders().then(({ providers: loadedProviders, error }) => {
54
+ if (cancelled) {
55
+ return;
56
+ }
57
+
58
+ setProviders(loadedProviders);
59
+ setProviderError(error);
60
+ });
61
+
62
+ return () => {
63
+ cancelled = true;
64
+ };
65
+ }, []);
66
+
67
+ async function handleSubmit(e) {
68
+ e.preventDefault();
69
+ setError("");
70
+ setLoading(true);
71
+
72
+ const result = await signIn("credentials", {
73
+ email: email.trim(),
74
+ password,
75
+ callbackUrl,
76
+ redirect: false,
77
+ });
78
+
79
+ if (result?.error) {
80
+ setError(ERROR_MESSAGES[result.error] ?? ERROR_MESSAGES.Default);
81
+ setLoading(false);
82
+ return;
83
+ }
84
+
85
+ if (!result?.url) {
86
+ setError(ERROR_MESSAGES.Default);
87
+ setLoading(false);
88
+ return;
89
+ }
90
+
91
+ window.location.href = result.url;
92
+ }
93
+
94
+ function handleOAuth(provider) {
95
+ signIn(provider, { callbackUrl });
96
+ }
97
+
98
+ return (
99
+ <div className="quark-auth-layout">
100
+ <div className="quark-auth-brand">
101
+ <Link href="/" aria-label="Go to home">
102
+ <QuarkLogo size={64} className="mb-8" />
103
+ </Link>
104
+ <p className="text-xs uppercase tracking-widest text-text-faint mb-3">
105
+ Welcome back
106
+ </p>
107
+ <h2 className="text-3xl font-bold text-text leading-tight mb-4">
108
+ Your work is waiting.
109
+ </h2>
110
+ <p className="text-sm text-text-muted leading-relaxed">
111
+ Authenticate to access your workspace.
112
+ </p>
113
+ </div>
114
+
115
+ <div className="quark-auth-form">
116
+ <div className="flex md:hidden mb-8">
117
+ <Link href="/" aria-label="Go to home">
118
+ <QuarkLogo size={44} />
119
+ </Link>
120
+ </div>
121
+
122
+ <div className="quark-auth-panel w-full max-w-sm">
123
+ <div className="mb-8">
124
+ <h1 className="text-2xl font-bold tracking-tight text-text">
125
+ Sign in
126
+ </h1>
127
+ <p className="text-xs uppercase tracking-widest text-text-muted mt-2">
128
+ Enter your email and password.
129
+ </p>
130
+ </div>
131
+
132
+ <ErrorBanner message={error} />
133
+
134
+ <form onSubmit={handleSubmit} className="space-y-5">
135
+ <div className="space-y-2">
136
+ <Label htmlFor="email">Email</Label>
137
+ <Input
138
+ id="email"
139
+ type="email"
140
+ autoComplete="email"
141
+ required
142
+ value={email}
143
+ onChange={(e) => setEmail(e.target.value)}
144
+ />
145
+ </div>
146
+
147
+ <div className="space-y-2">
148
+ <div className="flex items-center justify-between">
149
+ <Label htmlFor="password">Password</Label>
150
+ <Link
151
+ href="/auth/forgot-password"
152
+ className="text-xs text-primary hover:opacity-75 transition-opacity duration-200 linear uppercase tracking-widest"
153
+ >
154
+ Forgot?
155
+ </Link>
156
+ </div>
157
+ <PasswordInput
158
+ id="password"
159
+ autoComplete="current-password"
160
+ required
161
+ value={password}
162
+ onChange={(e) => setPassword(e.target.value)}
163
+ />
164
+ </div>
165
+
166
+ <Button
167
+ type="submit"
168
+ variant="primary"
169
+ className="w-full mt-2"
170
+ disabled={loading}
171
+ >
172
+ {loading ? "Signing in…" : "Continue →"}
173
+ </Button>
174
+ </form>
175
+
176
+ {providerError ? (
177
+ <p className="mt-4 text-xs uppercase tracking-widest text-text-muted">
178
+ {providerError}
179
+ </p>
180
+ ) : null}
181
+
182
+ {providers?.github || providers?.google ? (
183
+ <>
184
+ <div className="mt-6 flex items-center gap-3">
185
+ <hr className="flex-1 border-border" />
186
+ <span className="text-xs text-text-muted uppercase tracking-widest">
187
+ or
188
+ </span>
189
+ <hr className="flex-1 border-border" />
190
+ </div>
191
+
192
+ <div className="mt-4 flex flex-col gap-2">
193
+ {providers.github && (
194
+ <Button
195
+ variant="secondary"
196
+ className="w-full"
197
+ onClick={() => handleOAuth("github")}
198
+ >
199
+ Continue with GitHub
200
+ </Button>
201
+ )}
202
+ {providers.google && (
203
+ <Button
204
+ variant="secondary"
205
+ className="w-full"
206
+ onClick={() => handleOAuth("google")}
207
+ >
208
+ Continue with Google
209
+ </Button>
210
+ )}
211
+ </div>
212
+ </>
213
+ ) : null}
214
+
215
+ {allowSignup ? (
216
+ <p className="mt-8 text-xs text-text-muted uppercase tracking-widest">
217
+ No account?{" "}
218
+ <Link
219
+ href="/auth/register"
220
+ className="text-primary hover:opacity-75 transition-opacity duration-200 linear"
221
+ >
222
+ Sign up
223
+ </Link>
224
+ </p>
225
+ ) : null}
226
+ </div>
227
+ </div>
228
+ </div>
229
+ );
230
+ }
@@ -0,0 +1,10 @@
1
+ import { isSignupEnabled } from "@/lib/auth-signup";
2
+ import SignInPageClient from "./SignInPageClient";
3
+
4
+ export const metadata = {
5
+ title: "Sign In",
6
+ };
7
+
8
+ export default function SignInPage() {
9
+ return <SignInPageClient allowSignup={isSignupEnabled()} />;
10
+ }
@@ -0,0 +1,58 @@
1
+ "use client";
2
+
3
+ import Link from "next/link";
4
+
5
+ export default function GlobalError({ reset }) {
6
+ return (
7
+ <html lang="en">
8
+ <body style={{ margin: 0, background: "var(--color-bg, #05070a)" }}>
9
+ <main
10
+ className="fixed inset-0 flex flex-col items-center justify-center"
11
+ style={{ background: "var(--color-bg, #05070a)" }}
12
+ >
13
+ <p
14
+ className="font-mono uppercase"
15
+ style={{
16
+ color: "var(--color-text-faint, #3a3a4a)",
17
+ fontSize: "11px",
18
+ letterSpacing: "0.15em",
19
+ }}
20
+ >
21
+ 500
22
+ </p>
23
+ <p
24
+ className="font-mono mt-2"
25
+ style={{
26
+ color: "var(--color-text-faint, #2a2a3a)",
27
+ fontSize: "11px",
28
+ }}
29
+ >
30
+ something went wrong
31
+ </p>
32
+ <nav
33
+ className="mt-6 flex items-center gap-2"
34
+ style={{ fontSize: "11px", fontFamily: "monospace" }}
35
+ >
36
+ <button
37
+ type="button"
38
+ onClick={reset}
39
+ className="quark-home-link"
40
+ style={{
41
+ background: "none",
42
+ border: "none",
43
+ padding: 0,
44
+ cursor: "pointer",
45
+ }}
46
+ >
47
+ try again
48
+ </button>
49
+ <span style={{ color: "var(--color-text-faint, #2a2a3a)" }}>·</span>
50
+ <Link href="/" className="quark-home-link">
51
+ ← home
52
+ </Link>
53
+ </nav>
54
+ </main>
55
+ </body>
56
+ </html>
57
+ );
58
+ }