TioPeperino commited on
Commit
9d51f9f
·
verified ·
1 Parent(s): 76a5618

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +618 -690
index.html CHANGED
@@ -3,839 +3,767 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>QPrompt Redesigned - Professional Teleprompter</title>
7
- <!-- Font Awesome 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=Inter:wght@300;400;600;700&family=Roboto+Mono:wght@400;500&display=swap" rel="stylesheet">
11
 
 
 
 
 
 
 
12
  <style>
 
13
  :root {
14
- --bg-color: #121212;
15
- --surface-color: #1e1e1e;
16
- --surface-hover: #2d2d2d;
17
- --primary-color: #6366f1; /* Indigo */
18
- --primary-hover: #4f46e5;
19
- --accent-color: #ec4899; /* Pink */
20
- --text-primary: #ffffff;
21
- --text-secondary: #a1a1aa;
22
- --border-color: #333;
23
- --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
24
- --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
25
- --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
 
 
 
 
 
26
  }
27
 
28
  * {
29
- box-sizing: border-box;
30
  margin: 0;
31
  padding: 0;
 
 
 
 
 
32
  }
33
 
34
  body {
35
  font-family: 'Inter', sans-serif;
36
- background-color: var(--bg-color);
37
- color: var(--text-primary);
38
- height: 100vh;
39
- overflow: hidden;
40
- display: flex;
41
- flex-direction: column;
42
  }
43
 
44
- /* Header */
45
- header {
46
- background-color: var(--surface-color);
47
- border-bottom: 1px solid var(--border-color);
48
- padding: 0.75rem 1.5rem;
49
- display: flex;
50
- justify-content: space-between;
51
- align-items: center;
52
- z-index: 50;
53
  }
54
 
55
- .logo {
56
- display: flex;
57
- align-items: center;
58
- gap: 0.75rem;
59
- font-weight: 700;
60
- font-size: 1.25rem;
61
- color: var(--text-primary);
62
- text-decoration: none;
63
  }
64
 
65
- .logo i {
66
- color: var(--primary-color);
67
- font-size: 1.5rem;
 
 
 
 
 
 
 
 
68
  }
69
 
70
- .anycoder-link {
71
- font-size: 0.875rem;
72
- color: var(--text-secondary);
73
- text-decoration: none;
74
- transition: color 0.2s;
75
  }
76
 
77
- .anycoder-link:hover {
78
- color: var(--primary-color);
 
 
79
  }
80
 
81
- /* Main Layout */
82
- .app-container {
83
- display: flex;
84
- flex: 1;
85
- height: calc(100vh - 60px);
86
- overflow: hidden;
87
  }
88
 
89
- /* Sidebar (Controls) */
90
- .sidebar {
91
- width: 320px;
92
- background-color: var(--surface-color);
93
- border-right: 1px solid var(--border-color);
94
- padding: 1.5rem;
95
- display: flex;
96
- flex-direction: column;
97
- gap: 1.5rem;
98
- overflow-y: auto;
99
- transition: transform 0.3s ease;
100
  }
101
 
102
- .control-group {
103
- display: flex;
104
- flex-direction: column;
105
- gap: 0.5rem;
106
  }
107
 
108
- .control-label {
 
 
 
109
  font-size: 0.75rem;
 
110
  text-transform: uppercase;
111
- letter-spacing: 0.05em;
112
- color: var(--text-secondary);
 
 
 
 
 
 
 
 
 
 
 
113
  font-weight: 600;
114
  }
 
115
 
116
- .slider-container {
 
 
 
 
 
 
 
 
 
 
117
  display: flex;
 
118
  align-items: center;
119
- gap: 1rem;
120
  }
121
 
122
- input[type="range"] {
123
- -webkit-appearance: none;
124
- width: 100%;
125
- height: 6px;
126
- background: #333;
127
- border-radius: 3px;
128
- outline: none;
129
  }
 
 
130
 
131
- input[type="range"]::-webkit-slider-thumb {
132
- -webkit-appearance: none;
133
- width: 18px;
134
- height: 18px;
135
- background: var(--primary-color);
136
- border-radius: 50%;
137
- cursor: pointer;
138
- transition: background 0.2s;
139
  }
140
 
141
- input[type="range"]::-webkit-slider-thumb:hover {
142
- background: var(--primary-hover);
 
 
143
  }
144
 
145
- .value-display {
146
- font-family: 'Roboto Mono', monospace;
147
- font-size: 0.875rem;
148
- color: var(--text-primary);
149
- min-width: 3ch;
 
 
 
 
150
  }
151
 
152
- .btn {
153
- display: inline-flex;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  align-items: center;
155
- justify-content: center;
156
- gap: 0.5rem;
157
- padding: 0.75rem 1rem;
158
- border-radius: 0.5rem;
159
- font-weight: 600;
160
- cursor: pointer;
161
- transition: all 0.2s;
162
- border: none;
163
- font-family: inherit;
164
  }
165
 
166
- .btn-primary {
167
- background-color: var(--primary-color);
168
- color: white;
 
 
169
  }
170
 
171
- .btn-primary:hover {
172
- background-color: var(--primary-hover);
 
 
 
173
  }
174
 
175
- .btn-secondary {
176
- background-color: #333;
177
- color: white;
 
178
  }
179
 
180
- .btn-secondary:hover {
181
- background-color: #444;
 
 
 
 
 
182
  }
183
 
184
- .btn-danger {
185
- background-color: transparent;
186
- border: 1px solid #ef4444;
187
- color: #ef4444;
 
 
 
 
 
 
 
 
 
188
  }
189
 
190
- .btn-danger:hover {
191
- background-color: rgba(239, 68, 68, 0.1);
192
  }
193
 
194
- .toggle-switch {
 
 
195
  display: flex;
196
  align-items: center;
197
- justify-content: space-between;
198
- cursor: pointer;
199
  }
200
 
201
- .switch {
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  position: relative;
203
- display: inline-block;
204
- width: 44px;
205
- height: 24px;
206
  }
207
 
208
- .switch input {
209
- opacity: 0;
210
- width: 0;
211
- height: 0;
212
  }
213
-
214
- .slider {
215
  position: absolute;
216
- cursor: pointer;
217
- top: 0;
218
- left: 0;
219
- right: 0;
220
- bottom: 0;
221
- background-color: #333;
222
- transition: .4s;
223
- border-radius: 24px;
224
  }
225
 
226
- .slider:before {
227
- position: absolute;
228
- content: "";
229
- height: 18px;
230
- width: 18px;
231
- left: 3px;
232
- bottom: 3px;
233
- background-color: white;
234
- transition: .4s;
235
- border-radius: 50%;
236
  }
237
 
238
- input:checked + .slider {
239
- background-color: var(--primary-color);
 
240
  }
241
 
242
- input:checked + .slider:before {
243
- transform: translateX(20px);
 
244
  }
245
 
246
- /* Teleprompter Area */
247
- .prompter-area {
248
- flex: 1;
249
- position: relative;
250
- background-color: black;
251
- overflow: hidden;
252
- display: flex;
253
- justify-content: center;
254
  }
255
 
256
- .prompter-content {
257
- width: 100%;
258
- height: 100%;
259
- overflow-y: scroll; /* Allow manual scrolling when paused */
260
- padding: 0 2rem;
261
- /* Hide scrollbar for cleaner look */
262
- scrollbar-width: none;
263
- -ms-overflow-style: none;
264
  }
265
 
266
- .prompter-content::-webkit-scrollbar {
267
- display: none;
 
 
 
 
268
  }
