create-openfort 0.1.8 → 0.1.10

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 (50) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/index.js +16 -16
  3. package/package.json +1 -1
  4. package/template/backend/package.json +7 -1
  5. package/template/backend/pnpm-lock.yaml +187 -33
  6. package/template/backend/src/app.ts +1 -1
  7. package/template/openfort-templates/firebase/biome.json +3 -3
  8. package/template/openfort-templates/firebase/package.json +1 -1
  9. package/template/openfort-templates/firebase/src/App.tsx +10 -10
  10. package/template/openfort-templates/firebase/src/components/cards/head.tsx +157 -145
  11. package/template/openfort-templates/firebase/src/components/cards/main.tsx +63 -52
  12. package/template/openfort-templates/firebase/src/components/ui/Sheet.tsx +14 -16
  13. package/template/openfort-templates/firebase/src/components/ui/Tabs.tsx +46 -36
  14. package/template/openfort-templates/firebase/src/components/ui/TruncateData.tsx +14 -8
  15. package/template/openfort-templates/firebase/src/integrations/firebase/client.ts +6 -6
  16. package/template/openfort-templates/firebase/src/integrations/firebase/components/FirebaseAuthCard.tsx +74 -46
  17. package/template/openfort-templates/firebase/src/integrations/firebase/errors.ts +57 -37
  18. package/template/openfort-templates/firebase/src/integrations/firebase/index.ts +3 -3
  19. package/template/openfort-templates/firebase/src/integrations/openfort/index.ts +1 -1
  20. package/template/openfort-templates/firebase/src/integrations/openfort/providers.tsx +23 -11
  21. package/template/openfort-templates/firebase/src/ui/openfort/blockchain/ActionsCard.tsx +47 -35
  22. package/template/openfort-templates/firebase/src/ui/openfort/blockchain/SignCard.tsx +30 -28
  23. package/template/openfort-templates/firebase/src/ui/openfort/index.ts +4 -6
  24. package/template/openfort-templates/firebase/src/ui/openfort/profile/UserProfileCard.tsx +32 -20
  25. package/template/openfort-templates/firebase/src/ui/openfort/wallets/WalletCreation.tsx +51 -27
  26. package/template/openfort-templates/firebase/src/ui/openfort/wallets/WalletListCard.tsx +66 -40
  27. package/template/openfort-templates/firebase/src/ui/openfort/wallets/WalletPasswordSheets.tsx +65 -41
  28. package/template/openfort-templates/firebase/vite.config.ts +3 -3
  29. package/template/openfort-templates/headless/biome.json +3 -3
  30. package/template/openfort-templates/headless/package.json +1 -1
  31. package/template/openfort-templates/headless/src/components/cards/auth.tsx +2 -2
  32. package/template/openfort-templates/headless/src/components/cards/profile.tsx +1 -3
  33. package/template/openfort-templates/headless/src/components/providers.tsx +4 -1
  34. package/template/openfort-templates/headless/src/index.css +10 -4
  35. package/template/openfort-templates/openfort-ui/biome.json +3 -3
  36. package/template/openfort-templates/openfort-ui/package.json +1 -1
  37. package/template/openfort-templates/openfort-ui/src/App.tsx +1 -3
  38. package/template/openfort-templates/openfort-ui/src/components/cards/auth.tsx +9 -11
  39. package/template/openfort-templates/openfort-ui/src/components/cards/head.tsx +157 -145
  40. package/template/openfort-templates/openfort-ui/src/components/cards/main.tsx +50 -41
  41. package/template/openfort-templates/openfort-ui/src/components/cards/profile.tsx +29 -35
  42. package/template/openfort-templates/openfort-ui/src/components/cards/sign.tsx +35 -49
  43. package/template/openfort-templates/openfort-ui/src/components/cards/wallets.tsx +51 -37
  44. package/template/openfort-templates/openfort-ui/src/components/createWallet.tsx +63 -30
  45. package/template/openfort-templates/openfort-ui/src/components/passwordRecovery.tsx +61 -56
  46. package/template/openfort-templates/openfort-ui/src/components/providers.tsx +14 -15
  47. package/template/openfort-templates/openfort-ui/src/components/ui/Sheet.tsx +14 -16
  48. package/template/openfort-templates/openfort-ui/src/components/ui/Tabs.tsx +46 -36
  49. package/template/openfort-templates/openfort-ui/src/components/ui/TruncateData.tsx +14 -8
  50. package/template/openfort-templates/openfort-ui/vite.config.ts +2 -2
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.2.6/schema.json",
2
+ "$schema": "https://biomejs.dev/schemas/2.3.8/schema.json",
3
3
  "root": true,
