-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
526 lines (488 loc) · 17.1 KB
/
Copy pathindex.html
File metadata and controls
526 lines (488 loc) · 17.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>INSIGHT-FORGE</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: "#14b8a6",
accent: "#22d3ee",
surface: "#0b1220",
panel: "#07101f",
soft: "#0f1a2c",
stroke: "#1f2a3d",
},
boxShadow: {
glow: "0 0 0 1px rgba(31,42,61,.7), 0 30px 80px rgba(0,0,0,.55)",
},
},
},
};
</script>
<style>
.dots::after {
content: "";
animation: dots 1.5s infinite;
}
@keyframes dots {
0% {
content: "";
}
33% {
content: ".";
}
66% {
content: "..";
}
100% {
content: "...";
}
}
.status-pulse {
animation: pulse 1.6s ease-in-out infinite;
}
@keyframes pulse {
0%,
100% {
opacity: 0.65;
}
50% {
opacity: 1;
}
}
.reveal {
animation: reveal 0.45s ease-out forwards;
}
@keyframes reveal {
from {
opacity: 0;
transform: translateY(14px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.glass {
background: rgba(7, 14, 31, 0.68);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(31, 42, 61, 0.8);
}
.noise {
position: fixed;
inset: 0;
background: url("https://grainy-gradients.vercel.app/noise.svg");
opacity: 0.06;
pointer-events: none;
z-index: -1;
}
.orb {
position: fixed;
width: 520px;
height: 520px;
border-radius: 999px;
filter: blur(160px);
opacity: 0.35;
z-index: -2;
}
.orb1 {
background: rgba(20, 184, 166, 0.55);
top: -180px;
left: -180px;
}
.orb2 {
background: rgba(34, 211, 238, 0.55);
bottom: -190px;
right: -190px;
}
.hidden {
display: none;
}
.skel {
background: linear-gradient(
90deg,
rgba(255, 255, 255, 0.06),
rgba(255, 255, 255, 0.12),
rgba(255, 255, 255, 0.06)
);
background-size: 200% 100%;
animation: shimmer 1.15s infinite;
border: 1px solid rgba(31, 42, 61, 0.65);
}
@keyframes shimmer {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
</style>
</head>
<body class="bg-surface text-slate-100 min-h-screen overflow-hidden">
<div class="noise"></div>
<div class="orb orb1"></div>
<div class="orb orb2"></div>
<!-- AUTH SCREEN -->
<section
id="authScreen"
class="min-h-screen flex items-center justify-center px-6"
>
<div class="w-full max-w-6xl grid lg:grid-cols-2 gap-8 items-center">
<!-- Left: Branding -->
<div class="space-y-6">
<div class="flex items-center gap-3">
<div
class="w-11 h-11 rounded-2xl bg-primary/15 border border-stroke flex items-center justify-center shadow-glow"
>
<svg
width="26"
height="26"
viewBox="0 0 100 100"
fill="currentColor"
class="text-primary"
>
<polygon points="50,5 93,27 93,73 50,95 7,73 7,27" />
<circle cx="50" cy="50" r="18" fill="#07101f" />
</svg>
</div>
<div>
<p class="text-lg font-semibold tracking-tight">
Insight<span class="text-primary">Forge</span>
</p>
<p class="text-xs text-slate-400 -mt-0.5">
Extract clarity from the web
</p>
</div>
</div>
<h1
class="text-4xl md:text-5xl font-semibold tracking-tight leading-tight"
>
Turn any URL into <span class="text-primary">clean insight</span>.
</h1>
<p class="text-slate-300 max-w-xl leading-relaxed">
Paste a link — we extract the content, summarize it with AI, tag key
topics, and save results for instant reloads.
</p>
<!-- Feature grid -->
<div class="grid sm:grid-cols-2 gap-4 pt-2">
<div class="glass rounded-2xl p-4">
<p class="text-sm font-medium">⚡ Fast repeats</p>
<p class="text-xs text-slate-400 mt-1">
Redis caching makes already-seen links load almost instantly.
</p>
</div>
<div class="glass rounded-2xl p-4">
<p class="text-sm font-medium">🧠 Structured summaries</p>
<p class="text-xs text-slate-400 mt-1">
Readable output with takeaways — not a wall of text.
</p>
</div>
<div class="glass rounded-2xl p-4">
<p class="text-sm font-medium">🧷 Topic tagging</p>
<p class="text-xs text-slate-400 mt-1">
Auto-detected topics help you organize a reading list.
</p>
</div>
<div class="glass rounded-2xl p-4">
<p class="text-sm font-medium">🗂️ Saved history</p>
<p class="text-xs text-slate-400 mt-1">
Quickly reopen previous summaries from the sidebar.
</p>
</div>
</div>
</div>
<!-- Right: Auth card -->
<div class="glass rounded-3xl p-7 md:p-8 shadow-glow">
<div class="flex items-center justify-between gap-4">
<div>
<h2 class="text-xl font-semibold">Welcome back</h2>
<p class="text-sm text-slate-400 mt-1">
Log in to access your dashboard.
</p>
</div>
<span
id="authPill"
class="text-xs px-3 py-1 rounded-full bg-soft border border-stroke text-slate-300"
>
Login
</span>
</div>
<!-- Tabs -->
<div
class="mt-6 grid grid-cols-2 gap-2 p-1 rounded-2xl bg-soft border border-stroke"
>
<button
id="loginTab"
class="py-2 rounded-xl text-sm font-medium bg-panel border border-stroke"
>
Login
</button>
<button
id="signupTab"
class="py-2 rounded-xl text-sm font-medium text-slate-300 hover:text-white"
>
Sign up
</button>
</div>
<!-- Login form -->
<form id="loginForm" class="mt-6 space-y-4">
<div>
<label class="text-xs text-slate-400">Username</label>
<input
id="loginUser"
class="mt-2 w-full bg-surface border border-stroke rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-primary/70"
placeholder="name"
autocomplete="username"
/>
</div>
<div>
<label class="text-xs text-slate-400">Password</label>
<input
id="loginPass"
type="password"
class="mt-2 w-full bg-surface border border-stroke rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-primary/70"
placeholder="••••••••"
autocomplete="current-password"
/>
</div>
<button
type="submit"
class="w-full py-3.5 rounded-xl bg-primary hover:bg-teal-400 active:scale-[0.99] transition font-semibold text-slate-900"
>
Continue
</button>
<p id="authStatus" class="text-sm text-slate-400"></p>
<p class="text-xs text-slate-500 leading-relaxed"></p>
</form>
<!-- Signup form -->
<form id="signupForm" class="mt-6 space-y-4 hidden">
<div>
<label class="text-xs text-slate-400">Username</label>
<input
id="signupUser"
class="mt-2 w-full bg-surface border border-stroke rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-primary/70"
placeholder="create a username"
autocomplete="username"
/>
</div>
<div>
<label class="text-xs text-slate-400">Password</label>
<input
id="signupPass"
type="password"
class="mt-2 w-full bg-surface border border-stroke rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-primary/70"
placeholder="create a password"
autocomplete="new-password"
/>
</div>
<button
type="submit"
class="w-full py-3.5 rounded-xl bg-primary hover:bg-teal-400 active:scale-[0.99] transition font-semibold text-slate-900"
>
Create account
</button>
<p class="text-xs text-slate-500 leading-relaxed">
This creates a local demo account (saved in your browser).
</p>
</form>
</div>
</div>
</section>
<!-- APP SCREEN -->
<section id="appScreen" class="hidden">
<div class="flex h-screen">
<!-- SIDEBAR -->
<aside
class="w-80 border-r border-stroke bg-panel/70 backdrop-blur p-6 overflow-y-auto"
>
<div class="flex items-center gap-3 mb-7">
<div
class="w-10 h-10 rounded-2xl bg-primary/15 border border-stroke flex items-center justify-center"
>
<svg
width="24"
height="24"
viewBox="0 0 100 100"
fill="currentColor"
class="text-primary"
>
<polygon points="50,5 93,27 93,73 50,95 7,73 7,27" />
<circle cx="50" cy="50" r="18" fill="#07101f" />
</svg>
</div>
<div class="flex-1">
<div class="flex items-center justify-between">
<span class="text-lg font-semibold tracking-tight"
>Insight<span class="text-primary">Forge</span></span
>
</div>
<p class="text-xs text-slate-400">
Signed in as <span id="userLabel" class="text-slate-200"></span>
</p>
</div>
</div>
<button
id="logoutBtn"
class="w-full mb-6 py-2.5 rounded-xl bg-soft border border-stroke text-sm text-slate-200 hover:bg-surface transition"
>
Logout
</button>
<p class="text-xs text-slate-400 mb-3">Previous Summaries</p>
<div id="history" class="space-y-3">
<p class="text-xs text-slate-500">No summaries yet.</p>
</div>
</aside>
<!-- MAIN -->
<main class="flex-1 overflow-y-auto px-10 py-12">
<!-- Top -->
<div class="flex items-end justify-between gap-6 mb-10">
<div>
<h1 class="text-4xl font-semibold tracking-tight">Dashboard</h1>
<p class="mt-2 text-slate-400 max-w-2xl">
Paste a URL and generate a clean summary with topics +
takeaways.
</p>
</div>
<div class="text-right">
<span
id="statusPill"
class="inline-flex items-center gap-2 text-xs px-3 py-1 rounded-full bg-soft border border-stroke text-slate-300"
>
<span class="w-2 h-2 rounded-full bg-slate-500"></span>
Idle
</span>
</div>
</div>
<!-- Search Bar -->
<section class="glass rounded-3xl p-6 md:p-7 shadow-glow">
<label class="block text-xs text-slate-400 mb-2">Enter URL</label>
<div class="flex flex-col md:flex-row gap-3">
<div
class="flex-1 flex items-center gap-3 bg-surface border border-stroke rounded-2xl px-4 py-3 focus-within:ring-2 focus-within:ring-primary/60"
>
<span class="text-slate-400">🔗</span>
<input
id="urlInput"
type="url"
placeholder="https://example.com"
class="w-full bg-transparent outline-none text-slate-100 placeholder:text-slate-500"
/>
</div>
<button
id="analyzeBtn"
class="md:w-56 py-3.5 rounded-2xl bg-primary hover:bg-teal-400 active:scale-[0.99] transition font-semibold text-slate-900"
>
Generate Insight
</button>
</div>
<div class="mt-4 flex items-center gap-3">
<div
id="loader"
class="hidden w-5 h-5 border-2 border-primary border-t-transparent rounded-full animate-spin"
></div>
<p id="status" class="text-sm text-slate-400"></p>
</div>
</section>
<!-- RESULT -->
<section id="result" class="hidden mt-10 space-y-6">
<!-- Tabs -->
<div class="flex flex-wrap items-center justify-between gap-3">
<div
class="flex items-center gap-2 p-1 rounded-2xl bg-soft border border-stroke"
>
<button
id="tabSummary"
class="px-4 py-2 rounded-xl text-sm bg-panel border border-stroke"
>
Summary
</button>
<button
id="tabTakeaways"
class="px-4 py-2 rounded-xl text-sm text-slate-300 hover:text-white"
>
Key takeaways
</button>
</div>
<div class="flex items-center gap-2">
<span
id="wordCount"
class="text-xs text-slate-300 bg-soft px-3 py-1 rounded-full border border-stroke hidden"
>0 words</span
>
<button
id="copyBtn"
class="text-sm text-accent hover:underline"
>
Copy
</button>
<button
id="newBtn"
class="text-sm text-slate-400 hover:text-slate-200"
>
New URL
</button>
</div>
</div>
<div class="grid lg:grid-cols-3 gap-6">
<!-- Main card -->
<div class="lg:col-span-2 glass rounded-3xl p-7">
<div id="summaryView">
<h3 class="text-sm text-slate-400 mb-3">Summary</h3>
<p
id="summary"
class="leading-relaxed text-slate-200 whitespace-pre-wrap"
></p>
</div>
<div id="takeawaysView" class="hidden">
<h3 class="text-sm text-slate-400 mb-3">Key takeaways</h3>
<ul
id="takeaways"
class="space-y-2 text-slate-200 list-disc pl-5"
></ul>
</div>
</div>
<!-- Side card -->
<div class="glass rounded-3xl p-7">
<h3 class="text-sm text-slate-400 mb-4">Key Topics</h3>
<div id="topics" class="flex flex-wrap gap-2"></div>
<div class="mt-7">
<h3 class="text-sm text-slate-400 mb-3">Quick stats</h3>
<div class="space-y-2 text-sm">
<div
class="flex items-center justify-between text-slate-300"
>
<span>Words</span>
<span id="statWords">—</span>
</div>
<div
class="flex items-center justify-between text-slate-300"
>
<span>Est. read time</span>
<span id="statRead">—</span>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Skeleton (shown while waiting) -->
<section id="skeleton" class="hidden mt-10 space-y-6">
<div class="skel rounded-2xl h-10 w-72"></div>
<div class="grid lg:grid-cols-3 gap-6">
<div class="lg:col-span-2 skel rounded-3xl h-64"></div>
<div class="skel rounded-3xl h-64"></div>
</div>
</section>
</main>
</div>
</section>
<script src="app.js"></script>
</body>
</html>