-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
810 lines (774 loc) · 109 KB
/
Copy pathindex.html
File metadata and controls
810 lines (774 loc) · 109 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
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Новые Горизонты Инфобизнеса — Академия Кристины</title>
<style>
@import url('https://cdn.jsdelivr.net/npm/@fontsource/inter@5.0.20/400.css');
@import url('https://cdn.jsdelivr.net/npm/@fontsource/inter@5.0.20/600.css');
@import url('https://cdn.jsdelivr.net/npm/@fontsource/inter@5.0.20/700.css');
@import url('https://cdn.jsdelivr.net/npm/@fontsource/inter@5.0.20/800.css');
@import url('https://cdn.jsdelivr.net/npm/@fontsource/inter@5.0.20/900.css');
:root {
--cherry: #C41E3A; --cherry-light: #E8435D; --cherry-dark: #8B1528;
--gold: #D4AF37; --gold-light: #F0D670; --gold-dark: #A88B2C;
--cream: #FDF8F0; --cream-dark: #F5EDE0; --text-dark: #2A1A1A;
--text-light: #5A4A4A; --white: #FFFFFF;
--shadow: 0 8px 32px rgba(196,30,58,0.12);
--radius: 16px; --radius-sm: 8px;
}
* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; background: var(--cream); color: var(--text-dark); line-height: 1.7; min-height: 100vh; overflow-x: hidden; }
.page { display: none; animation: fadeIn .5s ease; } .page.active { display: block; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
@keyframes slideIn { from { opacity: 0; transform: translateX(-30px); } to { opacity: 1; transform: translateX(0); } }
@keyframes pulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.05); } }
@keyframes float { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
@keyframes shimmer { 0% { background-position: -200% center; } 100% { background-position: 200% center; } }
@keyframes cherryFloat { 0% { transform: translateY(100vh) rotate(0deg); opacity: 0; } 10% { opacity: .45; } 90% { opacity: .45; } 100% { transform: translateY(-100vh) rotate(360deg); opacity: 0; } }
@keyframes bounce { 0%,80%,100% { transform: translateY(0); } 40% { transform: translateY(-6px); } }
.cherry-particle { position: fixed; pointer-events: none; z-index: 0; font-size: 24px; animation: cherryFloat linear infinite; opacity: 0; }
.header { background: linear-gradient(135deg, var(--cherry-dark) 0%, var(--cherry) 50%, var(--cherry-light) 100%); padding: 12px 24px; display: flex; justify-content: space-between; align-items: center; box-shadow: 0 4px 20px rgba(196,30,58,0.3); position: sticky; top: 0; z-index: 100; }
.header-logo { color: var(--gold-light); font-weight: 800; font-size: 18px; display: flex; align-items: center; gap: 8px; }
.header-nav { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.header-nav button { background: rgba(255,255,255,0.15); border: 1px solid rgba(212,175,55,0.4); color: var(--gold-light); padding: 8px 16px; border-radius: var(--radius-sm); cursor: pointer; font-size: 14px; font-weight: 600; transition: all .3s; font-family: inherit; }
.header-nav button:hover { background: rgba(255,255,255,0.25); border-color: var(--gold); }
.header-nav button.gold { background: linear-gradient(135deg, var(--gold), var(--gold-light)); color: var(--cherry-dark); border: none; }
/* ========== LANDING — БЛЕДНЫЙ ОТТЕНОК ========== */
.landing { min-height: 100vh; display: flex; flex-direction: column; position: relative; overflow: hidden; }
.landing-bg { position: absolute; inset: 0; background: linear-gradient(160deg, #FFFDFA 0%, #FDF4F1 25%, #FAEBE9 50%, #FDF5E6 75%, #FFFDFA 100%); z-index: 0; }
.landing-bg::before { content: ''; position: absolute; inset: 0; background: radial-gradient(ellipse at 30% 20%, rgba(232,67,93,0.10) 0%, transparent 50%), radial-gradient(ellipse at 70% 80%, rgba(212,175,55,0.16) 0%, transparent 50%), radial-gradient(ellipse at 50% 50%, rgba(196,30,58,0.05) 0%, transparent 70%); }
.landing-content { position: relative; z-index: 1; flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px 24px; text-align: center; }
.landing-badge { display: inline-flex; align-items: center; gap: 8px; background: rgba(212,175,55,0.16); border: 1px solid rgba(168,139,44,0.4); color: var(--gold-dark); padding: 8px 20px; border-radius: 50px; font-size: 13px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; margin-bottom: 24px; animation: float 3s ease-in-out infinite; }
.landing-title { font-size: clamp(32px, 6vw, 64px); font-weight: 900; color: var(--cherry-dark); line-height: 1.1; margin-bottom: 16px; max-width: 800px; }
.landing-title .gold { background: linear-gradient(90deg, var(--gold-dark), var(--gold), var(--gold-light), var(--gold-dark)); background-size: 200% auto; -webkit-background-clip: text; -webkit-text-fill-color: transparent; animation: shimmer 3s linear infinite; }
.landing-subtitle { font-size: clamp(16px, 2.5vw, 22px); color: #7A6262; max-width: 600px; margin-bottom: 32px; line-height: 1.6; }
.landing-author { display: flex; align-items: center; gap: 16px; background: rgba(255,255,255,0.8); backdrop-filter: blur(10px); border: 1px solid rgba(212,175,55,0.4); box-shadow: 0 8px 24px rgba(196,30,58,0.08); padding: 16px 24px; border-radius: var(--radius); margin-bottom: 40px; }
.author-avatar { width: 56px; height: 56px; border-radius: 50%; background: linear-gradient(135deg, var(--cherry), var(--gold)); display: flex; align-items: center; justify-content: center; font-size: 24px; color: white; font-weight: 800; }
.author-info { text-align: left; } .author-name { color: var(--cherry); font-weight: 700; font-size: 18px; } .author-role { color: var(--text-light); font-size: 14px; }
.landing-cta { display: inline-flex; align-items: center; gap: 12px; background: linear-gradient(135deg, var(--gold), var(--gold-light)); color: var(--cherry-dark); padding: 18px 48px; border-radius: 50px; font-size: 18px; font-weight: 800; border: none; cursor: pointer; transition: all .3s; box-shadow: 0 8px 32px rgba(212,175,55,0.35); animation: pulse 2s ease-in-out infinite; }
.landing-cta:hover { transform: scale(1.05); box-shadow: 0 12px 40px rgba(212,175,55,0.5); }
.landing-features { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; max-width: 800px; margin-top: 48px; width: 100%; }
.landing-feature { background: rgba(255,255,255,0.82); backdrop-filter: blur(10px); border: 1px solid rgba(196,30,58,0.10); box-shadow: 0 4px 16px rgba(196,30,58,0.06); padding: 20px; border-radius: var(--radius); text-align: center; transition: transform .3s; }
.landing-feature:hover { transform: translateY(-4px); }
.landing-feature-icon { font-size: 32px; margin-bottom: 8px; } .landing-feature-text { color: #6B5454; font-size: 14px; font-weight: 600; }
.login-container { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; background: linear-gradient(160deg, var(--cream) 0%, var(--cream-dark) 100%); position: relative; }
.login-card { background: var(--white); border-radius: 24px; padding: 48px; max-width: 440px; width: 100%; box-shadow: var(--shadow); border: 1px solid rgba(212,175,55,0.2); position: relative; overflow: hidden; }
.login-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; background: linear-gradient(90deg, var(--cherry), var(--gold), var(--cherry)); }
.login-icon { width: 64px; height: 64px; background: linear-gradient(135deg, var(--cherry), var(--cherry-light)); border-radius: 16px; display: flex; align-items: center; justify-content: center; font-size: 28px; margin: 0 auto 24px; }
.login-title { text-align: center; font-size: 28px; font-weight: 800; color: var(--text-dark); margin-bottom: 8px; } .login-subtitle { text-align: center; color: var(--text-light); margin-bottom: 32px; font-size: 15px; }
.form-group { margin-bottom: 20px; } .form-label { display: block; font-weight: 600; color: var(--text-dark); margin-bottom: 8px; font-size: 14px; }
.form-input { width: 100%; padding: 14px 16px; border: 2px solid #E8E0D8; border-radius: var(--radius-sm); font-size: 16px; font-family: inherit; transition: all .3s; background: var(--cream); }
.form-input:focus { outline: none; border-color: var(--cherry); box-shadow: 0 0 0 4px rgba(196,30,58,0.1); } .form-input::placeholder { color: #B8B0A8; }
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 14px 28px; border-radius: var(--radius-sm); font-size: 16px; font-weight: 700; font-family: inherit; cursor: pointer; transition: all .3s; border: none; text-decoration: none; }
.btn-primary { background: linear-gradient(135deg, var(--cherry), var(--cherry-light)); color: white; width: 100%; box-shadow: 0 4px 16px rgba(196,30,58,0.3); }
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(196,30,58,0.4); }
.btn-gold { background: linear-gradient(135deg, var(--gold), var(--gold-light)); color: var(--cherry-dark); box-shadow: 0 4px 16px rgba(212,175,55,0.3); }
.btn-gold:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(212,175,55,0.4); }
.btn-outline { background: transparent; border: 2px solid var(--cherry); color: var(--cherry); } .btn-outline:hover { background: var(--cherry); color: white; }
.btn-back { background: transparent; border: none; color: var(--text-light); font-size: 14px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; padding: 8px 0; font-weight: 600; margin-bottom: 16px; transition: color .3s; font-family: inherit; }
.btn-back:hover { color: var(--cherry); }
.login-error { background: #FFF0F0; border: 1px solid var(--cherry-light); color: var(--cherry-dark); padding: 12px 16px; border-radius: var(--radius-sm); font-size: 14px; margin-bottom: 16px; display: none; }
.dashboard { padding: 32px 24px; max-width: 1200px; margin: 0 auto; } .dashboard-header { margin-bottom: 32px; }
.dashboard-welcome { font-size: 14px; color: var(--text-light); margin-bottom: 4px; } .dashboard-title { font-size: clamp(28px, 4vw, 40px); font-weight: 900; color: var(--text-dark); } .dashboard-title .gold { color: var(--gold); }
.progress-bar-container { background: var(--cream-dark); border-radius: 50px; height: 12px; margin: 16px 0; overflow: hidden; }
.progress-bar-fill { height: 100%; background: linear-gradient(90deg, var(--cherry), var(--gold)); border-radius: 50px; transition: width .5s ease; } .progress-text { font-size: 14px; color: var(--text-light); font-weight: 600; }
.modules-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; margin-top: 24px; }
.module-card { background: var(--white); border-radius: var(--radius); padding: 24px; box-shadow: 0 4px 16px rgba(0,0,0,0.06); border: 1px solid rgba(0,0,0,0.06); cursor: pointer; transition: all .3s; position: relative; overflow: hidden; }
.module-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); border-color: rgba(196,30,58,0.2); }
.module-card::before { content: ''; position: absolute; top: 0; left: 0; width: 4px; height: 100%; background: var(--cherry); } .module-card.completed::before { background: var(--gold); }
.module-number { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; background: linear-gradient(135deg, var(--cherry), var(--cherry-light)); color: white; border-radius: 10px; font-weight: 800; font-size: 18px; margin-bottom: 12px; }
.module-card.completed .module-number { background: linear-gradient(135deg, var(--gold), var(--gold-light)); color: var(--cherry-dark); }
.module-card-title { font-size: 18px; font-weight: 700; margin-bottom: 8px; color: var(--text-dark); } .module-card-desc { font-size: 14px; color: var(--text-light); margin-bottom: 16px; }
.module-status { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; padding: 4px 12px; border-radius: 50px; }
.module-status.locked { background: #F0ECE8; color: var(--text-light); } .module-status.available { background: #FFF5E6; color: var(--gold-dark); } .module-status.completed { background: #E8F8EE; color: #2D8B4E; }
.dashboard-actions { display: flex; gap: 12px; margin-top: 32px; flex-wrap: wrap; }
.intro-banner { background: linear-gradient(135deg, var(--cherry), var(--cherry-light)); border-radius: var(--radius); padding: 32px; color: white; margin-bottom: 24px; }
.intro-banner h2 { font-size: 24px; font-weight: 800; margin-bottom: 12px; } .intro-banner p { color: rgba(255,255,255,0.9); line-height: 1.7; }
.module-page { padding: 32px 24px; max-width: 800px; margin: 0 auto; } .module-page-header { margin-bottom: 32px; } .module-page-title { font-size: clamp(24px, 3.5vw, 36px); font-weight: 900; color: var(--text-dark); margin-bottom: 12px; }
.module-content { background: var(--white); border-radius: var(--radius); padding: 32px; box-shadow: 0 4px 16px rgba(0,0,0,0.04); border: 1px solid rgba(0,0,0,0.04); }
.module-content h3 { font-size: 20px; font-weight: 800; color: var(--cherry); margin: 28px 0 12px; padding-bottom: 8px; border-bottom: 2px solid var(--cream-dark); }
.module-content h4 { font-size: 17px; font-weight: 700; color: var(--text-dark); margin: 20px 0 8px; } .module-content p { margin-bottom: 12px; color: var(--text-dark); }
.module-content ul, .module-content ol { margin: 12px 0 16px 20px; } .module-content li { margin-bottom: 6px; color: var(--text-dark); }
.highlight-box { background: linear-gradient(135deg, #FFF8F0, #FFF0F0); border-left: 4px solid var(--cherry); padding: 16px 20px; border-radius: 0 var(--radius-sm) var(--radius-sm) 0; margin: 20px 0; }
.gold-box { background: linear-gradient(135deg, #FFFBF0, #FFF8E6); border-left: 4px solid var(--gold); padding: 16px 20px; border-radius: 0 var(--radius-sm) var(--radius-sm) 0; margin: 20px 0; }
.toc-list { list-style: none; padding: 0; margin-left: 0 !important; } .toc-list li { padding: 10px 0; border-bottom: 1px solid var(--cream-dark); display: flex; align-items: center; gap: 12px; font-size: 15px; color: var(--text-dark); } .toc-list li:last-child { border-bottom: none; }
.toc-num { width: 28px; height: 28px; background: var(--cream); border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 800; color: var(--cherry); flex-shrink: 0; } .toc-num.gold { background: linear-gradient(135deg, var(--gold), var(--gold-light)); color: var(--cherry-dark); }
.module-nav-buttons { display: flex; gap: 12px; margin-top: 32px; flex-wrap: wrap; }
/* ========== ФИНАЛ: РЕЗУЛЬТАТЫ + ОТЗЫВ ========== */
.final-status { background: #FFF8F0; border: 1px solid rgba(212,175,55,0.4); border-radius: var(--radius-sm); padding: 12px 16px; font-size: 14px; margin-bottom: 20px; color: var(--text-dark); }
.final-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 16px 0 8px; }
.final-stat { background: var(--cream); border: 1px solid var(--cream-dark); border-radius: var(--radius-sm); padding: 16px; text-align: center; }
.final-stat-value { font-size: 26px; font-weight: 900; color: var(--cherry); }
.final-stat-label { font-size: 13px; color: var(--text-light); font-weight: 600; }
.continue-options { display: flex; gap: 10px; flex-wrap: wrap; }
.continue-option { padding: 12px 18px; border: 2px solid #E8E0D8; border-radius: 50px; cursor: pointer; font-size: 14px; font-weight: 600; background: var(--white); color: var(--text-light); transition: all .3s; }
.continue-option.active { border-color: var(--cherry); background: rgba(196,30,58,0.06); color: var(--cherry); }
.continue-option:hover { border-color: var(--cherry-light); }
.yandex-box { text-align: center; }
.checklist { margin: 20px 0; } .checklist-item { display: flex; align-items: flex-start; gap: 12px; padding: 12px; background: var(--cream); border-radius: var(--radius-sm); margin-bottom: 8px; cursor: pointer; transition: background .2s; } .checklist-item:hover { background: var(--cream-dark); }
.checklist-checkbox { width: 20px; height: 20px; border: 2px solid var(--cherry); border-radius: 4px; flex-shrink: 0; margin-top: 2px; display: flex; align-items: center; justify-content: center; transition: all .3s; background: var(--white); } .checklist-checkbox.checked { background: var(--cherry); border-color: var(--cherry); } .checklist-checkbox.checked::after { content: '✓'; color: white; font-size: 12px; font-weight: 800; }
.checklist-text { font-size: 14px; color: var(--text-dark); }
.checklist-result { margin-top: 20px; padding: 24px; background: var(--cream); border-radius: var(--radius); text-align: center; border: 2px solid var(--cream-dark); }
.checklist-score { font-size: 48px; font-weight: 900; margin-bottom: 8px; } .checklist-score.excellent { color: #2D8B4E; } .checklist-score.good { color: var(--gold-dark); } .checklist-score.work { color: var(--cherry); }
.checklist-label { font-size: 18px; font-weight: 800; color: var(--text-dark); margin-bottom: 8px; } .checklist-recommendation { font-size: 14px; color: var(--text-light); line-height: 1.6; }
.hw-section { margin-top: 32px; background: var(--white); border-radius: var(--radius); padding: 24px; border: 2px solid var(--gold); } .hw-title { font-size: 20px; font-weight: 800; color: var(--gold-dark); margin-bottom: 16px; display: flex; align-items: center; gap: 8px; }
.hw-subtitle { font-size: 14px; color: var(--text-light); margin-bottom: 16px; } .hw-item { background: var(--cream); border-radius: var(--radius-sm); padding: 16px; margin-bottom: 12px; }
.hw-item-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; flex-wrap: wrap; gap: 8px; } .hw-item-title { font-weight: 700; color: var(--text-dark); }
.hw-rating-wrap { display: flex; flex-direction: column; align-items: center; gap: 4px; } .hw-rating { display: flex; gap: 8px; }
.hw-btn { width: 36px; height: 36px; border-radius: 50%; border: 2px solid; cursor: pointer; font-size: 18px; font-weight: 800; display: flex; align-items: center; justify-content: center; transition: all .3s; background: var(--white); }
.hw-btn.plus { border-color: #2D8B4E; color: #2D8B4E; } .hw-btn.plus:hover, .hw-btn.plus.active { background: #2D8B4E; color: white; }
.hw-btn.minus { border-color: var(--cherry); color: var(--cherry); } .hw-btn.minus:hover, .hw-btn.minus.active { background: var(--cherry); color: white; }
.hw-rating-label { font-size: 11px; color: var(--text-light); font-weight: 600; text-align: center; white-space: nowrap; }
.hw-textarea { width: 100%; min-height: 80px; padding: 12px; border: 2px solid #E8E0D8; border-radius: var(--radius-sm); font-family: inherit; font-size: 14px; resize: vertical; background: var(--white); transition: border-color .3s; }
.hw-textarea:focus { outline: none; border-color: var(--gold); }
.hw-score { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 700; margin-top: 8px; }
.hw-score.positive { color: #2D8B4E; } .hw-score.negative { color: var(--cherry); } .hw-score.neutral { color: var(--text-light); }
.draft-table-container { overflow-x: auto; margin: 16px 0; -webkit-overflow-scrolling: touch; }
.draft-table { width: 100%; border-collapse: collapse; font-size: 13px; min-width: 600px; }
.draft-table th { background: linear-gradient(135deg, var(--gold), var(--gold-light)); color: var(--cherry-dark); padding: 10px 12px; text-align: left; font-weight: 700; border: 1px solid var(--cream-dark); }
.draft-table td { border: 1px solid var(--cream-dark); padding: 0; vertical-align: top; }
.draft-cell { width: 100%; min-height: 44px; padding: 8px 10px; border: none; background: var(--white); font-family: inherit; font-size: 13px; color: var(--text-dark); resize: none; outline: none; transition: all .2s; }
.draft-cell:focus { background: #FFFBF0; box-shadow: inset 0 0 0 2px var(--gold); } .draft-cell::placeholder { color: #C8C0B8; font-style: italic; }
.draft-row-num { width: 30px; text-align: center; background: var(--cream); font-weight: 700; color: var(--text-light); padding: 8px; font-size: 12px; }
.table-actions { display: flex; gap: 12px; margin-top: 16px; flex-wrap: wrap; } .btn-sm { padding: 10px 20px; font-size: 14px; }
.pdf-section { padding: 32px 24px; max-width: 900px; margin: 0 auto; }
.pdf-list { background: var(--white); border-radius: var(--radius); box-shadow: 0 4px 16px rgba(0,0,0,0.04); overflow: hidden; }
.pdf-item { display: flex; align-items: center; gap: 16px; padding: 16px 24px; border-bottom: 1px solid var(--cream-dark); cursor: pointer; transition: all .3s; }
.pdf-item:last-child { border-bottom: none; } .pdf-item:hover { background: var(--cream); }
.pdf-icon { width: 44px; height: 44px; background: linear-gradient(135deg, var(--cherry), var(--cherry-light)); border-radius: 10px; display: flex; align-items: center; justify-content: center; color: white; font-size: 20px; flex-shrink: 0; }
.pdf-info { flex: 1; min-width: 0; } .pdf-name { font-weight: 700; color: var(--text-dark); font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .pdf-desc { font-size: 13px; color: var(--text-light); }
.pdf-actions { display: flex; gap: 8px; align-items: center; flex-shrink: 0; }
.pdf-view-btn { padding: 6px 10px; font-size: 11px; background: var(--cream); border: 1px solid var(--gold); border-radius: 6px; color: var(--gold-dark); cursor: pointer; transition: all .3s; font-family: inherit; font-weight: 600; white-space: nowrap; } .pdf-view-btn:hover { background: var(--gold); color: var(--cherry-dark); }
.pdf-arrow { color: var(--text-light); font-size: 20px; }
.pdf-viewer { padding: 32px 24px; max-width: 900px; margin: 0 auto; }
.pdf-viewer-content { background: var(--white); border-radius: var(--radius); padding: 40px; box-shadow: 0 4px 16px rgba(0,0,0,0.04); border: 1px solid rgba(0,0,0,0.04); min-height: 400px; }
.pdf-viewer-title { font-size: 24px; font-weight: 800; color: var(--text-dark); margin-bottom: 24px; padding-bottom: 16px; border-bottom: 2px solid var(--cream-dark); }
.pdf-table { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 14px; }
.pdf-table th { background: linear-gradient(135deg, var(--cherry), var(--cherry-light)); color: white; padding: 12px 16px; text-align: left; font-weight: 700; }
.pdf-table td { padding: 12px 16px; border-bottom: 1px solid var(--cream-dark); color: var(--text-dark); } .pdf-table tr:hover td { background: var(--cream); }
.bot-container { padding: 32px 24px; max-width: 540px; margin: 0 auto; }
.bot-window { background: var(--white); border-radius: 20px; box-shadow: 0 12px 40px rgba(0,0,0,0.1); overflow: hidden; border: 2px solid var(--cream-dark); }
.bot-header { background: linear-gradient(135deg, var(--cherry), var(--cherry-light)); padding: 16px 20px; display: flex; align-items: center; gap: 12px; }
.bot-avatar { width: 40px; height: 40px; background: rgba(255,255,255,0.2); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 20px; }
.bot-name { color: white; font-weight: 700; } .bot-status { color: rgba(255,255,255,0.7); font-size: 12px; }
.bot-messages { padding: 20px; min-height: 400px; max-height: 500px; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; background: var(--cream); -webkit-overflow-scrolling: touch; }
.bot-msg { max-width: 90%; padding: 12px 16px; border-radius: 16px; font-size: 14px; line-height: 1.5; animation: slideIn .3s ease; word-wrap: break-word; overflow-wrap: break-word; }
.bot-msg.bot { background: var(--white); align-self: flex-start; border-bottom-left-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
.bot-msg.user { background: linear-gradient(135deg, var(--cherry), var(--cherry-light)); color: white; align-self: flex-end; border-bottom-right-radius: 4px; }
.bot-input-area { padding: 16px; background: var(--white); border-top: 1px solid var(--cream-dark); display: flex; gap: 8px; }
.bot-input { flex: 1; padding: 12px 16px; border: 2px solid var(--cream-dark); border-radius: 50px; font-family: inherit; font-size: 14px; outline: none; } .bot-input:focus { border-color: var(--cherry); }
.bot-send { width: 44px; height: 44px; background: linear-gradient(135deg, var(--cherry), var(--cherry-light)); border: none; border-radius: 50%; color: white; font-size: 18px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: transform .3s; } .bot-send:hover { transform: scale(1.1); }
.bot-counter { text-align: center; padding: 8px; font-size: 12px; color: var(--text-light); background: var(--cream); }
.bot-quick-replies { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.bot-quick-reply { padding: 8px 16px; background: var(--cream); border: 1px solid var(--cherry); border-radius: 50px; font-size: 13px; font-weight: 600; color: var(--cherry); cursor: pointer; transition: all .3s; font-family: inherit; } .bot-quick-reply:hover { background: var(--cherry); color: white; }
.bot-typing { display: flex; gap: 4px; padding: 12px 16px; background: var(--white); border-radius: 16px; align-self: flex-start; border-bottom-left-radius: 4px; }
.bot-typing span { width: 8px; height: 8px; background: #C8C0B8; border-radius: 50%; animation: bounce 1.4s ease-in-out infinite; }
.bot-typing span:nth-child(2) { animation-delay: .2s; } .bot-typing span:nth-child(3) { animation-delay: .4s; }
.form-textarea { width: 100%; min-height: 100px; padding: 14px 16px; border: 2px solid #E8E0D8; border-radius: var(--radius-sm); font-family: inherit; font-size: 16px; resize: vertical; background: var(--cream); }
.form-textarea:focus { outline: none; border-color: var(--cherry); }
.form-success { text-align: center; padding: 40px 16px; } .form-success-icon { font-size: 64px; margin-bottom: 16px; }
.admin-panel { padding: 32px 24px; max-width: 1200px; margin: 0 auto; } .admin-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; flex-wrap: wrap; gap: 16px; } .admin-title { font-size: 28px; font-weight: 900; color: var(--text-dark); }
.admin-tabs { display: flex; gap: 8px; margin-bottom: 24px; border-bottom: 2px solid var(--cream-dark); padding-bottom: 0; flex-wrap: wrap; }
.admin-tab { padding: 12px 24px; font-size: 15px; font-weight: 700; color: var(--text-light); cursor: pointer; border: none; background: none; border-bottom: 3px solid transparent; margin-bottom: -2px; transition: all .3s; font-family: inherit; }
.admin-tab.active { color: var(--cherry); border-bottom-color: var(--cherry); } .admin-tab:hover { color: var(--cherry-light); }
.admin-section { display: none; } .admin-section.active { display: block; }
.admin-card { background: var(--white); border-radius: var(--radius); padding: 24px; box-shadow: 0 4px 16px rgba(0,0,0,0.04); margin-bottom: 20px; } .admin-card-title { font-size: 18px; font-weight: 800; color: var(--text-dark); margin-bottom: 16px; }
.student-list { display: grid; gap: 12px; } .student-item { display: grid; grid-template-columns: 1fr auto auto auto; gap: 16px; align-items: center; padding: 16px; background: var(--cream); border-radius: var(--radius-sm); font-size: 14px; }
.student-name { font-weight: 700; color: var(--text-dark); } .student-progress { font-size: 13px; color: var(--text-light); }
.student-badge { padding: 4px 12px; border-radius: 50px; font-size: 12px; font-weight: 700; }
.student-badge.active { background: #E8F8EE; color: #2D8B4E; } .student-badge.inactive { background: #F0ECE8; color: var(--text-light); }
.btn-danger { background: var(--cherry); color: white; border: none; cursor: pointer; } .btn-danger:hover { background: var(--cherry-dark); }
.register-form { display: flex; gap: 12px; flex-wrap: wrap; } .register-form .form-input { flex: 1; min-width: 200px; }
.review-admin-item { margin-bottom: 16px; padding: 16px; background: var(--cream); border-radius: var(--radius-sm); border-left: 3px solid var(--gold); }
.toast { position: fixed; bottom: 24px; right: 24px; background: var(--white); padding: 16px 24px; border-radius: var(--radius-sm); box-shadow: 0 8px 32px rgba(0,0,0,0.15); z-index: 2000; display: none; animation: slideIn .3s ease; border-left: 4px solid var(--gold); max-width: 360px; }
.toast.show { display: block; } .toast-message { font-size: 14px; font-weight: 600; color: var(--text-dark); }
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 1000; display: none; align-items: center; justify-content: center; padding: 24px; } .modal-overlay.active { display: flex; }
.modal { background: var(--white); border-radius: var(--radius); max-width: 600px; width: 100%; max-height: 80vh; overflow-y: auto; padding: 32px; box-shadow: 0 20px 60px rgba(0,0,0,0.3); animation: fadeIn .3s ease; }
.modal-close { float: right; background: none; border: none; font-size: 24px; cursor: pointer; color: var(--text-light); padding: 4px; } .modal-close:hover { color: var(--cherry); } .modal-title { font-size: 22px; font-weight: 800; color: var(--text-dark); margin-bottom: 16px; }
.footer { background: linear-gradient(135deg, var(--cherry-dark), var(--cherry)); color: rgba(255,255,255,0.8); padding: 32px 24px; text-align: center; margin-top: 48px; }
.footer a { color: var(--gold-light); text-decoration: none; font-weight: 600; } .footer a:hover { text-decoration: underline; }
@media (max-width: 768px) {
.modules-grid { grid-template-columns: 1fr; }
.header { padding: 10px 16px; flex-wrap: wrap; gap: 8px; } .header-nav { flex-wrap: wrap; gap: 8px; } .header-nav button { padding: 6px 12px; font-size: 12px; }
.login-card { padding: 32px 24px; } .module-content, .pdf-viewer-content { padding: 24px; }
.hw-item-header { flex-direction: column; align-items: flex-start; } .student-item { grid-template-columns: 1fr; gap: 8px; } .pdf-item { padding: 12px 16px; } .pdf-name { font-size: 13px; } .landing-author { flex-direction: column; text-align: center; } .author-info { text-align: center; } .bot-container { padding: 16px 12px; } .bot-window { border-radius: 16px; } .toast { left: 16px; right: 16px; max-width: none; }
}
@media (max-width: 480px) { .landing-title { font-size: 28px; } .landing-subtitle { font-size: 16px; } .dashboard { padding: 20px 16px; } .module-page { padding: 20px 16px; } .pdf-section { padding: 20px 16px; } .bot-container { padding: 12px 8px; } .pdf-actions { flex-direction: column; } .pdf-view-btn { font-size: 10px; padding: 4px 8px; } .final-stats { grid-template-columns: 1fr; } }
::-webkit-scrollbar { width: 8px; } ::-webkit-scrollbar-track { background: var(--cream); } ::-webkit-scrollbar-thumb { background: var(--cherry-light); border-radius: 4px; }
</style>
</head>
<body>
<div id="cherryParticles"></div>
<div id="toast" class="toast"><div id="toastMessage" class="toast-message"></div></div>
<div id="modalOverlay" class="modal-overlay"><div id="modalContent" class="modal"></div></div>
<!-- LANDING -->
<div id="page-landing" class="page active">
<div class="landing">
<div class="landing-bg"></div>
<div class="landing-content">
<div class="landing-badge">🍒 Академия «Новые Горизонты Инфобизнеса»</div>
<h1 class="landing-title">Как заставить <span class="gold">Telegram</span> работать за тебя</h1>
<p class="landing-subtitle">Обучение для коучей, наставников и психологов — без кода, без конструкторов, без страха. Только практика и результат.</p>
<div class="landing-author">
<div class="author-avatar">К</div>
<div class="author-info">
<div class="author-name">Кристина</div>
<div class="author-role">Техно-маркетолог и наставник Академии</div>
</div>
</div>
<button class="landing-cta" onclick="showPage('page-login')">Начать обучение →</button>
<div class="landing-features">
<div class="landing-feature"><div class="landing-feature-icon">🤖</div><div class="landing-feature-text">Соберёшь работающего бота</div></div>
<div class="landing-feature"><div class="landing-feature-icon">💬</div><div class="landing-feature-text">Готовые скрипты диалогов</div></div>
<div class="landing-feature"><div class="landing-feature-icon">📊</div><div class="landing-feature-text">CRM-панель в Telegram</div></div>
<div class="landing-feature"><div class="landing-feature-icon">🎁</div><div class="landing-feature-text">3 дня AI-агента в подарок</div></div>
</div>
</div>
</div>
</div>
<!-- LOGIN -->
<div id="page-login" class="page">
<div class="login-container">
<div class="login-card">
<button class="btn-back" onclick="showPage('page-landing')">← Назад</button>
<div class="login-icon">🍒</div>
<h2 class="login-title">Вход в курс</h2>
<p class="login-subtitle">Введите логин и пароль, полученные от Кристины</p>
<div id="loginError" class="login-error"></div>
<div class="form-group"><label class="form-label">Логин</label><input id="loginUsername" type="text" class="form-input" placeholder="Ваше имя"></div>
<div class="form-group"><label class="form-label">Пароль</label><input id="loginPassword" type="password" class="form-input" placeholder="Пароль"></div>
<button class="btn btn-primary" onclick="handleLogin()">Войти в курс</button>
<p style="text-align:center;margin-top:20px;font-size:13px;color:var(--text-light)">Нет доступа? Обратитесь к <a href="https://t.me/art_akrill" target="_blank" style="color:var(--cherry);font-weight:600">@art_akrill</a></p>
</div>
</div>
</div>
<!-- DASHBOARD -->
<div id="page-dashboard" class="page">
<header class="header">
<div class="header-logo">🍒 Новые Горизонты</div>
<div class="header-nav">
<button onclick="showPage('page-dashboard')">📚 Модули</button>
<button onclick="showPage('page-materials')">📁 PDF</button>
<button onclick="showPage('page-homework')">📝 ДЗ</button>
<button id="adminBtn" style="display:none" onclick="showPage('page-admin')">⚙️ Админ</button>
<button id="botBtn" style="display:none" onclick="showPage('page-bot')">🤖 Бот</button>
<button class="gold" onclick="handleLogout()">Выйти</button>
</div>
</header>
<div class="dashboard">
<div class="dashboard-header">
<div class="dashboard-welcome">Добро пожаловать,</div>
<h1 class="dashboard-title"><span class="gold" id="dashboardUserName"></span></h1>
<div class="progress-bar-container"><div id="progressBar" class="progress-bar-fill" style="width:0%"></div></div>
<div class="progress-text" id="progressText">Прогресс: 0 из 4 модулей</div>
</div>
<div class="intro-banner"><h2>👋 Добро пожаловать в обучение</h2><p>Академия «Новые Горизонты Инфобизнеса» — как заставить Telegram работать за тебя. Каждый модуль — текст + задание. Выполняй по порядку. Файлы открываются по ссылкам.</p></div>
<div class="modules-grid" id="modulesGrid"></div>
<div class="dashboard-actions"><button class="btn btn-outline" onclick="showPage('page-materials')">📁 PDF Материалы</button><button class="btn btn-outline" onclick="showPage('page-homework')">📝 Домашнее задание</button></div>
</div>
<div class="footer"><p>© Кристина — основательница Академии «Новые Горизонты Инфобизнеса». Техно-маркетолог и наставник.</p><p style="margin-top:8px">Telegram: <a href="https://t.me/art_akrill" target="_blank">@art_akrill</a> | <a href="https://t.me/fullstack_razrabotkaf" target="_blank">@fullstack_razrabotkaf</a> | <a href="https://yandex.by/profile/127652280359" target="_blank">⭐ Отзывы на Яндекс</a></p></div>
</div>
<!-- MODULE 0 -->
<div id="page-module-0" class="page">
<header class="header"><div class="header-logo">🍒 Новые Горизонты</div><div class="header-nav"><button onclick="showPage('page-dashboard')">← К модулям</button></div></header>
<div class="module-page"><button class="btn-back" onclick="goBack()">← Назад</button>
<div class="module-page-header"><h1 class="module-page-title">Введение — От автора</h1></div>
<div class="module-content"><h3>Привет. Я Кристина.</h3><p>Техно-маркетолог (Fullstack-разработчик), архитектор автономных систем и наставник. А также основательница Академии «Новые Горизонты Инфобизнеса».</p>
<p>Я учу собирать системы, которые работают без твоего участия: боты, скрипты диалогов и CRM прямо в Telegram.</p>
<div class="highlight-box"><strong>⚠️ Важно:</strong> Это не про «теплоту и лампу». Это про практику, скрипты и реальную автоматизацию.</div>
<h3>После курса ты:</h3><ul><li>Соберёшь работающего бота (даже если никогда не программировал)</li><li>Получишь готовый скрипт «Раздевающий вопрос» для глубоких диалогов с клиентами</li><li>Настроишь CRM-панель в Telegram, чтобы не терять контакты</li><li>Протестируешь моего AI-агента AIRA (бонус на 3 дня)</li></ul>
<h3>Как проходить курс:</h3><p>Каждый модуль — это текст + задание. Выполняй по порядку. Файлы открывай по ссылкам. В конце каждого модуля — чек-лист для самопроверки.</p>
<div class="gold-box"><strong>Оглавление курса:</strong><ul class="toc-list"><li><span class="toc-num gold">→</span> Введение – От автора (ты здесь)</li><li><span class="toc-num">1</span> Твоя база знаний</li><li><span class="toc-num">2</span> Три смертельные ошибки в лид-магните</li><li><span class="toc-num">3</span> Шаблон скрипта «Раздевающий вопрос»</li><li><span class="toc-num">4</span> CRM в кармане</li><li><span class="toc-num gold">★</span> Бонус – Демо AI-агента AIRA на 3 дня</li><li><span class="toc-num gold">🎓</span> Завершение курса — отзыв и результаты</li></ul></div>
<p style="margin-top:24px;font-weight:700;font-size:18px">Поехали! 🚀</p></div>
<div class="module-nav-buttons"><button class="btn btn-gold" onclick="completeModule(0);navigateTo('page-module-1')">Перейти к Модулю 1 →</button></div></div></div>
<!-- MODULE 1 -->
<div id="page-module-1" class="page">
<header class="header"><div class="header-logo">🍒 Новые Горизонты</div><div class="header-nav"><button onclick="showPage('page-dashboard')">← К модулям</button></div></header>
<div class="module-page"><button class="btn-back" onclick="goBack()">← Назад</button>
<div class="module-page-header"><h1 class="module-page-title">Модуль 1. Твоя база знаний</h1><p style="color:var(--text-light)">Откуда бот возьмёт уверенность общаться с клиентами</p></div>
<div class="module-content"><h3>Теория</h3><p>Большинство ботов — тупое меню с кнопками: «1 — Услуги, 2 — Цены, 3 — Связаться». Никто не нажимает. Потому что это скучно.</p>
<p>Твой бот должен <strong>говорить как ты</strong>. Отвечать на возражения так же убедительно, шутить там, где шутишь ты, задавать те же вопросы, что задаёшь вживую.</p>
<div class="highlight-box"><strong>Для этого нужна база знаний</strong> — файл, в который ты соберёшь:<br>• Реальные диалоги с клиентами<br>• Возражения и твои ответы<br>• Частые вопросы про цену, формат, сроки<br>• Истории успеха</div>
<h3>Задание модуля 1</h3><h4>ШАГ 1.</h4><p>Найди 10 диалогов «вопрос клиента — твой ответ».</p><h4>ШАГ 2.</h4><p>Найди 5 возражений: «Дорого», «Подумаю», «У меня уже есть психолог», «Я сам справлюсь», «А есть гарантия?»</p>
<h4>ШАГ 3.</h4><p>Напиши под каждым возражением твой реальный ответ.</p><h4>ШАГ 4.</h4><p>Вспомни 3 истории клиентов с крутым результатом (цифры).</p><h4>ШАГ 5.</h4><p>Ответь на 5 вопросов: «Сколько стоит?», «Какой формат?», «Как долго длится?», «Чем отличаешься?», «Что я получу?»</p>
<h3>Где всё это записать?</h3>
<div class="gold-box"><button class="btn btn-gold btn-sm" onclick="navigateTo('page-homework')">👉 Перейти к ДЗ — Таблица-черновик</button><p style="margin-top:8px;font-size:14px">Записывай ответы прямо в ячейки. Данные сохраняются автоматически.</p></div>
<div class="gold-box"><button class="btn btn-gold btn-sm" onclick="navigateToPdf('Пример_базы_коуч.pdf')">👉 Пример заполнения</button></div>
<h3>Чек-лист «10 признаков, что база знаний огонь»</h3><div class="checklist" id="checklist-1"></div>
<div class="gold-box"><button class="btn btn-gold btn-sm" onclick="navigateToPdf('Чек-лист_10_признаков.pdf')">👉 Открыть чек-лист в PDF</button></div>
<div class="highlight-box">Если набрал меньше 5 баллов по чек-листу, возьми себе на заметку, что тебе нужно будет доработать дальше.</div>
<h3>Результат модуля 1</h3><p>Ты имеешь заполненную таблицу базы знаний.</p></div>
<div class="module-nav-buttons"><button class="btn btn-outline" onclick="navigateTo('page-module-0')">← Введение</button><button class="btn btn-gold" onclick="completeModule(1);navigateTo('page-module-2')">Модуль 2 →</button></div></div></div>
<!-- MODULE 2 -->
<div id="page-module-2" class="page">
<header class="header"><div class="header-logo">🍒 Новые Горизонты</div><div class="header-nav"><button onclick="showPage('page-dashboard')">← К модулям</button></div></header>
<div class="module-page"><button class="btn-back" onclick="goBack()">← Назад</button>
<div class="module-page-header"><h1 class="module-page-title">Модуль 2. Три смертельные ошибки в лид-магните</h1><p style="color:var(--text-light)">Как бот всё сливает</p></div>
<div class="module-content"><h3>Теория</h3><p>Ты даёшь бесплатный PDF. Клиент качает, доволен — и молчит. Потому что получил ценность и ушёл.</p>
<h3>Ошибка №1: «Полезный мусор»</h3><div class="highlight-box"><strong>Как правильно:</strong> дай одну конкретную технику и сразу спроси: «Что из этого ты попробуешь первым?»</div>
<h3>Ошибка №2: «Слепая анкета»</h3><div class="highlight-box"><strong>Как правильно:</strong> сначала ценность, затем вопрос без контакта. Телефон — только после согласия на диалог.</div>
<h3>Ошибка №3: «Безликий автомат»</h3><div class="highlight-box"><strong>Как правильно:</strong> после выдачи лид-магнита спроси: «Что мешает применить это прямо сегодня?»</div>
<h3>Задание модуля 2</h3><div class="gold-box"><button class="btn btn-gold btn-sm" onclick="navigateTo('page-homework')">👉 Перейти к ДЗ — Исправить бота</button></div>
<h4>Пример:</h4><div style="overflow-x:auto"><table class="pdf-table"><thead><tr><th>Оффер</th><th>Формула</th></tr></thead><tbody><tr><td>«3 техники снять тревогу за 2 минуты»</td><td>Боль + крючок + вопрос</td></tr><tr><td>«5 фраз, которые убивают доверие»</td><td>Список + просьба привести пример</td></tr></tbody></table></div>
<div class="gold-box"><button class="btn btn-gold btn-sm" onclick="navigateToPdf('3_ошибки_чеклист.pdf')">👉 Открыть «3_ошибки_чеклист.pdf»</button></div></div>
<div class="module-nav-buttons"><button class="btn btn-outline" onclick="navigateTo('page-module-1')">← Модуль 1</button><button class="btn btn-gold" onclick="completeModule(2);navigateTo('page-module-3')">Модуль 3 →</button></div></div></div>
<!-- MODULE 3 -->
<div id="page-module-3" class="page">
<header class="header"><div class="header-logo">🍒 Новые Горизонты</div><div class="header-nav"><button onclick="showPage('page-dashboard')">← К модулям</button></div></header>
<div class="module-page"><button class="btn-back" onclick="goBack()">← Назад</button>
<div class="module-page-header"><h1 class="module-page-title">Модуль 3. Шаблон скрипта «Раздевающий вопрос»</h1><p style="color:var(--text-light)">Бот сам ведёт глубокий диалог</p></div>
<div class="module-content"><h3>Теория</h3><p>Хватит тупого «Чем помочь?» Клиент ответит: «Ничем, просто смотрю» – и всё.</p>
<div class="highlight-box"><strong>«Раздевающий вопрос»</strong> — снимает защиту, помогает человеку признать боль и раскрыться в диалоге.</div>
<div class="gold-box" style="text-align:center;font-size:18px"><strong>«На шкале от 1 до 10, насколько [проблема] мешает вам [последствие]?»</strong></div>
<h4>Пример для психолога:</h4><p><strong>Бот:</strong> «На шкале от 1 до 10 – насколько тревога мешает засыпать?»</p><p><strong>Клиент:</strong> «7» → <strong>Бот:</strong> «Расскажите подробнее...» → Клиент распаковывается → доверие растёт.</p>
<h3>Задание модуля 3</h3><div class="gold-box"><button class="btn btn-gold btn-sm" onclick="navigateTo('page-homework')">👉 Перейти к ДЗ — Адаптировать скрипт</button></div>
<div class="gold-box"><button class="btn btn-gold btn-sm" onclick="navigateToPdf('Раздевающий_вопрос.pdf')">👉 Открыть «Раздевающий_вопрос.pdf»</button></div>
<div class="gold-box"><button class="btn btn-gold btn-sm" onclick="navigateToPdf('Готовая_таблица_для_бота.xlsx')">👉 Открыть «Готовая_таблица_для_бота.xlsx»</button></div>
<p><strong>Задание выполнено</strong>, когда у тебя есть готовый текст «Раздевающего вопроса».</p></div>
<div class="module-nav-buttons"><button class="btn btn-outline" onclick="navigateTo('page-module-2')">← Модуль 2</button><button class="btn btn-gold" onclick="completeModule(3);navigateTo('page-module-4')">Модуль 4 →</button></div></div></div>
<!-- MODULE 4 -->
<div id="page-module-4" class="page">
<header class="header"><div class="header-logo">🍒 Новые Горизонты</div><div class="header-nav"><button onclick="showPage('page-dashboard')">← К модулям</button></div></header>
<div class="module-page"><button class="btn-back" onclick="goBack()">← Назад</button>
<div class="module-page-header"><h1 class="module-page-title">Модуль 4. CRM в кармане</h1><p style="color:var(--text-light)">Как не потерять ни одного контакта</p></div>
<div class="module-content"><h3>Теория</h3><p>Ты настроил бота, но забываешь ответить, отвечаешь невпопад, не помнишь кто на каком этапе.</p>
<div class="highlight-box"><strong>Выход</strong> – CRM-панель прямо в Telegram.<br>• Все диалоги пересылаются в один чат<br>• Ты видишь имя, телефон, ответы<br>• Можешь написать клиенту из того же чата</div>
<h3>Задание модуля 4</h3><div class="gold-box"><button class="btn btn-gold btn-sm" onclick="navigateTo('page-homework')">👉 Перейти к ДЗ — Настроить CRM</button></div>
<div class="gold-box"><button class="btn btn-gold btn-sm" onclick="navigateToPdf('CRM_инструкция.pdf')">👉 Открыть «CRM_инструкция.pdf»</button></div>
<div class="gold-box"><button class="btn btn-gold btn-sm" onclick="navigateToPdf('Контакты_шаблон.xlsx')">👉 Открыть «Контакты_шаблон.xlsx»</button></div>
<h3>Чек-лист «Как не потерять ни одного лида»</h3><div class="checklist" id="checklist-4"></div></div>
<div class="module-nav-buttons"><button class="btn btn-outline" onclick="navigateTo('page-module-3')">← Модуль 3</button><button class="btn btn-gold" onclick="completeModule(4);checkBonusUnlock();navigateTo('page-bonus')">Бонус →</button></div></div></div>
<!-- BONUS -->
<div id="page-bonus" class="page">
<header class="header"><div class="header-logo">🍒 Новые Горизонты</div><div class="header-nav"><button onclick="showPage('page-dashboard')">← К модулям</button></div></header>
<div class="module-page"><button class="btn-back" onclick="goBack()">← Назад</button>
<div class="module-page-header"><h1 class="module-page-title">🎁 Бонус. Демо AI-агента AIRA на 3 дня</h1><p style="color:var(--text-light)">Активируется после прохождения модулей 1–3</p></div>
<div class="module-content"><p>Ты сделал всё по курсу? Молодец. Попробуй моего AI-агента AIRA.</p>
<h3>Что умеет AIRA:</h3><ul><li>Понимает сложные вопросы</li><li>Использует твою базу знаний</li><li>Может отправить голосовое</li><li>Переключает на живого эксперта</li><li>Не тупит на возражениях</li></ul>
<div class="gold-box" style="text-align:center"><button class="btn btn-gold" onclick="navigateTo('page-bot')">👉 Открыть демо-бота AIRA</button><p style="margin-top:12px;font-size:14px">Лимит: 10 диалогов в день, 3 дня.</p></div>
<div class="gold-box"><button class="btn btn-gold btn-sm" onclick="navigateToPdf('5_фишек_AI_агента.pdf')">👉 Открыть «5 фишек AI-агента»</button></div></div>
<div class="module-nav-buttons"><button class="btn btn-outline" onclick="navigateTo('page-module-4')">← Модуль 4</button><button class="btn btn-gold" onclick="navigateTo('page-final')">Завершение курса →</button></div></div></div>
<!-- FINAL: РЕЗУЛЬТАТЫ + ОТЗЫВ + ЯНДЕКС -->
<div id="page-final" class="page">
<header class="header"><div class="header-logo">🍒 Новые Горизонты</div><div class="header-nav"><button onclick="showPage('page-dashboard')">← К модулям</button></div></header>
<div class="module-page"><button class="btn-back" onclick="goBack()">← Назад</button>
<div class="module-page-header"><h1 class="module-page-title">🎉 Поздравляем! Курс пройден</h1><p style="color:var(--text-light)">Последний блок — твои результаты и отзыв о курсе</p></div>
<div class="module-content">
<div id="finalNotifyStatus" class="final-status">⏳ Отправляем отчёт о прогрессе Кристине...</div>
<h3>📊 Твои результаты</h3>
<div class="final-stats">
<div class="final-stat"><div class="final-stat-value" id="fsModules">0/4</div><div class="final-stat-label">модуля пройдено</div></div>
<div class="final-stat"><div class="final-stat-value" id="fsChecklists">0/15</div><div class="final-stat-label">пунктов чек-листов</div></div>
<div class="final-stat"><div class="final-stat-value" id="fsHomework">0/9</div><div class="final-stat-label">заданий выполнено</div></div>
</div>
<h3>🌟 Оставь отзыв о курсе</h3>
<p>Расскажи, чем курс тебе помог и хочешь ли ты идти дальше — это очень помогает Академии расти.</p>
<div id="reviewFormContent">
<div class="form-group"><label class="form-label">Ваше имя</label><input id="reviewName" type="text" class="form-input" placeholder="Как вас зовут?"></div>
<div class="form-group"><label class="form-label">Чем курс вам помог?</label><textarea id="reviewText" class="form-textarea" placeholder="Поделитесь впечатлениями: что получилось, какие результаты, что понравилось..."></textarea></div>
<div class="form-group"><label class="form-label">Хотите ли продолжить обучение на следующем потоке?</label>
<div class="continue-options">
<div class="continue-option" onclick="selectContinue(this,'Да, обязательно! 🚀')">✅ Да, обязательно!</div>
<div class="continue-option" onclick="selectContinue(this,'Думаю 🤔')">🤔 Думаю</div>
<div class="continue-option" onclick="selectContinue(this,'Пока останусь с результатом курса')">⏸ Пока внедряю</div>
</div>
</div>
<button class="btn btn-primary" onclick="submitReview()">Отправить отзыв 🍒</button>
</div>
<div id="reviewSuccess" class="form-success" style="display:none">
<div class="form-success-icon">💖</div>
<h2 style="color:var(--text-dark);margin-bottom:12px">Спасибо за отзыв!</h2>
<p style="color:var(--text-light)">Твои слова вдохновляют Академию. Будем рады, если ты также оценишь курс на Яндекс Отзовиках ⭐</p>
</div>
<div class="gold-box yandex-box">
<h3 style="margin-top:0">⭐ Оцените курс на Яндекс</h3>
<p style="font-size:14px;color:var(--text-light)">Нам будет очень приятно, если вы поделитесь впечатлениями на Яндекс Отзовиках.</p>
<a class="btn btn-gold" href="https://yandex.by/profile/127652280359" target="_blank" rel="noopener">Оставить отзыв на Яндекс Отзовиках →</a>
</div>
</div>
<div class="module-nav-buttons"><button class="btn btn-outline" onclick="navigateTo('page-bonus')">← Бонус</button><button class="btn btn-gold" onclick="showPage('page-dashboard')">📚 К модулям</button></div></div></div>
<!-- PDF MATERIALS -->
<div id="page-materials" class="page">
<header class="header"><div class="header-logo">🍒 Новые Горизонты</div><div class="header-nav"><button onclick="showPage('page-dashboard')">← К модулям</button><button onclick="showPage('page-homework')">📝 ДЗ</button><button class="gold" onclick="handleLogout()">Выйти</button></div></header>
<div class="pdf-section"><button class="btn-back" onclick="goBack()">← Назад</button><h2 style="font-size:28px;font-weight:900;margin-bottom:8px">📁 PDF Материалы</h2><p style="color:var(--text-light);margin-bottom:24px">Файлы открываются по мере прохождения модулей</p><div class="pdf-list" id="pdfList"></div></div></div>
<!-- PDF VIEWER -->
<div id="page-pdf-viewer" class="page">
<header class="header"><div class="header-logo">🍒 Новые Горизонты</div><div class="header-nav"><button onclick="showPage('page-materials')">← К файлам</button><button onclick="showPage('page-dashboard')">← К модулям</button></div></header>
<div class="pdf-viewer"><button class="btn-back" onclick="goBack()">← Назад к файлам</button><div class="pdf-viewer-content" id="pdfViewerContent"></div></div></div>
<!-- HOMEWORK -->
<div id="page-homework" class="page">
<header class="header"><div class="header-logo">🍒 Новые Горизонты</div><div class="header-nav"><button onclick="showPage('page-dashboard')">← К модулям</button><button onclick="showPage('page-materials')">📁 PDF</button><button class="gold" onclick="handleLogout()">Выйти</button></div></header>
<div class="pdf-section"><button class="btn-back" onclick="goBack()">← Назад</button><h2 style="font-size:28px;font-weight:900;margin-bottom:8px">📝 Домашнее задание</h2><p style="color:var(--text-light);margin-bottom:24px">Заполняй задания по каждому модулю. Результаты сохраняются автоматически.</p><div id="homeworkContainer"></div></div></div>
<!-- BOT -->
<div id="page-bot" class="page">
<header class="header"><div class="header-logo">🍒 Новые Горизонты</div><div class="header-nav"><button onclick="showPage('page-dashboard')">← К модулям</button></div></header>
<div class="bot-container"><button class="btn-back" onclick="navigateTo('page-bonus')">← Назад к бонусу</button>
<div class="bot-window"><div class="bot-header"><div class="bot-avatar">🤖</div><div><div class="bot-name">AIRA — AI-агент Кристины</div><div class="bot-status">Онлайн • Демо 3 дня</div></div></div>
<div id="botMessages" class="bot-messages"><div class="bot-msg bot">Привет! Я AIRA — AI-агент Кристины 👋<br><br>Я обучена на материалах курса «Новые Горизонты Инфобизнеса». Помогу разобраться с заданиями, автоматизацией и подскажу, как продолжить обучение.<br><br>Что вас интересует?<div class="bot-quick-replies"><button class="bot-quick-reply" onclick="botReply('Расскажи про курс')">Про курс</button><button class="bot-quick-reply" onclick="botReply('Расскажи о Кристине')">О Кристине</button><button class="bot-quick-reply" onclick="botReply('Как продолжить обучение?')">Продолжить обучение</button><button class="bot-quick-reply" onclick="botReply('Как оставить отзыв?')">Как оставить отзыв?</button></div></div></div>
<div class="bot-counter">Осталось диалогов: <span id="botCounter">10</span> из 10 сегодня</div>
<div class="bot-input-area"><input id="botInput" type="text" class="bot-input" placeholder="Напишите сообщение..." onkeypress="if(event.key==='Enter')sendBotMessage()"><button class="bot-send" onclick="sendBotMessage()">➤</button></div></div></div></div>
<!-- ADMIN PANEL -->
<div id="page-admin" class="page">
<header class="header"><div class="header-logo">🍒 Админ-панель</div><div class="header-nav"><button onclick="showPage('page-dashboard')">← К курсу</button><button class="gold" onclick="handleLogout()">Выйти</button></div></header>
<div class="admin-panel"><div class="admin-header"><h2 class="admin-title">⚙️ Панель администратора</h2></div>
<div class="admin-tabs"><button class="admin-tab active" onclick="switchAdminTab('students', this)">👥 Студенты</button><button class="admin-tab" onclick="switchAdminTab('progress', this)">📊 Прогресс</button><button class="admin-tab" onclick="switchAdminTab('reviews', this)">🌟 Отзывы</button></div>
<div id="admin-students" class="admin-section active"><div class="admin-card"><h3 class="admin-card-title">Зарегистрировать нового студента</h3><div class="register-form"><input id="newStudentName" type="text" class="form-input" placeholder="Имя (логин)"><input id="newStudentPass" type="text" class="form-input" placeholder="Пароль"><button class="btn btn-gold" onclick="registerStudent()">+ Зарегистрировать</button></div></div>
<div class="admin-card"><h3 class="admin-card-title">Список студентов</h3><div id="studentList" class="student-list"></div></div></div>
<div id="admin-progress" class="admin-section"><div class="admin-card"><h3 class="admin-card-title">Прогресс студентов</h3><div id="progressList"></div></div></div>
<div id="admin-reviews" class="admin-section"><div class="admin-card"><h3 class="admin-card-title">Отзывы о курсе</h3><div id="reviewsList"></div></div></div></div></div>
<script>
// ==================== CONFIG ====================
const ADMIN_LOGIN='admin'; const ADMIN_PASS='zaqqaz';
const TG_BOT_TOKEN='8788227838:AAHxvmXEQ6C2rKfhl0e1cgdl1sn1eUUfAUk'; const TG_CHAT_ID='6300678737';
const AUTH_WORKER_URL = 'https://course-auth.chatbotsmarketolog.workers.dev';
const BOT_WORKER_URL = 'https://aira-bot.chatbotsmarketolog.workers.dev';
let navigationHistory = [];
let currentPage = 'page-landing';
function navigateTo(pageId) { if (currentPage !== pageId) { navigationHistory.push(currentPage); } showPage(pageId); }
function goBack() { if (navigationHistory.length > 0) { const prevPage = navigationHistory.pop(); showPage(prevPage); } else { showPage('page-dashboard'); } }
function showPage(pageId) {
currentPage = pageId;
document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
const pg = document.getElementById(pageId);
if (pg) { pg.classList.add('active'); window.scrollTo(0, 0); pg.style.animation = 'none'; pg.offsetHeight; pg.style.animation = 'fadeIn .5s ease'; }
if (pageId === 'page-dashboard') initDashboard();
if (pageId === 'page-materials') initMaterials();
if (pageId === 'page-homework') initHomework();
if (pageId === 'page-admin') initAdmin();
if (pageId === 'page-module-1') initChecklist('checklist-1', checklist1, 'm1');
if (pageId === 'page-module-4') initChecklist('checklist-4', checklist4, 'm4');
if (pageId === 'page-final') handleFinalBlock();
}
function navigateToPdf(filename) { navigationHistory.push(currentPage); openPdfViewer(filename); }
// ==================== TELEGRAM ====================
function escapeHtml(s) { return String(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); }
async function sendTelegramMessage(text) {
try {
const r = await fetch(`https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage`, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: TG_CHAT_ID, text: text, parse_mode: 'HTML' })
});
return r.ok;
} catch (e) { return false; }
}
// ==================== AUTH (CLOUD) ====================
async function handleLogin() {
const u = document.getElementById('loginUsername').value.trim();
const p = document.getElementById('loginPassword').value.trim();
const e = document.getElementById('loginError');
if (!u || !p) { e.textContent = 'Заполните все поля'; e.style.display = 'block'; return; }
e.textContent = 'Проверяем доступ в облаке...'; e.style.display = 'block';
try {
const res = await fetch(AUTH_WORKER_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'login', username: u, password: p }) });
const data = await res.json();
if (data.success) {
localStorage.setItem('courseCloudUser', u);
e.style.display = 'none';
showPage('page-dashboard');
showToast(`Добро пожаловать, ${u}! 🍒`);
} else {
e.textContent = 'Неверный логин или пароль'; e.style.display = 'block';
}
} catch (err) {
e.textContent = 'Ошибка соединения с сервером'; e.style.display = 'block';
}
}
function handleLogout() {
localStorage.removeItem('courseCloudUser');
navigationHistory = [];
showPage('page-landing');
}
// ==================== DB HELPERS (LOCAL FOR PROGRESS) ====================
function getDB() {
try { const d = localStorage.getItem('courseDB'); return d ? JSON.parse(d) : { students: {}, applications: [], reviews: [] }; } catch (e) { return { students: {}, applications: [], reviews: [] }; }
}
function saveDB(d) { try { localStorage.setItem('courseDB', JSON.stringify(d)); } catch (e) {} }
function getUserProgress(u) { const db = getDB(); return (db.students[u] && db.students[u].progress) || { completed: [], checklists: {}, homework: {}, botDialogs: 0, botLastReset: null }; }
function setUserProgress(u, p) { const db = getDB(); if (!db.students[u]) db.students[u] = {}; db.students[u].progress = p; saveDB(db); }
// ==================== ADMIN ====================
function registerStudent() {
const name = document.getElementById('newStudentName').value.trim();
const pass = document.getElementById('newStudentPass').value.trim();
if (!name || !pass) { showToast('Заполни имя и пароль'); return; }
const db = getDB();
if (db.students[name]) { showToast('Такой ученик уже существует'); return; }
db.students[name] = { password: pass, createdAt: new Date().toISOString(), progress: { completed: [], checklists: {}, homework: {}, botDialogs: 0, botLastReset: null }, syncedToCloud: false };
saveDB(db);
document.getElementById('newStudentName').value = ''; document.getElementById('newStudentPass').value = '';
showToast(`Студент "${name}" создан!`);
initAdmin();
}
function deleteStudent(name) { if (!confirm(`Удалить "${name}"?`)) return; const db = getDB(); delete db.students[name]; saveDB(db); showToast(`"${name}" удалён`); initAdmin(); }
function switchAdminTab(tab, btn) { document.querySelectorAll('.admin-tab').forEach(t => t.classList.remove('active')); document.querySelectorAll('.admin-section').forEach(s => s.classList.remove('active')); btn.classList.add('active'); document.getElementById('admin-' + tab).classList.add('active'); }
function collectStats(data) {
const pr = data.progress || { completed: [] };
const cm = pr.completed || [];
const mods = [1,2,3,4].filter(m => cm.includes(m)).length;
const m1 = (pr.checklists && pr.checklists.m1) ? pr.checklists.m1.length : 0;
const m4 = (pr.checklists && pr.checklists.m4) ? pr.checklists.m4.length : 0;
let hwDone = 0, hwTotal = 0;
homeworkData.forEach(hw => { (hw.tasks || []).forEach(t => { hwTotal++; const sv = pr.homework && pr.homework[t.id]; if (sv && sv.rating === 1) hwDone++; }); });
return { mods, m1, m4, hwDone, hwTotal, finished: cm.includes(6) };
}
function initAdmin() {
const db = getDB(); const students = Object.entries(db.students);
const sl = document.getElementById('studentList');
if (students.length === 0) { sl.innerHTML = '<p style="color:var(--text-light);text-align:center;padding:20px">Пока нет студентов</p>'; }
else {
sl.innerHTML = students.map(([name, data]) => {
const st = collectStats(data);
return `<div class="student-item"><div><div class="student-name">${escapeHtml(name)}</div><div class="student-progress">${new Date(data.createdAt).toLocaleDateString('ru-RU')}</div></div><div style="font-weight:700;color:var(--cherry)">${st.mods}/4</div><span class="student-badge ${st.mods>0?'active':'inactive'}">${st.finished?'🎓 Завершил':st.mods>0?'Активен':'Новый'}</span><button class="btn btn-danger btn-sm" onclick="deleteStudent('${name.replace(/'/g,"\\'")}')">Удалить</button></div>`;
}).join('');
}
const pl = document.getElementById('progressList');
if (students.length === 0) { pl.innerHTML = '<p style="color:var(--text-light);text-align:center;padding:20px">Пока нет студентов</p>'; }
else {
pl.innerHTML = students.map(([name, data]) => {
const st = collectStats(data);
return `<div style="padding:16px;background:var(--cream);border-radius:var(--radius-sm);margin-bottom:12px"><div style="display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px;margin-bottom:8px"><strong>${escapeHtml(name)}</strong>${st.finished?'<span style="font-size:12px;font-weight:700;color:#2D8B4E">🎓 Курс завершён</span>':''}</div><div style="font-size:13px;color:var(--text-light);line-height:1.8">📚 Модули: <b>${st.mods}/4</b> · ✅ Чек-лист базы знаний: <b>${st.m1}/10</b> · ✅ Чек-лист CRM: <b>${st.m4}/5</b> · 📝 ДЗ: <b>${st.hwDone}/${st.hwTotal}</b></div><div class="progress-bar-container" style="margin:8px 0 0"><div class="progress-bar-fill" style="width:${Math.round(st.mods/4*100)}%"></div></div></div>`;
}).join('');
}
const reviews = db.reviews || [];
const rl = document.getElementById('reviewsList');
if (reviews.length === 0) { rl.innerHTML = '<p style="color:var(--text-light);text-align:center;padding:20px">Пока нет отзывов</p>'; }
else {
rl.innerHTML = reviews.map(r => `<div class="review-admin-item"><div style="display:flex;justify-content:space-between;margin-bottom:8px;flex-wrap:wrap;gap:6px"><strong>${escapeHtml(r.name)}</strong><span style="font-size:12px;color:var(--text-light)">${new Date(r.date).toLocaleDateString('ru-RU')}</span></div><div style="font-size:14px;color:var(--text-dark);margin-bottom:8px">${escapeHtml(r.text)}</div><div style="font-size:13px;color:var(--gold-dark);font-weight:600">🎓 Следующее обучение: ${escapeHtml(r.wantsNext || '—')}</div></div>`).join('');
}
}
// ==================== DASHBOARD ====================
function initDashboard() {
const db = getDB(); const u = localStorage.getItem('courseCloudUser'); if (!u) return;
document.getElementById('dashboardUserName').textContent = u;
const pr = getUserProgress(u); const cm = pr.completed || []; const cc = Math.min(cm.filter(m => m > 0 && m < 5).length, 4); const pct = Math.round((cc / 4) * 100);
document.getElementById('progressBar').style.width = pct + '%';
document.getElementById('progressText').textContent = `Прогресс: ${cc} из 4 модулей (${pct}%)`;
if (cc >= 3) document.getElementById('botBtn').style.display = 'inline-flex';
if (u === ADMIN_LOGIN) document.getElementById('adminBtn').style.display = 'inline-flex';
const modules = [
{ id: 0, title: 'Введение', desc: 'От автора: о чём курс и что получишь', page: 'page-module-0' },
{ id: 1, title: 'Модуль 1', desc: 'Твоя база знаний', page: 'page-module-1' },
{ id: 2, title: 'Модуль 2', desc: 'Три смертельные ошибки в лид-магните', page: 'page-module-2' },
{ id: 3, title: 'Модуль 3', desc: 'Шаблон скрипта «Раздевающий вопрос»', page: 'page-module-3' },
{ id: 4, title: 'Модуль 4', desc: 'CRM в кармане', page: 'page-module-4' },
{ id: 5, title: 'Бонус', desc: 'Демо AI-агента AIRA на 3 дня', page: 'page-bonus' },
{ id: 6, title: 'Завершение курса', desc: 'Результаты, отзыв и следующие шаги', page: 'page-final' }
];
document.getElementById('modulesGrid').innerHTML = modules.map(m => {
const ic = cm.includes(m.id);
const num = m.id === 0 ? '→' : m.id === 5 ? '★' : m.id === 6 ? '🎓' : m.id;
const status = ic ? '✓ Пройден' : (m.id === 0 ? 'Начни здесь' : m.id === 6 ? 'Финал' : `Модуль ${m.id}`);
return `<div class="module-card ${ic?'completed':''}" onclick="navigateTo('${m.page}')"><div class="module-number">${num}</div><div class="module-card-title">${m.title}</div><div class="module-card-desc">${m.desc}</div><span class="module-status ${ic?'completed':'available'}">${status}</span></div>`;
}).join('');
}
function completeModule(id) {
const u = localStorage.getItem('courseCloudUser'); if (!u) return;
const pr = getUserProgress(u); if (!pr.completed) pr.completed = []; if (!pr.completed.includes(id)) pr.completed.push(id);
setUserProgress(u, pr); showToast('Модуль отмечен как пройденный! ✅');
}
function checkBonusUnlock() { const u = localStorage.getItem('courseCloudUser'); if (!u) return; const pr = getUserProgress(u); if (pr.completed && pr.completed.includes(1) && pr.completed.includes(2) && pr.completed.includes(3)) showToast('🎁 Бонус разблокирован! Демо AIRA доступно!'); }
// ==================== FINAL BLOCK: ОТЧЁТ + ОТЗЫВ ====================
function buildProgressReport(u) {
const pr = getUserProgress(u);
const cm = pr.completed || [];
const modulesDone = [1,2,3,4].filter(m => cm.includes(m)).length;
const extraBlocks = [cm.includes(0) ? 'Введение' : '', cm.includes(5) ? 'Бонус AIRA' : '', cm.includes(6) ? 'Финальный блок' : ''].filter(Boolean).join(', ') || '—';
const m1 = (pr.checklists && pr.checklists.m1) ? pr.checklists.m1.length : 0;
const m4 = (pr.checklists && pr.checklists.m4) ? pr.checklists.m4.length : 0;
let hwDone = 0, hwTotal = 0;
homeworkData.forEach(hw => { (hw.tasks || []).forEach(t => { hwTotal++; const sv = pr.homework && pr.homework[t.id]; if (sv && sv.rating === 1) hwDone++; }); });
let draftCells = 0;
if (pr.homework) { Object.keys(pr.homework).forEach(k => { if (k.indexOf('hw1_r') === 0 && String(pr.homework[k]).trim()) draftCells++; }); }
const now = new Date();
return [
'🎓 <b>СТУДЕНТ ПРОШЁЛ ПОСЛЕДНИЙ БЛОК КУРСА!</b>',
'',
'👤 Студент: <b>' + escapeHtml(u) + '</b>',
'📅 Завершено: ' + now.toLocaleDateString('ru-RU') + ' ' + now.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }),
'',
'📊 <b>ПРОГРЕСС И РЕЗУЛЬТАТЫ:</b>',
`• Основные модули: ${modulesDone} из 4`,
`• Пройденные блоки: ${escapeHtml(extraBlocks)}`,
`• Чек-лист «База знаний»: ${m1}/10`,
`• Чек-лист «CRM»: ${m4}/5`,
`• Домашние задания: ${hwDone}/${hwTotal} выполнено`,
`• Таблица-черновик: ${draftCells} заполненных ячеек`,
`• Диалогов с AIRA: ${pr.botDialogs || 0}`
].join('\n');
}
function renderFinalStats() {
const u = localStorage.getItem('courseCloudUser'); if (!u) return;
const pr = getUserProgress(u);
const cm = pr.completed || [];
const mods = [1,2,3,4].filter(m => cm.includes(m)).length;
const m1 = (pr.checklists && pr.checklists.m1) ? pr.checklists.m1.length : 0;
const m4 = (pr.checklists && pr.checklists.m4) ? pr.checklists.m4.length : 0;
let hwDone = 0, hwTotal = 0;
homeworkData.forEach(hw => { (hw.tasks || []).forEach(t => { hwTotal++; const sv = pr.homework && pr.homework[t.id]; if (sv && sv.rating === 1) hwDone++; }); });
const fsM = document.getElementById('fsModules'); if (fsM) fsM.textContent = `${mods}/4`;
const fsC = document.getElementById('fsChecklists'); if (fsC) fsC.textContent = `${m1 + m4}/15`;
const fsH = document.getElementById('fsHomework'); if (fsH) fsH.textContent = `${hwDone}/${hwTotal}`;
}
function handleFinalBlock() {
renderFinalStats();
const u = localStorage.getItem('courseCloudUser'); if (!u) return;
const nameInput = document.getElementById('reviewName');
if (nameInput && !nameInput.value) nameInput.value = u;
// отмечаем последний блок как пройденный
const pr = getUserProgress(u);
if (!pr.completed) pr.completed = [];
if (!pr.completed.includes(6)) pr.completed.push(6);
setUserProgress(u, pr);
sendFinalReport(false);
}
async function sendFinalReport(force) {
const u = localStorage.getItem('courseCloudUser'); if (!u) return;
const pr = getUserProgress(u);
const statusEl = document.getElementById('finalNotifyStatus');
if (pr.courseNotified && !force) {
if (statusEl) statusEl.innerHTML = '✅ <b>Отчёт о прогрессе отправлен Кристине</b>';
return;
}
if (statusEl) statusEl.innerHTML = '⏳ Отправляем отчёт о прогрессе Кристине...';
const ok = await sendTelegramMessage(buildProgressReport(u));
if (ok) {
const pr2 = getUserProgress(u); pr2.courseNotified = true; setUserProgress(u, pr2);
if (statusEl) statusEl.innerHTML = '✅ <b>Отчёт о прогрессе отправлен Кристине</b>';
showToast('Курс завершён! Отчёт отправлен 🎓');
} else {
if (statusEl) statusEl.innerHTML = '⚠️ Не удалось отправить отчёт. <button class="btn btn-outline btn-sm" style="margin-top:8px" onclick="sendFinalReport(true)">🔁 Попробовать снова</button>';
}
}
let selectedContinue = '';
function selectContinue(el, val) {
selectedContinue = val;
document.querySelectorAll('.continue-option').forEach(o => o.classList.remove('active'));
el.classList.add('active');
}
async function submitReview() {
const u = localStorage.getItem('courseCloudUser') || '';
const name = document.getElementById('reviewName').value.trim() || u || 'Студент';
const text = document.getElementById('reviewText').value.trim();
if (!text) { showToast('Напишите пару слов о ваших впечатлениях'); return; }
const cont = selectedContinue || 'Не выбрано';
const db = getDB(); if (!db.reviews) db.reviews = [];
db.reviews.push({ name, text, wantsNext: cont, date: new Date().toISOString(), user: u });
saveDB(db);
const msg = '🌟 <b>Новый отзыв о курсе</b>\n\n👤 Имя: ' + escapeHtml(name) + '\n💬 Отзыв: ' + escapeHtml(text) + '\n🎓 Следующее обучение: ' + escapeHtml(cont);
await sendTelegramMessage(msg);
document.getElementById('reviewFormContent').style.display = 'none';
document.getElementById('reviewSuccess').style.display = 'block';
showToast('Отзыв отправлен! Спасибо 💖');
}
// ==================== CHECKLISTS ====================
const checklist1 = ['У меня есть минимум 20 реальных диалогов','Среди них есть 5 возражений с закрывающими ответами','На каждое возражение я записал рабочий ответ','У меня есть 3 истории успеха с цифрами','Я записал ответы на 5 частых вопросов','Мои ответы написаны моим же тоном','Нет фраз «напишите в WhatsApp»','Каждый диалог заканчивается призывом к действию','Есть 3 разных сценария','Всё собрано в одном текстовом файле'];
const checklist4 = ['Пересылка из бота в мой Telegram-чат настроена','Я поставил каждому новому лиду тег','В течение 1 часа после контакта я написал личное сообщение','Все, кто не купил сегодня, добавлены в рассылку на 7 дней','У меня есть напоминалка написать «тёплому» раз в 3 дня'];
function initChecklist(cid, items, key) {
const c = document.getElementById(cid); if (!c) return;
const u = localStorage.getItem('courseCloudUser'); const pr = u ? getUserProgress(u) : {};
const ch = (pr.checklists && pr.checklists[key]) || [];
c.innerHTML = items.map((it, i) => `<div class="checklist-item" onclick="toggleChecklist('${key}',${i},'${cid}')"><div class="checklist-checkbox ${ch.includes(i)?'checked':''}"></div><div class="checklist-text"><strong>${i+1}.</strong> ${it}</div></div>`).join('') + `<div class="checklist-result" id="checklist-result-${key}"></div>`;
updateChecklistResult(key, items.length, ch.length);
}
function toggleChecklist(key, idx, cid) {
const u = localStorage.getItem('courseCloudUser'); if (!u) return;
const pr = getUserProgress(u); if (!pr.checklists) pr.checklists = {}; if (!pr.checklists[key]) pr.checklists[key] = [];
const i = pr.checklists[key].indexOf(idx); if (i > -1) pr.checklists[key].splice(i, 1); else pr.checklists[key].push(idx);
setUserProgress(u, pr); const items = key === 'm1' ? checklist1 : checklist4; initChecklist(cid, items, key);
}
function updateChecklistResult(key, total, checked) {
const el = document.getElementById(`checklist-result-${key}`); if (!el) return;
let sc, lb, rc;
if (checked >= 8) { sc = 'excellent'; lb = '🎉 Отлично! Ты готов!'; rc = 'Можешь переходить к следующему модулю.'; }
else if (checked >= 5) { sc = 'good'; lb = '👍 Хорошо, но можно лучше'; rc = 'Дособери диалоги, чтобы усилить базу знаний.'; }
else { sc = 'work'; lb = '💪 Есть над чем поработать'; rc = 'Продолжай собирать диалоги и возражения!'; }
el.innerHTML = `<div class="checklist-score ${sc}">${checked} / ${total}</div><div class="checklist-label">${lb}</div><div class="checklist-recommendation">${rc}</div>`;
}
// ==================== PDF MATERIALS ====================
const pdfFiles = [{name:'Пример_базы_коуч.pdf',desc:'Образец заполнения для коуча',module:1,type:'table'},{name:'Чек-лист_10_признаков.pdf',desc:'Проверка базы знаний',module:1,type:'checklist'},{name:'Лидмагнит_конструктор.xlsx',desc:'5 офферов для лид-магнита',module:2,type:'table'},{name:'3_ошибки_чеклист.pdf',desc:'Памятка на один лист',module:2,type:'text'},{name:'Раздевающий_вопрос.pdf',desc:'Скрипт из 7 шагов + пример диалога',module:3,type:'text'},{name:'Готовая_таблица_для_бота.xlsx',desc:'Шаблон для Typebot / Make',module:3,type:'table'},{name:'CRM_инструкция.pdf',desc:'Настройка пересылки диалогов в Telegram',module:4,type:'text'},{name:'Контакты_шаблон.xlsx',desc:'Таблица для ручной CRM',module:4,type:'table'},{name:'5_фишек_AI_агента.pdf',desc:'Сравнение обычного бота и AI-агента',module:5,type:'table'}];
function initMaterials() {
const u = localStorage.getItem('courseCloudUser'); if (!u) return; const pr = getUserProgress(u); const cm = pr.completed || [];
document.getElementById('pdfList').innerHTML = pdfFiles.map(f => {
const ul = f.module === 0 || cm.includes(f.module);
return `<div class="pdf-item" onclick="${ul?`navigateToPdf('${f.name}')`:`showToast('Файл откроется после прохождения Модуля ${f.module}')`}"><div class="pdf-icon">${f.type==='table'?'📊':f.type==='checklist'?'✅':'📄'}</div><div class="pdf-info"><div class="pdf-name">${f.name}</div><div class="pdf-desc">${f.desc}</div></div><div class="pdf-actions"><button class="pdf-view-btn" onclick="event.stopPropagation();openPdfViewer('${f.name}')">👁 Просмотр</button><div class="pdf-arrow">${ul?'→':'🔒'}</div></div></div>`;
}).join('');
}
function openPdfViewer(filename){const f=pdfFiles.find(x=>x.name===filename);if(!f)return;const content=document.getElementById('pdfViewerContent');content.innerHTML=getPdfViewerContent(f);showPage('page-pdf-viewer');}
function getPdfViewerContent(f){const c={'Пример_базы_коуч.pdf':`<h2 class="pdf-viewer-title">📄 Пример_базы_коуч.pdf</h2><div style="overflow-x:auto"><table class="pdf-table"><thead><tr><th>Вопрос клиента</th><th>Твой ответ</th><th>Возражение</th><th>Ответ на возражение</th></tr></thead><tbody><tr><td>Сколько стоит твой коучинг?</td><td>150 000 ₽ за 3 месяца. Включает 12 сессий и поддержку в Telegram.</td><td>Дорого</td><td>Понимаю. Но средний рост дохода моих клиентов – 300-500 тыс. за это же время.</td></tr><tr><td>А можно попробовать одну сессию?</td><td>Да есть диагностическая сессия за 15 000 ₽.</td><td>Думаю</td><td>Без проблем. Возьмите время до завтра.</td></tr><tr><td>Чем вы отличаетесь?</td><td>Я не даю теорию. Только пошаговый план под ваш бизнес.</td><td>Уже был у коуча</td><td>Тогда диагностика бесплатна если после неё вы не скажете "Это лучшее что я пробовал".</td></tr></tbody></table></div>`, 'Чек-лист_10_признаков.pdf':`<h2 class="pdf-viewer-title">✅ Чек-лист_10_признаков.pdf</h2><div class="checklist" id="pdfChecklist"></div><div style="margin-top:20px;padding:16px;background:var(--cream);border-radius:var(--radius-sm)"><strong>Результат:</strong><br>8-10 ✅ → отлично ты готов<br>5-7 ✅ → дособери диалоги<br>Меньше 5 → продолжай собирать</div>`, 'Лидмагнит_конструктор.xlsx':`<h2 class="pdf-viewer-title">📊 Лидмагнит_конструктор.xlsx</h2><div style="overflow-x:auto"><table class="pdf-table"><thead><tr><th>Оффер</th><th>Формула</th><th>Пример</th></tr></thead><tbody><tr><td>3 техники за 2 минуты</td><td>[Цифра]+[действие]+[время]→вопрос</td><td>«3 техники снять тревогу за 2 минуты. Какую попробуешь первой?»</td></tr><tr><td>5 ошибок которые убивают</td><td>«5 ошибок в [тема]»→вопрос</td><td>«5 фраз которые убивают доверие»</td></tr><tr><td>Чек-лист «Как [решить]»</td><td>Чек-лист→«Какой пункт неочевидный?»</td><td>«Чек-лист: как перестать тревожиться без таблеток»</td></tr><tr><td>Диагностика «[Боль]»</td><td>Бесплатный тест→«Напишите ДА»</td><td>«Диагностика: насколько тревога мешает жить»</td></tr><tr><td>PDF «[Результат] за [время]»</td><td>Ссылка→«Что возьмёте в работу?»</td><td>«PDF: как за 15 минут убрать страх выступлений»</td></tr></tbody></table></div>`, '3_ошибки_чеклист.pdf':`<h2 class="pdf-viewer-title">📄 3_ошибки_чеклист.pdf</h2><div style="overflow-x:auto"><table class="pdf-table"><thead><tr><th>Ошибка</th><th>Как исправить</th></tr></thead><tbody><tr><td>❌ Полезный мусор</td><td>Дай одну конкретную технику + сразу вопрос</td></tr><tr><td>❌ Слепая анкета</td><td>Сначала ценность потом вопрос без контакта</td></tr><tr><td>❌ Безликий автомат</td><td>«Что мешает применить это прямо сегодня?»</td></tr></tbody></table></div><p style="margin-top:16px;font-size:14px">Распечатай и повесь над монитором.</p>`, 'Раздевающий_вопрос.pdf':`<h2 class="pdf-viewer-title">📄 Раздевающий_вопрос.pdf</h2><div class="highlight-box"><strong>Шаг 1.</strong> «Привет! Я [имя]. Чтобы понять могу ли помочь задам несколько вопросов. Хорошо?»</div><div class="highlight-box"><strong>Шаг 2.</strong> «На шкале от 1 до 10 – насколько [проблема] мешает вам [последствие]?»</div><div class="highlight-box"><strong>Шаг 3.</strong> «Расскажите подробнее в каких ситуациях это проявляется?»</div><div class="highlight-box"><strong>Шаг 4.</strong> «Как долго это продолжается? Что уже пробовали?»</div><div class="highlight-box"><strong>Шаг 5.</strong> «Представьте что через месяц ничего не изменится...»</div><div class="highlight-box"><strong>Шаг 6.</strong> «У меня есть диагностика на 15-20 минут. Назначим?»</div><div class="highlight-box"><strong>Шаг 7.</strong> «После диагностики многие выбирают полную работу.»</div>`, 'Готовая_таблица_для_бота.xlsx':`<h2 class="pdf-viewer-title">📊 Готовая_таблица_для_бота.xlsx</h2><div style="overflow-x:auto"><table class="pdf-table"><thead><tr><th>Сообщение бота</th><th>Варианты ответа</th><th>Следующий шаг</th></tr></thead><tbody><tr><td>Привет! Какая у тебя боль?</td><td>(свободный ввод)</td><td>→ шаг 2</td></tr><tr><td>На шкале от 1 до 10?</td><td>1-10</td><td>→ если <5 → прощание если >5 → распаковка</td></tr><tr><td>Расскажи подробнее...</td><td>(свободный ввод)</td><td>→ предложение диагностики</td></tr></tbody></table></div>`, 'CRM_инструкция.pdf':`<h2 class="pdf-viewer-title">📄 CRM_инструкция.pdf</h2><h4 style="margin-top:20px">Для ManyChat:</h4><ol><li>Зайди в «Лид-формы» → «Уведомления»</li><li>Добавь вебхук: https://api.telegram.org/bot<ТОКЕН>/sendMessage</li><li>chat_id = твой Telegram ID (@userinfobot)</li></ol><h4 style="margin-top:20px">Для Typebot:</h4><ol><li>«Настройки бота» → «Webhooks»</li><li>URL: https://api.telegram.org/bot<ТОКЕН>/sendMessage?chat_id=<ID></li></ol><div class="highlight-box"><strong>Проверка:</strong> напиши боту — сообщение должно прийти в твой Telegram.</div>`, 'Контакты_шаблон.xlsx':`<h2 class="pdf-viewer-title">📊 Контакты_шаблон.xlsx</h2><div style="overflow-x:auto"><table class="pdf-table"><thead><tr><th>Дата</th><th>Имя</th><th>Контакт</th><th>Откуда</th><th>Боль</th><th>Статус</th><th>След. касание</th></tr></thead><tbody><tr><td>10.05</td><td>Анна</td><td>@anna_psy</td><td>Бот</td><td>Тревога</td><td>Тёплый</td><td>13.05</td></tr><tr><td>11.05</td><td>Михаил</td><td>+7XXX</td><td>Реклама</td><td>Нет клиентов</td><td>Диагностика</td><td>12.05</td></tr></tbody></table></div><p style="margin-top:12px;font-size:14px"><strong>Статусы:</strong> холодный тёплый назначена диагностика клиент отказ не дозвонился</p><p style="margin-top:8px;font-size:14px"><strong>Правило:</strong> раз в 3 дня проходи по строке «тёплый» и пиши.</p>`, '5_фишек_AI_агента.pdf':`<h2 class="pdf-viewer-title">📄 5_фишек_AI_агента.pdf</h2><div style="overflow-x:auto"><table class="pdf-table"><thead><tr><th>Обычный бот</th><th>AI-агент AIRA</th></tr></thead><tbody><tr><td>Работает только по жёсткому скрипту</td><td>Понимает свободную речь</td></tr><tr><td>Не запоминает контекст</td><td>Помнит всю историю диалога</td></tr><tr><td>Только текст и кнопки</td><td>Голосовые видео опросы файлы</td></tr><tr><td>Ты настраиваешь каждую ветку</td><td>Обучается на базе знаний</td></tr><tr><td>Бесплатные версии ограничены</td><td>Полная CRM сайт интеграции</td></tr></tbody></table></div><div class="gold-box" style="margin-top:16px"><strong>Результат:</strong> AI-агент закрывает в 3-5 раз больше лидов чем обычный бот-меню.</div>`}; return c[f.name]||`<h2 class="pdf-viewer-title">${f.name}</h2><p>Содержимое файла.</p>`;}
// ==================== HOMEWORK ====================
const homeworkData = [{ id: 'hw1', title: 'Модуль 1: База знаний — Таблица-черновик', isDraft: true, columns: ['A. Вопрос клиента', 'B. Твой ответ', 'C. Возражение', 'D. Ответ на возражение'], rows: 10 },{ id: 'hw2', title: 'Модуль 2: Лид-магнит', tasks: [{ id: 'hw2_t1', text: 'Выбрать один оффер из конструктора' },{ id: 'hw2_t2', text: 'Записать оффер в скрипт бота' },{ id: 'hw2_t3', text: 'Проверить бота по чек-листу «3 ошибки»' }] },{ id: 'hw3', title: 'Модуль 3: Раздевающий вопрос', tasks: [{ id: 'hw3_t1', text: 'Адаптировать скрипт под свою нишу' },{ id: 'hw3_t2', text: 'Вставить скрипт в бота' },{ id: 'hw3_t3', text: 'Написать готовый текст «Раздевающего вопроса»' }] },{ id: 'hw4', title: 'Модуль 4: CRM', tasks: [{ id: 'hw4_t1', text: 'Настроить пересылку из бота в Telegram' },{ id: 'hw4_t2', text: 'Заполнить таблицу контактов' },{ id: 'hw4_t3', text: 'Пройти чек-лист «Как не потерять лида»' }] }];
function initHomework() {
const u = localStorage.getItem('courseCloudUser'); if (!u) return; const pr = getUserProgress(u); if (!pr.homework) pr.homework = {};
const c = document.getElementById('homeworkContainer');
c.innerHTML = homeworkData.map(hw => {
if (hw.isDraft) { return `<div class="hw-section"><div class="hw-title">📝 ${hw.title}</div><p class="hw-subtitle">Таблица-черновик для тренировки. Записывай ответы прямо в ячейки. Данные сохраняются автоматически.</p><div class="draft-table-container"><table class="draft-table"><thead><tr><th style="width:30px">№</th>${hw.columns.map(col => `<th>${col}</th>`).join('')}</tr></thead><tbody>${Array.from({ length: hw.rows }, (_, i) => `<tr><td class="draft-row-num">${i + 1}</td>${hw.columns.map((_, j) => { const cellKey = `hw1_r${i}_c${j}`; const saved = pr.homework[cellKey] || ''; return `<td><textarea class="draft-cell" placeholder="Напиши здесь..." onblur="saveHWCell('${cellKey}', this.value)">${saved}</textarea></td>`; }).join('')}</tr>`).join('')}</tbody></table></div><div class="table-actions"><button class="btn btn-outline btn-sm" onclick="clearDraftTable()">🗑 Очистить таблицу</button><span style="font-size:13px;color:var(--text-light);align-self:center">Данные сохраняются автоматически</span></div></div>`; }
return `<div class="hw-section"><div class="hw-title">📝 ${hw.title}</div>${hw.tasks.map(t => { const sv = pr.homework[t.id] || {}; const r = sv.rating || 0; const tx = sv.text || ''; return `<div class="hw-item"><div class="hw-item-header"><div class="hw-item-title">${t.text}</div><div class="hw-rating-wrap"><div class="hw-rating"><button class="hw-btn plus ${r === 1 ? 'active' : ''}" onclick="setHWRating('${t.id}', 1)">+</button><button class="hw-btn minus ${r === -1 ? 'active' : ''}" onclick="setHWRating('${t.id}', -1)">−</button></div><span class="hw-rating-label">+ Выполнено / − Не выполнено</span></div></div><textarea class="hw-textarea" placeholder="Заметки, ответ, результат..." onblur="saveHWText('${t.id}', this.value)">${tx}</textarea><div class="hw-score ${r > 0 ? 'positive' : r < 0 ? 'negative' : 'neutral'}" id="hw-score-${t.id}">${r === 1 ? '✅ Выполнено' : r === -1 ? '❌ Не выполнено' : '⏳ Ожидает'}</div></div>`; }).join('')}</div>`;
}).join('');
}
function saveHWCell(key, val) { const u = localStorage.getItem('courseCloudUser'); if (!u) return; const pr = getUserProgress(u); if (!pr.homework) pr.homework = {}; pr.homework[key] = val; setUserProgress(u, pr); }
function clearDraftTable() { if (!confirm('Очистить все записи в таблице-черновике?')) return; const u = localStorage.getItem('courseCloudUser'); if (!u) return; const pr = getUserProgress(u); if (pr.homework) Object.keys(pr.homework).forEach(k => { if (k.startsWith('hw1_r')) delete pr.homework[k]; }); setUserProgress(u, pr); initHomework(); showToast('Таблица очищена'); }
function setHWRating(tid, rating) { const u = localStorage.getItem('courseCloudUser'); if (!u) return; const pr = getUserProgress(u); if (!pr.homework) pr.homework = {}; if (!pr.homework[tid]) pr.homework[tid] = {}; pr.homework[tid].rating = rating; setUserProgress(u, pr); const se = document.getElementById(`hw-score-${tid}`); if (se) { se.className = `hw-score ${rating > 0 ? 'positive' : rating < 0 ? 'negative' : 'neutral'}`; se.textContent = rating === 1 ? '✅ Выполнено' : rating === -1 ? '❌ Не выполнено' : '⏳ Ожидает'; } const item = se ? se.closest('.hw-item') : null; if (item) { item.querySelector('.hw-btn.plus').classList.toggle('active', rating === 1); item.querySelector('.hw-btn.minus').classList.toggle('active', rating === -1); } }
function saveHWText(tid, text) { const u = localStorage.getItem('courseCloudUser'); if (!u) return; const pr = getUserProgress(u); if (!pr.homework) pr.homework = {}; if (!pr.homework[tid]) pr.homework[tid] = {}; pr.homework[tid].text = text; setUserProgress(u, pr); showToast('Сохранено ✅'); }
// ==================== BOT (SMART AIRA) ====================
function sendBotMessage() {
const input = document.getElementById('botInput'); const text = input.value.trim(); if (!text) return;
const u = localStorage.getItem('courseCloudUser'); const progress = u ? getUserProgress(u) : {};
const today = new Date().toDateString();
if (!progress.botLastReset || progress.botLastReset !== today) { progress.botDialogs = 0; progress.botLastReset = today; }
if (progress.botDialogs >= 10) { showToast('Лимит диалогов на сегодня исчерпан (10/10)'); return; }
progress.botDialogs++; if (u) setUserProgress(u, progress);
document.getElementById('botCounter').textContent = 10 - progress.botDialogs;
const messages = document.getElementById('botMessages');
const userMsg = document.createElement('div'); userMsg.className = 'bot-msg user'; userMsg.textContent = text; messages.appendChild(userMsg);
input.value = '';
const typing = document.createElement('div'); typing.className = 'bot-typing'; typing.innerHTML = '<span></span><span></span><span></span>'; messages.appendChild(typing); messages.scrollTop = messages.scrollHeight;
setTimeout(async () => {
typing.remove();
try {
const response = await fetch(BOT_WORKER_URL + '/api/chat', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId: u || 'guest', message: text, sessionId: u })
});
const data = await response.json();
const botMsg = document.createElement('div'); botMsg.className = 'bot-msg bot';
botMsg.innerHTML = escapeHtml(data.response || 'Ошибка соединения. Попробуйте позже.').replace(/\n/g, '<br>');
if (data.quickReplies && data.quickReplies.length > 0) {
botMsg.innerHTML += `<div class="bot-quick-replies">${data.quickReplies.map(q => `<button class="bot-quick-reply" onclick="botReply('${q.replace(/'/g,"\\'")}')">${escapeHtml(q)}</button>`).join('')}</div>`;
}
messages.appendChild(botMsg); messages.scrollTop = messages.scrollHeight;
} catch (e) {
const botMsg = document.createElement('div'); botMsg.className = 'bot-msg bot'; botMsg.textContent = 'Ошибка соединения с AI-агентом.'; messages.appendChild(botMsg); messages.scrollTop = messages.scrollHeight;
}
}, 800);
}
function botReply(text) { document.getElementById('botInput').value = text; sendBotMessage(); }
// ==================== MODAL & TOAST ====================
function showModal(c) { document.getElementById('modalContent').innerHTML = `<button class="modal-close" onclick="closeModal()">✕</button>${c}`; document.getElementById('modalOverlay').classList.add('active'); }
function closeModal() { document.getElementById('modalOverlay').classList.remove('active'); }
function showToast(m) { const t = document.getElementById('toast'); document.getElementById('toastMessage').textContent = m; t.classList.add('show'); setTimeout(() => t.classList.remove('show'), 3000); }
// ==================== CHERRY PARTICLES ====================
function createCherryParticles() {
const container = document.getElementById('cherryParticles');
const emojis = ['🍒', '🌸', '🍒'];
for (let i = 0; i < 10; i++) {
const p = document.createElement('div');
p.className = 'cherry-particle';
p.textContent = emojis[Math.floor(Math.random() * emojis.length)];
p.style.left = Math.random() * 100 + 'vw';
p.style.animationDuration = (14 + Math.random() * 16) + 's';
p.style.animationDelay = (Math.random() * 18) + 's';
p.style.fontSize = (14 + Math.random() * 16) + 'px';
container.appendChild(p);
}
}
// ==================== INIT ====================
document.addEventListener('DOMContentLoaded', () => {
createCherryParticles();
const u = localStorage.getItem('courseCloudUser');
if (u) { showPage('page-dashboard'); } else { showPage('page-landing'); }
document.getElementById('modalOverlay').addEventListener('click', (e) => { if (e.target === e.currentTarget) closeModal(); });
});
</script>
</body>
</html>