4
4
  "vcs": {
5
5
  "enabled": true,
@@ -7,7 +7,8 @@
7
7
  "useIgnoreFile": true
8
8
  },
9
9
  "files": {
10
- "ignoreUnknown": true
10
+ "ignoreUnknown": true,
11
+ "includes": ["**/*.tsx", "**/*.ts", "**/*.jsx", "**/*.js"]
11
12
  },
12
13
  "formatter": {
13
14
  "enabled": true,
@@ -49,7 +50,6 @@
49
50
  },
50
51
  "overrides": [
51
52
  {
52
- "includes": ["**/*.tsx", "**/*.ts", "**/*.jsx", "**/*.js"],
53
53
  "linter": {
54
54
  "rules": {
55
55
  "correctness": {
@@ -21,7 +21,7 @@
21
21
  "wagmi": "^2.18.2"
22
22
  },
23
23
  "devDependencies": {
24
- "@biomejs/biome": "^2.2.6",
24
+ "@biomejs/biome": "^2.3.8",
25
25
  "@types/react": "^19.1.10",
26
26
  "@tailwindcss/vite": "^4.1.15",
27
27
  "tailwindcss": "^4.1.15",
@@ -1,23 +1,23 @@
1
+ import { useSignOut, useUser } from '@openfort/react'
1
2
  import { useEffect } from 'react'
2
3
  import { Main } from './components/cards/main'
3
4
  import { auth } from './integrations/firebase'
4
- import { useSignOut, useUser } from '@openfort/react'
5
5
 
6
6
  function App() {
7
- const { getAccessToken } = useUser();
8
- const { signOut } = useSignOut();
7
+ const { getAccessToken } = useUser()
8
+ const { signOut } = useSignOut()
9
9
 
10
10
  useEffect(() => {
11
- auth.onAuthStateChanged(user => {
12
- console.log("onAuthStateChanged");
11
+ auth.onAuthStateChanged((user) => {
12
+ console.log('onAuthStateChanged')
13
13
  if (user) {
14
- console.log("onAuthStateChanged - User is signed in:", user);
15
- getAccessToken();
14
+ console.log('onAuthStateChanged - User is signed in:', user)
15
+ getAccessToken()
16
16
  } else {
17
- console.log("onAuthStateChanged - No user is signed in");
18
- signOut();
17
+ console.log('onAuthStateChanged - No user is signed in')
18
+ signOut()
19
19
  }
20
- });
20
+ })
21
21
  }, [])
22
22
 
23
23
  return (
@@ -1,68 +1,75 @@
1
- import { useEffect, useMemo, useRef, useState } from "react";
1
+ import { useEffect, useMemo, useRef, useState } from 'react'
2
2
 
3
3
  type RoutePoint = {
4
- x: number;
5
- y: number;
6
- delay: number;
7
- };
4
+ x: number
5
+ y: number
6
+ delay: number
7
+ }
8
8
 
9
9
  type Route = {
10
- start: RoutePoint;
11
- end: RoutePoint;
12
- color: string;
13
- outDelay?: number;
14
- };
10
+ start: RoutePoint
11
+ end: RoutePoint
12
+ color: string
13
+ outDelay?: number
14
+ }
15
15
 
16
16
  function withOpacity(color: string, opacity: number) {
17
- if (color.startsWith("rgb")) {
18
- const nums = color.match(/[\d.]+/g)?.map(Number);
19
- if (!nums || nums.length < 3) throw new Error("Invalid rgb format");
20
- const [r, g, b] = nums;
21
- return `rgba(${r}, ${g}, ${b}, ${opacity})`;
17
+ if (color.startsWith('rgb')) {
18
+ const nums = color.match(/[\d.]+/g)?.map(Number)
19
+ if (!nums || nums.length < 3) throw new Error('Invalid rgb format')
20
+ const [r, g, b] = nums
21
+ return `rgba(${r}, ${g}, ${b}, ${opacity})`
22
22
  }
23
23
 
24
- throw new Error("Unsupported color format: " + color);
24
+ throw new Error(`Unsupported color format: ${color}`)
25
25
  }
26
26
 
27
- const GlowCanvas = ({ accentColor, backgroundColor }: { accentColor: string, backgroundColor: string }) => {
28
- const canvasRef = useRef<HTMLCanvasElement | null>(null);
29
- const mousePosRef = useRef<{ x: number; y: number } | null>(null);
30
- const animationRef = useRef<number | null>(null);
27
+ const GlowCanvas = ({
28
+ accentColor,
29
+ backgroundColor,
30
+ }: {
31
+ accentColor: string
32
+ backgroundColor: string
33
+ }) => {
34
+ const canvasRef = useRef<HTMLCanvasElement | null>(null)
35
+ const mousePosRef = useRef<{ x: number; y: number } | null>(null)
36
+ const animationRef = useRef<number | null>(null)
31
37
 
32
- const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
38
+ const [dimensions, setDimensions] = useState({ width: 0, height: 0 })
33
39
 
34
- const color = useMemo(() => withOpacity(accentColor, 0.7), [accentColor]);
40
+ const color = useMemo(() => withOpacity(accentColor, 0.7), [accentColor])
35
41
 
36
42
  useEffect(() => {
37
- const canvas = canvasRef.current;
38
- if (!canvas) return;
43
+ const canvas = canvasRef.current
44
+ if (!canvas) return
39
45
 
40
- const resizeObserver = new ResizeObserver(entries => {
41
- const { width, height } = entries[0].contentRect;
42
- setDimensions({ width, height });
43
- canvas.width = width;
44
- canvas.height = height;
45
- });
46
+ const resizeObserver = new ResizeObserver((entries) => {
47
+ const { width, height } = entries[0].contentRect
48
+ setDimensions({ width, height })
49
+ canvas.width = width
50
+ canvas.height = height
51
+ })
46
52
 
47
- resizeObserver.observe(canvas.parentElement as Element);
48
- return () => resizeObserver.disconnect();
49
- }, []);
53
+ resizeObserver.observe(canvas.parentElement as Element)
54
+ return () => resizeObserver.disconnect()
55
+ }, [])
50
56
 
51
57
  useEffect(() => {
52
- if (!dimensions.width || !dimensions.height) return;
58
+ if (!dimensions.width || !dimensions.height) return
53
59
 
54
- let startTime = Date.now();
60
+ let startTime = Date.now()
55
61
 
56
- const canvas = canvasRef.current;
57
- if (!canvas) return;
58
- const ctx = canvas.getContext("2d");
59
- if (!ctx) return;
62
+ const canvas = canvasRef.current
63
+ if (!canvas) return
64
+ const ctx = canvas.getContext('2d')
65
+ if (!ctx) return
60
66
 
61
- const gap = 14;
62
- const dotRadius = 1.5;
67
+ const gap = 14
68
+ const dotRadius = 1.5
63
69
 
64
70
  const generateDots = (width: number, height: number) => {
65
- const dots: { x: number; y: number; radius: number; opacity: number }[] = [];
71
+ const dots: { x: number; y: number; radius: number; opacity: number }[] =
72
+ []
66
73
 
67
74
  for (let x = 0; x < width; x += gap) {
68
75
  for (let y = 0; y < height; y += gap) {
@@ -72,62 +79,63 @@ const GlowCanvas = ({ accentColor, backgroundColor }: { accentColor: string, bac
72
79
  y,
73
80
  radius: dotRadius,
74
81
  opacity: Math.random() * 0.4 + 0.1,
75
- });
82
+ })
76
83
  }
77
84
  }
78
85
  }
79
- return dots;
80
- };
81
- const dots = generateDots(dimensions.width, dimensions.height);
86
+ return dots
87
+ }
88
+ const dots = generateDots(dimensions.width, dimensions.height)
82
89
 
83
90
  const draw = () => {
84
- ctx.clearRect(0, 0, dimensions.width, dimensions.height);
91
+ ctx.clearRect(0, 0, dimensions.width, dimensions.height)
85
92
 
86
93
  if (mousePosRef.current) {
87
- const { x, y } = mousePosRef.current;
94
+ const { x, y } = mousePosRef.current
88
95
 
89
- ctx.shadowBlur = 25;
90
- ctx.shadowColor = backgroundColor;
96
+ ctx.shadowBlur = 25
97
+ ctx.shadowColor = backgroundColor
91
98
 
92
- dots.forEach(dot => {
93
- const dx = dot.x - x;
94
- const dy = dot.y - y;
95
- const distance = Math.sqrt(dx * dx + dy * dy);
99
+ dots.forEach((dot) => {
100
+ const dx = dot.x - x
101
+ const dy = dot.y - y
102
+ const distance = Math.sqrt(dx * dx + dy * dy)
96
103
 
97
- ctx.beginPath();
98
- ctx.arc(dot.x, dot.y, dot.radius, 0, Math.PI * 2);
104
+ ctx.beginPath()
105
+ ctx.arc(dot.x, dot.y, dot.radius, 0, Math.PI * 2)
99
106
 
100
- const opacityFactor = 1 - distance / 100;
107
+ const opacityFactor = 1 - distance / 100
101
108
 
102
- ctx.fillStyle = withOpacity(accentColor, opacityFactor);
103
- ctx.fill();
104
- });
109
+ ctx.fillStyle = withOpacity(accentColor, opacityFactor)
110
+ ctx.fill()
111
+ })
105
112
  }
106
113
 
107
114
  // Draw the dots
108
- dots.forEach(dot => {
109
- ctx.beginPath();
110
- ctx.arc(dot.x, dot.y, dot.radius, 0, Math.PI * 2);
111
- ctx.fillStyle = withOpacity(backgroundColor, dot.opacity);
112
- ctx.fill();
113
- });
114
-
115
- drawRoutes();
115
+ dots.forEach((dot) => {
116
+ ctx.beginPath()
117
+ ctx.arc(dot.x, dot.y, dot.radius, 0, Math.PI * 2)
118
+ ctx.fillStyle = withOpacity(backgroundColor, dot.opacity)
119
+ ctx.fill()
120
+ })
121
+
122
+ drawRoutes()
116
123
  // If all routes are complete, restart the animation
117
- const currentTime = (Date.now() - startTime) / 1000;
118
- if (currentTime > 25) { // Reset after 15 seconds
119
- startTime = Date.now();
124
+ const currentTime = (Date.now() - startTime) / 1000
125
+ if (currentTime > 25) {
126
+ // Reset after 15 seconds
127
+ startTime = Date.now()
120
128
  }
121
129
 
122
- animationRef.current = requestAnimationFrame(draw);
123
- };
130
+ animationRef.current = requestAnimationFrame(draw)
131
+ }
124
132
 
125
133
  // Set up routes that will animate across the map
126
- const yOffset = 50;
127
- const scale = 12;
128
- const h = 11 * scale;
129
- const w = 18 * scale;
130
- const xOffset = (dimensions.width - w) / 2;
134
+ const yOffset = 50
135
+ const scale = 12
136
+ const h = 11 * scale
137
+ const w = 18 * scale
138
+ const xOffset = (dimensions.width - w) / 2
131
139
 
132
140
  const routes: Route[] = [
133
141
  {
@@ -156,26 +164,25 @@ const GlowCanvas = ({ accentColor, backgroundColor }: { accentColor: string, bac
156
164
  outDelay: 10,
157
165
  },
158
166
  {
159
- start: { x: xOffset + 3 * w / 4, y: yOffset + h / 3, delay: 2 },
167
+ start: { x: xOffset + (3 * w) / 4, y: yOffset + h / 3, delay: 2 },
160
168
  end: { x: xOffset + w / 4, y: yOffset + h / 3, delay: 4 },
161
169
  color,
162
170
  outDelay: 10,
163
171
  },
164
172
  {
165
- start: { x: xOffset + 3 * w / 4, y: yOffset + h, delay: 0 },
166
- end: { x: xOffset + 3 * w / 4, y: yOffset + h / 3, delay: 2 },
173
+ start: { x: xOffset + (3 * w) / 4, y: yOffset + h, delay: 0 },
174
+ end: { x: xOffset + (3 * w) / 4, y: yOffset + h / 3, delay: 2 },
167
175
  color,
168
176
  outDelay: 10,
169
177
  },
170
178
 
171
179
  {
172
- start: { x: xOffset + 2 * w / 4, y: yOffset + h, delay: 6 },
173
- end: { x: xOffset + 2 * w / 4, y: yOffset + 2 * h / 3, delay: 7 },
180
+ start: { x: xOffset + (2 * w) / 4, y: yOffset + h, delay: 6 },
181
+ end: { x: xOffset + (2 * w) / 4, y: yOffset + (2 * h) / 3, delay: 7 },
174
182
  color,
175
183
  outDelay: 10,
176
184
  },
177
185
 
178
-
179
186
  {
180
187
  start: { x: 200, y: 280, delay: 2 },
181
188
  end: { x: 260, y: 420, delay: 4 },
@@ -198,89 +205,96 @@ const GlowCanvas = ({ accentColor, backgroundColor }: { accentColor: string, bac
198
205
  end: { x: 180, y: 520, delay: 20 },
199
206
  color,
200
207
  },
201
- ];
208
+ ]
202
209
 
203
210
  function drawRoutes() {
204
- if (!ctx) return;
211
+ if (!ctx) return
205
212
 
206
- const debug = false;
213
+ const debug = false
207
214
  // const debug = true;
208
215
 
209
- const currentTime = (Date.now() - startTime) / 1000; // Time in seconds
210
- routes.forEach(route => {
211
- const elapsed = debug ? 100 : currentTime - route.start.delay;
212
- if (elapsed <= 0) return;
216
+ const currentTime = (Date.now() - startTime) / 1000 // Time in seconds
217
+ routes.forEach((route) => {
218
+ const elapsed = debug ? 100 : currentTime - route.start.delay
219
+ if (elapsed <= 0) return
213
220
 
214
- const duration = route.end.delay - route.start.delay; // animation duration
215
- const progress = Math.min(elapsed / duration, 1); // normal progress
221
+ const duration = route.end.delay - route.start.delay // animation duration
222
+ const progress = Math.min(elapsed / duration, 1) // normal progress
216
223
 
217
224
  // Fade from end to start after the line is fully drawn
218
- let startProgress = 0; // the starting point along the line
219
- const outDelay = route.outDelay || 0;
225
+ let startProgress = 0 // the starting point along the line
226
+ const outDelay = route.outDelay || 0
220
227
  if (elapsed > duration + outDelay) {
221
- const fadeProgress = Math.min((elapsed - (duration + outDelay)) / duration, 1);
222
- startProgress = fadeProgress; // move the start point forward
228
+ const fadeProgress = Math.min(
229
+ (elapsed - (duration + outDelay)) / duration,
230
+ 1,
231
+ )
232
+ startProgress = fadeProgress // move the start point forward
223
233
  }
224
234
 
225
235
  // Line vector
226
- const dx = route.end.x - route.start.x;
227
- const dy = route.end.y - route.start.y;
236
+ const dx = route.end.x - route.start.x
237
+ const dy = route.end.y - route.start.y
228
238
 
229
239
  for (let x = 0; x < dimensions.width; x += gap) {
230
240
  for (let y = 0; y < dimensions.height; y += gap) {
231
- const t = ((x - route.start.x) * dx + (y - route.start.y) * dy) / (dx * dx + dy * dy);
232
- if (t < startProgress || t > progress) continue; // only show dots in the visible segment
241
+ const t =
242
+ ((x - route.start.x) * dx + (y - route.start.y) * dy) /
243
+ (dx * dx + dy * dy)
244
+ if (t < startProgress || t > progress) continue // only show dots in the visible segment
233
245
 
234
- const closestX = route.start.x + dx * t;
235
- const closestY = route.start.y + dy * t;
236
- const distance = Math.hypot(x - closestX, y - closestY);
246
+ const closestX = route.start.x + dx * t
247
+ const closestY = route.start.y + dy * t
248
+ const distance = Math.hypot(x - closestX, y - closestY)
237
249
 
238
250
  if (distance < gap) {
239
- ctx.beginPath();
240
- ctx.arc(x, y, dotRadius, 0, Math.PI * 2);
251
+ ctx.beginPath()
252
+ ctx.arc(x, y, dotRadius, 0, Math.PI * 2)
241
253
 
242
254
  // Fade in: opacity goes from 0 → 1 as `progress` grows
243
- const opacity = Math.min(1, Math.max(0, Math.min(t - startProgress, progress - t) * 5));
244
- ctx.fillStyle = withOpacity(route.color, opacity);
255
+ const opacity = Math.min(
256
+ 1,
257
+ Math.max(0, Math.min(t - startProgress, progress - t) * 5),
258
+ )
259
+ ctx.fillStyle = withOpacity(route.color, opacity)
245
260
 
246
- ctx.fill();
261
+ ctx.fill()
247
262
  }
248
263
  }
249
264
  }
250
265
 
251
266
  if (debug) {
252
- const xStart = route.start.x;
253
- const yStart = route.start.y;
254
- const xEnd = route.start.x + dx * progress;
255
- const yEnd = route.start.y + dy * progress;
256
-
257
- ctx.beginPath();
258
- ctx.moveTo(xStart, yStart);
259
- ctx.lineTo(xEnd, yEnd);
260
- ctx.strokeStyle = route.color;
261
- ctx.lineWidth = 1.5;
262
- ctx.stroke();
263
-
264
- ctx.beginPath();
265
- ctx.arc(xEnd, yEnd, 3, 0, Math.PI * 2);
266
- ctx.fillStyle = route.color;
267
- ctx.fill();
267
+ const xStart = route.start.x
268
+ const yStart = route.start.y
269
+ const xEnd = route.start.x + dx * progress
270
+ const yEnd = route.start.y + dy * progress
271
+
272
+ ctx.beginPath()
273
+ ctx.moveTo(xStart, yStart)
274
+ ctx.lineTo(xEnd, yEnd)
275
+ ctx.strokeStyle = route.color
276
+ ctx.lineWidth = 1.5
277
+ ctx.stroke()
278
+
279
+ ctx.beginPath()
280
+ ctx.arc(xEnd, yEnd, 3, 0, Math.PI * 2)
281
+ ctx.fillStyle = route.color
282
+ ctx.fill()
268
283
  }
269
- });
284
+ })
270
285
  }
271
286
 
272
-
273
287
  const handleMouseMove = (e: MouseEvent) => {
274
- const rect = canvas.getBoundingClientRect();
288
+ const rect = canvas.getBoundingClientRect()
275
289
  mousePosRef.current = {
276
290
  x: e.x - rect.left,
277
291
  y: e.y - rect.top,
278
- };
279
- };
292
+ }
293
+ }
280
294
 
281
- document.addEventListener("mousemove", handleMouseMove);
295
+ document.addEventListener('mousemove', handleMouseMove)
282
296
 
283
- draw();
297
+ draw()
284
298
 
285
299
  return () => {
286
300
  document.removeEventListener("mousemove", handleMouseMove);
@@ -293,8 +307,8 @@ const GlowCanvas = ({ accentColor, backgroundColor }: { accentColor: string, bac
293
307
  ref={canvasRef}
294
308
  className="absolute inset-0 w-full h-full pointer-events-none"
295
309
  />
296
- );
297
- };
310
+ )
311
+ }
298
312
 
299
313
  export const Head = ({
300
314
  onStart,
@@ -315,11 +329,11 @@ export const Head = ({
315
329
  }) => {
316
330
  return (
317
331
  <div
318
- className='bg-zinc-900 w-(--card-width) flex flex-col items-center justify-center text-center relative'
332
+ className="bg-zinc-900 w-(--card-width) flex flex-col items-center justify-center text-center relative"
319
333
  style={{ '--color-sample': backgroundColor } as React.CSSProperties}
320
334
  >
321
335
  <div>
322
- <a href="https://openfort.io/" target="_blank">
336
+ <a href="https://openfort.io/" target="_blank" rel="noopener">
323
337
  <img src="/openfort.svg" className="logo" alt="Openfort logo" />
324
338
  </a>
325
339
  <a href={href} target="_blank">
@@ -327,22 +341,20 @@ export const Head = ({
327
341
  </a>
328
342
  </div>
329
343
  <h1 className="text-4xl font-bold mb-4">
330
- <span style={{ color: '#FC3627' }}>Openfort</span> + <span style={{ color }}>{sample}</span>
344
+ <span style={{ color: '#FC3627' }}>Openfort</span> +{' '}
345
+ <span style={{ color }}>{sample}</span>
331
346
  </h1>
332
- {
333
- subtitle && <p className="mb-6 text-sm max-w-2/3">{subtitle}</p>
334
- }
347
+ {subtitle && <p className="mb-6 text-sm max-w-2/3">{subtitle}</p>}
335
348
  <button
336
349
  className="lg:hidden mt-4 px-6 py-2 border border-zinc-500 rounded hover:bg-zinc-500/10 transition-colors cursor-pointer"
337
350
  onClick={onStart}
338
351
  >
339
352
  Click here to Start
340
353
  </button>
341
- <p className="absolute text-zinc-400 mb-6 text-sm bottom-0">Sign in to explore openfort capabilities.</p>
342
- <GlowCanvas
343
- accentColor={color}
344
- backgroundColor={backgroundColor}
345
- />
354
+ <p className="absolute text-zinc-400 mb-6 text-sm bottom-0">
355
+ Sign in to explore openfort capabilities.
356
+ </p>
357
+ <GlowCanvas accentColor={color} backgroundColor={backgroundColor} />
346
358
  </div>
347
359
  )
348
360
  }