deepspace 0.3.9 → 0.3.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 (120) hide show
  1. package/dist/cli.js +96 -18
  2. package/dist/cli.js.map +1 -1
  3. package/dist/index.d.ts +160 -1
  4. package/dist/index.js +283 -126
  5. package/dist/index.js.map +1 -1
  6. package/dist/server.d.ts +172 -2
  7. package/dist/server.js +581 -1
  8. package/dist/server.js.map +1 -1
  9. package/dist/worker.d.ts +252 -2
  10. package/dist/worker.js +588 -1
  11. package/dist/worker.js.map +1 -1
  12. package/features/admin-page/feature.json +29 -0
  13. package/features/admin-page/src/AdminPage.tsx +292 -0
  14. package/features/admin-page/src/admin-schema.ts +20 -0
  15. package/features/ai-chat/feature.json +41 -0
  16. package/features/ai-chat/src/AiChatPage.tsx +692 -0
  17. package/features/ai-chat/src/ChatPanel.tsx +1098 -0
  18. package/features/ai-chat/src/ai-chat-schema.ts +11 -0
  19. package/features/canvas/feature.json +45 -0
  20. package/features/canvas/src/CanvasEditorPage.tsx +87 -0
  21. package/features/canvas/src/CanvasListPage.tsx +202 -0
  22. package/features/canvas/src/canvas-schema.ts +33 -0
  23. package/features/canvas/src/components/CanvasToolbar.tsx +170 -0
  24. package/features/canvas/src/components/CanvasView.tsx +369 -0
  25. package/features/canvas/src/components/ShapeRenderer.tsx +114 -0
  26. package/features/cron/feature.json +33 -0
  27. package/features/cron/src/CronLogPage.tsx +100 -0
  28. package/features/cron/src/cron.ts +25 -0
  29. package/features/docs/feature.json +96 -0
  30. package/features/docs/src/DocsEditorPage.tsx +1012 -0
  31. package/features/docs/src/DocsListPage.tsx +951 -0
  32. package/features/docs/src/DocsOutlinePanel.tsx +68 -0
  33. package/features/docs/src/DocsPresence.tsx +138 -0
  34. package/features/docs/src/InviteDialog.tsx +336 -0
  35. package/features/docs/src/LibrarySidebar.tsx +464 -0
  36. package/features/docs/src/docs-favorites.ts +18 -0
  37. package/features/docs/src/docs-library-types.ts +15 -0
  38. package/features/docs/src/docs-schema.ts +80 -0
  39. package/features/docs/src/docs-ui.css +309 -0
  40. package/features/docs/src/editor/DocEditorSurface.tsx +257 -0
  41. package/features/docs/src/editor/DocsTiptapToolbar.tsx +560 -0
  42. package/features/docs/src/editor/useDocEditor.ts +206 -0
  43. package/features/docs/src/use-yjs-room-with-awareness.ts +285 -0
  44. package/features/file-attachments/feature.json +42 -0
  45. package/features/file-attachments/src/AttachmentsPage.tsx +864 -0
  46. package/features/file-attachments/src/attachments-constants.ts +9 -0
  47. package/features/file-attachments/src/attachments-schema.ts +45 -0
  48. package/features/file-attachments/src/useFilePreview.ts +471 -0
  49. package/features/file-attachments/src/useMimeTypeDetection.ts +138 -0
  50. package/features/file-manager/feature.json +24 -0
  51. package/features/file-manager/src/FileManagerPage.tsx +330 -0
  52. package/features/integration-test/feature.json +18 -0
  53. package/features/integration-test/src/IntegrationTestPage.tsx +423 -0
  54. package/features/integration-test/src/integration.spec.ts +42 -0
  55. package/features/items/feature.json +33 -0
  56. package/features/items/src/ItemsPage.tsx +325 -0
  57. package/features/items/src/items-constants.ts +10 -0
  58. package/features/items/src/items-schema.ts +27 -0
  59. package/features/kanban/feature.json +18 -0
  60. package/features/kanban/src/Kanban.tsx +283 -0
  61. package/features/landing/feature.json +62 -0
  62. package/features/landing/src/LandingPage.tsx +627 -0
  63. package/features/landing/src/primitives.tsx +389 -0
  64. package/features/landing/src/sections/FAQSection.tsx +110 -0
  65. package/features/landing/src/sections/FeaturesGridSection.tsx +311 -0
  66. package/features/landing/src/sections/HowItWorksSection.tsx +62 -0
  67. package/features/landing/src/sections/LogoCloudSection.tsx +58 -0
  68. package/features/landing/src/sections/ShowcaseSection.tsx +63 -0
  69. package/features/landing/src/sections/StatsSection.tsx +31 -0
  70. package/features/landing/src/sections/TeamSection.tsx +86 -0
  71. package/features/landing/src/sections/TestimonialsSection.tsx +68 -0
  72. package/features/landing/src/sections/VideoSection.tsx +71 -0
  73. package/features/leaderboard/feature.json +33 -0
  74. package/features/leaderboard/src/LeaderboardPage.tsx +372 -0
  75. package/features/leaderboard/src/leaderboard-constants.ts +21 -0
  76. package/features/leaderboard/src/leaderboard-schema.ts +36 -0
  77. package/features/messaging/feature.json +111 -0
  78. package/features/messaging/src/ChatMultiPage.tsx +300 -0
  79. package/features/messaging/src/ChatPage.tsx +75 -0
  80. package/features/messaging/src/components/chat/ChatHeader.tsx +76 -0
  81. package/features/messaging/src/components/chat/MessageActionSheet.tsx +168 -0
  82. package/features/messaging/src/components/chat/MessageInput.tsx +65 -0
  83. package/features/messaging/src/components/chat/MessageItem.tsx +352 -0
  84. package/features/messaging/src/components/chat/MessageList.tsx +248 -0
  85. package/features/messaging/src/components/chat/ReactionPicker.tsx +2 -0
  86. package/features/messaging/src/components/chat/ThreadPanel.tsx +107 -0
  87. package/features/messaging/src/components/chat/UserProfilePopover.tsx +158 -0
  88. package/features/messaging/src/components/chat-multi/AddMemberModal.tsx +188 -0
  89. package/features/messaging/src/components/chat-multi/BrowseGroupsModal.tsx +163 -0
  90. package/features/messaging/src/components/chat-multi/ChannelListItem.tsx +147 -0
  91. package/features/messaging/src/components/chat-multi/ChannelSettingsPanel.tsx +344 -0
  92. package/features/messaging/src/components/chat-multi/ChannelSidebar.tsx +460 -0
  93. package/features/messaging/src/components/chat-multi/CreateGroupModal.tsx +190 -0
  94. package/features/messaging/src/components/chat-multi/InvitationList.tsx +149 -0
  95. package/features/messaging/src/components/chat-multi/NewMessageModal.tsx +159 -0
  96. package/features/messaging/src/hooks/useChatChannel.ts +64 -0
  97. package/features/messaging/src/hooks/useLongPress.ts +74 -0
  98. package/features/messaging/src/hooks/useMultiChannel.ts +142 -0
  99. package/features/messaging/src/messaging-schema.ts +25 -0
  100. package/features/presence-test/feature.json +21 -0
  101. package/features/presence-test/src/PresenceTestPage.tsx +120 -0
  102. package/features/sidebar/feature.json +19 -0
  103. package/features/sidebar/src/AppSidebar.tsx +558 -0
  104. package/features/tasks/feature.json +33 -0
  105. package/features/tasks/src/TasksPage.tsx +598 -0
  106. package/features/tasks/src/tasks-constants.ts +43 -0
  107. package/features/tasks/src/tasks-schema.ts +56 -0
  108. package/features/testing/feature.json +49 -0
  109. package/features/testing/src/TestPage.tsx +145 -0
  110. package/features/testing/src/cpu-burn-action.ts +51 -0
  111. package/features/testing/src/subrequest-burn-action.ts +53 -0
  112. package/features/testing/src/test-schema.ts +23 -0
  113. package/features/topbar/feature.json +18 -0
  114. package/features/topbar/src/Topbar.tsx +353 -0
  115. package/features/tree/feature.json +26 -0
  116. package/features/tree/src/TreeSidebar.tsx +607 -0
  117. package/features/tree/src/tree-constants.ts +68 -0
  118. package/features/tree/src/tree-hooks.ts +258 -0
  119. package/package.json +4 -2
  120. package/scripts/add-feature.cjs +654 -0
