wu981526092 commited on
Commit
3e24559
·
1 Parent(s): 1eec052

Merge Community into Home page - Complete integration and cleanup

Browse files

✅ Community Integration:
- Move entire Community functionality to Home page
- Keep Hero section, replace Featured Templates with full Community tabs
- Add All Templates, Featured, My Likes tabs with like functionality
- Preserve all template management and interaction features

✅ File Cleanup:
- Delete Community.tsx page (no longer needed)
- Remove Community route from App.tsx
- Remove Community navigation from Sidebar.tsx
- Update Home description to reflect new functionality

✅ Feature Consolidation:
- Home page now serves as both landing and template discovery
- Users can access all templates without separate navigation
- Improved discoverability and workflow integration
- Maintains all Community features (like, filter, use templates)

� User Experience:
- Single unified experience for templates
- Reduced navigation complexity
- Better feature discovery from landing page

frontend/src/App.tsx CHANGED
@@ -4,7 +4,6 @@ import { Home } from './pages/Home'
4
  import { Playground } from './pages/Playground'
5
  import { Models } from './pages/Models'
6
  import { Assistants } from './pages/Assistants'
7
- import { Community } from './pages/Community'
8
  import { Settings } from './pages/Settings'
9
 
10
  function App() {
@@ -16,7 +15,6 @@ function App() {
16
  <Route path="playground" element={<Playground />} />
17
  <Route path="models" element={<Models />} />
18
  <Route path="assistants" element={<Assistants />} />
19
- <Route path="community" element={<Community />} />
20
  <Route path="settings" element={<Settings />} />
21
  </Route>
22
  </Routes>
 
4
  import { Playground } from './pages/Playground'
5
  import { Models } from './pages/Models'
6
  import { Assistants } from './pages/Assistants'
 
7
  import { Settings } from './pages/Settings'
8
 
9
  function App() {
 
15
  <Route path="playground" element={<Playground />} />
16
  <Route path="models" element={<Models />} />
17
  <Route path="assistants" element={<Assistants />} />
 
18
  <Route path="settings" element={<Settings />} />
19
  </Route>
20
  </Routes>
frontend/src/components/Sidebar.tsx CHANGED
@@ -6,8 +6,7 @@ import {
6
  MessageSquare,
7
  Settings,
8
  Brain,
9
- Bot,
10
- Users
11
  } from 'lucide-react'
12
 
13
  const navigation = [
@@ -15,7 +14,7 @@ const navigation = [
15
  name: 'Home',
16
  href: '/',
17
  icon: Home,
18
- description: 'Overview and getting started'
19
  },
20
  {
21
  name: 'Chat Playground',
@@ -35,12 +34,6 @@ const navigation = [
35
  icon: Bot,
36
  description: 'Manage your custom AI assistants'
37
  },
38
- {
39
- name: 'Community',
40
- href: '/community',
41
- icon: Users,
42
- description: 'Discover and share assistant templates'
43
- },
44
  {
45
  name: 'Settings',
46
  href: '/settings',
 
6
  MessageSquare,
7
  Settings,
8
  Brain,
9
+ Bot
 
10
  } from 'lucide-react'
11
 
12
  const navigation = [
 
14
  name: 'Home',
15
  href: '/',
16
  icon: Home,
17
+ description: 'Overview and AI assistant templates'
18
  },
19
  {
20
  name: 'Chat Playground',
 
34
  icon: Bot,
35
  description: 'Manage your custom AI assistants'
36
  },
 
 
 
 
 
 
37
  {
38
  name: 'Settings',
39
  href: '/settings',
frontend/src/pages/Community.tsx DELETED
@@ -1,313 +0,0 @@
1
- import { useState, useEffect } from 'react'
2
- import { useNavigate } from 'react-router-dom'
3
- import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
4
- import { Button } from '@/components/ui/button'
5
- import { Badge } from '@/components/ui/badge'
6
- import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
7
- import {
8
- Users,
9
- Star,
10
- Heart,
11
- Award
12
- } from 'lucide-react'
13
-
14
- // Community template interface
15
- interface CommunityTemplate {
16
- id: string
17
- name: string
18
- description: string
19
- author: string
20
- category: string
21
- tags: string[]
22
- model: string
23
- systemPrompt: string
24
- temperature: number
25
- maxTokens: number
26
- isOfficial: boolean
27
- createdAt: string
28
- }
29
-
30
- // Get predefined community templates
31
- function getCommunityTemplates(): CommunityTemplate[] {
32
- return [
33
- {
34
- id: 'code-reviewer',
35
- name: 'Code Review Expert',
36
- description: 'Professional code reviewer for detailed analysis and suggestions.',
37
- author: 'EdgeLLM Team',
38
- category: 'coding',
39
- tags: ['code review', 'programming'],
40
- model: 'Qwen/Qwen3-30B-A3B',
41
- systemPrompt: 'You are a senior software engineer. Analyze code for quality, best practices, performance, and security. Provide constructive feedback with specific examples.',
42
- temperature: 0.3,
43
- maxTokens: 1000,
44
-
45
- isOfficial: true,
46
- createdAt: '2024-01-15'
47
- },
48
- {
49
- id: 'writing-tutor',
50
- name: 'Writing Assistant',
51
- description: 'Helps improve writing with structure suggestions and clarity enhancements.',
52
- author: 'Community',
53
- category: 'writing',
54
- tags: ['writing', 'editing'],
55
- model: 'Qwen/Qwen3-30B-A3B',
56
- systemPrompt: 'You are a writing tutor. Help improve writing through structure, clarity, grammar, and style suggestions. Provide specific feedback and examples.',
57
- temperature: 0.4,
58
- maxTokens: 800,
59
-
60
- isOfficial: false,
61
- createdAt: '2024-01-20'
62
- },
63
- {
64
- id: 'creative-writer',
65
- name: 'Creative Writing Coach',
66
- description: 'Inspires creativity and helps develop compelling stories and characters.',
67
- author: 'Community',
68
- category: 'creative',
69
- tags: ['creative', 'storytelling'],
70
- model: 'Qwen/Qwen3-30B-A3B',
71
- systemPrompt: 'You are a creative writing coach. Help develop stories, characters, and narrative techniques. Provide encouraging feedback and creative suggestions.',
72
- temperature: 0.8,
73
- maxTokens: 1000,
74
-
75
- isOfficial: true,
76
- createdAt: '2024-01-30'
77
- }
78
- ]
79
- }
80
-
81
- export function Community() {
82
- const navigate = useNavigate()
83
- const [communityTemplates] = useState<CommunityTemplate[]>(getCommunityTemplates())
84
- const [likedTemplates, setLikedTemplates] = useState<string[]>([])
85
-
86
- useEffect(() => {
87
- loadLikedTemplates()
88
- }, [])
89
-
90
- const loadLikedTemplates = () => {
91
- try {
92
- const liked = JSON.parse(localStorage.getItem('likedTemplates') || '[]')
93
- setLikedTemplates(liked)
94
- } catch (error) {
95
- console.error('Failed to load liked templates:', error)
96
- }
97
- }
98
-
99
- const toggleLikeTemplate = (templateId: string) => {
100
- const updatedLiked = likedTemplates.includes(templateId)
101
- ? likedTemplates.filter(id => id !== templateId)
102
- : [...likedTemplates, templateId]
103
-
104
- setLikedTemplates(updatedLiked)
105
- localStorage.setItem('likedTemplates', JSON.stringify(updatedLiked))
106
- }
107
-
108
- const useTemplate = (template: CommunityTemplate) => {
109
- const assistantConfig = {
110
- name: template.name,
111
- description: template.description,
112
- model: template.model,
113
- systemPrompt: template.systemPrompt,
114
- temperature: template.temperature,
115
- maxTokens: template.maxTokens
116
- }
117
-
118
- localStorage.setItem('loadAssistantConfig', JSON.stringify(assistantConfig))
119
- navigate('/playground')
120
- }
121
-
122
- const featuredTemplates = communityTemplates.filter(t => t.isOfficial)
123
-
124
- return (
125
- <div className="min-h-screen bg-background">
126
- {/* Header */}
127
- <div className="border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
128
- <div className="max-w-6xl mx-auto p-6">
129
- <div className="flex items-center justify-between">
130
- <div className="flex items-center gap-3">
131
- <div className="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center">
132
- <Users className="h-5 w-5 text-white" />
133
- </div>
134
- <div>
135
- <h1 className="text-2xl font-bold">Community Templates</h1>
136
- <p className="text-sm text-muted-foreground">
137
- Discover and share AI assistant templates created by the community
138
- </p>
139
- </div>
140
- </div>
141
-
142
- </div>
143
- </div>
144
- </div>
145
-
146
- <div className="flex-1 p-6">
147
- <div className="max-w-6xl mx-auto space-y-6">
148
-
149
-
150
-
151
- {/* Tabs */}
152
- <Tabs defaultValue="all" className="space-y-6">
153
- <TabsList className="grid w-full grid-cols-3">
154
- <TabsTrigger value="all" className="flex items-center gap-2">
155
- <Users className="h-4 w-4" />
156
- All Templates
157
- </TabsTrigger>
158
- <TabsTrigger value="featured" className="flex items-center gap-2">
159
- <Star className="h-4 w-4" />
160
- Featured
161
- </TabsTrigger>
162
- <TabsTrigger value="liked" className="flex items-center gap-2">
163
- <Heart className="h-4 w-4" />
164
- My Likes
165
- </TabsTrigger>
166
- </TabsList>
167
-
168
- {/* All Templates Tab */}
169
- <TabsContent value="all" className="space-y-6">
170
- <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
171
- {communityTemplates.map((template) => (
172
- <CommunityTemplateCard
173
- key={template.id}
174
- template={template}
175
- isLiked={likedTemplates.includes(template.id)}
176
- onLike={() => toggleLikeTemplate(template.id)}
177
- onUse={() => useTemplate(template)}
178
- />
179
- ))}
180
- </div>
181
- </TabsContent>
182
-
183
- {/* Featured Templates Tab */}
184
- <TabsContent value="featured" className="space-y-6">
185
- <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
186
- {featuredTemplates.map((template) => (
187
- <CommunityTemplateCard
188
- key={template.id}
189
- template={template}
190
- isLiked={likedTemplates.includes(template.id)}
191
- onLike={() => toggleLikeTemplate(template.id)}
192
- onUse={() => useTemplate(template)}
193
- featured={true}
194
- />
195
- ))}
196
- </div>
197
- </TabsContent>
198
-
199
- {/* Liked Templates Tab */}
200
- <TabsContent value="liked" className="space-y-6">
201
- {likedTemplates.length > 0 ? (
202
- <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
203
- {communityTemplates
204
- .filter(t => likedTemplates.includes(t.id))
205
- .map((template) => (
206
- <CommunityTemplateCard
207
- key={template.id}
208
- template={template}
209
- isLiked={true}
210
- onLike={() => toggleLikeTemplate(template.id)}
211
- onUse={() => useTemplate(template)}
212
- />
213
- ))
214
- }
215
- </div>
216
- ) : (
217
- <Card className="text-center py-16">
218
- <Heart className="h-16 w-16 mx-auto text-muted-foreground mb-6" />
219
- <h3 className="text-xl font-medium mb-3">No liked templates yet</h3>
220
- <p className="text-muted-foreground mb-6 max-w-md mx-auto">
221
- Explore the community templates and click the heart icon to save your favorites for easy access.
222
- </p>
223
- </Card>
224
- )}
225
- </TabsContent>
226
- </Tabs>
227
-
228
-
229
- </div>
230
- </div>
231
- </div>
232
- )
233
- }
234
-
235
- // Community Template Card Component
236
- function CommunityTemplateCard({
237
- template,
238
- isLiked,
239
- onLike,
240
- onUse,
241
- featured = false
242
- }: {
243
- template: CommunityTemplate
244
- isLiked: boolean
245
- onLike: () => void
246
- onUse: () => void
247
- featured?: boolean
248
- }) {
249
- return (
250
- <Card className={`hover:shadow-lg transition-all duration-200 hover:-translate-y-1 ${featured ? 'ring-2 ring-yellow-200 shadow-md' : ''}`}>
251
- <CardHeader className="pb-3">
252
- <div className="flex items-start justify-between">
253
- <div className="flex-1">
254
- <div className="flex items-center gap-2 mb-1">
255
- <CardTitle className="text-base">{template.name}</CardTitle>
256
- {template.isOfficial && (
257
- <Badge variant="default" className="text-xs px-2 py-0 bg-green-600">
258
- <Award className="h-3 w-3 mr-1" />
259
- Official
260
- </Badge>
261
- )}
262
- {featured && (
263
- <Star className="h-4 w-4 text-yellow-500 fill-current" />
264
- )}
265
- </div>
266
- <p className="text-xs text-blue-600 font-medium">by {template.author}</p>
267
- <p className="text-sm text-muted-foreground mt-2 line-clamp-2">
268
- {template.description}
269
- </p>
270
- </div>
271
- <Button
272
- variant="ghost"
273
- size="sm"
274
- onClick={onLike}
275
- className={isLiked ? "text-red-500" : "text-muted-foreground hover:text-red-500"}
276
- title={isLiked ? "Unlike" : "Like"}
277
- >
278
- <Heart className={`h-4 w-4 ${isLiked ? 'fill-current' : ''}`} />
279
- </Button>
280
- </div>
281
- </CardHeader>
282
- <CardContent className="space-y-4">
283
- {/* Tags */}
284
- <div className="flex flex-wrap gap-1">
285
- {template.tags.slice(0, 3).map((tag) => (
286
- <Badge key={tag} variant="secondary" className="text-xs">
287
- {tag}
288
- </Badge>
289
- ))}
290
- </div>
291
-
292
- {/* Configuration */}
293
- <div className="grid grid-cols-2 gap-2 text-xs">
294
- <div className="bg-gray-50 rounded p-2">
295
- <span className="font-medium text-gray-600">Temperature:</span>
296
- <p className="text-gray-800">{template.temperature}</p>
297
- </div>
298
- <div className="bg-gray-50 rounded p-2">
299
- <span className="font-medium text-gray-600">Max Tokens:</span>
300
- <p className="text-gray-800">{template.maxTokens}</p>
301
- </div>
302
- </div>
303
-
304
- {/* Action */}
305
- <div className="flex justify-end">
306
- <Button size="sm" onClick={onUse}>
307
- Use Template
308
- </Button>
309
- </div>
310
- </CardContent>
311
- </Card>
312
- )
313
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/src/pages/Home.tsx CHANGED
@@ -3,7 +3,8 @@ import { useNavigate } from 'react-router-dom'
3
  import { Badge } from '@/components/ui/badge'
4
  import { Button } from '@/components/ui/button'
5
  import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
6
- import { Brain, MessageSquare, ArrowRight, Users, Award } from 'lucide-react'
 
7
 
8
  // Community template interface
9
  interface CommunityTemplate {
@@ -21,8 +22,8 @@ interface CommunityTemplate {
21
  createdAt: string
22
  }
23
 
24
- // Get featured community templates (only official ones for home page)
25
- function getFeaturedTemplates(): CommunityTemplate[] {
26
  return [
27
  {
28
  id: 'code-reviewer',
@@ -38,11 +39,25 @@ function getFeaturedTemplates(): CommunityTemplate[] {
38
  isOfficial: true,
39
  createdAt: '2024-01-15'
40
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  {
42
  id: 'creative-writer',
43
  name: 'Creative Writing Coach',
44
  description: 'Inspires creativity and helps develop compelling stories and characters.',
45
- author: 'EdgeLLM Team',
46
  category: 'creative',
47
  tags: ['creative', 'storytelling'],
48
  model: 'Qwen/Qwen3-30B-A3B',
@@ -58,9 +73,12 @@ function getFeaturedTemplates(): CommunityTemplate[] {
58
  export function Home() {
59
  const navigate = useNavigate()
60
  const [isOnline, setIsOnline] = useState(false)
 
 
61
 
62
  useEffect(() => {
63
  checkSystemStatus()
 
64
  }, [])
65
 
66
  const checkSystemStatus = async () => {
@@ -73,6 +91,24 @@ export function Home() {
73
  }
74
  }
75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  const useTemplate = (template: CommunityTemplate) => {
77
  const assistantConfig = {
78
  name: template.name,
@@ -87,7 +123,7 @@ export function Home() {
87
  navigate('/playground')
88
  }
89
 
90
- const featuredTemplates = getFeaturedTemplates()
91
 
92
  return (
93
  <div className="min-h-screen bg-background">
@@ -138,73 +174,145 @@ export function Home() {
138
  </div>
139
  </div>
140
 
141
- {/* Featured Templates Section */}
142
  <div className="py-16 bg-background">
143
  <div className="max-w-6xl mx-auto px-6">
144
  <div className="text-center mb-12">
145
  <div className="flex items-center justify-center gap-2 mb-4">
146
  <Users className="h-6 w-6 text-blue-600" />
147
- <h2 className="text-3xl font-bold text-gray-900">Featured Templates</h2>
148
  </div>
149
  <p className="text-gray-600 max-w-2xl mx-auto">
150
- Get started quickly with pre-configured AI assistants created by our team
151
  </p>
152
  </div>
153
 
154
- <div className="grid grid-cols-1 md:grid-cols-2 gap-8 mb-8">
155
- {featuredTemplates.map((template) => (
156
- <TemplateCard
157
- key={template.id}
158
- template={template}
159
- onUse={() => useTemplate(template)}
160
- />
161
- ))}
162
- </div>
 
 
 
 
 
 
163
 
164
- <div className="text-center">
165
- <Button
166
- variant="outline"
167
- onClick={() => navigate('/community')}
168
- className="flex items-center gap-2"
169
- >
170
- <Users className="h-4 w-4" />
171
- View All Templates
172
- <ArrowRight className="h-4 w-4" />
173
- </Button>
174
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  </div>
176
  </div>
177
  </div>
178
  )
179
  }
180
 
181
- // Template Card Component for Home page
182
- interface TemplateCardProps {
 
 
 
 
 
 
183
  template: CommunityTemplate
 
 
184
  onUse: () => void
185
- }
186
-
187
- function TemplateCard({ template, onUse }: TemplateCardProps) {
188
  return (
189
- <Card className="hover:shadow-lg transition-all duration-200 hover:-translate-y-1">
190
  <CardHeader className="pb-3">
191
  <div className="flex items-start justify-between">
192
  <div className="flex-1">
193
  <div className="flex items-center gap-2 mb-1">
194
- <CardTitle className="text-lg">{template.name}</CardTitle>
195
- <Badge variant="default" className="text-xs px-2 py-0 bg-green-600">
196
- <Award className="h-3 w-3 mr-1" />
197
- Official
198
- </Badge>
 
 
 
 
 
199
  </div>
200
- <p className="text-xs text-blue-600 font-medium mb-2">by {template.author}</p>
201
- <p className="text-sm text-muted-foreground">
202
  {template.description}
203
  </p>
204
  </div>
 
 
 
 
 
 
 
 
 
205
  </div>
206
  </CardHeader>
207
-
208
  <CardContent className="space-y-4">
209
  {/* Tags */}
210
  <div className="flex flex-wrap gap-1">
@@ -216,7 +324,7 @@ function TemplateCard({ template, onUse }: TemplateCardProps) {
216
  </div>
217
 
218
  {/* Configuration */}
219
- <div className="grid grid-cols-2 gap-3 text-xs">
220
  <div className="bg-gray-50 rounded p-2">
221
  <span className="font-medium text-gray-600">Temperature:</span>
222
  <p className="text-gray-800">{template.temperature}</p>
@@ -228,10 +336,11 @@ function TemplateCard({ template, onUse }: TemplateCardProps) {
228
  </div>
229
 
230
  {/* Action */}
231
- <Button onClick={onUse} className="w-full flex items-center gap-2">
232
- <MessageSquare className="h-4 w-4" />
233
- Try This Template
234
- </Button>
 
235
  </CardContent>
236
  </Card>
237
  )
 
3
  import { Badge } from '@/components/ui/badge'
4
  import { Button } from '@/components/ui/button'
5
  import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
6
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
7
+ import { Brain, MessageSquare, ArrowRight, Users, Award, Star, Heart } from 'lucide-react'
8
 
9
  // Community template interface
10
  interface CommunityTemplate {
 
22
  createdAt: string
23
  }
24
 
25
+ // Get all community templates
26
+ function getCommunityTemplates(): CommunityTemplate[] {
27
  return [
28
  {
29
  id: 'code-reviewer',
 
39
  isOfficial: true,
40
  createdAt: '2024-01-15'
41
  },
42
+ {
43
+ id: 'writing-tutor',
44
+ name: 'Writing Assistant',
45
+ description: 'Helps improve writing with structure suggestions and clarity enhancements.',
46
+ author: 'Community',
47
+ category: 'writing',
48
+ tags: ['writing', 'editing'],
49
+ model: 'Qwen/Qwen3-30B-A3B',
50
+ systemPrompt: 'You are a writing tutor. Help improve writing through structure, clarity, grammar, and style suggestions. Provide specific feedback and examples.',
51
+ temperature: 0.4,
52
+ maxTokens: 800,
53
+ isOfficial: false,
54
+ createdAt: '2024-01-20'
55
+ },
56
  {
57
  id: 'creative-writer',
58
  name: 'Creative Writing Coach',
59
  description: 'Inspires creativity and helps develop compelling stories and characters.',
60
+ author: 'Community',
61
  category: 'creative',
62
  tags: ['creative', 'storytelling'],
63
  model: 'Qwen/Qwen3-30B-A3B',
 
73
  export function Home() {
74
  const navigate = useNavigate()
75
  const [isOnline, setIsOnline] = useState(false)
76
+ const [communityTemplates] = useState<CommunityTemplate[]>(getCommunityTemplates())
77
+ const [likedTemplates, setLikedTemplates] = useState<string[]>([])
78
 
79
  useEffect(() => {
80
  checkSystemStatus()
81
+ loadLikedTemplates()
82
  }, [])
83
 
84
  const checkSystemStatus = async () => {
 
91
  }
92
  }
93
 
94
+ const loadLikedTemplates = () => {
95
+ try {
96
+ const liked = JSON.parse(localStorage.getItem('likedTemplates') || '[]')
97
+ setLikedTemplates(liked)
98
+ } catch (error) {
99
+ console.error('Failed to load liked templates:', error)
100
+ }
101
+ }
102
+
103
+ const toggleLikeTemplate = (templateId: string) => {
104
+ const updatedLiked = likedTemplates.includes(templateId)
105
+ ? likedTemplates.filter(id => id !== templateId)
106
+ : [...likedTemplates, templateId]
107
+
108
+ setLikedTemplates(updatedLiked)
109
+ localStorage.setItem('likedTemplates', JSON.stringify(updatedLiked))
110
+ }
111
+
112
  const useTemplate = (template: CommunityTemplate) => {
113
  const assistantConfig = {
114
  name: template.name,
 
123
  navigate('/playground')
124
  }
125
 
126
+ const featuredTemplates = communityTemplates.filter(t => t.isOfficial)
127
 
128
  return (
129
  <div className="min-h-screen bg-background">
 
174
  </div>
175
  </div>
176
 
177
+ {/* Community Templates Section */}
178
  <div className="py-16 bg-background">
179
  <div className="max-w-6xl mx-auto px-6">
180
  <div className="text-center mb-12">
181
  <div className="flex items-center justify-center gap-2 mb-4">
182
  <Users className="h-6 w-6 text-blue-600" />
183
+ <h2 className="text-3xl font-bold text-gray-900">AI Assistant Templates</h2>
184
  </div>
185
  <p className="text-gray-600 max-w-2xl mx-auto">
186
+ Discover pre-configured AI assistants for various tasks and workflows
187
  </p>
188
  </div>
189
 
190
+ <Tabs defaultValue="all" className="space-y-6">
191
+ <TabsList className="grid w-full grid-cols-3">
192
+ <TabsTrigger value="all" className="flex items-center gap-2">
193
+ <Users className="h-4 w-4" />
194
+ All Templates
195
+ </TabsTrigger>
196
+ <TabsTrigger value="featured" className="flex items-center gap-2">
197
+ <Star className="h-4 w-4" />
198
+ Featured
199
+ </TabsTrigger>
200
+ <TabsTrigger value="liked" className="flex items-center gap-2">
201
+ <Heart className="h-4 w-4" />
202
+ My Likes
203
+ </TabsTrigger>
204
+ </TabsList>
205
 
206
+ <TabsContent value="all">
207
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
208
+ {communityTemplates.map((template) => (
209
+ <CommunityTemplateCard
210
+ key={template.id}
211
+ template={template}
212
+ isLiked={likedTemplates.includes(template.id)}
213
+ onLike={() => toggleLikeTemplate(template.id)}
214
+ onUse={() => useTemplate(template)}
215
+ />
216
+ ))}
217
+ </div>
218
+ </TabsContent>
219
+
220
+ <TabsContent value="featured">
221
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
222
+ {featuredTemplates.map((template) => (
223
+ <CommunityTemplateCard
224
+ key={template.id}
225
+ template={template}
226
+ isLiked={likedTemplates.includes(template.id)}
227
+ onLike={() => toggleLikeTemplate(template.id)}
228
+ onUse={() => useTemplate(template)}
229
+ featured={true}
230
+ />
231
+ ))}
232
+ </div>
233
+ {featuredTemplates.length === 0 && (
234
+ <Card className="p-8 text-center">
235
+ <p className="text-muted-foreground">No featured templates available.</p>
236
+ </Card>
237
+ )}
238
+ </TabsContent>
239
+
240
+ <TabsContent value="liked">
241
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
242
+ {communityTemplates
243
+ .filter(t => likedTemplates.includes(t.id))
244
+ .map((template) => (
245
+ <CommunityTemplateCard
246
+ key={template.id}
247
+ template={template}
248
+ isLiked={true}
249
+ onLike={() => toggleLikeTemplate(template.id)}
250
+ onUse={() => useTemplate(template)}
251
+ />
252
+ ))}
253
+ </div>
254
+ {likedTemplates.length === 0 && (
255
+ <Card className="p-8 text-center">
256
+ <p className="text-muted-foreground">
257
+ You haven't liked any templates yet. Click the heart icon on templates you like!
258
+ </p>
259
+ </Card>
260
+ )}
261
+ </TabsContent>
262
+ </Tabs>
263
  </div>
264
  </div>
265
  </div>
266
  )
267
  }
268
 
269
+ // Community Template Card Component
270
+ function CommunityTemplateCard({
271
+ template,
272
+ isLiked,
273
+ onLike,
274
+ onUse,
275
+ featured = false
276
+ }: {
277
  template: CommunityTemplate
278
+ isLiked: boolean
279
+ onLike: () => void
280
  onUse: () => void
281
+ featured?: boolean
282
+ }) {
 
283
  return (
284
+ <Card className={`hover:shadow-lg transition-all duration-200 hover:-translate-y-1 ${featured ? 'ring-2 ring-yellow-200 shadow-md' : ''}`}>
285
  <CardHeader className="pb-3">
286
  <div className="flex items-start justify-between">
287
  <div className="flex-1">
288
  <div className="flex items-center gap-2 mb-1">
289
+ <CardTitle className="text-base">{template.name}</CardTitle>
290
+ {template.isOfficial && (
291
+ <Badge variant="default" className="text-xs px-2 py-0 bg-green-600">
292
+ <Award className="h-3 w-3 mr-1" />
293
+ Official
294
+ </Badge>
295
+ )}
296
+ {featured && (
297
+ <Star className="h-4 w-4 text-yellow-500 fill-current" />
298
+ )}
299
  </div>
300
+ <p className="text-xs text-blue-600 font-medium">by {template.author}</p>
301
+ <p className="text-sm text-muted-foreground mt-2 line-clamp-2">
302
  {template.description}
303
  </p>
304
  </div>
305
+ <Button
306
+ variant="ghost"
307
+ size="sm"
308
+ onClick={onLike}
309
+ className={isLiked ? "text-red-500" : "text-muted-foreground hover:text-red-500"}
310
+ title={isLiked ? "Unlike" : "Like"}
311
+ >
312
+ <Heart className={`h-4 w-4 ${isLiked ? 'fill-current' : ''}`} />
313
+ </Button>
314
  </div>
315
  </CardHeader>
 
316
  <CardContent className="space-y-4">
317
  {/* Tags */}
318
  <div className="flex flex-wrap gap-1">
 
324
  </div>
325
 
326
  {/* Configuration */}
327
+ <div className="grid grid-cols-2 gap-2 text-xs">
328
  <div className="bg-gray-50 rounded p-2">
329
  <span className="font-medium text-gray-600">Temperature:</span>
330
  <p className="text-gray-800">{template.temperature}</p>
 
336
  </div>
337
 
338
  {/* Action */}
339
+ <div className="flex justify-end">
340
+ <Button size="sm" onClick={onUse}>
341
+ Use Template
342
+ </Button>
343
+ </div>
344
  </CardContent>
345
  </Card>
346
  )
static/assets/index-7b7fcf98.js ADDED
The diff for this file is too large to render. See raw diff
 
static/assets/index-7b7fcf98.js.map ADDED
The diff for this file is too large to render. See raw diff
 
static/assets/index-b096dd94.css ADDED
@@ -0,0 +1 @@
 
 
1
+ *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background: 0 0% 100%;--foreground: 222.2 84% 4.9%;--card: 0 0% 100%;--card-foreground: 222.2 84% 4.9%;--popover: 0 0% 100%;--popover-foreground: 222.2 84% 4.9%;--primary: 221.2 83.2% 53.3%;--primary-foreground: 210 40% 98%;--secondary: 210 40% 96%;--secondary-foreground: 222.2 84% 4.9%;--muted: 210 40% 96%;--muted-foreground: 215.4 16.3% 46.9%;--accent: 210 40% 96%;--accent-foreground: 222.2 84% 4.9%;--destructive: 0 84.2% 60.2%;--destructive-foreground: 210 40% 98%;--border: 214.3 31.8% 91.4%;--input: 214.3 31.8% 91.4%;--ring: 221.2 83.2% 53.3%;--radius: .5rem}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}.pointer-events-none{pointer-events:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.inset-y-0{top:0;bottom:0}.left-0{left:0}.left-2{left:.5rem}.left-\[50\%\]{left:50%}.top-\[50\%\]{top:50%}.z-40{z-index:40}.z-50{z-index:50}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.mb-1{margin-bottom:.25rem}.mb-12{margin-bottom:3rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-96{max-height:24rem}.min-h-0{min-height:0px}.min-h-\[250px\]{min-height:250px}.min-h-\[60px\]{min-height:60px}.min-h-\[80px\]{min-height:80px}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-16{width:4rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-80{width:20rem}.w-\[480px\]{width:480px}.w-full{width:100%}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-6xl{max-width:72rem}.max-w-\[300px\]{max-width:300px}.max-w-\[75\%\]{max-width:75%}.max-w-\[80\%\]{max-width:80%}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-none{max-width:none}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-x-full{--tw-translate-x: -100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\[-50\%\]{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[-50\%\]{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.resize-y{resize:vertical}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-blue-500{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.border-green-200{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-input{border-color:hsl(var(--input))}.border-muted{border-color:hsl(var(--muted))}.border-primary{border-color:hsl(var(--primary))}.border-transparent{border-color:transparent}.bg-accent{background-color:hsl(var(--accent))}.bg-background{background-color:hsl(var(--background))}.bg-background\/50{background-color:hsl(var(--background) / .5)}.bg-background\/80{background-color:hsl(var(--background) / .8)}.bg-background\/95{background-color:hsl(var(--background) / .95)}.bg-black\/50{background-color:#00000080}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-50\/50{background-color:#eff6ff80}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-card{background-color:hsl(var(--card))}.bg-destructive{background-color:hsl(var(--destructive))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-600{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-muted{background-color:hsl(var(--muted))}.bg-muted\/30{background-color:hsl(var(--muted) / .3)}.bg-popover{background-color:hsl(var(--popover))}.bg-primary{background-color:hsl(var(--primary))}.bg-purple-600{--tw-bg-opacity: 1;background-color:rgb(147 51 234 / var(--tw-bg-opacity, 1))}.bg-secondary{background-color:hsl(var(--secondary))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-yellow-50{--tw-bg-opacity: 1;background-color:rgb(254 252 232 / var(--tw-bg-opacity, 1))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-blue-50{--tw-gradient-from: #eff6ff var(--tw-gradient-from-position);--tw-gradient-to: rgb(239 246 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-indigo-100{--tw-gradient-to: #e0e7ff var(--tw-gradient-to-position)}.fill-current{fill:currentColor}.p-0{padding:0}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0{padding-top:0;padding-bottom:0}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-3{padding-bottom:.75rem}.pb-6{padding-bottom:1.5rem}.pl-4{padding-left:1rem}.pl-8{padding-left:2rem}.pr-2{padding-right:.5rem}.pt-0{padding-top:0}.pt-2{padding-top:.5rem}.pt-6{padding-top:1.5rem}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-accent-foreground{color:hsl(var(--accent-foreground))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-blue-900{--tw-text-opacity: 1;color:rgb(30 58 138 / var(--tw-text-opacity, 1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-destructive{color:hsl(var(--destructive))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-foreground{color:hsl(var(--foreground))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-popover-foreground{color:hsl(var(--popover-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-purple-500{--tw-text-opacity: 1;color:rgb(168 85 247 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.underline-offset-4{text-underline-offset:4px}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring-0{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-yellow-200{--tw-ring-opacity: 1;--tw-ring-color: rgb(254 240 138 / var(--tw-ring-opacity, 1))}.ring-offset-background{--tw-ring-offset-color: hsl(var(--background))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur{--tw-backdrop-blur: blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}@keyframes enter{0%{opacity:var(--tw-enter-opacity, 1);transform:translate3d(var(--tw-enter-translate-x, 0),var(--tw-enter-translate-y, 0),0) scale3d(var(--tw-enter-scale, 1),var(--tw-enter-scale, 1),var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity, 1);transform:translate3d(var(--tw-exit-translate-x, 0),var(--tw-exit-translate-y, 0),0) scale3d(var(--tw-exit-scale, 1),var(--tw-exit-scale, 1),var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0))}}.duration-200{animation-duration:.2s}.duration-300{animation-duration:.3s}.ease-in-out{animation-timing-function:cubic-bezier(.4,0,.2,1)}.file\:border-0::file-selector-button{border-width:0px}.file\:bg-transparent::file-selector-button{background-color:transparent}.file\:text-sm::file-selector-button{font-size:.875rem;line-height:1.25rem}.file\:font-medium::file-selector-button{font-weight:500}.placeholder\:text-muted-foreground::-moz-placeholder{color:hsl(var(--muted-foreground))}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.last\:mb-0:last-child{margin-bottom:0}.hover\:-translate-y-1:hover{--tw-translate-y: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-blue-50:hover{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.hover\:bg-destructive\/80:hover{background-color:hsl(var(--destructive) / .8)}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--destructive) / .9)}.hover\:bg-primary\/80:hover{background-color:hsl(var(--primary) / .8)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-blue-700:hover{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.hover\:text-destructive:hover{color:hsl(var(--destructive))}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.hover\:text-red-500:hover{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.hover\:text-red-600:hover{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-lg:hover{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:border-blue-400:focus{--tw-border-opacity: 1;border-color:rgb(96 165 250 / var(--tw-border-opacity, 1))}.focus\:bg-accent:focus{background-color:hsl(var(--accent))}.focus\:text-accent-foreground:focus{color:hsl(var(--accent-foreground))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-blue-100:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(219 234 254 / var(--tw-ring-opacity, 1))}.focus\:ring-ring:focus{--tw-ring-color: hsl(var(--ring))}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color: hsl(var(--ring))}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.focus-visible\:ring-offset-background:focus-visible{--tw-ring-offset-color: hsl(var(--background))}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.peer:disabled~.peer-disabled\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\:opacity-70{opacity:.7}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=checked\]\:translate-x-5[data-state=checked]{--tw-translate-x: 1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked]{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:hsl(var(--background))}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:hsl(var(--primary))}.data-\[state\=unchecked\]\:bg-input[data-state=unchecked]{background-color:hsl(var(--input))}.data-\[state\=active\]\:text-foreground[data-state=active]{color:hsl(var(--foreground))}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.data-\[state\=open\]\:animate-in[data-state=open]{animation-name:enter;animation-duration:.15s;--tw-enter-opacity: initial;--tw-enter-scale: initial;--tw-enter-rotate: initial;--tw-enter-translate-x: initial;--tw-enter-translate-y: initial}.data-\[state\=closed\]\:animate-out[data-state=closed]{animation-name:exit;animation-duration:.15s;--tw-exit-opacity: initial;--tw-exit-scale: initial;--tw-exit-rotate: initial;--tw-exit-translate-x: initial;--tw-exit-translate-y: initial}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity: 0}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity: 0}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale: .95}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale: .95}.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y: -.5rem}.data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x: .5rem}.data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x: -.5rem}.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y: .5rem}.data-\[state\=closed\]\:slide-out-to-left-1\/2[data-state=closed]{--tw-exit-translate-x: -50%}.data-\[state\=closed\]\:slide-out-to-top-\[48\%\][data-state=closed]{--tw-exit-translate-y: -48%}.data-\[state\=open\]\:slide-in-from-left-1\/2[data-state=open]{--tw-enter-translate-x: -50%}.data-\[state\=open\]\:slide-in-from-top-\[48\%\][data-state=open]{--tw-enter-translate-y: -48%}@supports (backdrop-filter: var(--tw)){.supports-\[backdrop-filter\]\:bg-background\/60{background-color:hsl(var(--background) / .6)}}@media (min-width: 640px){.sm\:mt-0{margin-top:0}.sm\:inline{display:inline}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}.sm\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:text-left{text-align:left}}@media (min-width: 768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width: 1024px){.lg\:static{position:static}.lg\:inset-0{top:0;right:0;bottom:0;left:0}.lg\:hidden{display:none}.lg\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (min-width: 1280px){.xl\:w-\[520px\]{width:520px}}.\[\&\>span\]\:line-clamp-1>span{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}
static/index.html CHANGED
@@ -5,8 +5,8 @@
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <title>Edge LLM</title>
8
- <script type="module" crossorigin src="/assets/index-19d28edd.js"></script>
9
- <link rel="stylesheet" href="/assets/index-f4b0b810.css">
10
  </head>
11
  <body>
12
  <div id="root"></div>
 
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <title>Edge LLM</title>
8
+ <script type="module" crossorigin src="/assets/index-7b7fcf98.js"></script>
9
+ <link rel="stylesheet" href="/assets/index-b096dd94.css">
10
  </head>
11
  <body>
12
  <div id="root"></div>