269
 
270
- #prompter-text {
271
- color: white;
272
- font-family: sans-serif;
273
- line-height: 1.5;
274
- outline: none;
275
- white-space: pre-wrap;
276
- padding-top: 45vh; /* Start text in middle */
277
- padding-bottom: 45vh;
278
- margin: 0 auto;
279
- max-width: 90%;
280
- text-align: left;
281
- border: none;
282
- background: transparent;
283
- display: block;
284
  }
285
 
286
- /* Overlay Marker */
287
- .marker-overlay {
288
- position: absolute;
289
- top: 48%; /* Slightly above center for reading line */
290
- left: 0;
291
- width: 100%;
292
- height: 60px; /* Approximate height of a line or two */
293
- border-top: 2px solid rgba(255, 255, 255, 0.2);
294
- border-bottom: 2px solid rgba(255, 255, 255, 0.2);
295
  background: rgba(255, 255, 255, 0.05);
296
- pointer-events: none;
297
- z-index: 10;
298
  display: flex;
299
  align-items: center;
 
 
 
 
300
  }
301
-
302
- .marker-overlay::before {
303
- content: "\f0da"; /* FontAwesome caret right */
304
- font-family: "Font Awesome 6 Free";
305
- font-weight: 900;
306
- color: var(--primary-color);
307
- font-size: 2rem;
308
- margin-left: 1rem;
309
- opacity: 0.7;
310
  }
311
 
312
- .marker-overlay::after {
313
- content: "\f0d9"; /* FontAwesome caret left */
314
- font-family: "Font Awesome 6 Free";
315
- font-weight: 900;
316
- color: var(--primary-color);
317
- font-size: 2rem;
318
- margin-right: 1rem;
319
- opacity: 0.7;
320
- margin-left: auto;
321
  }
322
 
323
- /* Floating Controls (Play/Pause) */
324
- .floating-controls {
325
- position: absolute;
326
- bottom: 2rem;
327
- left: 50%;
328
- transform: translateX(-50%);
329
- background-color: rgba(30, 30, 30, 0.9);
330
- backdrop-filter: blur(10px);
331
- padding: 0.75rem 1.5rem;
332
- border-radius: 50px;
333
- display: flex;
334
- gap: 1.5rem;
335
- align-items: center;
336
- box-shadow: var(--shadow-lg);
337
  border: 1px solid var(--border-color);
338
- z-index: 20;
339
- transition: opacity 0.3s;
340
  }
 
 
341
 
342
- .floating-btn {
343
- background: none;
344
- border: none;
345
- color: var(--text-primary);
346
- font-size: 1.25rem;
347
- cursor: pointer;
348
- transition: color 0.2s;
349
- width: 40px;
350
- height: 40px;
351
- display: flex;
352
- align-items: center;
353
- justify-content: center;
354
- border-radius: 50%;
355
  }
356
 
357
- .floating-btn:hover {
358
- background-color: rgba(255,255,255,0.1);
359
- color: var(--primary-color);
 
 
 
 
 
 
360
  }
361
 
362
- .play-btn {
363
- background-color: var(--primary-color);
364
- width: 50px;
365
- height: 50px;
366
- font-size: 1.5rem;
367
  }
368
 
369
- .play-btn:hover {
370
- background-color: var(--primary-hover);
371
- color: white;
 
372
  }
373
 
374
- /* Mirror Classes */
375
- .mirror-x { transform: scaleX(-1); }
376
- .mirror-y { transform: scaleY(-1); }
377
- .mirror-xy { transform: scale(-1, -1); }
378
-
379
- /* Mobile Responsive */
380
- @media (max-width: 768px) {
381
- .app-container {
382
- flex-direction: column;
383
- }
384
-
385
- .sidebar {
386
- width: 100%;
387
- height: auto;
388
- max-height: 40vh;
389
- border-right: none;
390
- border-bottom: 1px solid var(--border-color);
391
- order: 2; /* Move below prompter on mobile or hide behind a menu */
392
- display: none; /* Hidden by default on mobile for cleaner view */
393
- position: absolute;
394
- bottom: 0;
395
- z-index: 100;
396
- box-shadow: 0 -4px 20px rgba(0,0,0,0.5);
397
- }
398
-
399
- .sidebar.active {
400
- display: flex;
401
- }
402
 
403
- .mobile-menu-btn {
404
- display: block;
405
- }
 
 
 
 
 
406
 
407
- .prompter-area {
408
- height: 100%;
409
- }
 
 
 
410
  }
411
 
412
- .mobile-menu-btn {
413
- display: none;
414
- background: none;
415
- border: none;
416
  color: white;
417
- font-size: 1.25rem;
418
- cursor: pointer;
 
 
419
  }
420
 
421
- @media (min-width: 769px) {
422
- .mobile-menu-btn {
423
- display: none;
424
- }
 
 
 
 
425
  }
426
 
427
- /* Edit Mode Styling */
428
- .prompter-content.editing #prompter-text {
429
- border: 1px dashed var(--border-color);
430
- background: rgba(255,255,255,0.05);
431
- cursor: text;
 
 
432
  }
 
433
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
  </style>
435
  </head>
436
- <body>
437
-
438
- <header>
439
- <a href="#" class="logo">
440
- <i class="fa-solid fa-closed-captioning"></i>
441
- QPrompt Redux
442
- </a>
443
- <a href="https://huggingface.co/spaces/akhaliq/anycoder" class="anycoder-link" target="_blank">Built with anycoder</a>
444
- <button class="mobile-menu-btn" id="toggleSettings">
445
- <i class="fa-solid fa-sliders"></i>
446
- </button>
447
- </header>
448
-
449
- <div class="app-container">
450
- <!-- Sidebar Controls -->
451
- <aside class="sidebar" id="sidebar">
452
- <div class="control-group">
453
- <div style="display: flex; justify-content: space-between; align-items: center;">
454
- <span class="control-label">Status</span>
455
- <button class="btn btn-secondary btn-sm" id="editBtn">
456
- <i class="fa-solid fa-pen"></i> Edit Text
457
- </button>
458
- </div>
459
- </div>
460
 
461
- <div class="control-group">
462
- <span class="control-label">Scroll Speed</span>
463
- <div class="slider-container">
464
- <i class="fa-solid fa-turtle" style="font-size: 0.8rem; color: var(--text-secondary);"></i>
465
- <input type="range" id="speedRange" min="0" max="100" value="25">
466
- <i class="fa-solid fa-rabbit" style="font-size: 0.8rem; color: var(--text-secondary);"></i>
467
- <span class="value-display" id="speedValue">25</span>
468
- </div>
469
- </div>
470
 
471
- <div class="control-group">
472
- <span class="control-label">Font Size</span>
473
- <div class="slider-container">
474
- <i class="fa-solid fa-font" style="font-size: 0.8rem; color: var(--text-secondary);"></i>
475
- <input type="range" id="fontSizeRange" min="20" max="150" value="60">
476
- <i class="fa-solid fa-font" style="font-size: 1.2rem; color: var(--text-secondary);"></i>
477
- <span class="value-display" id="fontSizeValue">60px</span>
478
- </div>
479
  </div>
480
-
481
- <div class="control-group">
482
- <span class="control-label">Line Height</span>
483
- <div class="slider-container">
484
- <i class="fa-solid fa-arrows-up-down" style="font-size: 0.8rem; color: var(--text-secondary);"></i>
485
- <input type="range" id="lineHeightRange" min="10" max="30" value="15">
486
- <span class="value-display" id="lineHeightValue">1.5</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
487
  </div>
