00Boobs00 commited on
Commit
105b526
·
verified ·
1 Parent(s): f641eff

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +882 -19
index.html CHANGED
@@ -1,19 +1,882 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Nexus Command Center</title>
7
+ <!-- Importing FontAwesome for Icons -->
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <!-- Google Fonts -->
10
+ <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;700&display=swap" rel="stylesheet">
11
+
12
+ <style>
13
+ /*
14
+ * MODERN CSS VARIABLES & RESET
15
+ */
16
+ :root {
17
+ --bg-dark: #0f172a;
18
+ --bg-panel: rgba(30, 41, 59, 0.7);
19
+ --primary: #6366f1; /* Indigo */
20
+ --primary-hover: #4f46e5;
21
+ --accent: #06b6d4; /* Cyan */
22
+ --success: #10b981;
23
+ --danger: #ef4444;
24
+ --text-main: #f8fafc;
25
+ --text-muted: #94a3b8;
26
+ --glass-border: 1px solid rgba(255, 255, 255, 0.1);
27
+ --shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.5);
28
+ --radius: 16px;
29
+ --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
30
+ }
31
+
32
+ * {
33
+ box-sizing: border-box;
34
+ margin: 0;
35
+ padding: 0;
36
+ }
37
+
38
+ body {
39
+ font-family: 'Outfit', sans-serif;
40
+ background-color: var(--bg-dark);
41
+ background-image:
42
+ radial-gradient(at 0% 0%, rgba(99, 102, 241, 0.15) 0px, transparent 50%),
43
+ radial-gradient(at 100% 100%, rgba(6, 182, 212, 0.15) 0px, transparent 50%);
44
+ background-attachment: fixed;
45
+ color: var(--text-main);
46
+ min-height: 100vh;
47
+ display: flex;
48
+ flex-direction: column;
49
+ overflow-x: hidden;
50
+ }
51
+
52
+ /*
53
+ * UTILITIES
54
+ */
55
+ .glass {
56
+ background: var(--bg-panel);
57
+ backdrop-filter: blur(12px);
58
+ -webkit-backdrop-filter: blur(12px);
59
+ border: var(--glass-border);
60
+ box-shadow: var(--shadow);
61
+ }
62
+
63
+ .btn {
64
+ border: none;
65
+ outline: none;
66
+ cursor: pointer;
67
+ padding: 0.6rem 1.2rem;
68
+ border-radius: 8px;
69
+ font-weight: 600;
70
+ font-family: inherit;
71
+ transition: var(--transition);
72
+ display: inline-flex;
73
+ align-items: center;
74
+ gap: 0.5rem;
75
+ }
76
+
77
+ .btn-primary {
78
+ background: linear-gradient(135deg, var(--primary), var(--accent));
79
+ color: white;
80
+ }
81
+
82
+ .btn-primary:hover {
83
+ transform: translateY(-2px);
84
+ box-shadow: 0 0 15px rgba(99, 102, 241, 0.4);
85
+ }
86
+
87
+ .btn-icon {
88
+ background: rgba(255,255,255,0.05);
89
+ color: var(--text-main);
90
+ padding: 0.5rem;
91
+ border-radius: 50%;
92
+ }
93
+
94
+ .btn-icon:hover {
95
+ background: rgba(255,255,255,0.15);
96
+ color: var(--accent);
97
+ }
98
+
99
+ /*
100
+ * HEADER
101
+ */
102
+ header {
103
+ padding: 1rem 2rem;
104
+ display: flex;
105
+ justify-content: space-between;
106
+ align-items: center;
107
+ position: sticky;
108
+ top: 0;
109
+ z-index: 100;
110
+ border-bottom: var(--glass-border);
111
+ }
112
+
113
+ .logo {
114
+ font-size: 1.5rem;
115
+ font-weight: 700;
116
+ background: linear-gradient(to right, var(--primary), var(--accent));
117
+ -webkit-background-clip: text;
118
+ -webkit-text-fill-color: transparent;
119
+ letter-spacing: -0.5px;
120
+ display: flex;
121
+ align-items: center;
122
+ gap: 0.5rem;
123
+ }
124
+
125
+ .header-controls {
126
+ display: flex;
127
+ align-items: center;
128
+ gap: 1.5rem;
129
+ }
130
+
131
+ .credit-link {
132
+ font-size: 0.85rem;
133
+ color: var(--text-muted);
134
+ text-decoration: none;
135
+ transition: var(--transition);
136
+ }
137
+
138
+ .credit-link:hover {
139
+ color: var(--accent);
140
+ }
141
+
142
+ .user-avatar {
143
+ width: 40px;
144
+ height: 40px;
145
+ border-radius: 50%;
146
+ border: 2px solid var(--primary);
147
+ object-fit: cover;
148
+ }
149
+
150
+ /*
151
+ * MAIN LAYOUT
152
+ */
153
+ main {
154
+ flex: 1;
155
+ padding: 2rem;
156
+ max-width: 1400px;
157
+ margin: 0 auto;
158
+ width: 100%;
159
+ display: grid;
160
+ grid-template-columns: repeat(12, 1fr);
161
+ grid-template-rows: auto auto;
162
+ gap: 1.5rem;
163
+ }
164
+
165
+ /*
166
+ * CARDS & WIDGETS
167
+ */
168
+ .card {
169
+ padding: 1.5rem;
170
+ border-radius: var(--radius);
171
+ display: flex;
172
+ flex-direction: column;
173
+ position: relative;
174
+ overflow: hidden;
175
+ animation: fadeIn 0.6s ease-out;
176
+ }
177
+
178
+ .card-header {
179
+ display: flex;
180
+ justify-content: space-between;
181
+ align-items: center;
182
+ margin-bottom: 1rem;
183
+ }
184
+
185
+ .card-title {
186
+ font-size: 1.1rem;
187
+ font-weight: 600;
188
+ color: var(--text-main);
189
+ display: flex;
190
+ align-items: center;
191
+ gap: 0.5rem;
192
+ }
193
+
194
+ /*
195
+ * WIDGET: CLOCK & DATE
196
+ */
197
+ .widget-welcome {
198
+ grid-column: span 12;
199
+ }
200
+
201
+ .welcome-text h1 {
202
+ font-size: 2rem;
203
+ margin-bottom: 0.25rem;
204
+ }
205
+
206
+ .date-display {
207
+ color: var(--text-muted);
208
+ font-size: 1rem;
209
+ }
210
+
211
+ /*
212
+ * WIDGET: FOCUS TIMER
213
+ */
214
+ .widget-timer {
215
+ grid-column: span 12;
216
+ md: span 4;
217
+ lg: span 4;
218
+ align-items: center;
219
+ justify-content: center;
220
+ min-height: 300px;
221
+ }
222
+
223
+ .timer-circle {
224
+ position: relative;
225
+ width: 200px;
226
+ height: 200px;
227
+ }
228
+
229
+ .timer-circle svg {
230
+ transform: rotate(-90deg);
231
+ width: 100%;
232
+ height: 100%;
233
+ }
234
+
235
+ .timer-circle circle {
236
+ fill: none;
237
+ stroke-width: 8;
238
+ stroke-linecap: round;
239
+ }
240
+
241
+ .circle-bg {
242
+ stroke: rgba(255,255,255,0.05);
243
+ }
244
+
245
+ .circle-progress {
246
+ stroke: var(--accent);
247
+ stroke-dasharray: 565; /* 2 * PI * 90 */
248
+ stroke-dashoffset: 0;
249
+ transition: stroke-dashoffset 1s linear;
250
+ }
251
+
252
+ .timer-text {
253
+ position: absolute;
254
+ top: 50%;
255
+ left: 50%;
256
+ transform: translate(-50%, -50%);
257
+ text-align: center;
258
+ }
259
+
260
+ .time-display {
261
+ font-size: 2.5rem;
262
+ font-weight: 700;
263
+ font-variant-numeric: tabular-nums;
264
+ }
265
+
266
+ .timer-controls {
267
+ margin-top: 1.5rem;
268
+ display: flex;
269
+ gap: 1rem;
270
+ }
271
+
272
+ /*
273
+ * WIDGET: TASKS
274
+ */
275
+ .widget-tasks {
276
+ grid-column: span 12;
277
+ md: span 8;
278
+ lg: span 5;
279
+ height: 400px;
280
+ }
281
+
282
+ .task-input-group {
283
+ display: flex;
284
+ gap: 0.5rem;
285
+ margin-bottom: 1rem;
286
+ }
287
+
288
+ .task-input {
289
+ flex: 1;
290
+ background: rgba(0,0,0,0.2);
291
+ border: 1px solid rgba(255,255,255,0.1);
292
+ padding: 0.8rem;
293
+ border-radius: 8px;
294
+ color: white;
295
+ font-family: inherit;
296
+ }
297
+
298
+ .task-input:focus {
299
+ outline: none;
300
+ border-color: var(--primary);
301
+ }
302
+
303
+ .task-list {
304
+ list-style: none;
305
+ overflow-y: auto;
306
+ flex: 1;
307
+ padding-right: 0.5rem;
308
+ }
309
+
310
+ /* Scrollbar styling */
311
+ .task-list::-webkit-scrollbar {
312
+ width: 6px;
313
+ }
314
+ .task-list::-webkit-scrollbar-thumb {
315
+ background: rgba(255,255,255,0.1);
316
+ border-radius: 3px;
317
+ }
318
+
319
+ .task-item {
320
+ display: flex;
321
+ align-items: center;
322
+ justify-content: space-between;
323
+ padding: 0.8rem;
324
+ background: rgba(255,255,255,0.03);
325
+ margin-bottom: 0.5rem;
326
+ border-radius: 8px;
327
+ transition: var(--transition);
328
+ border-left: 3px solid transparent;
329
+ }
330
+
331
+ .task-item:hover {
332
+ background: rgba(255,255,255,0.06);
333
+ transform: translateX(4px);
334
+ }
335
+
336
+ .task-item.completed {
337
+ opacity: 0.5;
338
+ text-decoration: line-through;
339
+ border-left-color: var(--success);
340
+ }
341
+
342
+ .task-item.pending {
343
+ border-left-color: var(--accent);
344
+ }
345
+
346
+ .task-actions button {
347
+ background: none;
348
+ border: none;
349
+ color: var(--text-muted);
350
+ cursor: pointer;
351
+ padding: 0.4rem;
352
+ transition: color 0.2s;
353
+ }
354
+
355
+ .task-actions button:hover {
356
+ color: var(--danger);
357
+ }
358
+
359
+ /*
360
+ * WIDGET: ANALYTICS (CANVAS)
361
+ */
362
+ .widget-analytics {
363
+ grid-column: span 12;
364
+ lg: span 3;
365
+ height: 300px;
366
+ }
367
+
368
+ canvas {
369
+ width: 100%;
370
+ height: 100%;
371
+ }
372
+
373
+ /*
374
+ * WIDGET: QUICK NOTES
375
+ */
376
+ .widget-notes {
377
+ grid-column: span 12;
378
+ lg: span 6;
379
+ height: 250px;
380
+ }
381
+
382
+ .notes-area {
383
+ width: 100%;
384
+ height: 100%;
385
+ background: rgba(0,0,0,0.2);
386
+ border: 1px solid rgba(255,255,255,0.1);
387
+ border-radius: 8px;
388
+ padding: 1rem;
389
+ color: var(--text-muted);
390
+ font-family: inherit;
391
+ resize: none;
392
+ font-size: 0.95rem;
393
+ line-height: 1.5;
394
+ }
395
+
396
+ .notes-area:focus {
397
+ outline: none;
398
+ border-color: var(--primary);
399
+ color: var(--text-main);
400
+ }
401
+
402
+ /*
403
+ * TOAST NOTIFICATION
404
+ */
405
+ .toast-container {
406
+ position: fixed;
407
+ bottom: 2rem;
408
+ right: 2rem;
409
+ z-index: 1000;
410
+ display: flex;
411
+ flex-direction: column;
412
+ gap: 0.5rem;
413
+ }
414
+
415
+ .toast {
416
+ background: var(--bg-panel);
417
+ backdrop-filter: blur(16px);
418
+ border-left: 4px solid var(--accent);
419
+ color: white;
420
+ padding: 1rem 1.5rem;
421
+ border-radius: 8px;
422
+ box-shadow: 0 10px 30px rgba(0,0,0,0.5);
423
+ display: flex;
424
+ align-items: center;
425
+ gap: 0.8rem;
426
+ animation: slideIn 0.3s ease-out forwards;
427
+ min-width: 250px;
428
+ }
429
+
430
+ .toast.success { border-left-color: var(--success); }
431
+ .toast.error { border-left-color: var(--danger); }
432
+
433
+ @keyframes slideIn {
434
+ from { transform: translateX(100%); opacity: 0; }
435
+ to { transform: translateX(0); opacity: 1; }
436
+ }
437
+
438
+ @keyframes fadeIn {
439
+ from { opacity: 0; transform: translateY(20px); }
440
+ to { opacity: 1; transform: translateY(0); }
441
+ }
442
+
443
+ /*
444
+ * RESPONSIVE MEDIA QUERIES
445
+ */
446
+ @media (min-width: 768px) {
447
+ .widget-timer { grid-column: span 6; }
448
+ .widget-tasks { grid-column: span 6; }
449
+ .widget-analytics { grid-column: span 12; }
450
+ .widget-notes { grid-column: span 12; }
451
+ }
452
+
453
+ @media (min-width: 1024px) {
454
+ .widget-welcome { grid-column: span 8; }
455
+ .widget-timer { grid-column: span 4; }
456
+ .widget-tasks { grid-column: span 5; }
457
+ .widget-analytics { grid-column: span 3; }
458
+ .widget-notes { grid-column: span 4; }
459
+ }
460
+
461
+ </style>
462
+ </head>
463
+ <body>
464
+
465
+ <!-- Header -->
466
+ <header class="glass">
467
+ <div class="logo">
468
+ <i class="fa-solid fa-cube"></i> NEXUS
469
+ </div>
470
+ <div class="header-controls">
471
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="credit-link">
472
+ Built with anycoder <i class="fa-solid fa-arrow-up-right-from-square" style="font-size: 0.7em;"></i>
473
+ </a>
474
+ <button class="btn-icon" id="theme-toggle" title="Toggle Theme (Demo)">
475
+ <i class="fa-solid fa-moon"></i>
476
+ </button>
477
+ <img src="https://picsum.photos/seed/nexusUser/100/100" alt="User" class="user-avatar">
478
+ </div>
479
+ </header>
480
+
481
+ <!-- Main Content -->
482
+ <main>
483
+ <!-- Welcome Widget -->
484
+ <section class="card glass widget-welcome">
485
+ <div class="welcome-text">
486
+ <h1 id="greeting">Welcome back, Operator.</h1>
487
+ <p class="date-display" id="current-date">Loading date...</p>
488
+ </div>
489
+ </section>
490
+
491
+ <!-- Timer Widget -->
492
+ <section class="card glass widget-timer">
493
+ <div class="card-header" style="width: 100%;">
494
+ <div class="card-title"><i class="fa-solid fa-hourglass-half"></i> Focus Flow</div>
495
+ </div>
496
+
497
+ <div class="timer-circle">
498
+ <svg>
499
+ <circle class="circle-bg" cx="50%" cy="50%" r="90"></circle>
500
+ <circle class="circle-progress" cx="50%" cy="50%" r="90" id="progress-ring"></circle>
501
+ </svg>
502
+ <div class="timer-text">
503
+ <div class="time-display" id="timer-display">25:00</div>
504
+ <div style="font-size: 0.8rem; color: var(--text-muted);">FOCUS MODE</div>
505
+ </div>
506
+ </div>
507
+
508
+ <div class="timer-controls">
509
+ <button class="btn btn-primary" id="start-btn"><i class="fa-solid fa-play"></i> Start</button>
510
+ <button class="btn btn-icon" id="reset-btn"><i class="fa-solid fa-rotate-right"></i></button>
511
+ </div>
512
+ </section>
513
+
514
+ <!-- Task List Widget -->
515
+ <section class="card glass widget-tasks">
516
+ <div class="card-header">
517
+ <div class="card-title"><i class="fa-solid fa-list-check"></i> Mission Tasks</div>
518
+ <span style="font-size: 0.8rem; color: var(--text-muted);" id="task-count">0 Active</span>
519
+ </div>
520
+
521
+ <form id="task-form" class="task-input-group">
522
+ <input type="text" class="task-input" id="task-input" placeholder="Enter new directive..." autocomplete="off">
523
+ <button type="submit" class="btn btn-primary"><i class="fa-solid fa-plus"></i></button>
524
+ </form>
525
+
526
+ <ul class="task-list" id="task-list">
527
+ <!-- Tasks injected via JS -->
528
+ </ul>
529
+ </section>
530
+
531
+ <!-- Analytics Widget -->
532
+ <section class="card glass widget-analytics">
533
+ <div class="card-header">
534
+ <div class="card-title"><i class="fa-solid fa-chart-line"></i> Efficiency</div>
535
+ </div>
536
+ <div style="flex: 1; position: relative;">
537
+ <canvas id="productivityChart"></canvas>
538
+ </div>
539
+ </section>
540
+
541
+ <!-- Notes Widget -->
542
+ <section class="card glass widget-notes">
543
+ <div class="card-header">
544
+ <div class="card-title"><i class="fa-regular fa-note-sticky"></i> Quick Log</div>
545
+ <button class="btn-icon" id="clear-notes" title="Clear Notes"><i class="fa-solid fa-trash"></i></button>
546
+ </div>
547
+ <textarea class="notes-area" id="quick-notes" placeholder="Type your observations here..."></textarea>
548
+ </section>
549
+ </main>
550
+
551
+ <!-- Toast Container -->
552
+ <div class="toast-container" id="toast-container"></div>
553
+
554
+ <script>
555
+ /**
556
+ * NEXUS COMMAND CENTER LOGIC
557
+ * Pure Vanilla JavaScript - No Frameworks
558
+ */
559
+
560
+ document.addEventListener('DOMContentLoaded', () => {
561
+ initClock();
562
+ initTimer();
563
+ initTasks();
564
+ initNotes();
565
+ initChart();
566
+ });
567
+
568
+ /* --- 1. UTILITY FUNCTIONS --- */
569
+ const $ = (selector) => document.querySelector(selector);
570
+
571
+ function showToast(message, type = 'info') {
572
+ const container = $('#toast-container');
573
+ const toast = document.createElement('div');
574
+ toast.className = `toast ${type}`;
575
+
576
+ let icon = 'fa-info-circle';
577
+ if (type === 'success') icon = 'fa-check-circle';
578
+ if (type === 'error') icon = 'fa-triangle-exclamation';
579
+
580
+ toast.innerHTML = `<i class="fa-solid ${icon}"></i> <span>${message}</span>`;
581
+
582
+ container.appendChild(toast);
583
+
584
+ // Remove after 3 seconds
585
+ setTimeout(() => {
586
+ toast.style.animation = 'slideIn 0.3s ease-out reverse forwards';
587
+ setTimeout(() => toast.remove(), 300);
588
+ }, 3000);
589
+ }
590
+
591
+ /* --- 2. CLOCK & DATE --- */
592
+ function initClock() {
593
+ const dateEl = $('#current-date');
594
+ const greetingEl = $('#greeting');
595
+ const hours = new Date().getHours();
596
+
597
+ // Dynamic Greeting
598
+ let greet = 'Welcome back, Operator.';
599
+ if (hours < 12) greet = 'Good morning, Operator.';
600
+ else if (hours < 18) greet = 'Good afternoon, Operator.';
601
+ else greet = 'Good evening, Operator.';
602
+ greetingEl.textContent = greet;
603
+
604
+ const updateTime = () => {
605
+ const now = new Date();
606
+ dateEl.textContent = now.toLocaleDateString('en-US', {
607
+ weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'
608
+ }) + ' • ' + now.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });
609
+ };
610
+
611
+ updateTime();
612
+ setInterval(updateTime, 1000);
613
+ }
614
+
615
+ /* --- 3. FOCUS TIMER --- */
616
+ function initTimer() {
617
+ let timeLeft = 25 * 60; // 25 minutes
618
+ let timerId = null;
619
+ let isRunning = false;
620
+
621
+ const display = $('#timer-display');
622
+ const ring = $('#progress-ring');
623
+ const startBtn = $('#start-btn');
624
+ const resetBtn = $('#reset-btn');
625
+
626
+ // Circle circumference for dashoffset calculation
627
+ const radius = ring.r.baseVal.value;
628
+ const circumference = 2 * Math.PI * radius;
629
+ ring.style.strokeDasharray = `${circumference} ${circumference}`;
630
+
631
+ function setProgress(percent) {
632
+ const offset = circumference - (percent / 100) * circumference;
633
+ ring.style.strokeDashoffset = offset;
634
+ }
635
+
636
+ function updateDisplay() {
637
+ const m = Math.floor(timeLeft / 60);
638
+ const s = timeLeft % 60;
639
+ display.textContent = `${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
640
+
641
+ const totalTime = 25 * 60;
642
+ const percent = ((totalTime - timeLeft) / totalTime) * 100;
643
+ setProgress(100 - percent); // Inverse progress (draining)
644
+ }
645
+
646
+ function toggleTimer() {
647
+ if (isRunning) {
648
+ clearInterval(timerId);
649
+ startBtn.innerHTML = '<i class="fa-solid fa-play"></i> Resume';
650
+ startBtn.classList.remove('btn-danger'); // Hypothetical class
651
+ } else {
652
+ timerId = setInterval(() => {
653
+ if (timeLeft > 0) {
654
+ timeLeft--;
655
+ updateDisplay();
656
+ } else {
657
+ clearInterval(timerId);
658
+ isRunning = false;
659
+ startBtn.innerHTML = '<i class="fa-solid fa-play"></i> Start';
660
+ showToast('Focus session complete!', 'success');
661
+ }
662
+ }, 1000);
663
+ startBtn.innerHTML = '<i class="fa-solid fa-pause"></i> Pause';
664
+ }
665
+ isRunning = !isRunning;
666
+ }
667
+
668
+ function resetTimer() {
669
+ clearInterval(timerId);
670
+ isRunning = false;
671
+ timeLeft = 25 * 60;
672
+ startBtn.innerHTML = '<i class="fa-solid fa-play"></i> Start';
673
+ updateDisplay();
674
+ setProgress(100);
675
+ }
676
+
677
+ startBtn.addEventListener('click', toggleTimer);
678
+ resetBtn.addEventListener('click', resetTimer);
679
+
680
+ // Initial set
681
+ updateDisplay();
682
+ }
683
+
684
+ /* --- 4. TASK MANAGER (Local Storage) --- */
685
+ function initTasks() {
686
+ const form = $('#task-form');
687
+ const input = $('#task-input');
688
+ const list = $('#task-list');
689
+ const countEl = $('#task-count');
690
+
691
+ let tasks = JSON.parse(localStorage.getItem('nexus_tasks')) || [
692
+ { id: 1, text: 'Review system logs', completed: false },
693
+ { id: 2, text: 'Update security protocols', completed: true }
694
+ ];
695
+
696
+ function save() {
697
+ localStorage.setItem('nexus_tasks', JSON.stringify(tasks));
698
+ render();
699
+ }
700
+
701
+ function render() {
702
+ list.innerHTML = '';
703
+ let activeCount = 0;
704
+
705
+ tasks.forEach(task => {
706
+ if (!task.completed) activeCount++;
707
+
708
+ const li = document.createElement('li');
709
+ li.className = `task-item ${task.completed ? 'completed' : 'pending'}`;
710
+ li.innerHTML = `
711
+ <span>${task.text}</span>
712
+ <div class="task-actions">
713
+ <button onclick="toggleTask(${task.id})"><i class="fa-solid fa-check"></i></button>
714
+ <button onclick="deleteTask(${task.id})"><i class="fa-solid fa-xmark"></i></button>
715
+ </div>
716
+ `;
717
+ list.appendChild(li);
718
+ });
719
+
720
+ countEl.textContent = `${activeCount} Active`;
721
+ }
722
+
723
+ window.toggleTask = (id) => {
724
+ tasks = tasks.map(t => t.id === id ? {...t, completed: !t.completed} : t);
725
+ save();
726
+ };
727
+
728
+ window.deleteTask = (id) => {
729
+ tasks = tasks.filter(t => t.id !== id);
730
+ save();
731
+ showToast('Task removed', 'info');
732
+ };
733
+
734
+ form.addEventListener('submit', (e) => {
735
+ e.preventDefault();
736
+ const text = input.value.trim();
737
+ if (!text) return;
738
+
739
+ tasks.unshift({
740
+ id: Date.now(),
741
+ text,
742
+ completed: false
743
+ });
744
+ input.value = '';
745
+ save();
746
+ showToast('New directive added', 'success');
747
+ });
748
+
749
+ render();
750
+ }
751
+
752
+ /* --- 5. QUICK NOTES --- */
753
+ function initNotes() {
754
+ const area = $('#quick-notes');
755
+ const clearBtn = $('#clear-notes');
756
+
757
+ // Load saved notes
758
+ area.value = localStorage.getItem('nexus_notes') || '';
759
+
760
+ // Auto-save on input
761
+ area.addEventListener('input', () => {
762
+ localStorage.setItem('nexus_notes', area.value);
763
+ });
764
+
765
+ clearBtn.addEventListener('click', () => {
766
+ if(confirm('Clear all notes?')) {
767
+ area.value = '';
768
+ localStorage.removeItem('nexus_notes');
769
+ showToast('Notes cleared', 'info');
770
+ }
771
+ });
772
+ }
773
+
774
+ /* --- 6. CANVAS CHART (Custom Drawing) --- */
775
+ function initChart() {
776
+ const canvas = $('#productivityChart');
777
+ const ctx = canvas.getContext('2d');
778
+
779
+ // Handle high DPI displays
780
+ const dpr = window.devicePixelRatio || 1;
781
+ const rect = canvas.getBoundingClientRect();
782
+ canvas.width = rect.width * dpr;
783
+ canvas.height = rect.height * dpr;
784
+ ctx.scale(dpr, dpr);
785
+
786
+ // Mock Data
787
+ const dataPoints = [20, 45, 30, 60, 55, 80, 70];
788
+ const labels = ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
789
+ const maxVal = 100;
790
+
791
+ function draw() {
792
+ const width = rect.width;
793
+ const height = rect.height;
794
+ const padding = 20;
795
+ const chartHeight = height - padding * 2;
796
+ const chartWidth = width - padding * 2;
797
+ const stepX = chartWidth / (dataPoints.length - 1);
798
+
799
+ ctx.clearRect(0, 0, width, height);
800
+
801
+ // Gradient Fill
802
+ const gradient = ctx.createLinearGradient(0, 0, 0, height);
803
+ gradient.addColorStop(0, 'rgba(6, 182, 212, 0.5)'); // Cyan
804
+ gradient.addColorStop(1, 'rgba(6, 182, 212, 0.0)');
805
+
806
+ // Draw Area
807
+ ctx.beginPath();
808
+ ctx.moveTo(padding, height - padding);
809
+
810
+ dataPoints.forEach((val, index) => {
811
+ const x = padding + index * stepX;
812
+ const y = height - padding - (val / maxVal) * chartHeight;
813
+ if (index === 0) ctx.lineTo(x, y);
814
+ else {
815
+ // Bezier curve for smoothness
816
+ const prevX = padding + (index - 1) * stepX;
817
+ const prevY = height - padding - (dataPoints[index - 1] / maxVal) * chartHeight;
818
+ const cp1x = prevX + (x - prevX) / 2;
819
+ const cp1y = prevY;
820
+ const cp2x = prevX + (x - prevX) / 2;
821
+ const cp2y = y;
822
+ ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
823
+ }
824
+ });
825
+
826
+ ctx.lineTo(width - padding, height - padding);
827
+ ctx.closePath();
828
+ ctx.fillStyle = gradient;
829
+ ctx.fill();
830
+
831
+ // Draw Line
832
+ ctx.beginPath();
833
+ dataPoints.forEach((val, index) => {
834
+ const x = padding + index * stepX;
835
+ const y = height - padding - (val / maxVal) * chartHeight;
836
+ if (index === 0) ctx.moveTo(x, y);
837
+ else {
838
+ const prevX = padding + (index - 1) * stepX;
839
+ const prevY = height - padding - (dataPoints[index - 1] / maxVal) * chartHeight;
840
+ const cp1x = prevX + (x - prevX) / 2;
841
+ const cp1y = prevY;
842
+ const cp2x = prevX + (x - prevX) / 2;
843
+ const cp2y = y;
844
+ ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
845
+ }
846
+ });
847
+ ctx.strokeStyle = '#06b6d4';
848
+ ctx.lineWidth = 3;
849
+ ctx.stroke();
850
+
851
+ // Draw Points
852
+ dataPoints.forEach((val, index) => {
853
+ const x = padding + index * stepX;
854
+ const y = height - padding - (val / maxVal) * chartHeight;
855
+
856
+ ctx.beginPath();
857
+ ctx.arc(x, y, 4, 0, Math.PI * 2);
858
+ ctx.fillStyle = '#fff';
859
+ ctx.fill();
860
+
861
+ // Labels
862
+ ctx.fillStyle = '#94a3b8';
863
+ ctx.font = '10px Outfit';
864
+ ctx.textAlign = 'center';
865
+ ctx.fillText(labels[index], x, height - 5);
866
+ });
867
+ }
868
+
869
+ draw();
870
+
871
+ // Redraw on resize
872
+ window.addEventListener('resize', () => {
873
+ const newRect = canvas.getBoundingClientRect();
874
+ canvas.width = newRect.width * dpr;
875
+ canvas.height = newRect.height * dpr;
876
+ ctx.scale(dpr, dpr);
877
+ draw();
878
+ });
879
+ }
880
+ </script>
881
+ </body>
882
+ </html>