@@ -0,0 +1,311 @@
1
+ /**
2
+ * Landing Section: Features Grid
3
+ *
4
+ * Bento-style 2-column grid with 4 feature cards.
5
+ */
6
+
7
+ import { type ReactNode } from 'react'
8
+ import { motion } from 'framer-motion'
9
+ import { Zap, Shield, BarChart3, Sparkles, Check } from 'lucide-react'
10
+ import {
11
+ ScrollReveal,
12
+ StaggerContainer,
13
+ staggerChild,
14
+ GlassCard,
15
+ PlaceholderImage,
16
+ SectionHeading,
17
+ cn,
18
+ } from '../primitives'
19
+
20
+ // ============================================================================
21
+ // Configuration
22
+ // ============================================================================
23
+
24
+ const FEATURES: Array<{
25
+ icon: typeof Zap
26
+ title: string
27
+ description: string
28
+ gradient: string
29
+ iconColor: string
30
+ borderGlow: string
31
+ image: string
32
+ Visual: (() => ReactNode) | null
33
+ }> = [
34
+ {
35
+ icon: Zap,
36
+ title: 'Lightning Fast',
37
+ description: 'Real-time sync and instant updates across all devices.',
38
+ gradient: 'from-amber-500/20 to-orange-500/20',
39
+ iconColor: 'text-amber-400',
40
+ borderGlow: 'group-hover:shadow-[0_0_30px_rgba(245,158,11,0.15)]',
41
+ image: '',
42
+ Visual: null,
43
+ },
44
+ {
45
+ icon: Shield,
46
+ title: 'Secure by Default',
47
+ description: 'Enterprise-grade security with role-based access and encryption.',
48
+ gradient: 'from-emerald-500/20 to-teal-500/20',
49
+ iconColor: 'text-emerald-400',
50
+ borderGlow: 'group-hover:shadow-[0_0_30px_rgba(16,185,129,0.15)]',
51
+ image: '',
52
+ Visual: ShieldVisual,
53
+ },
54
+ {
55
+ icon: BarChart3,
56
+ title: 'Powerful Analytics',
57
+ description: 'Built-in dashboards and real-time insights for better decisions.',
58
+ gradient: 'from-blue-500/20 to-cyan-500/20',
59
+ iconColor: 'text-blue-400',
60
+ borderGlow: 'group-hover:shadow-[0_0_30px_rgba(59,130,246,0.15)]',
61
+ image: '',
62
+ Visual: BarChartVisual,
63
+ },
64
+ {
65
+ icon: Sparkles,
66
+ title: 'AI-Powered',
67
+ description: 'Smart automation that learns from your workflow.',
68
+ gradient: 'from-violet-500/20 to-purple-500/20',
69
+ iconColor: 'text-violet-400',
70
+ borderGlow: 'group-hover:shadow-[0_0_30px_rgba(139,92,246,0.15)]',
71
+ image: '',
72
+ Visual: null,
73
+ },
74
+ ]
75
+
76
+ // ============================================================================
77
+ // Decorative Visuals
78
+ // ============================================================================
79
+
80
+ function SpeedPulseVisual() {
81
+ return (
82
+ <div className="relative h-24 w-full overflow-hidden rounded-lg bg-foreground/[0.02]">
83
+ <div className="absolute inset-0 flex items-center justify-center gap-[3px]">
84
+ {[0.3, 0.7, 0.5, 1, 0.6, 0.85, 0.45, 0.9, 0.35, 0.75, 0.55, 0.95, 0.4, 0.8, 0.65].map((h, i) => (
85
+ <motion.div
86
+ key={i}
87
+ className="w-[4px] rounded-full bg-gradient-to-t from-amber-500/60 to-orange-400/30"
88
+ initial={{ height: '10%' }}
89
+ whileInView={{ height: `${h * 80}%` }}
90
+ viewport={{ once: true }}
91
+ transition={{ delay: i * 0.04, duration: 0.6, ease: 'easeOut' }}
92
+ />
93
+ ))}
94
+ </div>
95
+ <div className="absolute bottom-0 inset-x-0 h-8 bg-gradient-to-t from-background/90 to-transparent" />
96
+ </div>
97
+ )
98
+ }
99
+
100
+ function ShieldVisual() {
101
+ const checkItems = ['Encryption', 'RBAC', 'Audit Log']
102
+ return (
103
+ <div className="relative h-24 w-full overflow-hidden rounded-lg bg-foreground/[0.02]">
104
+ <div className="flex flex-col gap-2 px-4 py-3">
105
+ {checkItems.map((item, i) => (
106
+ <motion.div
107
+ key={item}
108
+ className="flex items-center gap-2.5"
109
+ initial={{ opacity: 0, x: -12 }}
110
+ whileInView={{ opacity: 1, x: 0 }}
111
+ viewport={{ once: true }}
112
+ transition={{ delay: 0.15 + i * 0.12, duration: 0.4 }}
113
+ >
114
+ <div className="w-5 h-5 rounded-md bg-emerald-500/20 border border-emerald-500/30 flex items-center justify-center shrink-0">
115
+ <Check className="w-3 h-3 text-emerald-400" />
116
+ </div>
117
+ <span className="text-xs text-muted-foreground/60 font-medium">{item}</span>
118
+ <div className="flex-1 h-px bg-foreground/[0.04]" />
119
+ <span className="text-[10px] text-emerald-400/60 font-medium">Active</span>
120
+ </motion.div>
121
+ ))}
122
+ </div>
123
+ </div>
124
+ )
125
+ }
126
+
127
+ function BarChartVisual() {
128
+ const bars = [
129
+ { h: 35, label: 'Mon' },
130
+ { h: 58, label: 'Tue' },
131
+ { h: 42, label: 'Wed' },
132
+ { h: 78, label: 'Thu' },
133
+ { h: 65, label: 'Fri' },
134
+ { h: 88, label: 'Sat' },
135
+ { h: 52, label: 'Sun' },
136
+ ]
137
+ return (
138
+ <div className="relative h-24 w-full overflow-hidden rounded-lg bg-foreground/[0.02]">
139
+ <div className="absolute inset-0 flex items-end justify-center gap-2 px-4 pb-5 pt-2">
140
+ {bars.map((bar, i) => (
141
+ <div key={bar.label} className="flex flex-col items-center gap-1.5 flex-1">
142
+ <motion.div
143
+ className="w-full max-w-[24px] rounded-t-sm bg-gradient-to-t from-blue-500/50 to-cyan-400/30"
144
+ initial={{ height: 0 }}
145
+ whileInView={{ height: `${bar.h}%` }}
146
+ viewport={{ once: true }}
147
+ transition={{ delay: i * 0.06, duration: 0.5, ease: 'easeOut' }}
148
+ />
149
+ <span className="text-[8px] text-muted-foreground/60 font-medium">{bar.label}</span>
150
+ </div>
151
+ ))}
152
+ </div>
153
+ </div>
154
+ )
155
+ }
156
+
157
+ function SparkleVisual() {
158
+ const nodes = [
159
+ { x: 20, y: 30, delay: 0 },
160
+ { x: 50, y: 15, delay: 0.1 },
161
+ { x: 80, y: 35, delay: 0.2 },
162
+ { x: 35, y: 65, delay: 0.15 },
163
+ { x: 65, y: 55, delay: 0.25 },
164
+ { x: 50, y: 80, delay: 0.3 },
165
+ ]
166
+ const connections = [
167
+ [0, 1], [1, 2], [0, 3], [1, 4], [2, 4], [3, 5], [4, 5],
168
+ ]
169
+ return (
170
+ <div className="relative h-24 w-full overflow-hidden rounded-lg bg-foreground/[0.02]">
171
+ <svg className="absolute inset-0 w-full h-full" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">
172
+ {connections.map(([a, b], i) => (
173
+ <motion.line
174
+ key={i}
175
+ x1={nodes[a].x}
176
+ y1={nodes[a].y}
177
+ x2={nodes[b].x}
178
+ y2={nodes[b].y}
179
+ stroke="url(#sparkleGrad)"
180
+ strokeWidth="0.5"
181
+ initial={{ opacity: 0 }}
182
+ whileInView={{ opacity: 0.4 }}
183
+ viewport={{ once: true }}
184
+ transition={{ delay: 0.2 + i * 0.05, duration: 0.5 }}
185
+ />
186
+ ))}
187
+ <defs>
188
+ <linearGradient id="sparkleGrad" x1="0%" y1="0%" x2="100%" y2="100%">
189
+ <stop offset="0%" stopColor="rgb(139,92,246)" stopOpacity="0.6" />
190
+ <stop offset="100%" stopColor="rgb(168,85,247)" stopOpacity="0.3" />
191
+ </linearGradient>
192
+ </defs>
193
+ {nodes.map((node, i) => (
194
+ <motion.circle
195
+ key={i}
196
+ cx={node.x}
197
+ cy={node.y}
198
+ r="3"
199
+ fill="rgba(139,92,246,0.4)"
200
+ stroke="rgba(139,92,246,0.6)"
201
+ strokeWidth="0.5"
202
+ initial={{ scale: 0, opacity: 0 }}
203
+ whileInView={{ scale: 1, opacity: 1 }}
204
+ viewport={{ once: true }}
205
+ transition={{ delay: node.delay + 0.1, duration: 0.4, ease: 'easeOut' }}
206
+ />
207
+ ))}
208
+ {nodes.map((node, i) => (
209
+ <motion.circle
210
+ key={`glow-${i}`}
211
+ cx={node.x}
212
+ cy={node.y}
213
+ r="5"
214
+ fill="none"
215
+ stroke="rgba(139,92,246,0.15)"
216
+ strokeWidth="1"
217
+ initial={{ scale: 0 }}
218
+ whileInView={{ scale: [1, 1.8, 1] }}
219
+ viewport={{ once: true }}
220
+ transition={{ delay: node.delay + 0.5, duration: 2, repeat: Infinity, ease: 'easeInOut' }}
221
+ />
222
+ ))}
223
+ </svg>
224
+ </div>
225
+ )
226
+ }
227
+
228
+ // ============================================================================
229
+ // Feature Card
230
+ // ============================================================================
231
+
232
+ function BentoFeatureCard({
233
+ feature,
234
+ size = 'normal',
235
+ }: {
236
+ feature: (typeof FEATURES)[number]
237
+ size?: 'large' | 'normal'
238
+ }) {
239
+ const isLarge = size === 'large'
240
+
241
+ return (
242
+ <motion.div variants={staggerChild} className={isLarge ? 'md:col-span-2' : ''}>
243
+ <GlassCard className={cn('h-full overflow-hidden', feature.borderGlow)}>
244
+ <div
245
+ className={cn(
246
+ 'absolute inset-0 opacity-[0.15] group-hover:opacity-100 transition-opacity duration-700',
247
+ 'bg-gradient-to-br',
248
+ feature.gradient,
249
+ )}
250
+ />
251
+ <div className={cn('relative z-10 flex flex-col', isLarge ? 'p-8 md:p-10' : 'p-7')}>
252
+ <div className="flex items-start gap-5">
253
+ <div
254
+ className={cn(
255
+ 'shrink-0 rounded-xl flex items-center justify-center',
256
+ 'bg-foreground/[0.06] border border-foreground/[0.08]',
257
+ 'group-hover:scale-110 transition-transform duration-500',
258
+ isLarge ? 'w-14 h-14' : 'w-11 h-11',
259
+ )}
260
+ >
261
+ <feature.icon className={cn(feature.iconColor, isLarge ? 'w-7 h-7' : 'w-5 h-5')} />
262
+ </div>
263
+ <div className="flex-1 min-w-0">
264
+ <h3 className={cn('text-foreground font-semibold mb-2', isLarge ? 'text-xl' : 'text-base')}>
265
+ {feature.title}
266
+ </h3>
267
+ <p className={cn('text-muted-foreground leading-relaxed', isLarge ? 'text-base' : 'text-sm')}>
268
+ {feature.description}
269
+ </p>
270
+ </div>
271
+ </div>
272
+ {feature.Visual ? (
273
+ <div className={cn(isLarge ? 'mt-8' : 'mt-5')}>
274
+ <feature.Visual />
275
+ </div>
276
+ ) : isLarge ? (
277
+ <div className="mt-8">
278
+ <PlaceholderImage label="Add Image" src={feature.image || undefined} aspectRatio="aspect-[16/10]" />
279
+ </div>
280
+ ) : null}
281
+ </div>
282
+ </GlassCard>
283
+ </motion.div>
284
+ )
285
+ }
286
+
287
+ // ============================================================================
288
+ // Section
289
+ // ============================================================================
290
+
291
+ export default function FeaturesGridSection() {
292
+ return (
293
+ <section id="features" className="relative py-28 md:py-36">
294
+ <div className="max-w-6xl mx-auto px-6">
295
+ <SectionHeading
296
+ tag="Features"
297
+ title="Everything you need"
298
+ titleHighlight="all in one place"
299
+ subtitle="Powerful features designed to streamline your workflow."
300
+ />
301
+
302
+ <StaggerContainer className="grid grid-cols-1 md:grid-cols-3 gap-5" staggerDelay={0.08}>
303
+ <BentoFeatureCard feature={FEATURES[0]} size="large" />
304
+ <BentoFeatureCard feature={FEATURES[1]} />
305
+ <BentoFeatureCard feature={FEATURES[2]} />
306
+ <BentoFeatureCard feature={FEATURES[3]} size="large" />
307
+ </StaggerContainer>
308
+ </div>
309
+ </section>
310
+ )
311
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Landing Section: How It Works
3
+ *
4
+ * Numbered 3-step horizontal flow.
5
+ */
6
+
7
+ import { motion } from 'framer-motion'
8
+ import { StaggerContainer, staggerChild, SectionHeading } from '../primitives'
9
+
10
+ const STEPS = [
11
+ {
12
+ number: '01',
13
+ title: 'Sign Up',
14
+ description: 'Create your account in seconds. No credit card required, no complicated setup.',
15
+ },
16
+ {
17
+ number: '02',
18
+ title: 'Set Up',
19
+ description: 'Configure your workspace and invite your team. Everything is guided step by step.',
20
+ },
21
+ {
22
+ number: '03',
23
+ title: 'Go',
24
+ description: 'Start using the app right away. Everything you need is ready from day one.',
25
+ },
26
+ ]
27
+
28
+ export default function HowItWorksSection() {
29
+ return (
30
+ <section id="how-it-works" className="relative py-28 md:py-36">
31
+ <div className="max-w-5xl mx-auto px-6">
32
+ <SectionHeading
33
+ tag="How It Works"
34
+ title="Up and running in minutes"
35
+ subtitle="Three simple steps to get started."
36
+ />
37
+
38
+ <StaggerContainer className="grid grid-cols-1 md:grid-cols-3 gap-6 relative" staggerDelay={0.15}>
39
+ <div className="hidden md:block absolute top-[36px] left-[16.67%] right-[16.67%] h-px">
40
+ <div className="w-full h-full bg-gradient-to-r from-primary/40 via-violet-400/40 to-primary/40" />
41
+ </div>
42
+
43
+ {STEPS.map(step => (
44
+ <motion.div key={step.number} variants={staggerChild}>
45
+ <div className="relative text-center">
46
+ <div className="relative z-10 w-[72px] h-[72px] mx-auto mb-6 rounded-2xl bg-background/80 border border-foreground/[0.1] flex items-center justify-center shadow-lg">
47
+ <span className="text-2xl font-bold bg-gradient-to-br from-primary to-violet-400 bg-clip-text text-transparent">
48
+ {step.number}
49
+ </span>
50
+ </div>
51
+ <h3 className="text-xl font-semibold text-foreground mb-3">{step.title}</h3>
52
+ <p className="text-muted-foreground text-sm leading-relaxed max-w-[280px] mx-auto">
53
+ {step.description}
54
+ </p>
55
+ </div>
56
+ </motion.div>
57
+ ))}
58
+ </StaggerContainer>
59
+ </div>
60
+ </section>
61
+ )
62
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Landing Section: Logo Cloud
3
+ *
4
+ * Responsive grid of partner/integration logos.
5
+ */
6
+
7
+ import { ScrollReveal, SectionHeading, cn } from '../primitives'
8
+
9
+ interface Logo {
10
+ name: string
11
+ imageUrl?: string
12
+ }
13
+
14
+ const LOGOS: Logo[] = [
15
+ { name: 'Acme Corp' },
16
+ { name: 'Globex' },
17
+ { name: 'Initech' },
18
+ { name: 'Umbrella' },
19
+ { name: 'Stark Ind.' },
20
+ { name: 'Wayne Ent.' },
21
+ ]
22
+
23
+ export default function LogoCloudSection() {
24
+ return (
25
+ <section className="relative py-20 md:py-28">
26
+ <div className="max-w-5xl mx-auto px-6">
27
+ <SectionHeading tag="Trusted By" title="Used by teams you know" />
28
+
29
+ <ScrollReveal>
30
+ <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-6">
31
+ {LOGOS.map(logo => (
32
+ <div
33
+ key={logo.name}
34
+ className={cn(
35
+ 'flex items-center justify-center h-20 rounded-xl',
36
+ 'bg-foreground/[0.03] border border-foreground/[0.06]',
37
+ 'opacity-50 hover:opacity-100 transition-opacity duration-300',
38
+ )}
39
+ >
40
+ {logo.imageUrl ? (
41
+ <img
42
+ src={logo.imageUrl}
43
+ alt={logo.name}
44
+ className="max-h-10 max-w-[80%] object-contain brightness-0 invert opacity-60"
45
+ />
46
+ ) : (
47
+ <span className="text-sm font-medium text-muted-foreground tracking-wide">
48
+ {logo.name}
49
+ </span>
50
+ )}
51
+ </div>
52
+ ))}
53
+ </div>
54
+ </ScrollReveal>
55
+ </div>
56
+ </section>
57
+ )
58
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Landing Section: Showcase
3
+ *
4
+ * Alternating left/right product blocks.
5
+ */
6
+
7
+ import { ArrowRight } from 'lucide-react'
8
+ import { ScrollReveal, BrowserMockup, cn } from '../primitives'
9
+
10
+ const SHOWCASE_ITEMS = [
11
+ {
12
+ label: 'Overview',
13
+ title: 'See everything at a glance',
14
+ description: 'A clear, organized view of what matters most. Stay on top of your work without the clutter.',
15
+ image: '',
16
+ },
17
+ {
18
+ label: 'Workflow',
19
+ title: 'Work the way you want',
20
+ description: 'Flexible tools that adapt to your process. Set things up once and let the app handle the rest.',
21
+ image: '',
22
+ },
23
+ ]
24
+
25
+ export default function ShowcaseSection() {
26
+ return (
27
+ <section className="relative py-28 md:py-36">
28
+ <div className="max-w-6xl mx-auto px-6 space-y-24 md:space-y-32">
29
+ {SHOWCASE_ITEMS.map((item, idx) => {
30
+ const isReversed = idx % 2 !== 0
31
+ return (
32
+ <div
33
+ key={item.title}
34
+ className={cn(
35
+ 'flex flex-col gap-10 md:gap-16 items-center',
36
+ isReversed ? 'md:flex-row-reverse' : 'md:flex-row',
37
+ )}
38
+ >
39
+ <ScrollReveal className="flex-1 w-full" direction={isReversed ? 'right' : 'left'} delay={0.1}>
40
+ <BrowserMockup label={item.label} src={item.image || undefined} />
41
+ </ScrollReveal>
42
+ <ScrollReveal className="flex-1 w-full md:max-w-md" direction={isReversed ? 'left' : 'right'} delay={0.2}>
43
+ <span className="inline-block text-xs font-semibold tracking-[0.2em] uppercase text-primary/80 mb-3">
44
+ {item.label}
45
+ </span>
46
+ <h3 className="text-2xl sm:text-3xl md:text-4xl font-bold text-foreground leading-tight tracking-[-0.01em]">
47
+ {item.title}
48
+ </h3>
49
+ <p className="mt-4 text-muted-foreground text-base md:text-lg leading-relaxed">
50
+ {item.description}
51
+ </p>
52
+ <button className="mt-6 inline-flex items-center gap-2 text-sm font-medium text-primary hover:text-primary/80 transition-colors group">
53
+ Learn more
54
+ <ArrowRight className="w-4 h-4 transition-transform group-hover:translate-x-1" />
55
+ </button>
56
+ </ScrollReveal>
57
+ </div>
58
+ )
59
+ })}
60
+ </div>
61
+ </section>
62
+ )
63
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Landing Section: Stats Band
3
+ *
4
+ * Full-width gradient band with animated counter stats.
5
+ */
6
+
7
+ import { StaggerContainer, AnimatedStat } from '../primitives'
8
+
9
+ const STATS = [
10
+ { value: '99.9%', label: 'Uptime' },
11
+ { value: '10x', label: 'Faster' },
12
+ { value: '50K+', label: 'Users' },
13
+ { value: '<50ms', label: 'Response Time' },
14
+ ]
15
+
16
+ export default function StatsSection() {
17
+ return (
18
+ <section className="relative py-20 overflow-hidden">
19
+ <div className="absolute inset-0 bg-gradient-to-r from-primary/[0.08] via-violet-500/[0.06] to-primary/[0.08]" />
20
+ <div className="absolute inset-0 border-y border-foreground/[0.06]" />
21
+
22
+ <div className="relative max-w-5xl mx-auto px-6">
23
+ <StaggerContainer className="grid grid-cols-2 md:grid-cols-4 gap-8 md:gap-4" staggerDelay={0.08}>
24
+ {STATS.map(stat => (
25
+ <AnimatedStat key={stat.label} value={stat.value} label={stat.label} />
26
+ ))}
27
+ </StaggerContainer>
28
+ </div>
29
+ </section>
30
+ )
31
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Landing Section: Team / About
3
+ *
4
+ * Responsive grid of team member cards.
5
+ */
6
+
7
+ import { motion } from 'framer-motion'
8
+ import { Twitter, Github, Linkedin } from 'lucide-react'
9
+ import { StaggerContainer, staggerChild, GlassCard, SectionHeading, cn } from '../primitives'
10
+
11
+ interface TeamMember {
12
+ name: string
13
+ role: string
14
+ socials?: {
15
+ twitter?: string
16
+ github?: string
17
+ linkedin?: string
18
+ }
19
+ }
20
+
21
+ const TEAM_MEMBERS: TeamMember[] = [
22
+ { name: 'Alex Rivera', role: 'Founder & CEO', socials: { twitter: '#', linkedin: '#' } },
23
+ { name: 'Jordan Lee', role: 'Head of Engineering', socials: { github: '#', linkedin: '#' } },
24
+ { name: 'Sam Patel', role: 'Lead Designer', socials: { twitter: '#' } },
25
+ { name: 'Morgan Chen', role: 'Product Manager', socials: { linkedin: '#' } },
26
+ ]
27
+
28
+ const SOCIAL_ICONS = { twitter: Twitter, github: Github, linkedin: Linkedin } as const
29
+
30
+ export default function TeamSection() {
31
+ return (
32
+ <section id="team" className="relative py-28 md:py-36">
33
+ <div className="max-w-6xl mx-auto px-6">
34
+ <SectionHeading
35
+ tag="Team"
36
+ title="Meet the people behind the product"
37
+ subtitle="A small team with big ambitions, building something we believe in."
38
+ />
39
+
40
+ <StaggerContainer className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6" staggerDelay={0.08}>
41
+ {TEAM_MEMBERS.map(member => (
42
+ <motion.div key={member.name} variants={staggerChild}>
43
+ <GlassCard className="p-6 text-center" hoverEffect>
44
+ <div className="w-16 h-16 mx-auto mb-4 rounded-full bg-gradient-to-br from-primary/30 to-violet-500/30 border border-foreground/[0.1] flex items-center justify-center">
45
+ <span className="text-lg font-semibold text-muted-foreground">
46
+ {member.name.split(' ').map(n => n[0]).join('')}
47
+ </span>
48
+ </div>
49
+ <h3 className="text-base font-semibold text-foreground">{member.name}</h3>
50
+ <p className="text-sm text-muted-foreground mt-1">{member.role}</p>
51
+
52
+ {member.socials && Object.keys(member.socials).length > 0 && (
53
+ <div className="flex items-center justify-center gap-2 mt-4">
54
+ {(Object.entries(member.socials) as Array<[keyof typeof SOCIAL_ICONS, string]>).map(
55
+ ([platform, url]) => {
56
+ const Icon = SOCIAL_ICONS[platform]
57
+ if (!url) return null
58
+ return (
59
+ <a
60
+ key={platform}
61
+ href={url}
62
+ target="_blank"
63
+ rel="noopener noreferrer"
64
+ className={cn(
65
+ 'w-8 h-8 rounded-lg flex items-center justify-center',
66
+ 'bg-foreground/[0.04] border border-foreground/[0.08]',
67
+ 'text-muted-foreground/60 hover:text-muted-foreground hover:bg-foreground/[0.08]',
68
+ 'transition-all duration-200',
69
+ )}
70
+ aria-label={platform}
71
+ >
72
+ <Icon className="w-3.5 h-3.5" />
73
+ </a>
74
+ )
75
+ },
76
+ )}
77
+ </div>
78
+ )}
79
+ </GlassCard>
80
+ </motion.div>
81
+ ))}
82
+ </StaggerContainer>
83
+ </div>
84
+ </section>
85
+ )
86
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Landing Section: Testimonials
3
+ *
4
+ * 3-column grid of testimonial cards.
5
+ */
6
+
7
+ import { motion } from 'framer-motion'
8
+ import { Star } from 'lucide-react'
9
+ import { StaggerContainer, staggerChild, GlassCard, SectionHeading } from '../primitives'
10
+
11
+ const TESTIMONIALS = [
12
+ {
13
+ quote: 'This completely changed how I work. Everything is faster and more organized now.',
14
+ name: 'Alex Johnson',
15
+ role: 'Product Manager',
16
+ rating: 5,
17
+ },
18
+ {
19
+ quote: 'The simplicity is what sold me. I was up and running in minutes, not hours.',
20
+ name: 'Sarah Chen',
21
+ role: 'Designer',
22
+ rating: 5,
23
+ },
24
+ {
25
+ quote: 'Finally an app that works the way I think. The flexibility is incredible.',
26
+ name: 'Marcus Williams',
27
+ role: 'Developer',
28
+ rating: 5,
29
+ },
30
+ ]
31
+
32
+ export default function TestimonialsSection() {
33
+ return (
34
+ <section id="testimonials" className="relative py-28 md:py-36">
35
+ <div className="max-w-6xl mx-auto px-6">
36
+ <SectionHeading tag="Testimonials" title="Loved by people everywhere" />
37
+
38
+ <StaggerContainer className="grid grid-cols-1 md:grid-cols-3 gap-6" staggerDelay={0.12}>
39
+ {TESTIMONIALS.map(t => (
40
+ <motion.div key={t.name} variants={staggerChild}>
41
+ <GlassCard className="p-7 h-full flex flex-col" hoverEffect={false}>
42
+ <div className="flex gap-1 mb-5">
43
+ {Array.from({ length: t.rating }).map((_, i) => (
44
+ <Star key={i} className="w-4 h-4 fill-amber-400 text-amber-400" />
45
+ ))}
46
+ </div>
47
+ <p className="text-muted-foreground text-sm leading-relaxed flex-1">
48
+ &ldquo;{t.quote}&rdquo;
49
+ </p>
50
+ <div className="flex items-center gap-3 mt-6 pt-5 border-t border-foreground/[0.06]">
51
+ <div className="w-10 h-10 rounded-full bg-gradient-to-br from-primary/30 to-violet-500/30 border border-foreground/[0.1] flex items-center justify-center">
52
+ <span className="text-xs font-semibold text-muted-foreground">
53
+ {t.name.split(' ').map(n => n[0]).join('')}
54
+ </span>
55
+ </div>
56
+ <div>
57
+ <div className="text-sm font-medium text-foreground">{t.name}</div>
58
+ <div className="text-xs text-muted-foreground/60">{t.role}</div>
59
+ </div>
60
+ </div>
61
+ </GlassCard>
62
+ </motion.div>
63
+ ))}
64
+ </StaggerContainer>
65
+ </div>
66
+ </section>
67
+ )
68
+ }