488
- </div>
489
-
490
- <div class="control-group">
491
- <span class="control-label">Margin (Width)</span>
492
- <div class="slider-container">
493
- <i class="fa-solid fa-left-right" style="font-size: 0.8rem; color: var(--text-secondary);"></i>
494
- <input type="range" id="marginRange" min="50" max="100" value="90">
495
- <span class="value-display" id="marginValue">90%</span>
496
  </div>
497
  </div>
498
-
499
- <div class="control-group">
500
- <span class="control-label">Colors</span>
501
- <div style="display: flex; gap: 0.5rem;">
502
- <button class="btn btn-secondary" style="flex: 1;" onclick="changeTheme('white', 'black')">B/W</button>
503
- <button class="btn btn-secondary" style="flex: 1; background: white; color: black;" onclick="changeTheme('black', 'white')">W/B</button>
504
- <button class="btn btn-secondary" style="flex: 1; color: #ffff00;" onclick="changeTheme('#ffff00', 'black')">Y/B</button>
505
- <button class="btn btn-secondary" style="flex: 1; color: #00ff00;" onclick="changeTheme('#00ff00', 'black')">G/B</button>
 
 
 
 
 
 
 
 
 
 
506
  </div>
507
  </div>
508
-
509
- <div class="control-group">
510
- <span class="control-label">Mirroring</span>
511
- <div class="toggle-switch">
512
- <span>Flip Horizontal (X)</span>
513
- <label class="switch">
514
- <input type="checkbox" id="mirrorX">
515
- <span class="slider"></span>
516
- </label>
 
 
 
 
 
 
517
  </div>
518
- <div class="toggle-switch" style="margin-top: 0.5rem;">
519
- <span>Flip Vertical (Y)</span>
520
- <label class="switch">
521
- <input type="checkbox" id="mirrorY">
522
- <span class="slider"></span>
523
- </label>
 
 
 
524
  </div>
525
  </div>
526
-
527
- <div class="control-group" style="margin-top: auto;">
528
- <button class="btn btn-danger" id="clearBtn">
529
- <i class="fa-solid fa-trash"></i> Clear Text
530
- </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
531
  </div>
532
- </aside>
533
-
534
- <!-- Prompter Area -->
535
- <main class="prompter-area" id="prompterArea">
536
- <div class="marker-overlay"></div>
537
 
538
- <div class="prompter-content" id="scrollContainer">
539
- <div id="prompter-text" contenteditable="false">Welcome to QPrompt Redux!
540
-
541
- This is a modern, web-based teleprompter designed for content creators, speakers, and professionals.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
542
 
543
- How to use:
544
- 1. Click the "Edit Text" button or the Pen icon to paste your script here.
545
- 2. Adjust the Font Size and Speed using the sidebar controls.
546
- 3. Use the Mirroring options if you are using a beam-splitter glass.
547
- 4. Press the Play button below or Spacebar to start scrolling.
 
 
 
 
548
 
549
- Features:
550
- - Smooth scrolling engine
551
- - Dark mode optimized
552
- - Responsive design
553
- - Mirroring for professional rigs
554
- - Distraction-free interface
 
 
 
555
 
556
- Tip: You can scroll manually with your mouse wheel or trackpad even when paused.
 
 
 
 
 
 
 
 
557
 
558
- Paste your script here and start recording!
 
 
 
 
 
 
 
559
  </div>
560
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
561
 
562
- <!-- Floating Controls -->
563
- <div class="floating-controls" id="floatingControls">
564
- <button class="floating-btn" id="rewindBtn" title="Rewind to Top">
565
- <i class="fa-solid fa-backward-step"></i>
566
- </button>
567
- <button class="floating-btn play-btn" id="playBtn" title="Play/Pause (Space)">
568
- <i class="fa-solid fa-play"></i>
569
- </button>
570
- <button class="floating-btn" id="restartBtn" title="Restart">
571
- <i class="fa-solid fa-rotate-left"></i>
572
- </button>
573
- <div style="width: 1px; height: 20px; background: rgba(255,255,255,0.2);"></div>
574
- <button class="floating-btn" id="hideUIBtn" title="Hide UI">
575
- <i class="fa-solid fa-eye-slash"></i>
576
- </button>
577
  </div>
578
- </main>
579
- </div>
 
 
 
580
 
581
  <script>
582
- // DOM Elements
583
- const prompterText = document.getElementById('prompter-text');
584
- const scrollContainer = document.getElementById('scrollContainer');
585
- const playBtn = document.getElementById('playBtn');
586
- const rewindBtn = document.getElementById('rewindBtn');
587
- const restartBtn = document.getElementById('restartBtn');
588
- const editBtn = document.getElementById('editBtn');
589
- const clearBtn = document.getElementById('clearBtn');
590
- const speedRange = document.getElementById('speedRange');
591
- const speedValue = document.getElementById('speedValue');
592
- const fontSizeRange = document.getElementById('fontSizeRange');
593
- const fontSizeValue = document.getElementById('fontSizeValue');
594
- const lineHeightRange = document.getElementById('lineHeightRange');
595
- const lineHeightValue = document.getElementById('lineHeightValue');
596
- const marginRange = document.getElementById('marginRange');
597
- const marginValue = document.getElementById('marginValue');
598
- const mirrorXCheck = document.getElementById('mirrorX');
599
- const mirrorYCheck = document.getElementById('mirrorY');
600
- const hideUIBtn = document.getElementById('hideUIBtn');
601
- const sidebar = document.getElementById('sidebar');
602
- const toggleSettings = document.getElementById('toggleSettings');
603
- const floatingControls = document.getElementById('floatingControls');
604
- const header = document.querySelector('header');
605
-
606
- // State
607
- let isPlaying = false;
608
- let isEditing = false;
609
- let scrollSpeed = 25;
610
- let animationFrameId;
611
- let lastTimestamp = 0;
612
- let scroll accumulator = 0;
613
-
614
- // --- Core Logic ---
615
-
616
- function togglePlay() {
617
- if (isEditing) return;
618
- isPlaying = !isPlaying;
619
- updatePlayButton();
620
-
621
- if (isPlaying) {
622
- lastTimestamp = performance.now();
623
- animationFrameId = requestAnimationFrame(autoScroll);
624
- // Hide mouse cursor after 2 seconds of inactivity
625
- hideCursorTimer();
626
  } else {
627
- cancelAnimationFrame(animationFrameId);
628
- document.body.style.cursor = 'default';
629
  }
630
- }
631
-
632
- function updatePlayButton() {
633
- const icon = playBtn.querySelector('i');
634
- if (isPlaying) {
635
- icon.classList.remove('fa-play');
636
- icon.classList.add('fa-pause');
637
- } else {
638
- icon.classList.remove('fa-pause');
639
- icon.classList.add('fa-play');
640
- }
641
- }
642
-
643
- function autoScroll(timestamp) {
644
- if (!isPlaying) return;
645
-
646
- const deltaTime = timestamp - lastTimestamp;
647
- lastTimestamp = timestamp;
648
-
649
- // Calculate pixels to scroll based on speed (0-100)
650
- // Speed factor: adjust multiplier to feel natural
651
- const pixelsPerSecond = (scrollSpeed * scrollSpeed) / 10;
652
-
653
- if (pixelsPerSecond > 0) {
654
- const pixelsToScroll = (pixelsPerSecond * deltaTime) / 1000;
655
- scrollContainer.scrollTop += pixelsToScroll;
656
-
657
- // Stop at bottom
658
- if (scrollContainer.scrollTop + scrollContainer.clientHeight >= scrollContainer.scrollHeight - 1) {
659
- isPlaying = false;
660
- updatePlayButton();
661
- return;
662
- }
663
- }
664
-
665
- animationFrameId = requestAnimationFrame(autoScroll);
666
- }
667
-
668
- function toggleEdit() {
669
- isEditing = !isEditing;
670
- prompterText.contentEditable = isEditing;
671
- scrollContainer.classList.toggle('editing', isEditing);
672
-
673
- if (isEditing) {
674
- // Pause if playing
675
- if (isPlaying) togglePlay();
676
- editBtn.innerHTML = '<i class="fa-solid fa-check"></i> Done';
677
- editBtn.classList.remove('btn-secondary');
678
- editBtn.classList.add('btn-primary');
679
- prompterText.focus();
680
- } else {
681
- editBtn.innerHTML = '<i class="fa-solid fa-pen"></i> Edit Text';
682
- editBtn.classList.remove('btn-primary');
683
- editBtn.classList.add('btn-secondary');
684
- }
685
- }
686
-
687
- // --- UI Interactions ---
688
-
689
- // Play/Pause
690
- playBtn.addEventListener('click', togglePlay);
691
-
692
- // Keyboard Shortcuts
693
- document.addEventListener('keydown', (e) => {
694
- if (isEditing) return; // Don't trigger shortcuts while typing
695
-
696
- if (e.code === 'Space') {
697
- e.preventDefault();
698
- togglePlay();
699
- } else if (e.code === 'ArrowUp') {
700
- e.preventDefault();
701
- scrollSpeed = Math.min(100, parseInt(scrollSpeed) + 5);
702
- speedRange.value = scrollSpeed;
703
- speedValue.textContent = scrollSpeed;
704
- } else if (e.code === 'ArrowDown') {
705
- e.preventDefault();
706
- scrollSpeed = Math.max(0, parseInt(scrollSpeed) - 5);
707
- speedRange.value = scrollSpeed;
708
- speedValue.textContent = scrollSpeed;
709
- }
710
- });
711
-
712
- // Rewind
713
- rewindBtn.addEventListener('click', () => {
714
- scrollContainer.scrollTo({ top: 0, behavior: 'smooth' });
715
- });
716
-
717
- // Restart (Rewind + Play)
718
- restartBtn.addEventListener('click', () => {
719
- scrollContainer.scrollTop = 0;
720
- if (!isPlaying) togglePlay();
721
- });
722
-
723
- // Edit Mode
724
- editBtn.addEventListener('click', toggleEdit);
725
-
726
- // Clear Text
727
- clearBtn.addEventListener('click', () => {
728
- if (confirm("Are you sure you want to clear all text?")) {
729
- prompterText.innerText = "";
730
- if (!isEditing) toggleEdit();
731
- }
732
- });
733
-
734
- // Speed Control
735
- speedRange.addEventListener('input', (e) => {
736
- scrollSpeed = e.target.value;
737
- speedValue.textContent = scrollSpeed;
738
- });
739
-
740
- // Font Size
741
- fontSizeRange.addEventListener('input', (e) => {
742
- const size = e.target.value;
743
- prompterText.style.fontSize = `${size}px`;
744
- fontSizeValue.textContent = `${size}px`;
745
- });
746
-
747
- // Line Height
748
- lineHeightRange.addEventListener('input', (e) => {
749
- const val = e.target.value / 10;
750
- prompterText.style.lineHeight = val;
751
- lineHeightValue.textContent = val;
752
  });
753
 
754
- // Margin
755
- marginRange.addEventListener('input', (e) => {
756
- const val = e.target.value;
757
- prompterText.style.maxWidth = `${val}%`;
758
- marginValue.textContent = `${val}%`;
759
- });
760
-
761
- // Mirroring
762
- function updateMirror() {
763
- const x = mirrorXCheck.checked;
764
- const y = mirrorYCheck.checked;
765
-
766
- prompterText.className = ''; // reset
767
- if (x && y) prompterText.classList.add('mirror-xy');
768
- else if (x) prompterText.classList.add('mirror-x');
769
- else if (y) prompterText.classList.add('mirror-y');
770
- }
771
-
772
- mirrorXCheck.addEventListener('change', updateMirror);
773
- mirrorYCheck.addEventListener('change', updateMirror);
774
-
775
- // Theme Change
776
- window.changeTheme = function(textCol, bgCol) {
777
- prompterText.style.color = textCol;
778
- document.querySelector('.prompter-area').style.backgroundColor = bgCol;
779
- };
780
-
781
- // Hide UI
782
- let uiHidden = false;
783
- hideUIBtn.addEventListener('click', () => {
784
- uiHidden = !uiHidden;
785
- if (uiHidden) {
786
- sidebar.style.transform = 'translateX(-100%)';
787
- sidebar.style.display = 'none'; // For layout adjustment
788
- header.style.display = 'none';
789
- floatingControls.style.opacity = '0.2';
790
- hideUIBtn.innerHTML = '<i class="fa-solid fa-eye"></i>';
791
-
792
- // On hover restore opacity
793
- floatingControls.addEventListener('mouseenter', () => floatingControls.style.opacity = '1');
794
- floatingControls.addEventListener('mouseleave', () => floatingControls.style.opacity = '0.2');
795
- } else {
796
- sidebar.style.transform = 'none';
797
- sidebar.style.display = 'flex';
798
- header.style.display = 'flex';
799
- floatingControls.style.opacity = '1';
800
- hideUIBtn.innerHTML = '<i class="fa-solid fa-eye-slash"></i>';
801
-
802
- // Remove hover listeners
803
- floatingControls.replaceWith(floatingControls.cloneNode(true));
804
- // Re-fetch because reference changed
805
- document.getElementById('hideUIBtn').addEventListener('click', () => hideUIBtn.click());
806
- // Re-bind other float buttons (simple reload of page logic usually easier but here we rebind)
807
- // For simplicity in this single file demo, toggling visibility is enough
808
- location.reload(); // Simplest way to restore event listeners properly without complex re-binding logic in this scope
809
- }
810
- });
811
-
812
- // Mobile Menu
813
- toggleSettings.addEventListener('click', () => {
814
- sidebar.classList.toggle('active');
815
- if (sidebar.classList.contains('active')) {
816
- sidebar.style.display = 'flex';
817
- } else {
818
- sidebar.style.display = 'none';
819
- }
820
- });
821
-
822
- // Mouse inactivity logic
823
- let mouseTimer;
824
- function hideCursorTimer() {
825
- document.body.style.cursor = 'default';
826
- clearTimeout(mouseTimer);
827
- if(isPlaying) {
828
- mouseTimer = setTimeout(() => {
829
- document.body.style.cursor = 'none';
830
- }, 2000);
831
- }
832
- }
833
- document.addEventListener('mousemove', hideCursorTimer);
834
-
835
- // Initialize defaults
836
- prompterText.style.fontSize = '60px';
837
- prompterText.style.lineHeight = '1.5';
838
-
839
- </script>
840
- </body>
841
- </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>QPrompt - The Teleprompter for Creators</title>
7
+ <meta name="description" content="Free and open source teleprompter software for video creators. Built for productivity, ease of use, and smooth performance.">
 
 
 
8
 
9
+ <!-- Fonts & Icons -->
10
+ <link rel="preconnect" href="https://fonts.googleapis.com">
11
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
12
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700;800&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
13
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
14
+
15
  <style>
16
+ /* --- CSS VARIABLES & RESET --- */
17
  :root {
18
+ --bg-dark: #0a0a0c;
19
+ --bg-surface: #131316;
20
+ --bg-card: #1c1c21;
21
+
22
+ --primary: #fbbf24; /* Amber from original logo */
23
+ --primary-glow: rgba(251, 191, 36, 0.3);
24
+ --accent: #3b82f6; /* Modern Blue */
25
+
26
+ --text-main: #ffffff;
27
+ --text-muted: #9ca3af;
28
+ --text-dark: #111827;
29
+
30
+ --border-color: rgba(255, 255, 255, 0.08);
31
+ --glass: rgba(19, 19, 22, 0.7);
32
+
33
+ --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
34
+ --container-width: 1200px;
35
  }
36
 
37
  * {
 
38
  margin: 0;
39
  padding: 0;
40
+ box-sizing: border-box;
41
+ }
42
+
43
+ html {
44
+ scroll-behavior: smooth;
45
  }
46
 
47
  body {
48
  font-family: 'Inter', sans-serif;
49
+ background-color: var(--bg-dark);
50
+ color: var(--text-main);
51
+ line-height: 1.6;
52
+ overflow-x: hidden;
 
 
53
  }
54
 
55
+ a { text-decoration: none; color: inherit; transition: var(--transition); }
56
+ ul { list-style: none; }
57
+
58
+ /* --- UTILITIES --- */
59
+ .container {
60
+ max-width: var(--container-width);
61
+ margin: 0 auto;
62
+ padding: 0 20px;
 
63
  }
64
 
65
+ .text-gradient {
66
+ background: linear-gradient(135deg, var(--primary) 0%, #f59e0b 100%);
67
+ -webkit-background-clip: text;
68
+ -webkit-text-fill-color: transparent;
69
+ background-clip: text;
 
 
 
70
  }
71
 
72
+ .btn {
73
+ display: inline-flex;
74
+ align-items: center;
75
+ justify-content: center;
76
+ padding: 12px 28px;
77
+ border-radius: 8px;
78
+ font-weight: 600;
79
+ font-size: 1rem;
80
+ cursor: pointer;
81
+ transition: var(--transition);
82
+ gap: 10px;
83
  }
84
 
85
+ .btn-primary {
86
+ background: var(--primary);
87
+ color: var(--text-dark);
88
+ box-shadow: 0 4px 20px var(--primary-glow);
 
89
  }
90
 
91
+ .btn-primary:hover {
92
+ transform: translateY(-2px);
93
+ background: #f59e0b;
94
+ box-shadow: 0 8px 25px var(--primary-glow);
95
  }
96
 
97
+ .btn-outline {
98
+ background: transparent;
99
+ border: 1px solid var(--border-color);
100
+ color: var(--text-main);
 
 
101
  }
102
 
103
+ .btn-outline:hover {
104
+ border-color: var(--text-main);
105
+ background: rgba(255,255,255,0.05);
 
 
 
 
 
 
 
 
106
  }
107
 
108
+ .section-padding {
109
+ padding: 100px 0;
 
 
110
  }
111
 
112
+ .badge {
113
+ display: inline-block;
114
+ padding: 4px 12px;
115
+ border-radius: 50px;
116
  font-size: 0.75rem;
117
+ font-weight: 600;
118
  text-transform: uppercase;
119
+ letter-spacing: 1px;
120
+ background: rgba(251, 191, 36, 0.1);
121
+ color: var(--primary);
122
+ border: 1px solid rgba(251, 191, 36, 0.2);
123
+ margin-bottom: 20px;
124
+ }
125
+
126
+ /* --- HEADER --- */
127
+ .anycoder-bar {
128
+ background: linear-gradient(90deg, #6366f1, #a855f7);
129
+ text-align: center;
130
+ padding: 8px;
131
+ font-size: 0.85rem;
132
  font-weight: 600;
133
  }
134
+ .anycoder-bar a { color: white; }
135
 
136
+ .navbar {
137
+ position: sticky;
138
+ top: 0;
139
+ z-index: 1000;
140
+ background: var(--glass);
141
+ backdrop-filter: blur(12px);
142
+ border-bottom: 1px solid var(--border-color);
143
+ padding: 15px 0;
144
+ }
145
+
146
+ .nav-container {
147
  display: flex;
148
+ justify-content: space-between;
149
  align-items: center;
 
150
  }
151
 
152
+ .logo {
153
+ display: flex;
154
+ align-items: center;
155
+ gap: 10px;
156
+ font-weight: 800;
157
+ font-size: 1.5rem;
158
+ color: var(--text-main);
159
  }
160
+
161
+ .logo img { height: 32px; width: auto; }
162
 
163
+ .nav-links {
164
+ display: flex;
165
+ gap: 30px;
 
 
 
 
 
166
  }
167
 
168
+ .nav-links a {
169
+ font-size: 0.95rem;
170
+ color: var(--text-muted);
171
+ font-weight: 500;
172
  }
173
 
174
+ .nav-links a:hover { color: var(--primary); }
175
+
176
+ .mobile-toggle { display: none; font-size: 1.5rem; cursor: pointer; }
177
+
178
+ /* --- HERO SECTION --- */
179
+ .hero {
180
+ padding: 120px 0 80px;
181
+ position: relative;
182
+ overflow: hidden;
183
  }
184
 
185
+ /* Ambient Glow Background */
186
+ .hero::before {
187
+ content: '';
188
+ position: absolute;
189
+ top: -20%;
190
+ left: 50%;
191
+ transform: translateX(-50%);
192
+ width: 800px;
193
+ height: 800px;
194
+ background: radial-gradient(circle, rgba(59, 130, 246, 0.15) 0%, rgba(0,0,0,0) 70%);
195
+ z-index: -1;
196
+ pointer-events: none;
197
+ }
198
+
199
+ .hero-content {
200
+ display: grid;
201
+ grid-template-columns: 1fr 1fr;
202
  align-items: center;
203
+ gap: 60px;
 
 
 
 
 
 
 
 
204
  }
205
 
206
+ .hero-text h1 {
207
+ font-size: 3.5rem;
208
+ line-height: 1.1;
209
+ margin-bottom: 20px;
210
+ font-weight: 800;
211
  }
212
 
213
+ .hero-text p {
214
+ font-size: 1.2rem;
215
+ color: var(--text-muted);
216
+ margin-bottom: 40px;
217
+ max-width: 500px;
218
  }
219
 
220
+ .hero-buttons {
221
+ display: flex;
222
+ gap: 15px;
223
+ flex-wrap: wrap;
224
  }
225
 
226
+ .platform-icons {
227
+ margin-top: 30px;
228
+ display: flex;
229
+ gap: 20px;
230
+ color: var(--text-muted);
231
+ font-size: 1.5rem;
232
+ opacity: 0.7;
233
  }
234
 
235
+ /* CSS ONLY APP MOCKUP */
236
+ .app-mockup {
237
+ background: #000;
238
+ border-radius: 16px;
239
+ border: 1px solid var(--border-color);
240
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.7);
241
+ aspect-ratio: 16/10;
242
+ display: flex;
243
+ flex-direction: column;
244
+ overflow: hidden;
245
+ position: relative;
246
+ transform: perspective(1000px) rotateY(-5deg) rotateX(2deg);
247
+ transition: transform 0.5s ease;
248
  }
249
 
250
+ .app-mockup:hover {
251
+ transform: perspective(1000px) rotateY(0deg) rotateX(0deg);
252
  }
253
 
254
+ .mockup-header {
255
+ background: #1f1f1f;
256
+ padding: 10px 15px;
257
  display: flex;
258
  align-items: center;
259
+ gap: 8px;
260
+ border-bottom: 1px solid #333;
261
  }
262
 
263
+ .dot { width: 10px; height: 10px; border-radius: 50%; }
264
+ .dot.red { background: #ef4444; }
265
+ .dot.yellow { background: #f59e0b; }
266
+ .dot.green { background: #10b981; }
267
+
268
+ .mockup-screen {
269
+ flex: 1;
270
+ background: #000;
271
+ color: #fff;
272
+ padding: 40px;
273
+ font-family: 'Inter', sans-serif; /* Teleprompter font */
274
+ font-size: 2rem;
275
+ font-weight: 700;
276
+ text-align: center;
277
  position: relative;
278
+ display: flex;
279
+ align-items: center;
280
+ justify-content: center;
281
  }
282
 
283
+ /* Teleprompter Animation */
284
+ .scrolling-text {
285
+ animation: scrollUp 10s linear infinite;
 
286
  }
287
+
288
+ .marker {
289
  position: absolute;
290
+ left: 20px;
291
+ top: 50%;
292
+ transform: translateY(-50%);
293
+ color: var(--primary);
294
+ font-size: 1.5rem;
295
+ opacity: 0.8;
 
 
296
  }
297
 
298
+ @keyframes scrollUp {
299
+ 0% { transform: translateY(100%); opacity: 0; }
300
+ 10% { opacity: 1; }
301
+ 90% { opacity: 1; }
302
+ 100% { transform: translateY(-150%); opacity: 0; }
 
 
 
 
 
303
  }
304
 
305
+ /* --- FEATURES GRID --- */
306
+ .features-section {
307
+ background: var(--bg-surface);
308
  }
309
 
310
+ .section-header {
311
+ text-align: center;
312
+ margin-bottom: 60px;
313
  }
314
 
315
+ .section-header h2 {
316
+ font-size: 2.5rem;
317
+ margin-bottom: 15px;
 
 
 
 
 
318
  }
319
 
320
+ .features-grid {
321
+ display: grid;
322
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
323
+ gap: 30px;
 
 
 
 
324
  }
325
 
326
+ .feature-card {
327
+ background: var(--bg-card);
328
+ padding: 30px;
329
+ border-radius: 16px;
330
+ border: 1px solid var(--border-color);
331
+ transition: var(--transition);
332
  }
333
 
334
+ .feature-card:hover {
335
+ border-color: var(--primary);
336
+ transform: translateY(-5px);
 
 
 
 
 
 
 
 
 
 
 
337
  }
338
 
339
+ .feature-icon {
340
+ width: 50px;
341
+ height: 50px;
 
 
 
 
 
 
342
  background: rgba(255, 255, 255, 0.05);
343
+ border-radius: 12px;
 
344
  display: flex;
345
  align-items: center;
346
+ justify-content: center;
347
+ font-size: 1.25rem;
348
+ color: var(--primary);
349
+ margin-bottom: 20px;
350
  }
351
+
352
+ .feature-card h3 {
353
+ font-size: 1.25rem;
354
+ margin-bottom: 10px;
 
 
 
 
 
355
  }
356
 
357
+ .feature-card p {
358
+ color: var(--text-muted);
359
+ font-size: 0.95rem;
 
 
 
 
 
 
360
  }
361
 
362
+ /* --- OS SHOWCASE --- */
363
+ .os-grid {
364
+ display: grid;
365
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
366
+ gap: 20px;
367
+ text-align: center;
368
+ margin-top: 40px;
369
+ }
370
+
371
+ .os-item {
372
+ padding: 20px;
373
+ background: var(--bg-card);
374
+ border-radius: 12px;
 
375
  border: 1px solid var(--border-color);
 
 
376
  }
377
+
378
+ .os-item i { font-size: 2rem; margin-bottom: 10px; display: block; }
379
 
380
+ /* --- COMMUNITY SECTION --- */
381
+ .community-grid {
382
+ display: grid;
383
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
384
+ gap: 20px;
 
 
 
 
 
 
 
 
385
  }
386
 
387
+ .community-card {
388
+ background: var(--bg-card);
389
+ border: 1px solid var(--border-color);
390
+ padding: 25px;
391
+ border-radius: 12px;
392
+ display: flex;
393
+ flex-direction: column;
394
+ justify-content: space-between;
395
+ height: 100%;
396
  }
397
 
398
+ .community-card:hover {
399
+ background: rgba(255,255,255,0.03);
 
 
 
400
  }
401
 
402
+ .c-icon {
403
+ font-size: 2rem;
404
+ margin-bottom: 15px;
405
+ color: var(--accent);
406
  }
407
 
408
+ .c-title { font-weight: 700; font-size: 1.1rem; margin-bottom: 8px; }
409
+ .c-desc { font-size: 0.9rem; color: var(--text-muted); margin-bottom: 20px; }
410
+
411
+ .c-link {
412
+ margin-top: auto;
413
+ font-size: 0.9rem;
414
+ font-weight: 600;
415
+ color: var(--primary);
416
+ display: flex;
417
+ align-items: center;
418
+ gap: 5px;
419
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
 
421
+ /* --- FOOTER --- */
422
+ footer {
423
+ background: #000;
424
+ padding: 60px 0 30px;
425
+ border-top: 1px solid var(--border-color);
426
+ font-size: 0.9rem;
427
+ color: var(--text-muted);
428
+ }
429
 
430
+ .footer-content {
431
+ display: flex;
432
+ justify-content: space-between;
433
+ flex-wrap: wrap;
434
+ gap: 40px;
435
+ margin-bottom: 40px;
436
  }
437
 
438
+ .footer-logo {
 
 
 
439
  color: white;
440
+ font-weight: 700;
441
+ font-size: 1.2rem;
442
+ margin-bottom: 15px;
443
+ display: block;
444
  }
445
 
446
+ .footer-links h4 { color: white; margin-bottom: 15px; }
447
+ .footer-links li { margin-bottom: 10px; }
448
+ .footer-links a:hover { color: var(--primary); }
449
+
450
+ .social-row {
451
+ display: flex;
452
+ gap: 15px;
453
+ margin-top: 20px;
454
  }
455
 
456
+ .social-row a {
457
+ width: 36px; height: 36px;
458
+ border-radius: 50%;
459
+ background: rgba(255,255,255,0.1);
460
+ display: flex;
461
+ align-items: center;
462
+ justify-content: center;
463
  }
464
+ .social-row a:hover { background: var(--primary); color: #000; }
465
 
466
+ .copyright {
467
+ text-align: center;
468
+ padding-top: 30px;
469
+ border-top: 1px solid rgba(255,255,255,0.1);
470
+ }
471
+
472
+ /* --- RESPONSIVE --- */
473
+ @media (max-width: 992px) {
474
+ .hero-content { grid-template-columns: 1fr; text-align: center; gap: 40px; }
475
+ .hero-text p { margin: 0 auto 30px; }
476
+ .hero-buttons { justify-content: center; }
477
+ .platform-icons { justify-content: center; }
478
+ .app-mockup { max-width: 600px; margin: 0 auto; }
479
+ }
480
+
481
+ @media (max-width: 768px) {
482
+ .nav-links { display: none; position: absolute; top: 100%; left: 0; width: 100%; background: var(--bg-card); flex-direction: column; padding: 20px; text-align: center; border-bottom: 1px solid var(--border-color); }
483
+ .nav-links.active { display: flex; }
484
+ .mobile-toggle { display: block; }
485
+ .hero-text h1 { font-size: 2.5rem; }
486
+ }
487
  </style>
488
  </head>
489
+ <body id="page-top">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
490
 
491
+ <!-- Anycoder Header -->
492
+ <div class="anycoder-bar">
493
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">Built with anycoder</a>
494
+ </div>
 
 
 
 
 
495
 
496
+ <!-- Navbar -->
497
+ <nav class="navbar">
498
+ <div class="container nav-container">
499
+ <a href="#" class="logo">
500
+ <i class="fa-solid fa-video" style="color: var(--primary);"></i> QPrompt
501
+ </a>
502
+ <div class="mobile-toggle" id="mobileToggle">
503
+ <i class="fa-solid fa-bars"></i>
504
  </div>
505
+ <ul class="nav-links" id="navLinks">
506
+ <li><a href="#features">Features</a></li>
507
+ <li><a href="#community">Community</a></li>
508
+ <li><a href="https://forum.qprompt.app/">Forum</a></li>
509
+ <li><a href="https://l10n.qprompt.app/">Translations</a></li>
510
+ <li><a href="https://github.com/Cuperino/QPrompt" target="_blank"><i class="fab fa-github"></i> Source</a></li>
511
+ <li><a href="https://sourceforge.net/projects/qprompt/files/latest/download" class="btn btn-primary" style="padding: 8px 16px; font-size: 0.9rem;">Download</a></li>
512
+ </ul>
513
+ </div>
514
+ </nav>
515
+
516
+ <!-- Hero Section -->
517
+ <section class="hero">
518
+ <div class="container hero-content">
519
+ <div class="hero-text">
520
+ <span class="badge">Open Source & Free</span>
521
+ <h1>Speak with <br><span class="text-gradient">Confidence.</span></h1>
522
+ <p>The teleprompter designed for creators who value productivity. Fluid motion, jitter-free performance, and cross-platform compatibility.</p>
523
+ <div class="hero-buttons">
524
+ <a href="https://github.com/Cuperino/QPrompt-Teleprompter/releases/latest" class="btn btn-primary">
525
+ <i class="fa-solid fa-download"></i> Download Now
526
+ </a>
527
+ <a href="#features" class="btn btn-outline">
528
+ Learn More
529
+ </a>
530
  </div>
531
+ <div class="platform-icons">
532
+ <i class="fab fa-windows" title="Windows"></i>
533
+ <i class="fab fa-apple" title="macOS"></i>
534
+ <i class="fab fa-linux" title="Linux"></i>
535
+ <i class="fab fa-android" title="Android"></i>
 
 
 
536
  </div>
537
  </div>
538
+
539
+ <!-- CSS Animated Mockup -->
540
+ <div class="app-mockup">
541
+ <div class="mockup-header">
542
+ <div class="dot red"></div>
543
+ <div class="dot yellow"></div>
544
+ <div class="dot green"></div>
545
+ </div>
546
+ <div class="mockup-screen">
547
+ <div class="marker"><i class="fa-solid fa-caret-right"></i></div>
548
+ <div class="scrolling-text">
549
+ Welcome to QPrompt.<br><br>
550
+ Focus on your audience.<br>
551
+ Read naturally.<br>
552
+ No jitter.<br>
553
+ No hassle.<br><br>
554
+ Ready to record?
555
+ </div>
556
  </div>
557
  </div>
558
+ </div>
559
+ </section>
560
+
561
+ <!-- Value Prop / Reasons -->
562
+ <section class="section-padding" id="reasons">
563
+ <div class="container">
564
+ <div class="section-header">
565
+ <h2>Why Creators Choose QPrompt</h2>
566
+ <p style="color: var(--text-muted);">Built with productivity, ease of use, and smooth performance in mind.</p>
567
+ </div>
568
+ <div class="features-grid">
569
+ <div class="feature-card">
570
+ <div class="feature-icon"><i class="fa-solid fa-eye"></i></div>
571
+ <h3>Be Present</h3>
572
+ <p>Have your audience watch you speak directly to them. Plan your script to be respectful of their time, and QPrompt will be respectful of yours.</p>
573
  </div>
574
+ <div class="feature-card">
575
+ <div class="feature-icon"><i class="fa-solid fa-bolt"></i></div>
576
+ <h3>Be Productive</h3>
577
+ <p>Search text, add markers, move quickly, and make changes on the fly. Spend less time fixing scripts and more time creating content.</p>
578
+ </div>
579
+ <div class="feature-card">
580
+ <div class="feature-icon"><i class="fa-solid fa-mobile-screen"></i></div>
581
+ <h3>Any Setup</h3>
582
+ <p>Works with professional studio teleprompters, tablets, webcams, and phones. Record faster regardless of your hardware.</p>
583
  </div>
584
  </div>
585
+ </div>
586
+ </section>
587
+
588
+ <!-- Features Deep Dive -->
589
+ <section class="section-padding features-section" id="features">
590
+ <div class="container">
591
+ <div class="section-header">
592
+ <h2>Everything you need</h2>
593
+ </div>
594
+ <div class="features-grid" style="grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));">
595
+ <!-- List of features -->
596
+ <div class="feature-card" style="border: none; background: transparent; padding: 0;">
597
+ <ul style="color: var(--text-muted); font-size: 1.1rem;">
598
+ <li style="margin-bottom: 15px;"><i class="fa-solid fa-check" style="color: var(--primary); margin-right: 10px;"></i> Fluid, jitter-free motion</li>
599
+ <li style="margin-bottom: 15px;"><i class="fa-solid fa-check" style="color: var(--primary); margin-right: 10px;"></i> Background transparency</li>
600
+ <li style="margin-bottom: 15px;"><i class="fa-solid fa-check" style="color: var(--primary); margin-right: 10px;"></i> Mirror screens (Flip X/Y)</li>
601
+ <li style="margin-bottom: 15px;"><i class="fa-solid fa-check" style="color: var(--primary); margin-right: 10px;"></i> Built-in chronometer</li>
602
+ <li style="margin-bottom: 15px;"><i class="fa-solid fa-check" style="color: var(--primary); margin-right: 10px;"></i> 180+ Languages supported</li>
603
+ </ul>
604
+ </div>
605
+ <div class="feature-card" style="border: none; background: transparent; padding: 0;">
606
+ <ul style="color: var(--text-muted); font-size: 1.1rem;">
607
+ <li style="margin-bottom: 15px;"><i class="fa-solid fa-check" style="color: var(--primary); margin-right: 10px;"></i> Rich text formatting</li>
608
+ <li style="margin-bottom: 15px;"><i class="fa-solid fa-check" style="color: var(--primary); margin-right: 10px;"></i> Native performance (C++/Qt)</li>
609
+ <li style="margin-bottom: 15px;"><i class="fa-solid fa-check" style="color: var(--primary); margin-right: 10px;"></i> Multi-screen support</li>
610
+ <li style="margin-bottom: 15px;"><i class="fa-solid fa-check" style="color: var(--primary); margin-right: 10px;"></i> Offline capable</li>
611
+ <li style="margin-bottom: 15px;"><i class="fa-solid fa-check" style="color: var(--primary); margin-right: 10px;"></i> Completely Free & Open Source</li>
612
+ </ul>
613
+ </div>
614
  </div>
 
 
 
 
 
615
 
616
+ <!-- Download Options -->
617
+ <div class="os-grid">
618
+ <a href="https://snapcraft.io/qprompt" class="os-item text-main">
619
+ <i class="fab fa-linux"></i>
620
+ <span>Snap Store</span>
621
+ </a>
622
+ <a href="https://flathub.org/apps/details/com.cuperino.qprompt" class="os-item text-main">
623
+ <i class="fas fa-box-open"></i>
624
+ <span>FlatHub</span>
625
+ </a>
626
+ <a href="https://github.com/Cuperino/QPrompt/releases" class="os-item text-main">
627
+ <i class="fab fa-windows"></i>
628
+ <span>Windows Installer</span>
629
+ </a>
630
+ <a href="https://github.com/Cuperino/QPrompt/releases" class="os-item text-main">
631
+ <i class="fab fa-apple"></i>
632
+ <span>macOS DMG</span>
633
+ </a>
634
+ </div>
635
+ </div>
636
+ </section>
637
+
638
+ <!-- Community Section -->
639
+ <section class="section-padding" id="community">
640
+ <div class="container">
641
+ <div class="section-header">
642
+ <h2>Join the Community</h2>
643
+ <p class="text-muted">QPrompt is built by the community, for the community.</p>
644
+ </div>
645
+ <div class="community-grid">
646
+ <!-- Github -->
647
+ <div class="community-card">
648
+ <div>
649
+ <i class="fab fa-github c-icon"></i>
650
+ <h3 class="c-title">Open Source</h3>
651
+ <p class="c-desc">Check out the code, build it yourself, or contribute to the project.</p>
652
+ </div>
653
+ <a href="https://github.com/Cuperino/QPrompt" class="c-link">View on GitHub <i class="fa-solid fa-arrow-right"></i></a>
654
+ </div>
655
+
656
+ <!-- Feedback -->
657
+ <div class="community-card">
658
+ <div>
659
+ <i class="fa-solid fa-bug c-icon"></i>
660
+ <h3 class="c-title">Feedback</h3>
661
+ <p class="c-desc">Found a bug? Have a feature request? We listen to all our users.</p>
662
+ </div>
663
+ <a href="https://github.com/Cuperino/QPrompt/issues" class="c-link">File Report <i class="fa-solid fa-arrow-right"></i></a>
664
+ </div>
665
 
666
+ <!-- Translate -->
667
+ <div class="community-card">
668
+ <div>
669
+ <i class="fa-solid fa-language c-icon"></i>
670
+ <h3 class="c-title">Translate</h3>
671
+ <p class="c-desc">Help bring QPrompt to more creators by contributing translations.</p>
672
+ </div>
673
+ <a href="https://l10n.cuperino.com/projects/qprompt/" class="c-link">Contribute <i class="fa-solid fa-arrow-right"></i></a>
674
+ </div>
675
 
676
+ <!-- Patreon -->
677
+ <div class="community-card">
678
+ <div>
679
+ <i class="fab fa-patreon c-icon"></i>
680
+ <h3 class="c-title">Support Us</h3>
681
+ <p class="c-desc">Get early access to builds and vote on future development priorities.</p>
682
+ </div>
683
+ <a href="https://www.patreon.com/qpromptapp" class="c-link">Become a Patron <i class="fa-solid fa-arrow-right"></i></a>
684
+ </div>
685
 
686
+ <!-- Discord -->
687
+ <div class="community-card">
688
+ <div>
689
+ <i class="fab fa-discord c-icon"></i>
690
+ <h3 class="c-title">Chat</h3>
691
+ <p class="c-desc">Join the conversation with other creators and the developer.</p>
692
+ </div>
693
+ <a href="https://discord.gg/8TSCZH2WyK" class="c-link">Join Discord <i class="fa-solid fa-arrow-right"></i></a>
694
+ </div>
695
 
696
+ <!-- Forum -->
697
+ <div class="community-card">
698
+ <div>
699
+ <i class="fa-solid fa-comments c-icon"></i>
700
+ <h3 class="c-title">Forum</h3>
701
+ <p class="c-desc">Share tips, tricks, and your studio setup with the community.</p>
702
+ </div>
703
+ <a href="https://forum.cuperino.com/c/qprompt/5" class="c-link">Visit Forum <i class="fa-solid fa-arrow-right"></i></a>
704
  </div>
705
  </div>
706
+ </div>
707
+ </section>
708
+
709
+ <!-- Footer -->
710
+ <footer>
711
+ <div class="container">
712
+ <div class="footer-content">
713
+ <div style="flex: 2; min-width: 250px;">
714
+ <a href="#" class="footer-logo">QPrompt</a>
715
+ <p>The open-source teleprompter software for all video creators. Built for performance and ease of use.</p>
716
+ <div class="social-row">
717
+ <a href="https://x.com/qpromptapp"><i class="fab fa-twitter"></i></a>
718
+ <a href="https://github.com/Cuperino/QPrompt-Teleprompter/"><i class="fab fa-github"></i></a>
719
+ <a href="https://discord.gg/8TSCZH2WyK"><i class="fab fa-discord"></i></a>
720
+ <a href="https://t.me/imaginaryteleprompter"><i class="fab fa-telegram"></i></a>
721
+ </div>
722
+ </div>
723
+
724
+ <div class="footer-links" style="flex: 1; min-width: 150px;">
725
+ <h4>Project</h4>
726
+ <ul>
727
+ <li><a href="https://sourceforge.net/projects/qprompt/files/latest/download">Download</a></li>
728
+ <li><a href="#features">Features</a></li>
729
+ <li><a href="https://github.com/Cuperino/QPrompt">Source Code</a></li>
730
+ <li><a href="https://www.patreon.com/qpromptapp">Development Updates</a></li>
731
+ </ul>
732
+ </div>
733
 
734
+ <div class="footer-links" style="flex: 1; min-width: 150px;">
735
+ <h4>Legal & Docs</h4>
736
+ <ul>
737
+ <li><a href="https://docs.cuperino.com/">Documentation</a></li>
738
+ <li><a href="https://github.com/Cuperino/QPrompt-Teleprompter/blob/main/COPYING">License (GPLv3)</a></li>
739
+ <li><a href="https://github.com/Cuperino/QPrompt-Teleprompter/#code-of-conduct">Code of Conduct</a></li>
740
+ <li><a href="https://github.com/Cuperino/Signatures/blob/main/CLA.md">CLA</a></li>
741
+ </ul>
742
+ </div>
 
 
 
 
 
 
743
  </div>
744
+ <div class="copyright">
745
+ <p>&copy; 2021-2024 Javier O. Cordero Pérez. All rights reserved.</p>
746
+ </div>
747
+ </div>
748
+ </footer>
749
 
750
  <script>
751
+ // Mobile Navigation Toggle
752
+ const mobileToggle = document.getElementById('mobileToggle');
753
+ const navLinks = document.getElementById('navLinks');
754
+
755
+ mobileToggle.addEventListener('click', () => {
756
+ navLinks.classList.toggle('active');
757
+ const icon = mobileToggle.querySelector('i');
758
+ if (navLinks.classList.contains('active')) {
759
+ icon.classList.remove('fa-bars');
760
+ icon.classList.add('fa-times');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
761
  } else {
762
+ icon.classList.remove('fa-times');
763
+ icon.classList.add('fa-bars');
764
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
765
  });
766
 
767
+ // Close mobile menu when clicking a link
768
+ document.querySelectorAll('.nav-links a').forEach(link => {
769
+ link.addEventListener