PageSourceSearch

https://hipoteka.ai/

html hipoteka.ai collected 2026-10-05 14:34:43 UTC 267,955 bytes, 5,838 lines download raw bytes

1    <!DOCTYPE html>
2<html lang="en">
3<head>
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6    <title>Магазин</title>
7    <meta name="theme-color" content="#000000">
8    <meta name="color-scheme" content="dark">
9    
9<script src="https://telegram.org/js/telegram-web-app.js"></script>
9
10    
10<script src="localizations.js"></script>
10
11    <style>
12        :root {
13            --tg-theme-bg-color: #000000;
14            --tg-theme-text-color: #fff0fa;
15            --tg-theme-hint-color: #a97bb7;
16            --tg-theme-link-color: #ff4fa3;
17            --tg-theme-button-color: #ff4fa3;
18            --tg-theme-button-text-color: #fff0fa;
19            --tg-theme-card-bg: #121212;
20            --tg-theme-card-border: #ff4fa3;
21        }
22
23        body {
24            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
25            margin: 0;
26            padding: 0;
27            background-color: var(--tg-theme-bg-color);
28            color: var(--tg-theme-text-color);
29            overflow-x: hidden;
30            border-bottom: none !important;
31            position: relative;
32        }
33
34        /* Большое размытое фиолетовое пятно на фоне */
35        body::before {
36            content: "";
37            position: fixed;
38            top: 0;
39            left: 0;
40            width: 100vw;
41            height: 100vh;
42            background: radial-gradient(50% 50% at 50% 42%, rgba(160, 132, 238, 0.48) 0%, rgba(160, 132, 238, 0.20) 38%, rgba(160, 132, 238, 0) 72%);
43            filter: blur(120px);
44            transform: rotate(-12deg);
45            pointer-events: none;
46            z-index: 0;
47        }
48
49        html, body {
50            background: #000 !important;
51            background-color: #000 !important;
52            border: none !important;
53        }
54
55        /* Disable mobile tap highlight and callouts globally */
56        * {
57            -webkit-tap-highlight-color: transparent;
58        }
59        html, body, a, button, input, textarea {
60            -webkit-tap-highlight-color: transparent;
61            -webkit-touch-callout: none;
62        }
63        a, button, input, textarea {
64            outline: none;
65        }
66        body, a, button {
67            -webkit-user-select: none;
68            user-select: none;
69        }
70
71        .container {
72            padding: 15px;
73            padding-bottom: 99px; /* чуть выше панели */
74            position: relative;
75            z-index: 1;
76        }
77
78        header {
79            display: flex;
80            justify-content: space-between;
81            align-items: center;
82            padding: 10px 15px;
83            border-bottom: none !important;
84            position: sticky;
85            top: 0;
86            z-index: 10;
87            background: rgba(0, 0, 0, 0.65);
88            box-shadow: none !important;
89            backdrop-filter: blur(16px);
90            -webkit-backdrop-filter: blur(16px);
91            position: relative;
92        }
93
94        #user-balance {
95            display: flex;
96            align-items: center;
97            gap: 12px;
98            margin-left: auto;
99        }
100
101        .currency-panel {
102            background: rgba(255, 255, 255, 0.1);
103            border-radius: 20px;
104            padding: 8px 16px;
105            display: flex;
106            align-items: center;
107            justify-content: center;
108            gap: 12px;
109            backdrop-filter: blur(10px);
110            -webkit-backdrop-filter: blur(10px);
111            border: 1px solid rgba(255, 255, 255, 0.2);
112            position: relative;
113            padding-right: 50px;
114            min-height: 24px;
115        }
116        
117        .currency-item {
118            display: flex;
119            align-items: center;
120            justify-content: center;
121            gap: 4px;
122            line-height: 1;
123        }
124
125        .currency-panel .currency-icon {
126            color: #a084ee;
127            font-size: 1.1em;
128            display: flex;
129            align-items: center;
130            justify-content: center;
131            line-height: 1;
132        }
133
134        .currency-panel .currency-value {
135            color: #fff;
136            font-weight: bold;
137            font-size: 1.1em;
138            display: flex;
139            align-items: center;
140            justify-content: center;
141            line-height: 1;
142        }
143
144        .add-currency-btn {
145            background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
146            color: #fff;
147            border: none;
148            border-radius: 20px;
149            width: 40px;
150            height: 40px;
151            display: flex;
152            align-items: center;
153            justify-content: center;
154            cursor: pointer;
155            font-size: 18px;
156            font-weight: bold;
157            transition: transform 0.2s, background 0.2s;
158            box-shadow: 0 2px 8px rgba(160, 132, 238, 0.3);
159            position: absolute;
160            right: 0;
161            top: 50%;
162            transform: translateY(-50%);
163            border: 1px solid rgba(255, 255, 255, 0.2);
164        }
165
166        .add-currency-btn:hover {
167            transform: translateY(-50%) scale(1.05);
168        }
169
170        .add-currency-btn:active {
171            transform: translateY(-50%) scale(0.95);
172        }
173
174        nav {
175            display: flex;
176            justify-content: space-around;
177            padding: 10px 0;
178            border-bottom: 1px solid var(--tg-theme-hint-color);
179            background: #000 !important;
180        }
181
182        nav button {
183            background: none;
184            border: none;
185            color: var(--tg-theme-link-color);
186            font-size: 1em;
187            cursor: pointer;
188            padding: 10px 15px;
189            border-radius: 8px;
190            transition: background 0.2s, color 0.2s;
191        }
192
193        nav button.active {
194            background-color: var(--tg-theme-button-color);
195            color: var(--tg-theme-button-text-color);
196            box-shadow: none;
197        }
198
199        .page {
200            display: none;
201        }
202
203        .page.active {
204            display: block;
205        }
206
207        /* Стили для свитчера стилей удалены */
208
209        .shop-grid {
210            display: flex;
211            flex-direction: column;
212            gap: 18px;
213            padding-top: 15px;
214        }
215
216        .item-card {
217            background: var(--tg-theme-card-bg);
218            border-radius: 18px;
219            box-shadow: none !important;
220            border: 2px solid #8888a0;
221            display: flex;
222            flex-direction: column;
223            align-items: stretch;
224            justify-content: flex-start;
225            height: 100%;
226            width: 100%;
227            overflow: visible;
228            padding: 0;
229            position: relative;
230        }
231
232        /* Специальные стили для карточек персонажей */
233        .item-card.girl-card {
234            display: flex;
235            flex-direction: row;
236            align-items: stretch;
237            height: auto;
238            min-height: 200px;
239            width: 100%;
240            padding: 0;
241        }
242
243        .item-card-image {
244            width: 100%;
245            height: 62%;
246            min-height: 120px;
247            object-fit: cover;
248            border-radius: 16px 16px 0 0;
249            background: #131313;
250            border-bottom: none;
251            display: block;
252        }
253
254        /* Стили для изображения в карточках персонажей */
255        .item-card.girl-card .item-card-image {
256            width: 150px;
257            height: 100%;
258            min-height: 200px;
259            border-radius: 16px 0 0 16px;
260            flex-shrink: 0;
261            object-fit: cover;
262            background: var(--tg-theme-card-bg);
263            object-position: center;
264            margin: 0;
265            padding: 0;
266        }
267        
268        /* Стили для карточек подписок */
269        .item-card.pack-card {
270            display: flex;
271            flex-direction: row;
272            align-items: center;
273            height: 70px;
274            width: 100%;
275            padding: 0;
276            cursor: pointer;
277            transition: all 0.2s ease;
278        }
279
280        .item-card.pack-card:hover {
281            transform: scale(1.02);
282            border-color: #a084ee;
283        }
284
285        .item-card.pack-card.selected {
286            border-color: #a084ee;
287            background: rgba(160, 132, 238, 0.1);
288        }
289
290        /* Стили для паков с текстом вместо изображения */
291        .pack-card-image {
292            width: 100px;
293            height: 100%;
294            min-height: 120px;
295            background: #000000;
296            border-radius: 16px 0 0 16px;
297            display: flex;
298            align-items: center;
299            justify-content: center;
300            border-bottom: none;
301            flex-shrink: 0;
302        }
303        
304        .pack-card-text {
305            font-size: 1.2em;
306            font-weight: bold;
307            color: #FFFFFF;
308            text-align: center;
309            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
310            width: 100%;
311        }
312
313        /* Стили для контентной области карточек подписок */
314        .item-card.pack-card .item-card-content {
315            flex: 1;
316            display: flex;
317            flex-direction: column;
318            justify-content: center;
319            height: 100%;
320            padding: 15px;
321            position: relative;
322        }
323
324        /* Стили для имени в карточках подписок */
325        .item-card.pack-card .item-name {
326            font-size: 1.3em;
327            font-weight: bold;
328            color: #fff;
329            margin-top: 0;
330            margin-bottom: 0px;
331            text-align: left;
332            margin-top: 51px;
333        }
334
335        /* Стили для цены в карточках подписок */
336        .pack-price {
337            color: #a084ee;
338            font-size: 0.85em;
339            font-weight: bold;
340            text-align: left;
341        }
342
343         /* Стили для галочки выбора */
344         .pack-checkbox {
345             position: absolute;
346             top: 50%;
347             right: 20px;
348             transform: translateY(-50%);
349             width: 32px;
350             height: 32px;
351             border: 2px solid #a084ee;
352             border-radius: 50%;
353             background: transparent;
354             display: flex;
355             align-items: center;
356             justify-content: center;
357             transition: all 0.2s ease;
358         }
359
360         .pack-checkbox.checked {
361             background: #a084ee;
362         }
363
364         .pack-checkbox.checked::after {
365             content: '✓';
366             color: #fff;
367             font-size: 18px;
368             font-weight: bold;
369         }
370        
371        /* Чёрный фон для изображений в карточках с одеждой */
372        .item-card:not(.girl-card) .item-card-image {
373            background: #000000;
374        }
375        
376        /* Серый фон для нижней части карточек с одеждой */
377        .item-card:not(.girl-card) {
378            background: #080808;
379        }
380        
381        /* Отступ снизу для контента карточек с одеждой, чтобы кнопка не наезжала */
382        .item-card:not(.girl-card) .item-card-content {
383            padding-bottom: 70px;
384        }
385
386        .item-card-title-overlay {
387            position: absolute;
388            left: 0; right: 0;
389            top: 60%;
390            z-index: 2;
391            display: flex;
392            justify-content: flex-start;
393            align-items: center;
394            padding: 0 14px;
395        }
396        
397        /* Поднимаем название для паков на 5px */
398        .pack-card .item-card-title-overlay {
399            top: calc(60% - 15px);
400        }
401
402        /* Скрываем overlay для карточек персонажей */
403        .item-card.girl-card .item-card-title-overlay {
404            display: none;
405        }
406
407        .item-card-title-text {
408            font-weight: bold;
409            color: #fff;
410            font-size: 0.95em;
411            background: rgba(24,24,32,0.82);
412            border-radius: 8px;
413            padding: 3px 10px 2px 10px;
414            box-shadow: none;
415            margin-bottom: 0;
416            margin-top: 0;
417            letter-spacing: 0.2px;
418            max-width: 90%;
419            overflow: hidden;
420            text-overflow: ellipsis;
421            white-space: nowrap;
422        }
423
424        .item-card-content {
425            flex: 1 1 auto;
426            display: flex;
427            flex-direction: column;
428            justify-content: flex-end;
429            align-items: stretch;
430            padding: 6px 14px 14px 14px;
431            background: transparent;
432        }
433
434        /* Стили для контентной области карточек персонажей */
435        .item-card.girl-card .item-card-content {
436            flex: 1;
437            display: flex;
438            flex-direction: column;
439            justify-content: flex-start;
440            padding: 20px 20px 70px 20px; /* extra bottom space for relationship badge */
441            position: relative;
442        }
443
444        .item-name {
445            font-weight: bold;
446            color: #fff;
447            font-size: 1.13em;
448            margin-bottom: 2px;
449            text-align: left;
450        }
451
452        /* Стили для имени в карточках персонажей */
453        .item-card.girl-card .item-name {
454            font-size: 1.4em;
455            font-weight: bold;
456            color: #fff;
457            margin-bottom: 8px;
458            text-align: left;
459        }
460
461        .item-desc {
462            color: #bfaed1;
463            font-size: 0.98em;
464            margin-bottom: 10px;
465            text-align: left;
466            overflow: hidden;
467            white-space: normal;
468            line-height: 1.18em;
469            max-height: 2.36em;
470            height: auto;
471        }
472
473        /* Стили для описания в карточках персонажей */
474        .item-card.girl-card .item-desc {
475            color: #bfaed1;
476            font-size: 1.0em;
477            line-height: 1.4em;
478            margin-bottom: 0;
479            margin-top: 8px;
480            overflow: hidden;
481            display: -webkit-box;
482            -webkit-line-clamp: 4;
483            line-clamp: 4;
484            -webkit-box-orient: vertical;
485            white-space: normal;
486        }
487
488        /* Стили для уровня взаимоотношений */
489        .girl-relationship-level {
490            position: absolute;
491            bottom: 20px;
492            right: 5px;
493            background: transparent;
494            color: #a084ee;
495            font-size: 0.9em;
496            font-weight: bold;
497            padding: 6px 12px;
498            border-radius: 12px;
499            border: none;
500            backdrop-filter: none;
501            -webkit-backdrop-filter: none;
502        }
503
504        /* Чаты (под описанием), слева от статуса */
505        .girl-chats-label {
506            position: absolute;
507            bottom: 29px;
508            left: 15px;
509            color: #bfaed1;
510            font-size: 0.9em; /* match status font size */
511            line-height: 1; /* keep baseline consistent */
512        }
513
514        .item-card-action {
515            position: absolute;
516            left: 0; right: 0;
517            bottom: 10px;
518            display: flex;
519            justify-content: flex-end;
520            align-items: center;
521            padding: 0 14px;
522            z-index: 3;
523        }
524
525        .buy-button {
526            background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
527            color: #ffffff;
528            border: none;
529            padding: 5px 16px;
530            border-radius: 10px;
531            cursor: pointer;
532            font-size: 1em;
533            font-weight: bold;
534            box-shadow: none;
535            transition: background 0.2s, color 0.2s;
536            display: flex;
537            align-items: center;
538            gap: 6px;
539            min-width: 0;
540        }
541
542        .buy-button:disabled {
543            background: #3a2a3d;
544            color: #a97bb7;
545            cursor: not-allowed;
546            box-shadow: none;
547        }
548
549
550
551        #bottom-nav {
552            position: fixed;
553            left: 0; right: 0; bottom: 24px;
554            display: flex;
555            justify-content: center;
556            z-index: 1001;
557            background: transparent !important;
558            box-shadow: none !important;
559            padding: 0;
560            border: none !important;
561        }
562
563         /* Секция Upgrade для подписок */
564         .upgrade-section {
565             position: fixed;
566             left: 50%;
567             bottom: 30px;
568             transform: translateX(-50%);
569             display: none;
570             flex-direction: column;
571             align-items: center;
572             gap: 12px;
573             z-index: 1100;
574         }
575
576         .upgrade-text {
577             color: #bfaed1;
578             font-size: 1.2em;
579             text-align: center;
580             line-height: 1.5em;
581             max-width: 320px;
582             margin-bottom: 100px;
583             margin-top: 20px;
584             padding: 0 0px;
585             margin-left: auto;
586             margin-right: auto;
587         }
588         .upgrade-text .line { display: flex; align-items: center; justify-content: center; gap: 8px; }
589         .upgrade-text .sep { width: 100%; height: 1px; background: rgba(160, 132, 238, 0.35); margin: 6px 0; border: none; }
590
591         /* Кнопка Upgrade для подписок */
592         .upgrade-button {
593             background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
594             color: #fff;
595             border: none;
596             border-radius: 25px;
597             padding: 15px 30px;
598             font-size: 1.1em;
599             font-weight: bold;
600             cursor: pointer;
601             display: flex;
602             align-items: center;
603             gap: 8px;
604             box-shadow: 0 4px 20px rgba(160, 132, 238, 0.3);
605             transition: all 0.2s ease;
606         }
607
608        .upgrade-button:hover {
609            transform: scale(1.05);
610        }
611
612        .upgrade-button:active {
613            transform: scale(0.95);
614        }
615
616        .upgrade-button:disabled {
617            background: #3a2a3d;
618            color: #a97bb7;
619            cursor: not-allowed;
620            transform: scale(1);
621        }
622
623         /* Стили для описания выбранного пака */
624         .pack-description {
625             margin-top: 20px;
626             padding: 20px;
627             background: rgba(160, 132, 238, 0.1);
628             border-radius: 12px;
629             border: 1px solid rgba(160, 132, 238, 0.2);
630             color: #bfaed1;
631             font-size: 1.05em;
632             line-height: 1.4em;
633             text-align: left;
634             display: none;
635             backdrop-filter: blur(4px);
636             -webkit-backdrop-filter: blur(4px);
637         }
638
639        .pack-description.show {
640            display: block;
641        }
642        #bottom-nav-inner {
643            background: rgba(40, 40, 50, 0.65);
644            border-radius: 40px;
645            box-shadow: none !important;
646            display: flex;
647            align-items: center;
648            justify-content: center;
649            padding: 12px 18px;
650            min-width: 0;
651            width: auto;
652            backdrop-filter: blur(16px);
653            -webkit-backdrop-filter: blur(16px);
654            border: 1.5px solid rgba(180,180,200,0.18);
655        }
656        #bottom-nav button,
657        #bottom-nav button:focus,
658        #bottom-nav button:active,
659        #bottom-nav button:focus-visible {
660            outline: none !important;
661            box-shadow: none !important;
662            background: none !important;
663        }
664        #bottom-nav button {
665            -webkit-tap-highlight-color: transparent;
666            user-select: none;
667        }
668        #bottom-nav button {
669            pointer-events: auto;
670            background: none;
671            border: none;
672            margin: 0 8px;
673            border-radius: 50%;
674            width: 64px;
675            height: 64px;
676            display: flex;
677            align-items: center;
678            justify-content: center;
679            box-shadow: none;
680            transition: background 0.2s, color 0.2s;
681            color: #a97bb7;
682            font-size: 1.2em;
683            outline: none;
684            border: none;
685        }
686        #bottom-nav button.active {
687            background: none;
688            color: #a084ee;
689        }
690        #bottom-nav svg {
691            display: block;
692            width: 44px;
693            height: 44px;
694            transition: filter 0.2s, color 0.2s;
695        }
696        /* Hide page titles */
697        #page-title { display: none; }
698        #bottom-nav button.active svg {
699            filter: drop-shadow(0 0 8px #a084eecc) drop-shadow(0 0 2px #d8b4fe);
700            color: #a084ee;
701        }
702        #bottom-nav button:focus {
703            outline: none !important;
704            box-shadow: none !important;
705        }
706        @media (max-width: 600px) {
707            #bottom-nav-inner { padding: 0 6px; }
708            #bottom-nav button { width: 48px; height: 48px; }
709            #bottom-nav svg { width: 22px; height: 22px; }
710        }
711        
712        /* Hide navigation during character creation */
713        body.character-creation-active #bottom-nav {
714            display: none;
715        }
716
717        /* Hide navigation on lollipops page */
718        body.lollipops-active #bottom-nav {
719            display: none !important;
720        }
721        .page-title {
722            font-size: 1.35em;
723            font-weight: bold;
724            color: #fff;
725            letter-spacing: 0.2px;
726            margin-bottom: 0;
727        }
728        /* Модальное окно и блюр */
729        #modal-blur-bg {
730            position: fixed;
731            left: 0; top: 0; right: 0; bottom: 0;
732            z-index: 2000;
733            background: rgba(0,0,0,0.25);
734            backdrop-filter: blur(8px);
735            -webkit-backdrop-filter: blur(8px);
736            display: none;
737        }
738        #modal-buy {
739            position: fixed;
740            left: 50%; top: 50%;
741            transform: translate(-50%, -50%);
742            z-index: 2100;
743            background: #121212;
744            border-radius: 18px;
745            box-shadow: 0 4px 32px 0 #000a;
746            min-width: 270px;
747            max-width: 90vw;
748            padding: 28px 22px 22px 22px;
749            display: none;
750            flex-direction: column;
751            align-items: center;
752        }
753        #modal-buy .modal-close {
754            position: absolute;
755            right: 16px; top: 12px;
756            background: none;
757            border: none;
758            color: #fff;
759            font-size: 1.7em;
760            cursor: pointer;
761            z-index: 1;
762        }
763        #modal-buy .modal-title {
764            font-size: 1.15em;
765            font-weight: bold;
766            color: #fff;
767            margin-bottom: 8px;
768            text-align: center;
769        }
770        #modal-buy .modal-desc {
771            color: #bfaed1;
772            font-size: 1em;
773            margin-bottom: 18px;
774            text-align: center;
775        }
776        #modal-buy .modal-buy-btn {
777            background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
778            color: #23162e;
779            border: none;
780            padding: 8px 28px;
781            border-radius: 10px;
782            cursor: pointer;
783            font-size: 1.08em;
784            font-weight: bold;
785            box-shadow: none;
786            transition: background 0.2s, color 0.2s;
787            display: flex;
788            align-items: center;
789            gap: 8px;
790            min-width: 0;
791        }
792        #modal-buy .modal-buy-btn:disabled {
793            background: #3a2a3d;
794            color: #a97bb7;
795            cursor: not-allowed;
796        }
797        .item-card.not-bought {
798            border-color: #3a3a3a !important;
799        }
800        .item-card.pack-card {
801            border-color: #8888a0 !important;
802        }
803        .pack-card .item-card-action {
804            justify-content: center;
805            align-items: center;
806            height: 56px;
807            min-height: 56px;
808            display: flex;
809        }
810        .pack-card .buy-button {
811            width: 80%;
812            min-width: 120px;
813            max-width: 95%;
814            display: flex;
815            justify-content: center;
816            align-items: center;
817            height: 44px;
818            font-size: 1.15em;
819        }
820        *:focus, *:active {
821            outline: none !important;
822            box-shadow: none !important;
823        }
824        
825        /* Убираем выделение при клике на карточки девушек */
826        .girl-card-clickable {
827            -webkit-tap-highlight-color: transparent;
828            -webkit-touch-callout: none;
829            -webkit-user-select: none;
830            -khtml-user-select: none;
831            -moz-user-select: none;
832            -ms-user-select: none;
833            user-select: none;
834        }
835        
836        .girl-card-clickable:active {
837            background-color: transparent !important;
838        }
839        .buy-button, .item-card {
840            transition: transform 0.13s cubic-bezier(.4,1.3,.6,1);
841        }
842        .buy-button.scaling, .item-card.scaling {
843            transform: scale(1.04);
844        }
845        
846        /* Стили для подсветки карточки */
847        .item-card.highlight {
848            animation: highlightPulse 3s cubic-bezier(0.4, 0, 0.2, 1);
849            box-shadow: 0 0 25px rgba(255, 193, 7, 0.6);
850            border-color: #ffc107 !important;
851        }
852        
853        @keyframes highlightPulse {
854            0% {
855                box-shadow: 0 0 15px rgba(255, 193, 7, 0.4);
856                transform: scale(1);
857                border-color: #ffc107 !important;
858            }
859            25% {
860                box-shadow: 0 0 30px rgba(255, 193, 7, 0.8);
861                transform: scale(1.03);
862                border-color: #ffd54f !important;
863            }
864            50% {
865                box-shadow: 0 0 40px rgba(255, 193, 7, 1);
866                transform: scale(1.06);
867                border-color: #ffeb3b !important;
868            }
869            75% {
870                box-shadow: 0 0 30px rgba(255, 193, 7, 0.8);
871                transform: scale(1.03);
872                border-color: #ffd54f !important;
873            }
874            100% {
875                box-shadow: 0 0 15px rgba(255, 193, 7, 0.4);
876                transform: scale(1);
877                border-color: #ffc107 !important;
878            }
879        }
880        .item-buy-card .item-card-action {
881            justify-content: center;
882            align-items: center;
883            height: 56px;
884            min-height: 56px;
885            display: flex;
886        }
887        .item-buy-card .buy-button {
888            width: 80%;
889            min-width: 120px;
890            max-width: 95%;
891            display: flex;
892            justify-content: center;
893            align-items: center;
894            height: 44px;
895            font-size: 1.15em;
896        }
897        /* Убираем старые стили для карточек девушек, так как теперь используется новая компоновка */
898        
899        /* Стили для лейбла на карточке девушки */
900        .girl-card-label {
901            position: absolute;
902            top: -14px;
903            left: 50%;
904            transform: translateX(-50%);
905            z-index: 5;
906            background: rgba(255, 79, 163, 0.9);
907            color: #fff;
908            font-size: 0.85em;
909            font-weight: bold;
910            padding: 4px 12px;
911            border-radius: 6px;
912            text-align: center;
913            text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
914            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
915            backdrop-filter: blur(4px);
916            -webkit-backdrop-filter: blur(4px);
917            min-width: 80px;
918            max-width: 200px;
919            white-space: nowrap;
920            overflow: hidden;
921            text-overflow: ellipsis;
922        }
923        /* Модальное окно девушки */
924        #girl-modal-bg {
925            position: fixed;
926            left: 0; top: 0; right: 0; bottom: 0;
927            z-index: 3000;
928            background: rgba(0,0,0,0.7);
929            display: none;
930        }
931        #girl-modal {
932            position: fixed;
933            left: 0; top: 0; right: 0; bottom: 0;
934            z-index: 3100;
935            background: none;
936            display: none;
937            min-height: 100vh;
938            padding: 0;
939            overflow: visible;
940            animation: fadeIn 0.18s;
941        }
942        #girl-modal .girl-modal-inner {
943            position: absolute;
944            left: 24px; right: 24px; top: 24px; bottom: 24px;
945            margin: auto;
946            background: #131313;
947            border-radius: 28px;
948            box-shadow: 0 8px 40px 0 #000a;
949            overflow: hidden;
950            min-width: 0;
951            max-width: 370px;
952            height: 78vh;
953            max-height: 620px;
954            display: flex;
955            flex-direction: column;
956            align-items: stretch;
957            border: 1.5px solid #212121;
958            margin-bottom: 8vh;
959        }
960        #girl-modal .girl-modal-photo {
961            position: absolute;
962            top: 0; left: 0; width: 100%; height: 60vh;
963            object-fit: cover;
964            z-index: 1;
965            border-radius: 28px 28px 0 0;
966            background: #000000;
967            display: block;
968        }
969        
970        #girl-modal .girl-modal-photo-container {
971            position: absolute;
972            top: 0; left: 0; width: 100%; height: 60vh;
973            z-index: 1;
974            border-radius: 28px 28px 0 0;
975            overflow: hidden;
976        }
977        
978        #girl-modal .girl-modal-photo-loading {
979            position: absolute;
980            top: 0; left: 0; width: 100%; height: 100%;
981            display: flex;
982            align-items: center;
983            justify-content: center;
984            background: #000000;
985            border-radius: 28px 28px 0 0;
986        }
987        #girl-modal .girl-modal-fade {
988            position: absolute;
989            left: 0; right: 0; bottom: 0;
990            height: 37%;
991            background: linear-gradient(0deg, #000000 65%, rgba(0, 0, 0, 0) 100%);
992            pointer-events: none;
993            z-index: 2;
994        }
995        #girl-modal .girl-modal-content {
996            position: absolute;
997            left: 0; right: 0; bottom: 0;
998            z-index: 3;
999            width: 100%;
1000            max-width: 370px;
1001            margin: 0 auto;
1002            padding: 45vh 18px 32px 18px;
1003            display: flex;
1004            flex-direction: column;
1005            align-items: flex-start;
1006            pointer-events: auto;
1007            box-sizing: border-box;
1008            overflow-y: auto;
1009        }
1010        #girl-modal .girl-modal-name {
1011            font-size: 1.25em;
1012            font-weight: bold;
1013            color: #fff;
1014            margin-bottom: 10px;
1015            margin-top: 24px;
1016            text-shadow: 
1017                0 1px 2px rgba(0,0,0,0.8),
1018                0 2px 4px rgba(0,0,0,0.6),
1019                0 4px 8px rgba(0,0,0,0.4);
1020        }
1021        #girl-modal .girl-modal-desc {
1022            color: #ffffff;
1023            font-size: 1.15em;
1024            margin-bottom: 18px;
1025            white-space: pre-line;
1026            text-shadow: 
1027                0 1px 2px rgba(0,0,0,0.7),
1028                0 2px 4px rgba(0,0,0,0.5);
1029        }
1030        #girl-modal .girl-modal-rel {
1031            color: #a084ee;
1032            font-size: 1.08em;
1033            margin-bottom: 18px;
1034            text-shadow: 0 2px 12px #000a;
1035        }
1036        
1037        #girl-modal .girl-modal-loyalty {
1038            width: 100%;
1039            margin-bottom: 28px;
1040        }
1041        
1042        /* New layout rows for loyalty section */
1043        #girl-modal .girl-modal-loyalty-top {
1044            display: flex;
1045            align-items: center;
1046            justify-content: space-between;
1047            margin-bottom: 6px;
1048            width: 100%;
1049        }
1050        #girl-modal .girl-modal-points {
1051            color: #bfaed1;
1052            font-size: 0.95em;
1053        }
1054        #girl-modal .girl-modal-upgrade {
1055            color: #ff4f4f;
1056            font-weight: bold;
1057            font-size: 0.95em;
1058            white-space: nowrap;
1059            cursor: pointer;
1060        }
1061        #girl-modal .girl-modal-loyalty-bottom {
1062            display: flex;
1063            align-items: center;
1064            justify-content: space-between;
1065            margin-top: 6px;
1066            width: 100%;
1067        }
1068 
1069        /* Old label row removed in favor of new rows */
1070 
1071        #girl-modal .girl-modal-loyalty-current {
1072            color: #a084ee;
1073            font-weight: bold;
1074            white-space: nowrap;
1075            overflow: hidden;
1076            text-overflow: ellipsis;
1077            min-width: 0;
1078            flex: 1;
1079            max-width: 45%;
1080        }
1081 
1082        #girl-modal .girl-modal-loyalty-next {
1083            color: #bfaed1;
1084            font-size: 0.9em;
1085            white-space: nowrap;
1086            overflow: hidden;
1087            text-overflow: ellipsis;
1088            min-width: 0;
1089            flex: 1;
1090            max-width: 45%;
1091            text-align: right;
1092        }
1093        
1094        /* Медиа-запрос для очень маленьких экранов */
1095        @media (max-width: 360px) {
1096            #girl-modal .girl-modal-content {
1097                padding-left: 12px;
1098                padding-right: 12px;
1099            }
1100            
1101            #girl-modal .girl-modal-loyalty-current,
1102            #girl-modal .girl-modal-loyalty-next {
1103                font-size: 0.85em;
1104                max-width: 40%;
1105            }
1106        }
1107        
1108
1109        
1110        #girl-modal .girl-modal-loyalty-bar {
1111            width: 100%;
1112            height: 8px;
1113            background: rgba(255, 255, 255, 0.1);
1114            border-radius: 4px;
1115            overflow: hidden;
1116            position: relative;
1117        }
1118        
1119        #girl-modal .girl-modal-loyalty-fill {
1120            height: 100%;
1121            background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
1122            border-radius: 4px;
1123            transition: width 0.3s ease;
1124        }
1125        
1126        #girl-modal .girl-modal-loyalty-text {
1127            color: #a084ee;
1128            font-size: 0.9em;
1129            margin-top: 6px;
1130            text-align: center;
1131            text-shadow: 0 2px 12px #000a;
1132        }
1133        #girl-modal .girl-modal-btn {
1134            width: 80%;
1135            min-width: 120px;
1136            max-width: 220px;
1137            margin: 0;
1138            display: flex;
1139            align-items: center;
1140            justify-content: center;
1141            height: 44px;
1142            font-size: 1.18em;
1143            font-weight: bold;
1144            background: #a084ee;
1145            color: #fff;
1146            border-radius: 14px;
1147            box-shadow: none;
1148            border: none;
1149            cursor: pointer;
1150            padding: 0;
1151            transition: background 0.2s, color 0.2s, transform 0.1s;
1152            gap: 10px;
1153        }
1154        #girl-modal .girl-modal-btn:active {
1155            transform: scale(1.04);
1156        }
1157        #girl-modal .girl-modal-btns-row {
1158            display: flex;
1159            align-items: center;
1160            justify-content: center;
1161            width: 100%;
1162            margin: 8px auto 8px auto;
1163            gap: 12px;
1164            max-width: 340px;
1165        }
1166        #girl-modal .girl-modal-close {
1167            position: static;
1168            margin: 0;
1169            background: #111;
1170            color: #fff;
1171            width: 44px;
1172            height: 44px;
1173            min-width: 44px;
1174            max-width: 44px;
1175            border-radius: 14px;
1176            display: flex;
1177            align-items: center;
1178            justify-content: center;
1179            z-index: 10;
1180            cursor: pointer;
1181            box-shadow: none;
1182            border: none;
1183            font-weight: bold;
1184            font-size: 1.18em;
1185            transition: background 0.2s, color 0.2s, transform 0.1s;
1186            flex-shrink: 0;
1187            padding: 0;
1188        }
1189        #girl-modal .girl-modal-close:active {
1190            transform: scale(1.04);
1191        }
1192        #girl-modal .girl-modal-btn:disabled {
1193            background: #3a2a3d;
1194            color: #a97bb7;
1195            cursor: not-allowed;
1196        }
1197
1198        /* Daily bonus gift button */
1199        .daily-bonus-btn {
1200            background: none;
1201            color: #fff;
1202            border: none;
1203            border-radius: 0;
1204            width: auto;
1205            height: auto;
1206            display: inline-flex;
1207            align-items: center;
1208            justify-content: center;
1209            cursor: pointer;
1210            font-size: 28px;
1211            line-height: 1;
1212            font-weight: bold;
1213            transition: transform 0.2s, box-shadow 0.2s;
1214            box-shadow: none;
1215            margin-right: 10px;
1216            position: relative;
1217            padding: 0;
1218            overflow: visible;
1219            background-color: transparent !important;
1220        }
1221        .daily-bonus-btn:hover { transform: scale(1.05); }
1222        .daily-bonus-btn:active { transform: scale(0.95); }
1223        .daily-bonus-btn, .daily-bonus-btn:focus, .daily-bonus-btn:active {
1224            outline: none !important;
1225            box-shadow: none !important;
1226            background: none !important;
1227            background-color: transparent !important;
1228        }
1229        .daily-bonus-btn .gift-emoji {
1230            display: inline-block;
1231            line-height: 1;
1232            filter: none;
1233            -webkit-filter: none;
1234            -webkit-font-smoothing: antialiased;
1235            -moz-osx-font-smoothing: grayscale;
1236        }
1237        .daily-bonus-btn.claimable {
1238            box-shadow: 0 0 18px rgba(255, 255, 255, 0.45), 0 2px 8px rgba(255, 79, 163, 0.35);
1239        }
1240        .daily-bonus-btn.claimable::after {
1241            content: '';
1242            position: absolute;
1243            inset: -8px;
1244            border-radius: 50%;
1245            background: radial-gradient(circle, rgba(255,255,255,0.55) 0%, rgba(255,255,255,0.28) 38%, rgba(255,255,255,0) 72%);
1246            filter: blur(6px);
1247            z-index: -1;
1248            pointer-events: none;
1249            animation: glowPulse 2s ease-in-out infinite;
1250        }
1251        @keyframes glowPulse {
1252            0%, 100% { opacity: 0.7; transform: scale(1); }
1253            50% { opacity: 1; transform: scale(1.06); }
1254        }
1255        @keyframes wobbleGift {
1256            0%, 100% { transform: rotate(0deg); }
1257            15% { transform: rotate(-10deg); }
1258            30% { transform: rotate(8deg); }
1259            45% { transform: rotate(-6deg); }
1260            60% { transform: rotate(4deg); }
1261            75% { transform: rotate(-2deg); }
1262        }
1263        .daily-bonus-btn.wobble {
1264            animation: wobbleGift 2s ease-in-out infinite;
1265        }
1266
1267        /* Payment method switcher */
1268        .payment-switcher {
1269            display: flex;
1270            align-items: center;
1271            gap: 8px;
1272            position: absolute;
1273            left: 50%;
1274            top: 120%;
1275            transform: translate(-50%, -50%);
1276        }
1277
1278        .payment-switcher-btn {
1279            background: rgba(255, 255, 255, 0.1);
1280            border: 1px solid rgba(255, 255, 255, 0.2);
1281            border-radius: 8px;
1282            padding: 6px 12px;
1283            color: #fff;
1284            font-size: 12px;
1285            font-weight: bold;
1286            cursor: pointer;
1287            transition: all 0.2s ease;
1288            backdrop-filter: blur(10px);
1289            -webkit-backdrop-filter: blur(10px);
1290            display: flex;
1291            align-items: center;
1292            justify-content: center;
1293            text-align: center;
1294            line-height: 1;
1295        }
1296
1297        /* Back button on lollipops page */
1298        #page-lollipops .back-button {
1299            background: rgba(0, 0, 0, 0.5);
1300            border: 1px solid rgba(255, 255, 255, 0.2);
1301            border-radius: 8px;
1302            margin-left: 10px;
1303            padding: 6px 12px;
1304            color: #fff;
1305            cursor: pointer;
1306            transition: all 0.2s ease;
1307            backdrop-filter: blur(10px);
1308            -webkit-backdrop-filter: blur(10px);
1309            display: none; /* hidden by default; shown/positioned in header on lollipops */
1310            align-items: center;
1311            justify-content: center;
1312            z-index: 100;
1313            width: 40px;
1314            height: 28px;
1315            box-sizing: border-box;
1316        }
1317
1318        /* When on lollipops, pin back button to left edge inside header, left of stars */
1319        body.lollipops-active header .back-button {
1320            position: absolute;
1321            background: rgba(255, 255, 255, 0.1);
1322            border: 1px solid rgba(255, 255, 255, 0.2);
1323            top: 10px;
1324            border-radius: 8px;
1325            padding: 2px 12px;
1326            color: #fff;
1327            font-size: 10px;
1328            font-weight: bold;
1329            cursor: pointer;
1330            transition: all 0.2s ease;
1331            backdrop-filter: blur(10px);
1332            -webkit-backdrop-filter: blur(10px);
1333            display: flex;
1334            align-items: center;
1335            justify-content: center;
1336            text-align: center;
1337            line-height: 1;
1338        }
1339
1340        #page-lollipops .back-button:hover {
1341            background: rgba(255, 255, 255, 0.15);
1342            border-color: rgba(255, 255, 255, 0.3);
1343        }
1344
1345        #page-lollipops .back-button:active {
1346            transform: scale(0.95);
1347        }
1348
1349        #page-lollipops .back-button svg {
1350            width: 20px;
1351            height: 20px;
1352        }
1353
1354        .payment-switcher-btn:hover {
1355            background: rgba(255, 255, 255, 0.15);
1356            border-color: rgba(255, 255, 255, 0.3);
1357        }
1358
1359        .payment-switcher-btn.active {
1360            background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
1361            border-color: #a084ee;
1362            color: #23162e;
1363            box-shadow: 0 2px 8px rgba(160, 132, 238, 0.3);
1364        }
1365
1366        .payment-switcher-btn:active {
1367            transform: scale(0.95);
1368        }
1369
1370        /* Daily bonus modal */
1371        #daily-bonus-blur {
1372            position: fixed;
1373            left: 0; top: 0; right: 0; bottom: 0;
1374            z-index: 4200;
1375            background: rgba(0,0,0,0.25);
1376            backdrop-filter: blur(8px);
1377            -webkit-backdrop-filter: blur(8px);
1378            display: none;
1379        }
1380        #daily-bonus-modal {
1381            position: fixed;
1382            left: 50%; top: 50%;
1383            transform: translate(-50%, -50%);
1384            z-index: 4300;
1385            background: #121212;
1386            border-radius: 18px;
1387            box-shadow: 0 4px 32px 0 #000a;
1388            min-width: 280px;
1389            max-width: 90vw;
1390            padding: 28px 22px 22px 22px;
1391            display: none;
1392            flex-direction: column;
1393            align-items: center;
1394            border: 1.5px solid #212121;
1395        }
1396        #daily-bonus-modal .title {
1397            font-size: 1.2em;
1398            font-weight: bold;
1399            color: #fff;
1400            margin-bottom: 12px;
1401            text-align: center;
1402        }
1403        #daily-bonus-modal .subtitle {
1404            color: #bfaed1;
1405            font-size: 1em;
1406            margin-bottom: 18px;
1407            text-align: center;
1408        }
1409        #daily-bonus-modal .claim-info {
1410            color: #fff;
1411            font-size: 1.05em;
1412            margin-bottom: 12px;
1413            text-align: center;
1414        }
1415        #daily-bonus-modal .claim-timer {
1416            color: #a084ee;
1417            font-size: 1.05em;
1418            margin-bottom: 16px;
1419            text-align: center;
1420        }
1421        #daily-bonus-modal .btn {
1422            width: 80%;
1423            min-width: 160px;
1424            max-width: 260px;
1425            height: 44px;
1426            border-radius: 12px;
1427            border: none;
1428            cursor: pointer;
1429            font-weight: bold;
1430            font-size: 1.05em;
1431            display: flex;
1432            align-items: center;
1433            justify-content: center;
1434            gap: 8px;
1435            margin: 6px 0;
1436            transition: transform 0.14s, background 0.2s, color 0.2s;
1437        }
1438        #daily-bonus-modal .btn:active { transform: scale(1.02); }
1439        #daily-bonus-modal .btn-primary {
1440            background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
1441            color: #23162e;
1442        }
1443        #daily-bonus-modal .btn-primary:disabled {
1444            background: #3a2a3d;
1445            color: #a97bb7;
1446            cursor: not-allowed;
1447        }
1448        #daily-bonus-modal .btn-secondary {
1449            background: #111;
1450            color: #fff;
1451        }
1452        #daily-bonus-modal .close-x {
1453            position: absolute;
1454            right: 12px; top: 10px;
1455            background: none;
1456            border: none;
1457            color: #fff;
1458            font-size: 1.6em;
1459            cursor: pointer;
1460        }
1461        .bonus-claimed-anim {
1462            position: fixed;
1463            left: 50%; top: 50%;
1464            transform: translate(-50%, -50%);
1465            z-index: 4400;
1466            color: #fff;
1467            font-size: 1.3em;
1468            padding: 10px 16px;
1469            background: rgba(0,0,0,0.5);
1470            border-radius: 12px;
1471            animation: bonusPop 0.9s ease-out forwards;
1472        }
1473        @keyframes bonusPop {
1474            0% { opacity: 0; transform: translate(-50%, -40%) scale(0.95); }
1475            20% { opacity: 1; transform: translate(-50%, -50%) scale(1.06); }
1476            60% { opacity: 1; transform: translate(-50%, -50%) scale(1.0); }
1477            100% { opacity: 0; transform: translate(-50%, -60%) scale(0.98); }
1478        }
1479        /* Create-character card */
1480        .create-card {
1481            background: var(--tg-theme-card-bg);
1482            border: 2px dashed #a084ee;
1483            border-radius: 18px;
1484            display: flex;
1485            align-items: center;
1486            justify-content: center;
1487            gap: 12px;
1488            width: 100%;
1489            height: 120px;
1490            cursor: pointer;
1491        }
1492        .create-card .plus-btn {
1493            width: 64px;
1494            height: 64px;
1495            border-radius: 16px;
1496            background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
1497            color: #fff;
1498            border: none;
1499            display: flex;
1500            align-items: center;
1501            justify-content: center;
1502            font-size: 1.8em;
1503            font-weight: bold;
1504            box-shadow: 0 4px 18px rgba(160, 132, 238, 0.35);
1505        }
1506        .create-card .plus-btn.loading {
1507            position: relative;
1508            color: transparent;
1509            pointer-events: none;
1510            opacity: 0.9;
1511        }
1512        .create-card .plus-btn.loading::after {
1513            content: '';
1514            position: absolute;
1515            top: 50%;
1516            left: 50%;
1517            width: 22px;
1518            height: 22px;
1519            border: 3px solid rgba(255,255,255,0.35);
1520            border-top-color: #ffffff;
1521            border-radius: 50%;
1522            transform: translate(-50%, -50%);
1523            animation: spin 0.8s linear infinite;
1524        }
1525        .create-card .label {
1526            color: #fff;
1527            font-weight: bold;
1528            font-size: 1.1em;
1529        }
1530        
1531        /* Character Creation Style Selection */
1532        .character-creation-container {
1533            padding: 20px;
1534            max-width: 800px;
1535            margin: 0 auto;
1536        }
1537        
1538        .style-selection-title {
1539            text-align: center;
1540            font-size: 1.4em;
1541            font-weight: bold;
1542            color: #fff;
1543            margin-bottom: 30px;
1544        }
1545        
1546        .style-cards-container {
1547            display: flex;
1548            gap: 20px;
1549            justify-content: center;
1550            width: 90%;
1551            margin: 0 auto;
1552        }
1553        
1554        .style-card {
1555            position: relative;
1556            flex: 1;
1557            aspect-ratio: 3/4;
1558            max-width: calc(50% - 10px);
1559            border-radius: 20px;
1560            overflow: hidden;
1561            cursor: pointer;
1562            transition: transform 0.3s ease, box-shadow 0.3s ease;
1563            border: 3px solid transparent;
1564        }
1565        
1566        .style-card:hover {
1567            transform: scale(1.05);
1568            box-shadow: 0 10px 30px rgba(160, 132, 238, 0.4);
1569            border-color: #a084ee;
1570        }
1571        
1572        .style-card.selected {
1573            border-color: #a084ee;
1574            box-shadow: 0 0 20px rgba(160, 132, 238, 0.6);
1575            transform: scale(1.02);
1576        }
1577        
1578        .style-video {
1579            width: 100%;
1580            height: 100%;
1581            object-fit: cover;
1582            display: block;
1583        }
1584        
1585        .style-label {
1586            position: absolute;
1587            bottom: 0;
1588            left: 0;
1589            right: 0;
1590            background: linear-gradient(transparent, rgba(0,0,0,0.8));
1591            color: #fff;
1592            font-size: 1.5em;
1593            font-weight: bold;
1594            text-align: center;
1595            padding: 30px 20px 20px;
1596        }
1597        
1598        /* Responsive design for mobile devices */
1599        @media (max-width: 768px) {
1600            .style-cards-container {
1601                width: 95%;
1602                gap: 15px;
1603            }
1604            
1605            .style-card {
1606                max-width: calc(50% - 7.5px);
1607            }
1608            
1609            .style-label {
1610                font-size: 1.2em;
1611                padding: 20px 15px 15px;
1612            }
1613        }
1614        
1615        @media (max-width: 480px) {
1616            .style-cards-container {
1617                width: 98%;
1618                gap: 10px;
1619            }
1620            
1621            .style-card {
1622                max-width: calc(50% - 5px);
1623            }
1624            
1625            .style-label {
1626                font-size: 1em;
1627                padding: 15px 10px 10px;
1628            }
1629        }
1630        
1631        /* Character Creation Navigation Buttons */
1632        .character-creation-navigation {
1633            display: flex;
1634            justify-content: center;
1635            align-items: center;
1636            gap: 20px;
1637            margin-top: 40px;
1638            width: 100%;
1639        }
1640        
1641        .nav-button {
1642            border: none;
1643            border-radius: 12px;
1644            font-size: 1.1em;
1645            font-weight: bold;
1646            cursor: pointer;
1647            transition: all 0.3s ease;
1648            outline: none;
1649        }
1650        
1651        .nav-back {
1652            width: 40px;
1653            height: 40px;
1654            background: rgba(0, 0, 0, 0.7);
1655            color: #fff;
1656            border-radius: 8px;
1657            display: flex;
1658            align-items: center;
1659            justify-content: center;
1660            position: relative;
1661        }
1662        
1663        .nav-back::before {
1664            content: '';
1665            width: 0;
1666            height: 0;
1667            border-top: 6px solid transparent;
1668            border-bottom: 6px solid transparent;
1669            border-right: 10px solid #fff;
1670            margin-left: -2px;
1671        }
1672        
1673        .nav-back:hover {
1674            background: rgba(0, 0, 0, 0.8);
1675            transform: translateY(-2px);
1676        }
1677        
1678        .nav-next {
1679            width: 120px;
1680            height: 40px;
1681            background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
1682            color: #000;
1683            border-radius: 12px;
1684            box-shadow: 0 4px 15px rgba(160, 132, 238, 0.3);
1685            font-weight: bold;
1686            transition: all 0.3s ease;
1687        }
1688        
1689        .nav-next:hover {
1690            transform: translateY(-2px);
1691            box-shadow: 0 6px 20px rgba(160, 132, 238, 0.4);
1692        }
1693        
1694        .nav-next:disabled {
1695            background: #666;
1696            color: #999;
1697            box-shadow: none;
1698            cursor: not-allowed;
1699            transform: none;
1700        }
1701        
1702        .nav-next:disabled:hover {
1703            transform: none;
1704            box-shadow: none;
1705        }
1706        
1707        .nav-next:active {
1708            transform: translateY(0);
1709        }
1710        
1711        .nav-back:active {
1712            transform: translateY(0);
1713        }
1714        
1715        /* Step 2 Selection Styles */
1716        .selection-section {
1717            margin-bottom: 30px;
1718        }
1719        
1720        .section-title {
1721            font-size: 1.2em;
1722            font-weight: bold;
1723            color: #fff;
1724            margin-bottom: 15px;
1725            text-align: center;
1726        }
1727        
1728        /* Ethnicity Cards */
1729        .ethnicity-cards-container {
1730            display: flex;
1731            gap: 10px;
1732            justify-content: center;
1733            flex-wrap: wrap;
1734            margin-bottom: 20px;
1735        }
1736        
1737        .ethnicity-card {
1738            width: 60px;
1739            height: 80px;
1740            border-radius: 8px;
1741            overflow: hidden;
1742            cursor: pointer;
1743            transition: all 0.3s ease;
1744            border: 2px solid transparent;
1745            position: relative;
1746        }
1747        
1748        .ethnicity-card:hover {
1749            transform: scale(1.05);
1750            border-color: #a084ee;
1751        }
1752        
1753        .ethnicity-card.selected {
1754            border-color: #a084ee;
1755            box-shadow: 0 0 15px rgba(160, 132, 238, 0.6);
1756        }
1757        
1758        .ethnicity-image {
1759            width: 100%;
1760            height: 100%;
1761            object-fit: cover;
1762        }
1763        
1764        .ethnicity-label {
1765            position: absolute;
1766            bottom: 0;
1767            left: 0;
1768            right: 0;
1769            background: linear-gradient(transparent, rgba(0,0,0,0.8));
1770            color: #fff;
1771            font-size: 0.7em;
1772            font-weight: bold;
1773            text-align: center;
1774            padding: 8px 2px 4px;
1775        }
1776        
1777        /* Age Cards */
1778        .age-cards-container {
1779            display: flex;
1780            gap: 10px;
1781            justify-content: center;
1782            flex-wrap: wrap;
1783            margin-bottom: 20px;
1784        }
1785        
1786        .age-card {
1787            width: 70px;
1788            height: 30px;
1789            background: rgba(160, 132, 238, 0.2);
1790            border: 2px solid transparent;
1791            border-radius: 8px;
1792            cursor: pointer;
1793            transition: all 0.3s ease;
1794            display: flex;
1795            align-items: center;
1796            justify-content: center;
1797        }
1798        
1799        .age-card:hover {
1800            background: rgba(160, 132, 238, 0.3);
1801            border-color: #a084ee;
1802        }
1803        
1804        .age-card.selected {
1805            background: rgba(160, 132, 238, 0.4);
1806            border-color: #a084ee;
1807            box-shadow: 0 0 10px rgba(160, 132, 238, 0.5);
1808        }
1809        
1810        .age-label {
1811            color: #fff;
1812            font-size: 0.8em;
1813            font-weight: bold;
1814            text-align: center;
1815        }
1816        
1817        /* Eye Color Cards */
1818        .eye-color-cards-container {
1819            display: flex;
1820            gap: 15px;
1821            justify-content: center;
1822            flex-wrap: wrap;
1823            margin-bottom: 20px;
1824        }
1825        
1826        .eye-color-card {
1827            width: 60px;
1828            height: 50px;
1829            border-radius: 8px;
1830            overflow: hidden;
1831            cursor: pointer;
1832            transition: all 0.3s ease;
1833            border: 3px solid transparent;
1834            position: relative;
1835        }
1836        
1837        .eye-color-card:hover {
1838            transform: scale(1.1);
1839            border-color: #a084ee;
1840        }
1841        
1842        .eye-color-card.selected {
1843            border-color: #a084ee;
1844            box-shadow: 0 0 15px rgba(160, 132, 238, 0.6);
1845        }
1846        
1847        .eye-color-image {
1848            width: 100%;
1849            height: 100%;
1850            object-fit: cover;
1851        }
1852        
1853        .eye-color-label {
1854            position: absolute;
1855            bottom: -25px;
1856            left: 50%;
1857            transform: translateX(-50%);
1858            color: #fff;
1859            font-size: 0.8em;
1860            font-weight: bold;
1861            text-align: center;
1862            white-space: nowrap;
1863        }
1864        
1865        /* Step 3: Hair styles */
1866        .hair-style-cards-container {
1867            display: flex;
1868            gap: 10px;
1869            justify-content: center;
1870            flex-wrap: wrap;
1871            margin-bottom: 20px;
1872        }
1873        .hair-style-card {
1874            width: 80px;
1875            height: 100px;
1876            border-radius: 10px;
1877            overflow: hidden;
1878            cursor: pointer;
1879            transition: all 0.3s ease;
1880            border: 2px solid transparent;
1881            position: relative;
1882        }
1883        .hair-style-card:hover { transform: scale(1.05); border-color: #a084ee; }
1884        .hair-style-card.selected { border-color: #a084ee; box-shadow: 0 0 15px rgba(160,132,238,0.6); }
1885        .hair-style-image { width: 100%; height: 100%; object-fit: cover; display: block; }
1886        .hair-style-label {
1887            position: absolute; bottom: 0; left: 0; right: 0;
1888            background: linear-gradient(transparent, rgba(0,0,0,0.85));
1889            color: #fff; font-size: 0.75em; font-weight: bold; text-align: center; padding: 8px 2px 4px;
1890        }
1891        
1892        /* Step 3: Hair colors */
1893        .hair-color-cards-container { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
1894        .hair-color-card {
1895            width: 70px; height: 36px; border-radius: 8px; border: 2px solid transparent;
1896            display: flex; align-items: center; justify-content: center; cursor: pointer;
1897            transition: all 0.3s ease; color: #000; font-weight: 700; font-size: 0.8em;
1898        }
1899        .hair-color-card:hover { transform: translateY(-2px); border-color: #a084ee; }
1900        .hair-color-card.selected { outline: 2px solid #a084ee; outline-offset: 0; }
1901        .hair-color-card .hair-color-label { text-shadow: 0 1px 2px rgba(0,0,0,0.25); }
1902        
1903        /* Color backgrounds */
1904        .hair-color-card[data-hair-color="blonde"] { background: #f7e07b; }
1905        .hair-color-card[data-hair-color="brunette"] { background: #6b4f3a; color:#fff; }
1906        .hair-color-card[data-hair-color="black"] { background: #111; color:#fff; }
1907        .hair-color-card[data-hair-color="red"] { background: #d14b4b; color:#fff; }
1908        .hair-color-card[data-hair-color="pink"] { background: #ff6fb7; }
1909        .hair-color-card[data-hair-color="white"] { background: #f0f0f0; }
1910        .hair-color-card[data-hair-color="blue"] { background: #4a7bd1; color:#fff; }
1911        .hair-color-card[data-hair-color="green"] { background: #3aa55d; color:#fff; }
1912        .hair-color-card[data-hair-color="purple"] { background: #7c4dff; color:#fff; }
1913        .hair-color-card.multicolor { background: linear-gradient(90deg, #ff2a2a 0%, #7a2aff 50%, #7fff2a 100%); color:#fff; }
1914
1915        /* Step 4: Body / Breast / Butt cards */
1916        .body-type-cards-container, .breast-size-cards-container, .butt-size-cards-container {
1917            display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin-bottom: 20px;
1918        }
1919        .body-type-card, .breast-size-card, .butt-size-card {
1920            width: 90px; height: 110px; border-radius: 10px; overflow: hidden; cursor: pointer; transition: all 0.3s ease; border: 2px solid transparent; position: relative;
1921        }
1922        .body-type-card:hover, .breast-size-card:hover, .butt-size-card:hover { transform: scale(1.05); border-color: #a084ee; }
1923        .body-type-card.selected, .breast-size-card.selected, .butt-size-card.selected { border-color: #a084ee; box-shadow: 0 0 15px rgba(160,132,238,0.6); }
1924        .body-type-image, .breast-size-image, .butt-size-image { width: 100%; height: 100%; object-fit: cover; display: block; }
1925        .body-type-label, .breast-size-label, .butt-size-label { position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(transparent, rgba(0,0,0,0.85)); color: #fff; font-size: 0.75em; font-weight: bold; text-align: center; padding: 8px 2px 4px; }
1926
1927        /* Step 5: Personality */
1928        .personality-cards-container { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
1929        @media (min-width: 520px) { .personality-cards-container { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
1930        .personality-card {
1931            background: #121212; border: 1.5px solid #212121; border-radius: 12px; padding: 8px; color: #fff;
1932            display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 4px;
1933            text-align: center; cursor: pointer; transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
1934        }
1935        .personality-card:hover { transform: translateY(-2px); border-color: #a084ee; box-shadow: 0 6px 18px rgba(160,132,238,0.25); }
1936        .personality-card.selected { outline: 2px solid #a084ee; outline-offset: 0; box-shadow: 0 0 0 3px rgba(160,132,238,0.25) inset; }
1937        .personality-emoji { font-size: 1.4em; line-height: 1; }
1938        .personality-title { font-weight: 800; margin: 0; font-size: 0.95em; }
1939        .personality-desc { font-size: 0.85em; color: #bfaed1; line-height: 1.2; width: 100%; }
1940
1941        /* Step 6: Relationship */
1942        .relationship-cards-container {
1943            display: grid;
1944            grid-template-columns: repeat(3, minmax(0, 1fr));
1945            gap: 10px;
1946        }
1947        .relationship-card {
1948            position: relative;
1949            background: #121212;
1950            border: 1.5px solid #212121;
1951            border-radius: 10px;
1952            width: 100%;
1953            padding-top: 100%; /* Square */
1954            cursor: pointer;
1955            transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
1956            --rel-card-size: 100px;
1957        }
1958        .relationship-card:hover { transform: translateY(-2px); border-color: #a084ee; box-shadow: 0 6px 18px rgba(160,132,238,0.25); }
1959        .relationship-card.selected { outline: 2px solid #a084ee; outline-offset: 0; box-shadow: 0 0 0 3px rgba(160,132,238,0.25) inset; }
1960        .relationship-emoji, .relationship-title {
1961            position: absolute; left: 50%; transform: translateX(-50%);
1962            text-align: center; color: #fff;
1963        }
1964        .relationship-emoji { top: 35%; line-height: 1; font-size: clamp(14px, 0.18 * var(--rel-card-size, 100px), 26px); }
1965        .relationship-title { top: 65%; font-weight: 800; font-size: clamp(11px, 0.12 * var(--rel-card-size, 100px), 18px); }
1966        
1967        /* Summary page */
1968        .summary-cards-container {
1969            display: grid;
1970            grid-template-columns: repeat(3, minmax(0, 1fr));
1971            gap: 12px;
1972        }
1973        
1974        .summary-category {
1975            display: flex;
1976            flex-direction: column;
1977            gap: 8px;
1978        }
1979        
1980        .summary-category-label {
1981            font-size: 0.8em;
1982            font-weight: normal;
1983            color: #fff;
1984            text-align: center;
1985        }
1986        
1987        .summary-card {
1988            position: relative;
1989            background: #121212;
1990            border: 1.5px solid #212121;
1991            border-radius: 10px;
1992            width: 100%;
1993            padding-top: 100%; /* square */
1994            overflow: hidden;
1995        }
1996        .summary-card img {
1997            position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
1998        }
1999        .summary-card .summary-overlay {
2000            position: absolute; left: 0; right: 0; bottom: 0;
2001            background: linear-gradient(transparent, rgba(0,0,0,0.85));
2002            color: #fff; text-align: center; padding: 10px 6px 8px;
2003            font-weight: 700; font-size: 0.9em;
2004        }
2005        .summary-card .summary-text {
2006            position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 700;
2007            padding: 6px; text-align: center;
2008        }
2009        
2010        .nav-bring-to-life {
2011            width: 120px;
2012            height: 40px;
2013            background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
2014            color: #000;
2015            border-radius: 12px;
2016            box-shadow: 0 4px 15px rgba(160, 132, 238, 0.3);
2017            font-weight: bold;
2018            transition: all 0.3s ease;
2019        }
2020        
2021        .nav-bring
2021-to-life:hover {
2022            transform: translateY(-2px);
2023            box-shadow: 0 6px 20px rgba(160, 132, 238, 0.4);
2024        }
2025        
2026        .nav-bring-to-life:active {
2027            transform: translateY(0);
2028        }
2029        
2030        /* Character Creation Status Modal */
2031        #creation-status-modal {
2032            position: fixed;
2033            top: 0;
2034            left: 0;
2035            width: 100%;
2036            height: 100%;
2037            background: rgba(0, 0, 0, 0.8);
2038            display: none;
2039            justify-content: center;
2040            align-items: center;
2041            z-index: 5000;
2042        }
2043        
2044        .creation-status-content {
2045            background: #121212;
2046            border: 2px solid #a084ee;
2047            border-radius: 20px;
2048            padding: 30px;
2049            text-align: center;
2050            min-width: 320px;
2051            max-width: 90vw;
2052        }
2053        
2054        .creation-status-title {
2055            color: #fff;
2056            font-size: 1.5em;
2057            font-weight: bold;
2058            margin-bottom: 20px;
2059        }
2060        
2061        .creation-status-message {
2062            color: #bfaed1;
2063            font-size: 1.1em;
2064            margin-bottom: 20px;
2065        }
2066        
2067        .progress-container {
2068            width: 100%;
2069            background: #2a2a2a;
2070            border-radius: 10px;
2071            height: 20px;
2072            margin-bottom: 20px;
2073            overflow: hidden;
2074        }
2075        
2076        .progress-bar {
2077            height: 100%;
2078            background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
2079            border-radius: 10px;
2080            width: 0%;
2081            transition: width 0.1s ease;
2082            position: relative;
2083        }
2084        
2085        .progress-text {
2086            position: absolute;
2087            top: 50%;
2088            left: 50%;
2089            transform: translate(-50%, -50%);
2090            color: #000;
2091            font-weight: bold;
2092            font-size: 0.8em;
2093        }
2094        
2095        .creation-status-btn {
2096            background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
2097            color: #000;
2098            border: none;
2099            border-radius: 12px;
2100            padding: 12px 24px;
2101            font-weight: bold;
2102            font-size: 1em;
2103            cursor: pointer;
2104            transition: all 0.3s ease;
2105            margin: 0 auto;
2106            display: block;
2107        }
2108        
2109        .creation-status-btn:hover {
2110            transform: translateY(-2px);
2111            box-shadow: 0 6px 20px rgba(160, 132, 238, 0.4);
2112        }
2113        
2114        .creation-status-btn:active {
2115            transform: translateY(0);
2116        }
2117        
2118        /* Create-character modal */
2119        #create-modal-blur {
2120            position: fixed; inset: 0; display: none; z-index: 3200;
2121            background: rgba(0,0,0,0.4);
2122            backdrop-filter: blur(8px);
2123            -webkit-backdrop-filter: blur(8px);
2124        }
2125        #create-modal {
2126            position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
2127            display: none; z-index: 3300;
2128            background: #121212; border-radius: 18px; padding: 22px; min-width: 260px; max-width: 90vw;
2129            border: 1.5px solid #212121; box-shadow: 0 8px 40px 0 #000a;
2130        }
2131        #create-modal .title { color: #fff; font-weight: bold; font-size: 1.15em; margin-bottom: 10px; text-align: center; }
2132        #create-modal .desc { color: #bfaed1; font-size: 1.02em; text-align: center; margin-bottom: 16px; }
2133        #create-modal .btns { display: flex; align-items: center; justify-content: center; gap: 12px; }
2134        #create-modal .btn {
2135            background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
2136            color: #fff; border: none; border-radius: 12px; padding: 10px 20px; font-weight: bold; cursor: pointer;
2137        }
2138        #create-modal .close { background: #111; }
2139
2140        /* Loading Screen Styles */
2141        .loading-screen {
2142            position: fixed;
2143            top: 0;
2144            left: 0;
2145            width: 100%;
2146            height: 100%;
2147            background: #0a0a0a;
2148            display: flex;
2149            align-items: center;
2150            justify-content: center;
2151            z-index: 9999;
2152            opacity: 1;
2153            transition: opacity 0.5s ease-out;
2154        }
2155
2156        .loading-screen.hidden {
2157            opacity: 0;
2158            pointer-events: none;
2159        }
2160
2161        .loading-content {
2162            text-align: center;
2163            color: #fff;
2164        }
2165
2166        .loading-spinner {
2167            width: 60px;
2168            height: 60px;
2169            border: 4px solid rgba(160, 132, 238, 0.3);
2170            border-top: 4px solid #a084ee;
2171            border-radius: 50%;
2172            animation: spin 1s linear infinite;
2173            margin: 0 auto 20px;
2174        }
2175
2176        @keyframes spin {
2177            0% { transform: rotate(0deg); }
2178            100% { transform: rotate(360deg); }
2179        }
2180
2181        .loading-title {
2182            font-size: 1.5em;
2183            font-weight: bold;
2184            margin-bottom: 10px;
2185            color: #fff;
2186        }
2187
2188        .loading-subtitle {
2189            font-size: 1em;
2190            color: #bfaed1;
2191            margin: 0;
2192        }
2193
2194        /* Photo loading indicator */
2195        .photo-loading-spinner {
2196            width: 40px;
2197            height: 40px;
2198            border: 3px solid rgba(160, 132, 238, 0.3);
2199            border-top: 3px solid #a084ee;
2200            border-radius: 50%;
2201            animation: spin 1s linear infinite;
2202            margin: 0 auto;
2203        }
2204
2205        .photo-loading-container {
2206            display: flex;
2207            align-items: center;
2208            justify-content: center;
2209            width: 150px;
2210            height: 100%;
2211            min-height: 200px;
2212            background: #121212;
2213            border-radius: 16px 0 0 16px;
2214            position: relative;
2215            overflow: hidden;
2216            flex-shrink: 0;
2217        }
2218    </style>
2219</head>
2220<body>
2221
2222    <header>
2223        <div id="page-title" class="page-title"></div>
2224            <div id="user-balance">
2225                <button id="daily-bonus-btn" class="daily-bonus-btn" title="Daily Bonus">🎁</button>
2226                 <div class="currency-panel">
2227                     <div class="currency-item">
2228                         <span class="currency-icon">💬</span>
2229                         <span class="currency-value">0</span>
2230                     </div>
2231                     <div class="currency-item">
2232                         <span class="currency-icon">🎁</span>
2233                         <span class="currency-value">0</span>
2234                     </div>
2235                     <div class="currency-item">
2236                         <span class="currency-icon">🍑</span>
2237                         <span class="currency-value">0</span>
2238                     </div>
2239                     <button class="add-currency-btn">+</button>
2240                 </div>
2241             </div>
2242     </header>
2243
2244    <nav id="bottom-nav">
2245        <div id="bottom-nav-inner">
2246            <button id="nav-girls" class="active" aria-label="Девушки">
2247                <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-4a2 2 0 0 0-2-2H9a2 2 0 0 0-2 2v4"/><path d="M12 7a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"/></svg>
2248            </button>
2249
2250            <button id="nav-lollipops" aria-label="Леденцы">
2251                <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2252                    <line x1="12" y1="1" x2="12" y2="23"/>
2253                    <path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/>
2254                </svg>
2255            </button>
2256        </div>
2257    </nav>
2258
2259    <div class="container">
2260        <!-- Loading Screen -->
2261        <div id="loading-screen" class="loading-screen">
2262            <div class="loading-content">
2263                <div class="loading-spinner"></div>
2264                <h2 class="loading-title">Loading Characters...</h2>
2265                <p class="loading-subtitle">Please wait while we fetch your characters</p>
2266            </div>
2267        </div>
2268
2269        <div id="page-girls" class="page active">
2270            <div id="girls-shop" class="shop-grid"></div>
2271        </div>
2272
2273
2274
2275        <div id="page-lollipops" class="page">
2276            <button id="back-button" class="back-button" aria-label="Назад">
2277                <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2278                    <path d="M19 12H5"/>
2279                    <path d="M12 19l-7-7 7-7"/>
2280                </svg>
2281            </button>
2282            <div id="lollipops-shop" class="shop-grid"></div>
2283            <div id="pack-description" class="pack-description"></div>
2284            <div id="upgrade-text" class="upgrade-text"></div>
2285        </div>
2286
2287        <div id="page-character-creation" class="page">
2288            <div class="character-creation-container">
2289                <div class="style-selection-title">Chose Style</div>
2290                <div class="style-cards-container">
2291                    <div class="style-card" data-style="realistic">
2292                        <video class="style-video" autoplay muted loop>
2293                            <source src="Videos/Selection.mp4" type="video/mp4">
2294                        </video>
2295                        <div class="style-label">Realistic</div>
2296                    </div>
2297                    <div class="style-card" data-style="anime">
2298                        <video class="style-video" autoplay muted loop>
2299                            <source src="Videos/Selection2.mp4" type="video/mp4">
2300                        </video>
2301                        <div class="style-label">Anime</div>
2302                    </div>
2303                </div>
2304                <div class="character-creation-navigation">
2305                    <button class="nav-button nav-back"></button>
2306                    <button class="nav-button nav-next" disabled>Next</button>
2307                </div>
2308            </div>
2309        </div>
2310
2311        <div id="page-character-creation-step2" class="page">
2312            <div class="character-creation-container">
2313                
2314                <!-- Ethnicity Selection -->
2315                <div class="selection-section">
2316                    <div class="section-title">Choose Ethnicity</div>
2317                    <div class="ethnicity-cards-container">
2318                        <div class="ethnicity-card" data-ethnicity="caucasian">
2319                            <img class="ethnicity-image" src="" alt="Caucasian" loading="lazy">
2320                            <div class="ethnicity-label">Caucasian</div>
2321                        </div>
2322                        <div class="ethnicity-card" data-ethnicity="latina">
2323                            <img class="ethnicity-image" src="" alt="Latina" loading="lazy">
2324                            <div class="ethnicity-label">Latina</div>
2325                        </div>
2326                        <div class="ethnicity-card" data-ethnicity="asian">
2327                            <img class="ethnicity-image" src="" alt="Asian" loading="lazy">
2328                            <div class="ethnicity-label">Asian</div>
2329                        </div>
2330                        <div class="ethnicity-card" data-ethnicity="arab">
2331                            <img class="ethnicity-image" src="" alt="Arab" loading="lazy">
2332                            <div class="ethnicity-label">Arab</div>
2333                        </div>
2334                        <div class="ethnicity-card" data-ethnicity="black">
2335                            <img class="ethnicity-image" src="" alt="Black" loading="lazy">
2336                            <div class="ethnicity-label">Black</div>
2337                        </div>
2338                    </div>
2339                </div>
2340
2341                <!-- Age Selection -->
2342                <div class="selection-section">
2343                    <div class="section-title">Choose Age</div>
2344                    <div class="age-cards-container">
2345                        <div class="age-card" data-age="teen">
2346                            <div class="age-label">Teen (18+)</div>
2347                        </div>
2348                        <div class="age-card" data-age="20s">
2349                            <div class="age-label">20s</div>
2350                        </div>
2351                        <div class="age-card" data-age="30s">
2352                            <div class="age-label">30s</div>
2353                        </div>
2354                        <div class="age-card" data-age="40-55">
2355                            <div class="age-label">40-55</div>
2356                        </div>
2357                    </div>
2358                </div>
2359
2360                <!-- Eye Color Selection -->
2361                <div class="selection-section">
2362                    <div class="section-title">Choose Eye Color</div>
2363                    <div class="eye-color-cards-container">
2364                        <div class="eye-color-card" data-eye-color="brown">
2365                            <img class="eye-color-image" src="Photos/Creation/eyeBrown.jpg" alt="Brown Eyes" loading="lazy">
2366                            <div class="eye-color-label">Brown</div>
2367                        </div>
2368                        <div class="eye-color-card" data-eye-color="blue">
2369                            <img class="eye-color-image" src="Photos/Creation/eyeBlue.jpg" alt="Blue Eyes" loading="lazy">
2370                            <div class="eye-color-label">Blue</div>
2371                        </div>
2372                        <div class="eye-color-card" data-eye-color="green">
2373                            <img class="eye-color-image" src="Photos/Creation/eyeGreen.jpg" alt="Green Eyes" loading="lazy">
2374                            <div class="eye-color-label">Green</div>
2375                        </div>
2376                    </div>
2377                </div>
2378
2379                <div class="character-creation-navigation">
2380                    <button class="nav-button nav-back"></button>
2381                    <button class="nav-button nav-next" disabled>Next</button>
2382                </div>
2383            </div>
2384        </div>
2385        
2386        <div id="page-character-creation-step3" class="page">
2387            <div class="character-creation-container">
2388                <div class="selection-section">
2389                    <div class="section-title">Choose Hair Style</div>
2390                    <div class="hair-style-cards-container">
2391                        <div class="hair-style-card" data-hair="straight">
2392                            <img class="hair-style-image" src="" alt="Straight" loading="lazy">
2393                            <div class="hair-style-label">Straight</div>
2394                        </div>
2395                        <div class="hair-style-card" data-hair="bangs">
2396                            <img class="hair-style-image" src="" alt="Bangs" loading="lazy">
2397                            <div class="hair-style-label">Bangs</div>
2398                        </div>
2399                        <div class="hair-style-card" data-hair="curly">
2400                            <img class="hair-style-image" src="" alt="Curly" loading="lazy">
2401                            <div class="hair-style-label">Curly</div>
2402                        </div>
2403                        <div class="hair-style-card" data-hair="bun">
2404                            <img class="hair-style-image" src="" alt="Bun" loading="lazy">
2405                            <div class="hair-style-label">Bun</div>
2406                        </div>
2407                        <div class="hair-style-card" data-hair="short">
2408                            <img class="hair-style-image" src="" alt="Short" loading="lazy">
2409                            <div class="hair-style-label">Short</div>
2410                        </div>
2411                        <div class="hair-style-card" data-hair="long">
2412                            <img class="hair-style-image" src="" alt="Long" loading="lazy">
2413                            <div class="hair-style-label">Long</div>
2414                        </div>
2415                        <div class="hair-style-card" data-hair="ponytail">
2416                            <img class="hair-style-image" src="" alt="Ponytail" loading="lazy">
2417                            <div class="hair-style-label">Ponytail</div>
2418                        </div>
2419                    </div>
2420                </div>
2421
2422                <div class="selection-section">
2423                    <div class="section-title">Choose Hair Color</div>
2424                    <div class="hair-color-cards-container">
2425                        <div class="hair-color-card" data-hair-color="blonde"><span class="hair-color-label">Blonde</span></div>
2426                        <div class="hair-color-card" data-hair-color="brunette"><span class="hair-color-label">Brunette</span></div>
2427                        <div class="hair-color-card" data-hair-color="black"><span class="hair-color-label">Black</span></div>
2428                        <div class="hair-color-card" data-hair-color="red"><span class="hair-color-label">Red</span></div>
2429                        <div class="hair-color-card" data-hair-color="pink"><span class="hair-color-label">Pink</span></div>
2430                        <div class="hair-color-card" data-hair-color="white"><span class="hair-color-label">White</span></div>
2431                        <div class="hair-color-card" data-hair-color="blue"><span class="hair-color-label">Blue</span></div>
2432                        <div class="hair-color-card" data-hair-color="green"><span class="hair-color-label">Green</span></div>
2433                        <div class="hair-color-card" data-hair-color="purple"><span class="hair-color-label">Purple</span></div>
2434                        <div class="hair-color-card multicolor" data-hair-color="multicolor"><span class="hair-color-label">Multicolor</span></div>
2435                    </div>
2436                </div>
2437
2438                <div class="character-creation-navigation">
2439                    <button class="nav-button nav-back"></button>
2440                    <button class="nav-button nav-next" disabled>Next</button>
2441                </div>
2442            </div>
2443        </div>
2444
2445        <div id="page-character-creation-step4" class="page">
2446            <div class="character-creation-container">
2447                <!-- Body Type -->
2448                <div class="selection-section">
2449                    <div class="section-title">Choose Body Type</div>
2450                    <div class="body-type-cards-container">
2451                        <div class="body-type-card" data-body="slim">
2452                            <img class="body-type-image" src="" alt="Slim" loading="lazy">
2453                            <div class="body-type-label">Slim</div>
2454                        </div>
2455                        <div class="body-type-card" data-body="athletic">
2456                            <img class="body-type-image" src="" alt="Athletic" loading="lazy">
2457                            <div class="body-type-label">Athletic</div>
2458                        </div>
2459                        <div class="body-type-card" data-body="voluptuous">
2460                            <img class="body-type-image" src="" alt="Voluptuous" loading="lazy">
2461                            <div class="body-type-label">Voluptuous</div>
2462                        </div>
2463                        <div class="body-type-card" data-body="curvy">
2464                            <img class="body-type-image" src="" alt="Curvy" loading="lazy">
2465                            <div class="body-type-label">Curvy</div>
2466                        </div>
2467                    </div>
2468                </div>
2469
2470                <!-- Breast Size -->
2471                <div class="selection-section">
2472                    <div class="section-title">Choose Breast Size</div>
2473                    <div class="breast-size-cards-container">
2474                        <div class="breast-size-card" data-breast="small">
2475                            <img class="breast-size-image" src="" alt="Small" loading="lazy">
2476                            <div class="breast-size-label">Small</div>
2477                        </div>
2478                        <div class="breast-size-card" data-breast="medium">
2479                            <img class="breast-size-image" src="" alt="Medium" loading="lazy">
2480                            <div class="breast-size-label">Medium</div>
2481                        </div>
2482                        <div class="breast-size-card" data-breast="large">
2483                            <img class="breast-size-image" src="" alt="Large" loading="lazy">
2484                            <div class="breast-size-label">Large</div>
2485                        </div>
2486                        <div class="breast-size-card" data-breast="huge">
2487                            <img class="breast-size-image" src="" alt="Huge" loading="lazy">
2488                            <div class="breast-size-label">Huge<
2488/div>
2489                        </div>
2490                    </div>
2491                </div>
2492
2493                <!-- Butt Size -->
2494                <div class="selection-section">
2495                    <div class="section-title">Choose Butt Size</div>
2496                    <div class="butt-size-cards-container">
2497                        <div class="butt-size-card" data-butt="small">
2498                            <img class="butt-size-image" src="" alt="Small" loading="lazy">
2499                            <div class="butt-size-label">Small</div>
2500                        </div>
2501                        <div class="butt-size-card" data-butt="medium">
2502                            <img class="butt-size-image" src="" alt="Medium" loading="lazy">
2503                            <div class="butt-size-label">Medium</div>
2504                        </div>
2505                        <div class="butt-size-card" data-butt="large">
2506                            <img class="butt-size-image" src="" alt="Large" loading="lazy">
2507                            <div class="butt-size-label">Large</div>
2508                        </div>
2509                        <div class="butt-size-card" data-butt="athletic">
2510                            <img class="butt-size-image" src="" alt="Athletic" loading="lazy">
2511                            <div class="butt-size-label">Athletic</div>
2512                        </div>
2513                    </div>
2514                </div>
2515
2516                <div class="character-creation-navigation">
2517                    <button class="nav-button nav-back"></button>
2518                    <button class="nav-button nav-next" disabled>Next</button>
2519                </div>
2520            </div>
2521        </div>
2522
2523        <div id="page-character-creation-step5" class="page">
2524            <div class="character-creation-container">
2525                <div class="selection-section">
2526                    <div class="section-title">Choose Personality</div>
2527                    <div class="personality-cards-container">
2528                        <div class="personality-card" data-personality="caregiver">
2529                            <div class="personality-emoji">🤱</div>
2530                            <div class="personality-title">Caregiver</div>
2531                            <div class="personality-desc">Nurturing, protective, and always there to offer comfort.</div>
2532                        </div>
2533                        <div class="personality-card" data-personality="sage">
2534                            <div class="personality-emoji">🧙</div>
2535                            <div class="personality-title">Sage</div>
2536                            <div class="personality-desc">Wise, reflective, and a source of guidance.</div>
2537                        </div>
2538                        <div class="personality-card" data-personality="innocent">
2539                            <div class="personality-emoji">🌼</div>
2540                            <div class="personality-title">Innocent</div>
2541                            <div class="personality-desc">Optimistic, naive, and sees world with wonder.</div>
2542                        </div>
2543                        <div class="personality-card" data-personality="jester">
2544                            <div class="personality-emoji">🎭</div>
2545                            <div class="personality-title">Jester</div>
2546                            <div class="personality-desc">Playful, humorous, and always there to make you laugh.</div>
2547                        </div>
2548                        <div class="personality-card" data-personality="temptress">
2549                            <div class="personality-emoji">😈</div>
2550                            <div class="personality-title">Temptress</div>
2551                            <div class="personality-desc">Flirtatious, playful, and always leaving you wanting more.</div>
2552                        </div>
2553                        <div class="personality-card" data-personality="dominant">
2554                            <div class="personality-emoji">🦁</div>
2555                            <div class="personality-title">Dominant</div>
2556                            <div class="personality-desc">Assertive, controlling, and commanding.</div>
2557                        </div>
2558                        <div class="personality-card" data-personality="submissive">
2559                            <div class="personality-emoji">🙇</div>
2560                            <div class="personality-title">Submissive</div>
2561                            <div class="personality-desc">Obedient, yielding, and happy to follow.</div>
2562                        </div>
2563                        <div class="personality-card" data-personality="lover">
2564                            <div class="personality-emoji">💘</div>
2565                            <div class="personality-title">Lover</div>
2566                            <div class="personality-desc">Romantic, affectionate, and cherishes deep emotional</div>
2567                        </div>
2568                        <div class="personality-card" data-personality="nympho">
2569                            <div class="personality-emoji">🔥</div>
2570                            <div class="personality-title">Nympho</div>
2571                            <div class="personality-desc">Insatiable, passionate, and constantly craving intimacy.</div>
2572                        </div>
2573                        <div class="personality-card" data-personality="mean">
2574                            <div class="personality-emoji">🧊</div>
2575                            <div class="personality-title">Mean</div>
2576                            <div class="personality-desc">Cold, dismissive, and often sarcastic.</div>
2577                        </div>
2578                        <div class="personality-card" data-personality="confidant">
2579                            <div class="personality-emoji">🤝</div>
2580                            <div class="personality-title">Confidant</div>
2581                            <div class="personality-desc">Trustworthy, a good listener, and always can offer advice.</div>
2582                        </div>
2583                        <div class="personality-card" data-personality="experimenter">
2584                            <div class="personality-emoji">🧪</div>
2585                            <div class="personality-title">Experimenter</div>
2586                            <div class="personality-desc">
2586Curious, willing, and always eager to try new things.</div>
2587                        </div>
2588                    </div>
2589                </div>
2590
2591                <div class="character-creation-navigation">
2592                    <button class="nav-button nav-back"></button>
2593                    <button class="nav-button nav-next" disabled>Next</button>
2594                </div>
2595            </div>
2596        </div>
2597
2598        <div id="page-character-creation-step6" class="page">
2599            <div class="character-creation-container">
2600                <div class="selection-section">
2601                    <div class="section-title">Choose Relationship</div>
2602                    <div class="relationship-cards-container">
2603                        <div class="relationship-card" data-relationship="stranger">
2604                            <div class="relationship-emoji">🕵️‍♂️</div>
2605                            <div class="relationship-title">Stranger</div>
2606                        </div>
2607                        <div class="relationship-card" data-relationship="school_mate">
2608                            <div class="relationship-emoji">🎒</div>
2609                            <div class="relationship-title">School Mate</div>
2610                        </div>
2611                        <div class="relationship-card" data-relationship="colleague">
2612                            <div class="relationship-emoji">💼</div>
2613                            <div class="relationship-title">Colleague</div>
2614                        </div>
2615                        <div class="relationship-card" data-relationship="mentor">
2616                            <div class="relationship-emoji">🧑‍🏫</div>
2617                            <div class="relationship-title">Mentor</div>
2618                        </div>
2619                        <div class="relationship-card" data-relationship="girlfriend">
2620                            <div class="relationship-emoji">💖</div>
2621                            <div class="relationship-title">Girlfriend</div>
2622                        </div>
2623                        <div class="relationship-card" data-relationship="sex_friend">
2624                            <div class="relationship-emoji">🔥</div>
2625                            <div class="relationship-title">Sex Friend</div>
2626                        </div>
2627                        <div class="relationship-card" data-relationship="wife">
2628                            <div class="relationship-emoji">💍</div>
2629                            <div class="relationship-title">Wife</div>
2630                        </div>
2631                        <div class="relationship-card" data-relationship="mistress">
2632                            <div class="relationship-emoji">👠</div>
2633                            <div class="relationship-title">Mistress</div>
2634                        </div>
2635                        <div class="relationship-card" data-relationship="friend">
2636                            <div class="relationship-emoji">🤝</div>
2637                            <div class="relationship-title">Friend</div>
2638                        </div>
2639                        <div class="relationship-card" data-relationship="best_friend">
2640                            <div class="relationship-emoji">🌟</div>
2641                            <div class="relationship-title">Best Friend</div>
2642                        </div>
2643                        <div class="relationship-card" data-relationship="step_sister">
2644                            <div class="relationship-emoji">👧</div>
2645                            <div class="relationship-title">Step Sister</div>
2646                        </div>
2647                        <div class="relationship-card" data-relationship="step_mom">
2648                            <div class="relationship-emoji">👩‍👧</div>
2649                            <div class="relationship-title">Step Mom</div>
2650                        </div>
2651                    </div>
2652                </div>
2653
2654                <div class="character-creation-navigation">
2655                    <button class="nav-button nav-back"></button>
2656                    <button class="nav-button nav-next" disabled>Next</button>
2657                </div>
2658            </div>
2659        </div>
2660
2661        <div id="page-character-creation-summary" class="page">
2662            <div class="character-creation-container">
2663                <div class="selection-section">
2664                    <div class="section-title">Summary</div>
2665                    <div class="summary-cards-container">
2666                        <!-- Style -->
2667                        <div class="summary-category">
2668                            <div class="summary-category-label">Style</div>
2669                            <div class="summary-card" id="summary-style">
2670                                <div class="summary-card-content">
2671                                    <div class="summary-card-title">Loading...</div>
2672                                </div>
2673                            </div>
2674                        </div>
2675
2676                        <!-- Ethnicity -->
2677                        <div class="summary-category">
2678                            <div class="summary-category-label">Ethnicity</div>
2679                            <div class="summary-card" id="summary-ethnicity">
2680                                <div class="summary-card-content">
2681                                    <div class="summary-card-title">Loading...</div>
2682                                </div>
2683                            </div>
2684                        </div>
2685
2686                        <!-- Age -->
2687                        <div class="summary-category">
2688                            <div class="summary-category-label">Age</div>
2689                            <div class="summary-card" id="summary-age">
2690                                <div class="summary-card-content">
2691                                    <div class="summary-card-title">Loading...</div>
2692                                </div>
2693                            </div>
2694                        </div>
2695
2696                        <!-- Eye Color -->
2697                        <div class="summary-category">
2698                            <div class="summary-category-label">Eye Color</div>
2699                            <div class="summary-card" id="summary-eye-color">
2700                                <div class="summary-card-content">
2701                                    <div class="summary-card-title">Loading...</div>
2702                                </div>
2703                            </div>
2704                        </div>
2705
2706                        <!-- Hair Style -->
2707                        <div class="summary-category">
2708                            <div class="summary-category-label">Hair Style</div>
2709                            <div class="summary-card" id="summary-hair-style">
2710                                <div class="summary-card-content">
2711                                    <div class="summary-card-title">Loading...</div>
2712                                </div>
2713                            </div>
2714                        </div>
2715
2716                        <!-- Hair Color -->
2717                        <div class="summary-category">
2718                            <div class="summary-category-label">Hair Color</div>
2719                            <div class="summary-card" id="summary-hair-color">
2720                                <div class="summary-card-content">
2721                                    <div class="summary-card-title">Loading...</div>
2722                                </div>
2723                            </div>
2724                        </div>
2725
2726                        <!-- Body Type -->
2727                        <div class="summary-category">
2728                            <div class="summary-category-label">Body Type</div>
2729                            <div class="summary-card" id="summary-body-type">
2730                                <div class="summary-card-content">
2731                                    <div class="summary-card-title">Loading...</div>
2732                                </div>
2733                            </div>
2734                        </div>
2735
2736                        <!-- Breast Size -->
2737                        <div class="summary-category">
2738                            <div class="summary-category-label">Breast Size</div>
2739                            <div class="summary-card" id="summary-breast-size">
2740                                <div class="summary-card-content">
2741                                    <div class="summary-card-title">Loading...</div>
2742                                </div>
2743                            </div>
2744                        </div>
2745
2746                        <!-- Butt Size -->
2747                        <div class="summary-category">
2748                            <div class="summary-category-label">Butt Size</div>
2749                            <div class="summary-card" id="summary-butt-size">
2750                                <div class="summary-card-content">
2751                                    <div class="summary-card-title">Loading...</div>
2752                                </div>
2753                            </div>
2754                        </div>
2755
2756                        <!-- Personality -->
2757                        <div class="summary-category">
2758                            <div class="summary-category-label">Personality</div>
2759                            <div class="summary-card" id="summary-personality">
2760                                <div class="summary-card-content">
2761                                    <div class="summary-card-title">Loading...</div>
2762                                </div>
2763                            </div>
2764                        </div>
2765
2766                        <!-- Relationship -->
2767                        <div class="summary-category">
2768                            <div class="summary-category-label">Relationship</div>
2769                            <div class="summary-card" id="summary-relationship">
2770                                <div class="summary-card-content">
2771                                    <div class="summary-card-title">Loading...</div>
2772                                </div>
2773                            </div>
2774                        </div>
2775                    </div>
2776                </div>
2777
2778                <div class="character-creation-navigation">
2779                    <button class="nav-button nav-back"></button>
2780                    <button class="nav-button nav-bring-to-life">Bring To Life</button>
2781                </div>
2782            </div>
2783        </div>
2784    </div>
2785
2786    <!-- Кнопка Upgrade для подписок -->
2787    <div id="upgrade-section" class="upgrade-section">
2788        <button id="upgrade-button" class="upgrade-button">
2789            <span class="upgrade-button-text"></span>
2790        </button>
2791    </div>
2792
2793     <!-- Character Creation Status Modal -->
2794     <div id="creation-status-modal">
2795         <div class="creation-status-content">
2796             <div class="creation-status-title"></div>
2797             <div class="creation-status-message" id="creation-status-message"></div>
2798             <div class="progress-container" id="progress-container">
2799                 <div class="progress-bar" id="progress-bar">
2800                     <div class="progress-text" id="progress-text">0%</div>
2801                 </div>
2802             </div>
2803             <button class="creation-status-btn" id="creation-status-btn" style="display: none;">OK</button>
2804         </div>
2805     </div>
2806
2807
2808    
2809
2810    
2810<script>
2811        // ============================================
2812        // LOCALIZATION SERVICE (with local cache)
2813        // ============================================
2814        
2815        // Note: BUILT_IN_LOCALIZATIONS is now loaded from external file localizations.js
2816        // This keeps index.html clean and makes localization updates easier
2817        
2818        class LocalizationService {
2819            constructor(config = {}) {
2820                this.defaultLanguage = 'en';
2821                
2822                this.localizations = {};
2823                this.currentLanguage = 'en';
2824                this.userId = null;
2825                this.isInitialized = false;
2826                
2827                // Storage key for user language preference
2828                this.storageKey = 'user_language';
2829            }
2830            
2831            // Initialize the service
2832            async initialize(userId = null) {
2833                this.userId = userId;
2834                
2835                // Step 1: Use built-in localizations immediately (instant load!)
2836                this.localizations = BUILT_IN_LOCALIZATIONS;
2837                this.isInitialized = true;
2838                console.log('[LocalizationService] ⚡ Instant load from built-in cache');
2839                
2840                // Step 2: Always use 'en' language
2841                this.currentLanguage = 'en';
2842                
2843                console.log('[LocalizationService] ✅ Initialized with language:', this.currentLanguage);
2844                
2845                // Note: Localizations are now updated only at build time via update-localizations.js
2846                // No runtime fetching from Google Sheets for better performance and offline support
2847            }
2848            
2849            // Get translation by key
2850            get(key, userId = null) {
2851                if (!key) return key;
2852                
2853                const normalizedKey = key.toLowerCase();
2854                const lang = this.currentLanguage;
2855                
2856                // Try current language
2857                if (this.localizations[lang] && this.localizations[lang][normalizedKey] !== undefined) {
2858                    return this.localizations[lang][normalizedKey].replace(/\\n
2858/g, '\n');
2859                }
2860                
2861                // Fallback to default language
2862                if (this.localizations[this.defaultLanguage] && 
2863                    this.localizations[this.defaultLanguage][normalizedKey] !== undefined) {
2864                    console.warn(`[LocalizationService] Key "${key}" not found for "${lang}", using default language`);
2865                    return this.localizations[this.defaultLanguage][normalizedKey].replace(/\\n/g, '\n');
2866                }
2867                
2868                // Return key in brackets if not found
2869                console.warn(`[LocalizationService] Translation not found for key: ${key}`);
2870                return `[${key}]`;
2871            }
2872            
2873            // Set language for current user
2874            setLanguage(languageCode) {
2875                const lang = languageCode.toLowerCase();
2876                
2877                if (!this.localizations[lang]) {
2878                    console.warn(`[LocalizationService] Language "${lang}" not available`);
2879                    return false;
2880                }
2881                
2882                this.currentLanguage = lang;
2883                this.saveLanguageToStorage(lang);
2884                
2885                console.log('[LocalizationService] Language changed to:', lang);
2886                
2887                return true;
2888            }
2889            
2890            // Get current language
2891            getLanguage() {
2892                return this.currentLanguage;
2893            }
2894            
2895            // Get available languages
2896            getAvailableLanguages() {
2897                return Object.keys(this.localizations);
2898            }
2899            
2900            // Get language from localStorage
2901            getStoredLanguage() {
2902                try {
2903                    return localStorage.getItem(this.storageKey);
2904                } catch (e) {
2905                    return null;
2906                }
2907            }
2908            
2909            // Save language to localStorage
2910            saveLanguageToStorage(lang) {
2911                try {
2912                    localStorage.setItem(this.storageKey, lang);
2913                } catch (e) {
2914                    console.warn('[LocalizationService] Failed to save language to storage:', e);
2915                }
2916            }
2917        }
2918        
2919        // Global localization instance
2920        let localizationService = null;
2921        
2922        // Helper function for getting translations
2923        function t(key) {
2924            if (!localizationService || !localizationService.isInitialized) {
2925                return `[${key}]`;
2926            }
2927            return localizationService.get(key);
2928        }
2929        
2930        // ============================================
2931        // MAIN APPLICATION
2932        // ============================================
2933        
2934        document.addEventListener('DOMContentLoaded', function() {
2935            const tg = window.Telegram.WebApp;
2936            tg.ready();
2937            tg.expand();
2938
2939            // Форсируем тёмную тему через theme_params, если Telegram не передал их явно
2940            const darkThemeParams = {
2941                bg_color: '#000000',
2942                secondary_bg_color: '#000000',
2943                header_bg_color: '#000000',
2944                text_color: '#000000',
2945                hint_color: '#000000',
2946                link_color: '#000000',
2947                button_color: '#000000',
2948                button_text_color: '#000000',
2949            };
2950            const themeParams = tg.themeParams || {};
2951            // Если Telegram не передал bg_color или он не тёмный, применяем свои значения
2952            function applyThemeVars(params) {
2953                const root = document.documentElement;
2954                root.style.setProperty('--tg-theme-bg-color', params.bg_color || '#000');
2955                root.style.setProperty('--tg-theme-card-bg', params.secondary_bg_color || '#121212');
2956                root.style.setProperty('--tg-theme-text-color', params.text_color || '#000000');
2957                root.style.setProperty('--tg-theme-hint-color', params.hint_color || '#000000');
2958                root.style.setProperty('--tg-theme-link-color', params.link_color || '#000000');
2959                root.style.setProperty('--tg-theme-button-color', params.button_color || '#000000');
2960                root.style.setProperty('--tg-theme-button-text-color', params.button_text_color || '#000000');
2961            }
2962            // Проверяем, есть ли bg_color и он ли тёмный, иначе форсируем
2963            if (!themeParams.bg_color || themeParams.bg_color.toLowerCase() !== '#000000') {
2964                applyThemeVars(darkThemeParams);
2965            } else {
2966                applyThemeVars(themeParams);
2967            }
2968
2969            // --- MOCK DATA (заглушки, т.к. нет бэкенда) ---
2970            const user = {
2971                id: tg.initDataUnsafe?.user?.id || '000000',
2972                name: tg.initDataUnsafe?.user?.first_name || '', // Will be set after localization init
2973                lollipops: 0, // HardCurrency
2974                energy: 0,    // SoftCurrency
2975                purchasedItems: [],
2976                gifts: 0
2977            };
2978            
2979            // ============================================
2980            // INITIALIZE LOCALIZATION SERVICE
2981            // ============================================
2982            
2983            // Determine user's language from Telegram (fallback)
2984            const telegramLanguage = tg.initDataUnsafe?.user?.language_code || 'en';
2985            
2986            // Initialize localization service
2987            // Localizations are loaded from localizations.js (updated at build time)
2988            localizationService = new LocalizationService({
2989                defaultLanguage: telegramLanguage === 'en' ? 'en' : 'ru'
2990            });
2991            
2992            // Function to fetch user language from API
2993            async function fetchUserLanguage() {
2994                try {
2995                    const response = await fetch(`${API_BASE}/getlang?user=${user.id}`);
2996                    if (!response.ok) {
2997                        console.warn('[Language] Failed to fetch language from API, using fallback');
2998                        return null;
2999                    }
3000                    // API returns JSON-serialized string
3001                    const languageCode = await response.json();
3002                    // Handle null or empty values
3003                    if (!languageCode || typeof languageCode !== 'string' || languageCode.trim() === '') {
3004                        console.log('[Language] No language found in API response');
3005                        return null;
3006                    }
3007                    console.log('[Language] Fetched language from API:', languageCode);
3008                    return languageCode.trim().toLowerCase();
3009                } catch (error) {
3010                    console.warn('[Language] Error fetching language from API:', error);
3011                    return null;
3012                }
3013            }
3014            
3015            // Function to update modal window texts after language change
3016            function updateModalTexts() {
3017                // Update Daily Bonus modal
3018                const dailyBonusModal = document.getElementById('daily-bonus-modal');
3019                if (dailyBonusModal) {
3020                    const title = dailyBonusModal.querySelector('.title');
3021                    const claimInfo = dailyBonusModal.querySelector('.claim-info');
3022                    const claimBtn = dailyBonusModal.querySelector('#daily-claim-btn');
3023                    const upgradeBtn = dailyBonusModal.querySelector('#daily-upgrade-btn');
3024                    const closeX = dailyBonusModal.querySelector('.close-x');
3025                    
3026                    if (title) title.textContent = t('modal_dailyBonus_title');
3027                    if (claimInfo) claimInfo.textContent = t('modal_dailyBonus_info');
3028                    if (claimBtn) claimBtn.innerHTML = `<span>🎁</span> ${t('button_claim')}`;
3029                    if (upgradeBtn) upgradeBtn.innerHTML = `<span>⚡</span> ${t('button_upgrade')}`;
3030                    if (closeX) closeX.setAttribute('aria-label', t('button_close'));
3031                }
3032                
3033                // Update Character Creation modal
3034                const createModal = document.getElementById('create-modal');
3035                if (createModal) {
3036                    const title = createModal.querySelector('.title');
3037                    const benefits = createModal.querySelector('.benefits');
3038                    const closeBtn = createModal.querySelector('.close');
3039                    
3040                    if (title) title.textContent = t('modal_create_title');
3041                    if (benefits) benefits.textContent = t('girl_creation_modal_window');
3042                    if (closeBtn) closeBtn.textContent = t('button_close');
3043                }
3044                
3045                // Update Creation Status modal
3046                const creationStatusTitle = document.querySelector('.creation-status-title');
3047                const creationStatusBtn = document.getElementById('creation-status-btn');
3048                
3049                if (creationStatusTitle) {
3050                    creationStatusTitle.textContent = t('modal_create_title');
3051                }
3052                if (creationStatusBtn) {
3053                    creationStatusBtn.textContent = t('button_ok');
3054                }
3055            }
3056            
3057            // Initialize localization (async)
3058            (async function() {
3059                try {
3060                    await localizationService.initialize(user.id);
3061                    
3062                    // Fetch language from API first (at every app start)
3063                    const apiLanguage = await fetchUserLanguage();
3064                    
3065                    // Determine which language to use
3066                    let languageToUse = null;
3067                    
3068                    if (apiLanguage) {
3069                        // Use language from API if available
3070                        const availableLangs = localizationService.getAvailableLanguages();
3071                        if (availableLangs.includes(apiLanguage)) {
3072                            languageToUse = apiLanguage;
3073                        } else {
3074                            console.warn(`[Language] Language "${apiLanguage}" from API is not available, using fallback`);
3075                        }
3076                    }
3077                    
3078                    // Fallback to stored language or Telegram language
3079                    if (!languageToUse) {
3080                        const storedLang = localizationService.getStoredLanguage();
3081                        if (storedLang) {
3082                            languageToUse = storedLang;
3083                        } else {
3084                            // First time user - use Telegram language
3085                            const availableLangs = localizationService.getAvailableLanguages();
3086                            if (availableLangs.includes(telegramLanguage)) {
3087                                languageToUse = telegramLanguage;
3088                            }
3089                        }
3090                    }
3091                    
3092                    // Set the determined language
3093                    if (languageToUse) {
3094                        localizationService.setLanguage(languageToUse);
3095                    }
3096                    
3097                    // Set default user name if not set
3098                    if (!user.name) {
3099                        user.name = t('user_default_name');
3100                    }
3101                    
3102                    // Initialize UI elements with localized text
3103                    const upgradeButtonText = document.querySelector('.upgrade-button-text');
3104                    if (upgradeButtonText) {
3105                        upgradeButtonText.textContent = t('button_upgrade_main');
3106                    }
3107                    
3108                    const creationStatusBtn = document.getElementById('creation-status-btn');
3109                    if (creationStatusBtn) {
3110                        creationStatusBtn.textContent = t('button_ok');
3111                    }
3112                    
3113                    // Initialize creation summary cards with localized "Loading..." text
3114                    const summaryCardTitles = document.querySelectorAll('.summary-card-title');
3115                    summaryCardTitles.forEach(title => {
3116                        if (title.textContent === 'Loading...') {
3117                            title.textContent = t('creation_loading');
3118                        }
3119                    });
3120                    
3121                    console.log('[App] Localization initialized successfully');
3122                    
3123                    // Update modal texts after language is set (with delays to ensure modals are created)
3124                    setTimeout(() => {
3125                        if (typeof updateModalTexts === 'function') {
3126                            updateModalTexts();
3127                        }
3128                    }, 100);
3129                    // Also update after a longer delay to catch any modals created later
3130                    setTimeout(() => {
3131                        if (typeof updateModalTexts === 'function') {
3132                            updateModalTexts();
3133                        }
3134                    }, 500);
3135                } catch (error) {
3136                    console.error('[App] Failed to initialize localization:', error);
3137                    // Continue with fallback keys
3138                }
3139                
3140                // Initialize store and render UI (always, regardless of localization success)
3141                await initializeStore();
3142                switchPage(currentPage);
3143            })();
3144            
3145            // Девушки теперь загружаются из API
3146            let girlsData = [];
3147            let girlsPhotos = new Map(); // Кэш для фотографий девушек
3148            let photosLoaded = false; // Флаг для отслеживания загрузки фотографий
3149            let girlsDataLoaded = false; // Флаг для отслеживания загрузки данных девушек
3150            let girlsPhotosLoaded = false; // Флаг для отслеживания загрузки фотографий девушек
3151            let girlsShopRendered = false; // Флаг для отслеживания рендеринга магазина девушек
3152
3153
3154
3155            // Данные для паков теперь будут загружаться
3156            let lollipopPacks = [];
3157
3158            // --- DOM Elements ---
3159            const userInfoEl = document.getElementById('page-title');
3160            const userBalanceEl = document.getElementById('user-balance');
3161            const navButtons = {
3162                girls: document.getElementById('nav-girls'),
3163                lollipops: document.getElementById('nav-lollipops')
3164            };
3165            const pages = {
3166                girls: document.getElementById('page-girls'),
3167                lollipops: document.getElementById('page-lollipops'),
3168                'character-creation': document.getElementById('page-character-creation'),
3169                'character-creation-step2': document.getElementById('page-character-creation-step2'),
3170                'character-creation-step3': document.getElementById('page-character-creation-step3'),
3171                'character-creation-step4': document.getElementById('page-character-creation-step4'),
3172                'character-creation-step5': document.getElementById('page-character-creation-step5'),
3173                'character-creation-step6': document.getElementById('page-character-creation-step6'),
3174                'character-creation-summary': document.getElementById('page-character-creation-summary')
3175            };
3176            const shops = {
3177                girls: document.getElementById('girls-shop'),
3178                lollipops: document.getElementById('lollipops-shop')
3179            };
3180
3181             // --- State ---
3182             let currentStyle = 'real'; // Всегда используем стиль 'real'
3183             let selectedPackId = null; // ID выбранного пака
3184             let lastSelectedPackId = null; // ID последней выбранной карточки для восстановления
3185             let isPaymentInProgress = false; // Защита от двойного открытия инвойса
3186             let selectedPaymentMethod = 'card'; // Выбранный метод оплаты: 'stars' или 'card'
3187             
3188            // Ссылки на Tribute для оплаты картой по подпискам (по языкам интерфейса)
3189            const CARD_PAYMENT_LINKS_CONFIG = {
3190                default: {
3191                    bronze: 'https://t.me/tribute/app?startapp=sCus',
3192                    silver: 'https://t.me/tribute/app?startapp=sCuq',
3193                    gold: 'https://t.me/tribute/app?startapp=sCeP',
3194                    platinum: 'https://t.me/tribute/app?startapp=sEGR'
3195                },
3196                ru: {
3197                    bronze: 'https://t.me/tribute/app?startapp=sFvs',
3198                    silver: 'https://t.me/tribute/app?startapp=sFvr',
3199                    gold: 'https://t.me/tribute/app?startapp=sFvq',
3200                    platinum: 'https://t.me/tribute/app?startapp=sFvx'
3201                }
3202            };
3203
3204            function getActiveLanguageCode() {
3205                // Always return 'en'
3206                return 'en';
3207            }
3208
3209            function getCardPaymentLinksForLanguage() {
3210                const langCode = getActiveLanguageCode();
3211                if (CARD_PAYMENT_LINKS_CONFIG[langCode]) {
3212                    return CARD_PAYMENT_LINKS_CONFIG[langCode];
3213                }
3214                return CARD_PAYMENT_LINKS_CONFIG.default;
3215            }
3216            
3217            // Стиль всегда 'real', функция получения стиля с сервера удалена
3218            
3219            function getInitialPage() {
3220                const urlParams = new URLSearchParams(window.location.search);
3221                const page = urlParams.get('page');
3222                if (page && ['girls', 'lollipops'].includes(page)) {
3223                    return page;
3224                }
3225                return 'girls';
3226            }
3227            
3228            function getHighlightId() {
3229                const urlParams = new URLSearchParams(window.location.search);
3230                return urlParams.get('highlight');
3231            }
3232            
3233            function highlightCard(id, type) {
3234                console.log('highlightCard called:', { id, type, highlightId, highlightShown });
3235                if (!highlightId || highlightId !== id || highlightShown) {
3236                    console.log('highlightCard: early return - no highlightId, id mismatch, or already shown');
3237                    return;
3238                }
3239                
3240                // Находим карточку по id
3241                let card = null;
3242                if (type === 'pack') {
3243                    // Для паков ищем по имени пака
3244                    const pack = lollipopPacks.find(p => p.name === id);
3245                    console.log('Looking for pack:', id, 'Found pack:', pack);
3246                    if (pack) {
3247                        card = document.querySelector(`[data-id="${pack.id}"][data-type="pack"]`);
3248                        console.log('Looking for pack card:', `[data-id="${pack.id}"][data-type="pack"]`, card);
3249                    }
3250                }
3251                
3252                if (card) {
3253                    console.log('Card found, adding highlight');
3254                    // Устанавливаем флаг, что подсветка была показана
3255                    highlightShown = true;
3256                    
3257                    // Добавляем класс подсветки
3258                    card.classList.add('highlight');
3259                    
3260                    // Прокручиваем к карточке
3261                    card.scrollIntoView({ 
3262                        behavior: 'smooth', 
3263                        block: 'center' 
3264                    });
3265                    
3266                    // Убираем подсветку через 3 секунды
3267                    setTimeout(() => {
3268                        card.classList.remove('highlight');
3269                    }, 3000);
3270                } else {
3271                    console.log('Card not found');
3272                }
3273            }
3274
3275            let currentPage = getInitialPage();
3276            let highlightId = getHighlightId();
3277            let highlightShown = false; // Флаг для отслеживания показа подсветки
3278
3279            // --- Functions ---
3280
3281            // Обёртка для fetch
3282            async function debugFetch(url, options) {
3283                try {
3284                    const resp = await fetch(url, options);
3285                    const text = await resp.clone().text();
3286                    // Пытаемся вернуть JSON, если возможно
3287                    try { return { resp, json: JSON.parse(text) }; } catch { return { resp, text }; }
3288                } catch (e) {
3289                    throw e;
3290                }
3291            }
3292
3293            // API base URL
3294            const API_BASE = 'https://api.candyaitunnel.xyz';
3295
3296            // Получение баланса валюты
3297            async function fetchCurrency() {
3298                try {
3299                    const { resp, json: data } = await debugFetch(`${API_BASE}/currency?user=${user.id}`);
3300                    if (!resp.ok) throw new Error();
3301                    user.lollipops = data.HardCurrency || 0;
3302                    user.energy = data.SoftCurrency || 0;
3303                    user.gifts = data.Gifts || 0;
3304                } catch {
3305                    user.lollipops = 0;
3306                    user.energy = 0;
3307                    user.gifts = 0;
3308                }
3309            }
3310
3311            // Функция для показа загрузочного экрана
3312            function showLoadingScreen() {
3313                const loadingScreen = document.getElementById('loading-screen');
3314                if (loadingScreen) {
3315                    loadingScreen.classList.remove('hidden');
3316                }
3317            }
3318
3319            // Функция для скрытия загрузочного экрана
3320            function hideLoadingScreen() {
3321                const loadingScreen = document.getElementById('loading-screen');
3322                if (loadingScreen) {
3323                    loadingScreen.classList.add('hidden');
3324                    setTimeout(() => {
3325                        loadingScreen.remove();
3326                    }, 500);
3327                }
3328            }
3329
3330            // Функция для принудительного обновления данных девушек (например, после покупки)
3331            async function refreshGirlsData() {
3332                try {
3333                    const { resp, json } = await debugFetch(`${API_BASE}/girls?user=${user.id}`);
3334                    if (resp.ok) {
3335                        girlsData = json;
3336                        girlsDataLoaded = true; // Устанавливаем флаг
3337                        girlsShopRendered = false; // Сбрасываем флаг рендеринга чтобы пересоздать карточки
3338                        console.log('Refreshed girls data:', girlsData);
3339                        return true;
3340                    }
3341                } catch (error) {
3342                    console.error('Failed to refresh girls data:', error);
3343                }
3344                return false;
3345            }
3346
3347            // Функция для загрузки фотографий девушек
3348            async function loadGirlsPhotos() {
3349                // Не загружаем фотографии повторно если они уже загружены
3350                if (girlsPhotosLoaded) {
3351                    console.log('Girls photos already loaded, skipping...');
3352                    return;
3353                }
3354                
3355                try {
3356                    const { resp, json } = await debugFetch(`${API_BASE}/photos?user=${user.id}`);
3357                    if (resp.ok && Array.isArray(json)) {
3358                        // Очищаем кэш и загружаем новые фотографии
3359                        girlsPhotos.clear();
3360                        json.forEach(photoData => {
3361                            if (photoData.GirlId !== undefined && photoData.Photo) {
3362                                // Используем GirlId как ключ для кэша
3363                                girlsPhotos.set(photoData.GirlId, photoData.Photo);
3364                            }
3365                        });
3366                        girlsPhotosLoaded = true; // Устанавливаем флаг после успешной загрузки
3367                        console.log('Loaded photos for girls:', girlsPhotos.size);
3368                        
3369                        // Обновляем отображение карточек с фотографиями
3370                        updateGirlCardsWithPhotos();
3371                    }
3372                } catch (error) {
3373                    console.error('Failed to load girls photos:', error);
3374                }
3375            }
3376
3377            // Функция для принудительного обновления фотографий девушек
3378            async function refreshGirlsPhotos() {
3379                girlsPhotosLoaded = false; // Сбрасываем флаг
3380                girlsPhotos.clear(); // Очищаем кэш
3381                await loadGirlsPhotos(); // Загружаем заново
3382            }
3383
3384            // Функция для обновления карточек девушек с фотографиями
3385            function updateGirlCardsWithPhotos() {
3386                const girlCards = document.querySelectorAll('.girl-card');
3387                girlCards.forEach(card => {
3388                    const girlName = card.dataset.id; // dataset.id содержит GirlName
3389                    const loadingContainer = card.querySelector('.photo-loading-container');
3390                    
3391                    // Находим девушку в данных по имени чтобы получить GirlId
3392                    const girl = girlsData.find(g => g.GirlName === girlName);
3393                    if (!girl) return;
3394                    
3395                    if (loadingContainer && girlsPhotos.has(girl.GirlId)) {
3396                        const photo = girlsPhotos.get(girl.GirlId);
3397                        
3398                        // Создаем элемент изображения
3399                        const img = document.createElement('img');
3400                        img.className = 'item-card-image';
3401                        img.src = `data:image/jpeg;base64,${photo}`;
3402                        img.alt = girlName;
3403                        img.onerror = function() { 
3404                            this.onerror = null; 
3405                            this.src = `https://placehold.co/300x220/9C27B0/FFFFFF?text=${encodeURIComponent(girlName)}`; 
3406                        };
3407                        
3408                        // Заменяем контейнер загрузки на изображение
3409                        loadingContainer.parentNode.replaceChild(img, loadingContainer);
3410                    } else if (loadingContainer && !girlsPhotos.has(girl.GirlId)) {
3411                        // Если фотография не найдена, показываем placeholder
3412                        const img = document.createElement('img');
3413                        img.className = 'item-card-image';
3414                        img.src = `https://placehold.co/300x220/9C27B0/FFFFFF?text=${encodeURIComponent(girlName)}`;
3415                        img.alt = girlName;
3416                        
3417                        // Заменяем контейнер загрузки на placeholder
3418                        loadingContainer.parentNode.replaceChild(img, loadingContainer);
3419                    }
3420                });
3421                
3422                // Обновляем модальное окно если оно открыто
3423                updateModalPhotoIfOpen();
3424            }
3425            
3426            // Функция для обновления фотографии в модальном окне если оно открыто
3427            function updateModalPhotoIfOpen() {
3428                const girlModal = document.getElementById('girl-modal');
3429                if (!girlModal || girlModal.style.display === 'none') return;
3430                
3431                const girlModalPhotoLoading = girlModal.querySelector('.girl-modal-photo-loading');
3432                const girlModalPhoto = girlModal.querySelector('.girl-modal-photo');
3433                
3434                if (!girlModalPhotoLoading || !girlModalPhoto) return;
3435                
3436                // Получаем имя девушки из модального окна
3437                const girlModalName = girlModal.querySelector('.girl-modal-name');
3438                if (!girlModalName) return;
3439                
3440                const girlName = girlModalName.textContent;
3441                const girl = girlsData.find(g => g.GirlName === girlName);
3442                if (!girl) return;
3443                
3444                // Для локальных девушек используем локальный файл
3445                if (Number(girl.GirlId) < 1000) {
3446                    girlModalPhoto.src = `Photos/${encodeURIComponent(girl.GirlName)}.jpg`;
3447                    girlModalPhoto.style.display = 'block';
3448                    girlModalPhotoLoading.style.display = 'none';
3449                }
3449 else if (girlsPhotos.has(girl.GirlId)) {
3450                    // Если фотография загрузилась, показываем её
3451                    const photo = girlsPhotos.get(girl.GirlId);
3452                    girlModalPhoto.src = `data:image/jpeg;base64,${photo}`;
3453                    girlModalPhoto.style.display = 'block';
3454                    girlModalPhotoLoading.style.display = 'none';
3455                }
3456            }
3457
3458            // Инициализация ленивой загрузки локальных фото девушек в списке
3459            function initLocalGirlLazyLoading() {
3460                try {
3461                    const images = document.querySelectorAll('img.lazy-local[data-src]');
3462                    if (!images || images.length === 0) return;
3463                    // Фолбэк: если IntersectionObserver недоступен — сразу выставляем src
3464                    if (!('IntersectionObserver' in window)) {
3465                        images.forEach(img => {
3466                            if (!img.getAttribute('src')) {
3467                                img.setAttribute('src', img.getAttribute('data-src'));
3468                                img.removeAttribute('data-src');
3469                            }
3470                        });
3471                        return;
3472                    }
3473                    const observer = new IntersectionObserver((entries, obs) => {
3474                        entries.forEach(entry => {
3475                            if (entry.isIntersecting) {
3476                                const img = entry.target;
3477                                const ds = img.getAttribute('data-src');
3478                                if (ds && !img.getAttribute('src')) {
3479                                    img.setAttribute('src', ds);
3480                                    img.removeAttribute('data-src');
3481                                }
3482                                obs.unobserve(img);
3483                            }
3484                        });
3485                    }, { rootMargin: '200px 0px', threshold: 0.01 });
3486                    images.forEach(img => observer.observe(img));
3487                } catch {}
3488            }
3489
3490            // Главная асинхронная функция для инициализации магазина
3491            async function initializeStore() {
3492                // Показываем загрузочный экран
3493                showLoadingScreen();
3494
3495                await fetchCurrency();
3496                // Загружаем девушек только если они еще не загружены
3497                if (!girlsDataLoaded) {
3498                    console.log('Loading girls data from API...');
3499                    try {
3500                        const { resp, json } = await debugFetch(`${API_BASE}/girls?user=${user.id}`);
3501                        if (!resp.ok) throw new Error(`HTTP error! status: ${resp.status}`);
3502                        girlsData = json;
3503                        girlsDataLoaded = true; // Устанавливаем флаг после успешной загрузки
3504
3505                        // Debug logging to check girls data
3506                        console.log('Loaded girls data:', girlsData);
3507                        girlsData.forEach((girl, index) => {
3508                            console.log(`Girl ${index}:`, girl.GirlName, 'Photo:', girl.Photo ? girl.Photo.substring(0, 50) + '...' : 'No photo');                                                                                                                
3509                        });
3510                    } catch (error) {
3511                        girlsData = [];
3512                        girlsDataLoaded = false; // Сбрасываем флаг при ошибке
3513                        tg.showAlert(t('error_loadCharacters'));
3514                    }
3515                } else {
3516                    console.log('Using cached girls data, skipping API call');
3517                }
3518
3519                // Скрываем загрузочный экран после загрузки девушек
3520                hideLoadingScreen();
3521
3522                // Загружаем фотографии девушек в фоновом режиме только если данные девушек были загружены и фотографии еще не загружены
3523                if (girlsDataLoaded && !girlsPhotosLoaded) {
3524                    loadGirlsPhotos();
3525                }
3526
3527                // Загружаем продукты (паки валют)
3528                try {
3529                    const { resp, json: apiProducts } = await debugFetch(`${API_BASE}/products?user=${user.id}`);
3530                    if (!resp.ok) {
3531                        throw new Error(`HTTP error! status: ${resp.status}`);
3532                    }
3533                    lollipopPacks = apiProducts
3534                        .filter(product => {
3535                            // Accept bronze/silver/gold packs (platinum скрываем)
3536                            const name = String(product.Name || '').toLowerCase();
3537                            return name.includes('bronze') || name.includes('silver') || name.includes('gold');
3538                        })
3539                        .map((product, index) => {
3540                            const name = String(product.Name || '');
3541                            return {
3542                                id: 201 + index,
3543                                name: name,
3544                                stars: product.Price,
3545                                lollipops: 0,
3546                                icon: '⭐',
3547                                image: `https://placehold.co/150x120/FFC107/FFFFFF?text=Unlimited%20Messages&font-size=16&font-weight=bold`
3548                            };
3549                        });
3550                } catch (error) {
3551                    lollipopPacks = [];
3552                    tg.showAlert(t('error_loadProducts'));
3553                }
3554                updateUI();
3555            }
3556
3557            function updateUI() {
3558                // Название вкладки
3559                let title = '';
3560                if (currentPage === 'girls') title = t('page_title_characters');
3561                else if (currentPage === 'lollipops') title = t('page_title_subscriptions');
3562                userInfoEl.textContent = title;
3563                
3564                // Показываем переключатель оплаты только на странице подписок
3565                const paymentSwitcher = document.getElementById('payment-switcher');
3566                if (paymentSwitcher) {
3567                    paymentSwitcher.style.display = currentPage === 'lollipops' ? 'flex' : 'none';
3568                }
3569                
3570                // На странице подписок скрываем подарок и панель валют
3571                if (currentPage === 'lollipops') {
3572                    userBalanceEl.innerHTML = '';
3573                } else {
3574                    userBalanceEl.innerHTML = `
3575                        <button id="daily-bonus-btn" class="daily-bonus-btn" title="Daily Bonus"><span class="gift-emoji">🎁</span></button>
3576                        <div class="currency-panel">
3577                            <div class="currency-item">
3578                                <span class="currency-icon">💬</span>
3579                                <span class="currency-value">${user.energy}</span>
3580                            </div>
3581                            <div class="currency-item">
3582                                <span class="currency-icon">🎁</span>
3583                                <span class="currency-value">${user.gifts}</span>
3584                            </div>
3585                            <div class="currency-item">
3586                                <span class="currency-icon">🍑</span>
3587                                <span class="currency-value">${user.lollipops}</span>
3588                            </div>
3589                            <button class="add-currency-btn">+</button>
3590                        </div>
3591                    `;
3592                }
3593                
3594                // Добавляем переключатель оплаты отдельно в header
3595                const header = document.querySelector('header');
3596                let existingSwitcher = document.getElementById('payment-switcher');
3597                if (existingSwitcher) {
3598                    existingSwitcher.remove();
3599                }
3600                
3601                if (currentPage === 'lollipops') {
3602                    const paymentSwitcher = document.createElement('div');
3603                    paymentSwitcher.className = 'payment-switcher';
3604                    paymentSwitcher.id = 'payment-switcher';
3605                    paymentSwitcher.innerHTML = `
3606                        <button class="payment-switcher-btn ${selectedPaymentMethod === 'stars' ? 'active' : ''}" data-method="stars">${t('payment_stars')}</button>
3607                        <button class="payment-switcher-btn ${selectedPaymentMethod === 'card' ? 'active' : ''}" data-method="card">${t('payment_card')}</button>
3608                    `;
3609                    header.insertBefore(paymentSwitcher, userBalanceEl);
3610                    
3611                    // Добавляем обработчики для переключателя оплаты
3612                    const paymentSwitcherBtns = paymentSwitcher.querySelectorAll('.payment-switcher-btn');
3613                    paymentSwitcherBtns.forEach(btn => {
3614                        btn.addEventListener('click', () => {
3615                            const method = btn.dataset.method;
3616                            selectedPaymentMethod = method;
3617                            
3618                            // Обновляем активное состояние кнопок
3619                            paymentSwitcherBtns.forEach(b => b.classList.remove('active'));
3620                            btn.classList.add('active');
3621                            
3622                            console.log('[Payment] Method switched to:', method);
3623                            
3624                            // Перерисовываем цены в карточках подписок
3625                            if (currentPage === 'lollipops') {
3626                                renderLollipopsShop();
3627                            }
3628                        });
3629                    });
3630                }
3631                
3632                // Добавляем обработчик события для кнопки с плюсиком (только если не на странице подписок)
3633                if (currentPage !== 'lollipops') {
3634                    const addCurrencyBtn = userBalanceEl.querySelector('.add-currency-btn');
3635                    if (addCurrencyBtn) {
3636                        addCurrencyBtn.addEventListener('click', () => switchPage('lollipops'));
3637                    }
3638                }
3639                
3640                
3641                // Re-bind daily bonus button and refresh state so wobble applies even before opening modal
3642                bindDailyBonusBtn();
3643                refreshDailyBonusState();
3644                renderGirlsShop();
3645                renderLollipopsShop();
3646                // После любого рендера пересчитываем высоту описания девушек
3647                if (currentPage === 'girls') {
3648                    setTimeout(() => adjustGirlDescriptions && adjustGirlDescriptions(), 0);
3649                    setTimeout(() => adjustGirlDescriptions && adjustGirlDescriptions(), 120);
3650                }
3651            }
3652
3653             function switchPage(pageName) {
3654                 currentPage = pageName;
3655                 Object.keys(pages).forEach(key => {
3656                     pages[key].classList.toggle('active', key === pageName);
3657                     if (navButtons[key]) {
3658                         navButtons[key].classList.toggle('active', key === pageName);
3659                     }
3660                 });
3661                 
3662                 // Скрываем/показываем навигацию для всех страниц создания персонажа
3663                 if (pageName.startsWith('character-creation')) {
3664                     document.body.classList.add('character-creation-active');
3665                 } else {
3666                     document.body.classList.remove('character-creation-active');
3667                 }
3668                 
3669                 // Hide/show navigation on lollipops page
3670                 if (pageName === 'lollipops') {
3671                     document.body.classList.add('lollipops-active');
3672                 } else {
3673                     document.body.classList.remove('lollipops-active');
3674                 }
3675                
3676                // Move back button into header on lollipops page; return it back otherwise
3677                (function relocateBackButton() {
3678                    const headerEl = document.querySelector('header');
3679                    const lollipopsPageEl = pages.lollipops;
3680                    const backBtnEl = document.getElementById('back-button');
3681                    if (!backBtnEl || !headerEl || !lollipopsPageEl) return;
3682                    if (pageName === 'lollipops') {
3683                        // Place before payment switcher (first in header)
3684                        headerEl.insertBefore(backBtnEl, headerEl.firstChild);
3685                        backBtnEl.style.display = 'flex';
3686                    } else {
3687                        lollipopsPageEl.insertBefore(backBtnEl, lollipopsPageEl.firstChild);
3688                        backBtnEl.style.display = 'none';
3689                    }
3690                })();
3691                 
3692                 // Скрываем кнопку Upgrade и описание если переключаемся не на страницу подписок
3693                 if (pageName !== 'lollipops') {
3694                     hideUpgradeButton();
3695                     hidePackDescription();
3696                     selectedPackId = null; // Сбрасываем только текущий выбор, но сохраняем lastSelectedPackId
3697                     const ut = document.getElementById('upgrade-text');
3698                     if (ut) ut.innerHTML = '';
3699                 }
3700                 
3701                 updateUI();
3702             }
3703
3704            // Функция переключения стиля удалена, всегда используется 'real'
3705
3706             // Функции для работы с выбором паков
3707            function togglePackSelection(card, packId) {
3708                console.log('togglePackSelection called:', { card, packId });
3709                
3710                 // Убираем выделение с других карточек
3711                 document.querySelectorAll('.pack-card').forEach(c => {
3712                     c.classList.remove('selected');
3713                     c.querySelector('.pack-checkbox').classList.remove('checked');
3714                 });
3715                 
3716                 // Выделяем текущую карточку
3717                 card.classList.add('selected');
3718                 card.querySelector('.pack-checkbox').classList.add('checked');
3719                 selectedPackId = packId;
3720                 lastSelectedPackId = packId; // Сохраняем выбранный ID
3721                 
3722                 // Показываем описание выбранного пака
3723                 showPackDescription(packId);
3724                 
3725                 // Обновляем текст над кнопкой Upgrade
3726                 updateUpgradeText(packId);
3727                 
3728                 // Показываем кнопку Upgrade
3729                 showUpgradeButton();
3730             }
3731
3732            function showUpgradeButton() {
3733                const upgradeSection = document.getElementById('upgrade-section');
3734                if (upgradeSection) {
3735                    upgradeSection.style.display = 'flex';
3736                    if (selectedPackId) {
3737                        updateUpgradeText(selectedPackId);
3738                    }
3739                }
3740            }
3741
3742            function hideUpgradeButton() {
3743                const upgradeSection = document.getElementById('upgrade-section');
3744                if (upgradeSection) {
3745                    upgradeSection.style.display = 'none';
3746                }
3747            }
3748
3749            function updateUpgradeText(packId) {
3750                const pack = lollipopPacks.find(p => String(p.id) === String(packId));
3751                const upgradeTextEl = document.getElementById('upgrade-text');
3752                
3753                if (pack && upgradeTextEl) {
3754                    let html = '';
3755                    const lname = pack.name.toLowerCase();
3756                    if (lname.includes('bronze')) {
3757                        html = `<div class="line">💬 ${t('subscription_feature_unlimitedMessages')}</div>`;
3758                    }
3758 else if (lname.includes('silver')) {
3759                        html = `<div class="line">💬 ${t('subscription_feature_unlimitedMessages')}</div>` +
3760                               '<div class="sep"></div>' +
3761                               `<div class="line">📷 ${t('subscription_feature_unlimitedPhotos')}</div>` +
3762                               '<div class="sep"></div>' +
3763                               `<div class="line">🧠 ${t('subscription_feature_customCharacters')}</div>`;
3764                    } else if (lname.includes('gold')) {
3765                        html = `<div class="line">💬 ${t('subscription_feature_unlimitedMessages')}</div>` +
3766                               '<div class="sep"></div>' +
3767                               `<div class="line">📷 ${t('subscription_feature_unlimitedPhotos')}</div>` +
3768                               '<div class="sep"></div>' +
3769                               `<div class="line">🔞 ${t('subscription_feature_createPhotos')} 🔞</div>` +
3770                               '<div class="sep"></div>' +
3771                               `<div class="line">🧠 ${t('subscription_feature_customCharacters')}</div>` +
3772                               '<div class="sep"></div>' +
3773                               `<div class="line">⚡ ${t('subscription_feature_fasterResponse')}</div>` +
3774                               '<div class="sep"></div>' +
3775                               `<div class="line">🎬 ${t('subscription_feature_customScenarios')}</div>` 
3776                    }
3776 else if (lname.includes('platinum')) {
3777                        html = `<div class="line">💬 ${t('subscription_feature_unlimitedMessages')}</div>` +
3778                               '<div class="sep"></div>' +
3779                               `<div class="line">📷 ${t('subscription_feature_unlimitedPhotos')}</div>` +
3780                               '<div class="sep"></div>' +
3781                               `<div class="line">🔞 ${t('subscription_feature_createPhotos')} 🔞</div>` +
3782                               '<div class="sep"></div>' +
3783                               `<div class="line">🧠 ${t('subscription_feature_customCharacters')}</div>` +
3784                               '<div class="sep"></div>' +
3785                               `<div class="line">⚡ ${t('subscription_feature_fasterResponse')}</div>` +
3786                               '<div class="sep"></div>' +
3787                               `<div class="line">🎬 ${t('subscription_feature_customScenarios')}</div>` 
3788                    } else {
3789                        html = `<div class="line">💬 ${t('subscription_feature_unlimitedMessages')}</div>`;
3790                    }
3791                    upgradeTextEl.innerHTML = html;
3792                }
3793            }
3794
3795             function showPackDescription(packId) {
3796                 const pack = lollipopPacks.find(p => String(p.id) === packId);
3797                 const descriptionEl = document.getElementById('pack-description');
3798                 
3799                 console.log('showPackDescription called:', { packId, pack, descriptionEl });
3800                 
3801                 if (pack && descriptionEl) {
3802                     // Определяем описание в зависимости от выбранного пака
3803                     let description = '';
3804                     if (pack.name.toLowerCase().includes('small')) {
3805                         description = '💬 Unlimited messaging';
3806                     } else if (pack.name.toLowerCase().includes('medium')) {
3807                         description = '💬 Unlimited messaging<br>🤳 Unlimited photos<br>📖 Create your scenarios';
3808                     } else {
3809                         description = '💬 Unlimited messaging<br>🤳 Unlimited photos<br>📖 Create your scenarios<br>🧑‍🤝‍🧑 Create your characters';
3810                     }
3811                     
3812                     descriptionEl.innerHTML = description;
3813                     descriptionEl.classList.add('show');
3814                     console.log('Description set:', description);
3815                 } else {
3816                     console.log('Pack or descriptionEl not found:', { pack, descriptionEl });
3817                 }
3818             }
3819
3820            function hidePackDescription() {
3821                const descriptionEl = document.getElementById('pack-description');
3822                if (descriptionEl) {
3823                    descriptionEl.classList.remove('show');
3824                }
3825            }
3826
3827            // Функция для покупки выбранного пака
3828            async function handlePackPurchase(pack) {
3829                if (isPaymentInProgress) { console.log('[Upgrade] payment already in progress'); return; }
3830                isPaymentInProgress = true;
3831                
3832                try {
3833                    if (selectedPaymentMethod === 'card') {
3834                        // Оплата картой - перенаправляем на соответствующую ссылку
3835                        const paymentLink = getCardPaymentLink(pack.name);
3836                        console.log('[Upgrade] Redirecting to card payment:', paymentLink);
3837                        window.open(paymentLink, '_blank');
3838                        isPaymentInProgress = false;
3839                        return;
3840                    }
3841                    
3842                    // Оплата звёздами - используем существующую логику
3843                    const invoiceUrl = `${API_BASE}/getInvoice?user=${user.id}&packName=${encodeURIComponent(pack.name)}`;
3844                    console.log('[Upgrade] requesting invoice:', invoiceUrl);
3845                    const { resp, json, text } = await debugFetch(invoiceUrl);
3846                    if (!resp.ok) {
3847                        tg.showAlert(t('error_paymentLink'));
3848                        isPaymentInProgress = false;
3849                        return;
3850                    }
3851                    // Try to extract link from various possible fields or raw string
3852                    let invoiceLink = null;
3853                    if (typeof json === 'string' && json) invoiceLink = json;
3854                    if (!invoiceLink && typeof text === 'string' && text) invoiceLink = text;
3855                    if (!invoiceLink && json && typeof json === 'object') {
3856                        invoiceLink = json.invoice_link || json.link || json.url || json.invoiceUrl || json.result || null;
3857                    }
3858
3859                    if (!invoiceLink) {
3860                        tg.showAlert('Payment link is missing.');
3861                        isPaymentInProgress = false;
3862                        return;
3863                    }
3864
3865                    // Open invoice natively. Не делаем фоллбек, чтобы избежать дублей
3866                    try {
3867                        await tg.openInvoice(invoiceLink);
3868                    } catch (e) {
3869                        console.log('[Upgrade] openInvoice error', e);
3870                        isPaymentInProgress = false;
3871                    }
3872                } catch (error) {
3873                    console.error('Error buying pack:', error);
3874                    tg.showAlert('Purchase error. Please try again later.');
3875                    isPaymentInProgress = false;
3876                }
3877            }
3878
3879            // Функция для форматирования имен вещей и паков
3880            function formatDisplayName(name, type) {
3881                if (!name) return '';
3882                
3883                let formattedName = name;
3884                
3885                if (type === 'pack') {
3886                    // Форматирование имен паков
3887                    const packNameMap = {
3888                        'starter_pack': 'Starter Pack',
3889                        'premium_pack': 'Premium Pack',
3890                        'vip_pack': 'VIP Pack',
3891                        'special_offer': 'Special Offer',
3892                        'limited_edition': 'Limited Edition',
3893                        'bundle_pack': 'Bundle Pack'
3894                    };
3895                    
3896                    // Проверяем точное совпадение
3897                    if (packNameMap[name]) {
3898                        formattedName = packNameMap[name];
3899                    } else {
3900                        // Если точного совпадения нет, форматируем по правилам
3901                        formattedName = name
3902                            .replace(/_/g, ' ') // Заменяем подчеркивания на пробелы
3903                            .split(' ')
3904                            .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
3905                            .join(' ');
3906                    }
3907                }
3908                
3909                return formattedName;
3910            }
3911
3912            // Вычисление цены за неделю в Stars: floor(stars/4) для месячных подписок, floor(stars/52) для годовой
3913            function computeWeeklyStars(stars, packName) {
3914                const total = Number(stars) || 0;
3915                const name = String(packName || '').toLowerCase();
3916                let divisor = 4; // по умолчанию для месячных подписок
3917                
3918                if (name.includes('platinum')) {
3919                    divisor = 52; // для годовой подписки
3920                }
3921                
3922                const weekly = Math.floor(total / divisor);
3923                return Math.max(1, weekly);
3924            }
3925
3926            // Получение ссылки для оплаты картой по типу подписки
3927            function getCardPaymentLink(packName) {
3928                const name = String(packName || '').toLowerCase();
3929                const links = getCardPaymentLinksForLanguage();
3930                if (name.includes('bronze')) {
3931                    return links.bronze;
3932                } else if (name.includes('silver')) {
3933                    return links.silver;
3934                } else if (name.includes('gold')) {
3935                    return links.gold;
3936                } else if (name.includes('platinum')) {
3937                    return links.platinum;
3938                } else {
3939                    return links.bronze; // fallback для неизвестных подписок
3940                }
3941            }
3942
3943            // Форматирование цены в зависимости от способа оплаты
3944            function formatPriceDisplay(stars, paymentMethod, packName) {
3945                const name = String(packName || '').toLowerCase();
3946                
3947                if (paymentMethod === 'card') {
3948                    // Для карты показываем фиксированные цены в долларах
3949                    let weeklyEuros;
3950                    if (name.includes('bronze')) {
3951                        weeklyEuros = 1.99;
3952                    } else if (name.includes('silver')) {
3953                        weeklyEuros = 3.99;
3954                    } else if (name.includes('gold')) {
3955                        weeklyEuros = 5.99;
3956                    } else if (name.includes('platinum')) {
3957                        weeklyEuros = 1.79;
3958                    } else {
3959                        weeklyEuros = 2.99; // fallback
3960                    }
3961                    const weeklyText = t('subscription_price_week').replace('{0}', `$${weeklyEuros}`);
3962                    return weeklyText;
3963                } else {
3964                    // Для звёзд показываем только звёзды за неделю
3965                    const weeklyStars = computeWeeklyStars(stars, packName);
3966                    const weeklyText = t('subscription_price_stars').replace('{0}', weeklyStars);
3967                    return weeklyText;
3968                }
3969            }
3970
3971            // Persisted chats counter per girl (50..800), stored in localStorage
3972            function getGirlChatsCount(girlName) {
3973                try {
3974                    const key = `girlChats:${girlName}`;
3975                    const saved = localStorage.getItem(key);
3976                    const val = Number(saved);
3977                    if (Number.isFinite(val) && val >= 50 && val <= 800) return val;
3978                    const generated = Math.floor(Math.random() * (800 - 50 + 1)) + 50;
3979                    localStorage.setItem(key, String(generated));
3980                    return generated;
3981                } catch {
3982                    // Fallback if storage is unavailable
3983                    return Math.floor(Math.random() * (800 - 50 + 1)) + 50;
3984                }
3985            }
3986
3987            function createCard(item, type) {
3988                let isPurchased = false;
3989                let canAfford = true;
3990                let price = '', itemName = '', buttonText = '', description = '', id = '', icon = '';
3991                let imageUrl = '';
3992
3993                if (type === 'girl') {
3994                    isPurchased = item.Bought;
3995                    canAfford = user.lollipops >= item.Price && !isPurchased;
3996                    price = item.Price;
3997                    itemName = item.GirlName;
3998                    buttonText = isPurchased ? 'Bought' : 'Buy';
3999                    description = item.DetailedDescription || item.Description || '';
4000                    id = item.GirlName;
4001                    icon = '🍬';
4002                    // Для девушек больше не используем поле Photo, так как фотографии загружаются отдельно
4003                    imageUrl = ''; // Будет заменено на индикатор загрузки
4004                    
4005                    // Debug logging for card creation
4006                    console.log('Creating card for girl:', itemName);
4007                } else if (type === 'pack') {
4008                    // Все паки теперь только за Telegram Stars
4009                    price = item.stars; // Цена в Telegram Stars
4010                    canAfford = true; // Для Hard валюты всегда доступно (оплата через Telegram)
4011                    
4012                    // Простое переименование паков
4013                    if (item.name.toLowerCase().includes('bronze')) {
4014                        itemName = t('subscription_bronze_app');
4015                    } else if (item.name.toLowerCase().includes('silver')) {
4016                        itemName = t('subscription_silver_app');
4017                    } else if (item.name.toLowerCase().includes('gold')) {
4018                        itemName = t('subscription_gold_app');
4019                    } else {
4020                        itemName = item.name;
4021                    }
4022                    
4023                    buttonText = 'Buy';
4024                    description = '';
4025                    id = item.id;
4026                    icon = '⭐'; // Всегда звёзды для паков
4027                    imageUrl = item.image || `https://placehold.co/300x220/FFC107/000000?text=${encodeURIComponent(itemName)}`;
4028                }
4029
4030                const card = document.createElement('div');
4031                card.className = 'item-card' + (type === 'girl' ? ' girl-card' : '');
4032                card.setAttribute('data-id', id);
4033                card.setAttribute('data-type', type);
4034                
4035                // Добавляем лейбл для девушек, если он есть
4036                const labelHtml = (type === 'girl' && item.Label && item.Label.trim() !== '') 
4037                    ? `<div class="girl-card-label">${item.Label}</div>` 
4038                    : '';
4039                
4040                if (type === 'pack') {
4041                    // Для паков создаем новую структуру с выбором
4042                    const priceText = formatPriceDisplay(item.stars, selectedPaymentMethod, item.name);
4043                    const icon = selectedPaymentMethod === 'card' ? '💳' : '⭐';
4044                    card.innerHTML = `
4045                        <div class="item-card-content">
4046                            <div class="item-name">${itemName}</div>
4047                            <div class="pack-price">${icon} ${priceText}</div>
4048                            <div class="pack-checkbox"></div>
4049                        </div>
4050                    `;
4051                } else {
4052                    // Для карточек персонажей создаем новую структуру
4053                    if (type === 'girl') {
4054                        const chatsCount = getGirlChatsCount(itemName);
4055                        
4056                        // Проверяем, загружена ли фотография
4057                        let photoHtml = '';
4058                        if (Number(item.GirlId) < 1000) {
4059                            // Для локальных девушек используем локальный файл и ленивую загрузку
4060                            const localPath = `Photos/${encodeURIComponent(itemName)}.jpg`;
4061                            photoHtml = `<img class="item-card-image lazy-local" data-src="${localPath}" alt="${itemName}" loading="lazy" onerror="this.onerror=null;this.src='https://placehold.co/300x220/9C27B0/FFFFFF?text=${encodeURIComponent(itemName)}'">`;
4062                        } else if (girlsPhotosLoaded && girlsPhotos.has(item.GirlId)) {
4063                            // Если фото уже загружено из API, показываем его
4064                            const photo = girlsPhotos.get(item.GirlId);
4065                            photoHtml = `<img class="item-card-image" src="data:image/jpeg;base64,${photo}" alt="${itemName}" onerror="this.onerror=null;this.src='https://placehold.co/300x220/9C27B0/FFFFFF?text=${encodeURIComponent(itemName)}'">`;
4066                        } else {
4067                            // Если фото еще не загружено, показываем индикатор загрузки
4068                            photoHtml = `
4069                                <div class="photo-loading-container">
4070                                    <div class="photo-loading-spinner"></div>
4071                                </div>
4072                            `;
4073                        }
4074                        
4075                        card.innerHTML = `
4076                            ${labelHtml}
4077                            ${photoHtml}
4078                            <div class="item-card-content">
4079                                <div class="item-name">${itemName}</div>
4080                                <div class="item-desc">${description}</div>
4081                                <div class="girl-chats-label">${chatsCount}k ${t('character_chats')}</div>
4082                                <div class="girl-relationship-level">${item.CurrentLoyaltyLevel || t('character_unknown')}</div>
4083                            </div>
4084                        `;
4085                    } else {
4086                        // Для остальных карточек оставляем старую структуру
4087                        card.innerHTML = `
4088                            ${labelHtml}
4089                            <img class="item-card-image" src="${imageUrl}" alt="${itemName}" onerror="this.onerror=null;this.src='https://placehold.co/300x220/9C27B0/FFFFFF?text=${encodeURIComponent(itemName)}'">
4090                            <div class="item-card-title-overlay">
4091                                <span class="item-card-title-text">${itemName}</span>
4092                            </div>
4093                            <div class="item-card-content">
4094                                <div class="item-desc">${description}</div>
4095                            </div>
4096                        `;
4097                    }
4098                }
4099                if (type === 'pack') {
4100                    card.classList.add('pack-card');
4101                    // Добавляем обработчик клика для выбора карточки
4102                    card.addEventListener('click', () => {
4103                        togglePackSelection(card, id);
4104                    });
4105                } else if (!isPurchased) {
4106                    card.classList.add('not-bought');
4107                    card.style.cursor = 'default';
4108                }
4109                
4110                // Добавляем обработчик клика для карточек девушек
4111                if (type === 'girl') {
4112                    card.classList.add('girl-card-clickable');
4113                    card.style.cursor = 'pointer';
4114                    card.onclick = function() {
4115                        // Передаем объект девушки напрямую, а не ищем по имени
4116                        openGirlModal(item);
4117                    };
4118                }
4119                
4120                return card;
4121            }
4122
4123            function renderGirlsShop() {
4124                // Если магазин уже отрендерен, не пересоздаем карточки
4125                if (girlsShopRendered) {
4126                    console.log('Girls shop already rendered, skipping...');
4127                    return;
4128                }
4129                
4130                shops.girls.innerHTML = '';
4131                // Add create-character card on top
4132                const createCardEl = document.createElement('div');
4133                createCardEl.className = 'create-card';
4134                createCardEl.innerHTML = `<button class="plus-btn">+</button><div class="label">${t('character_create')}</div>`;                                                                  
4135                const plusBtn = createCardEl.querySelector('.plus-btn');
4136                createCardEl.addEventListener('click', async () => {
4137                    // Show loading on the button while checking subscription
4138                    if (plusBtn) {
4139                        plusBtn.classList.add('loading');
4140                        plusBtn.setAttribute('disabled', 'true');
4141                    }
4142                    try {
4143                        const subscriptionResponse = await fetch(`${API_BASE}/subscription?user=${user.id}`);
4144                        const subscriptionStatusRaw = await subscriptionResponse.text();
4145                        const subscriptionStatus = subscriptionStatusRaw
4146                            .trim()
4147                            .replace(/^\"|\"$/g, '')
4148                            .toLowerCase();
4149                        if (subscriptionStatus === 'none' || subscriptionStatus === 'bronze') {
4150                            // Update texts in case language changed
4151                            if (typeof updateModalTexts === 'function') {
4152                                updateModalTexts();
4153                            }
4154                            const createModalBlurEl = document.getElementById('create-modal-blur');
4155                            const createModalEl = document.getElementById('create-modal');
4156                            if (createModalBlurEl && createModalEl) {
4157                                createModalBlurEl.style.display = 'block';
4158                                createModalEl.style.display = 'block';
4159                            }
4160                            return;
4161                        }
4162                        // Allow Silver, Gold, Platinum to proceed
4163                        if (subscriptionStatus === 'silver' || subscriptionStatus === 'gold' || subscriptionStatus === 'platinum') {
4164                            openCreateModal();
4165                            return;
4166                        }
4167                        // Fallback: if unexpected status, show upgrade modal
4168                        // Update texts in case language changed
4169                        if (typeof updateModalTexts === 'function') {
4170                            updateModalTexts();
4171                        }
4172                        const createModalBlurEl = document.getElementById('create-modal-blur');
4173                        const createModalEl = document.getElementById('create-modal');
4174                        if (createModalBlurEl && createModalEl) {
4175                            createModalBlurEl.style.display = 'block';
4176                            createModalEl.style.display = 'block';
4177                        }
4178                    } catch (e) {
4179                        console.error('Error checking subscription for create card:', e);
4180                        // Update texts in case language changed
4181                        if (typeof updateModalTexts === 'function') {
4182                            updateModalTexts();
4183                        }
4184                        const createModalBlurEl = document.getElementById('create-modal-blur');
4185                        const createModalEl = document.getElementById('create-modal');
4186                        if (createModalBlurEl && createModalEl) {
4187                            createModalBlurEl.style.display = 'block';
4188                            createModalEl.style.display = 'block';
4189                        }
4190                    } finally {
4191                        if (plusBtn) {
4192                            plusBtn.classList.remove('loading');
4193                            plusBtn.removeAttribute('disabled');
4194                        }
4195                    }
4196                });
4197                shops.girls.appendChild(createCardEl);
4198
4199                // Safety check for girlsData
4200                if (!girlsData || !Array.isArray(girlsData) || girlsData.length === 0) {
4201                    shops.girls.innerHTML = '<p>Loading characters...</p>';
4202                    return;
4203                }
4204                girlsData.forEach(girl => shops.girls.appendChild(createCard(girl, 'girl')));
4205                
4206                // Отмечаем что магазин отрендерен
4207                girlsShopRendered = true;
4208            }
4209
4210
4211            
4212            function renderLollipopsShop() {
4213                shops.lollipops.innerHTML = '';
4214                if(lollipopPacks.length === 0) {
4215                    shops.lollipops.innerHTML = '<p>Loading products...</p>'
4216                    return;
4217                }
4218                lollipopPacks.forEach(pack => shops.lollipops.appendChild(createCard(pack, 'pack')));
4219                
4220                 // Восстанавливаем выбор или выбираем последнюю карточку по умолчанию
4221                 if (lollipopPacks.length > 0 && currentPage === 'lollipops') {
4222                     let packToSelect = null;
4223                     
4224                     // Если есть сохраненный выбор, пытаемся его восстановить
4225                     if (lastSelectedPackId) {
4226                         packToSelect = lollipopPacks.find(p => String(p.id) === String(lastSelectedPackId));
4227                         console.log('Trying to restore last selection:', lastSelectedPackId, 'Found pack:', packToSelect);
4228                     }
4229                     
4230                     // Если не удалось восстановить, выбираем последнюю карточку
4231                     if (!packToSelect) {
4232                         packToSelect = lollipopPacks[lollipopPacks.length - 1];
4233                         console.log('Auto-selecting last pack as fallback:', packToSelect);
4234                     }
4235                     
4236                     const cardToSelect = document.querySelector(`[data-id="${packToSelect.id}"][data-type="pack"]`);
4237                     console.log('Found card to select:', cardToSelect);
4238                     if (cardToSelect) {
4239                         console.log('Calling togglePackSelection for selection');
4240                         togglePackSelection(cardToSelect, packToSelect.id);
4241                     }
4242                 }
4243                
4244                // Подсвечиваем карточку если есть параметр highlight
4245                console.log('renderLollipopsShop: highlightId =', highlightId);
4246                if (highlightId) {
4247                    console.log('renderLollipopsShop: calling highlightCard with delay');
4248                    setTimeout(() => {
4249                        highlightCard(highlightId, 'pack');
4250                    }, 100);
4251                }
4252            }
4253            
4254            async function handleBuy(e) {
4255                const target = e.target;
4256                if (!target.classList.contains('buy-button')) return;
4257
4258                const id = target.dataset.id;
4259                const type = target.dataset.type;
4260
4261                if (type === 'girl') {
4262                    if (!girlsData || !Array.isArray(girlsData)) return;
4263                    const girl = girlsData.find(g => g.GirlName === id);
4264                    if (girl && !girl.Bought) {
4265                        // Покупка через API
4266                        try {
4267                            const { resp, json: buyResult } = await debugFetch(`${API_BASE}/buy?user=${user.id}&girlName=${encodeURIComponent(girl.GirlName)}`);
4268                            if (buyResult.Success) {
4269                                tg.HapticFeedback.notificationOccurred('success');
4270                                tg.showAlert(t('alert_alreadyBought'));
4271                                await fetchCurrency();
4272                                // Обновляем список девушек
4273                                await refreshGirlsData();
4274                                
4275                                // Обновляем кнопку в модальном окне, если оно открыто
4276                                const girlModalBtn = document.querySelector('.girl-modal-btn');
4277                                if (girlModalBtn && girlModalBtn.dataset.girlId === String(girl.GirlId)) {
4278                                    girlModalBtn.textContent = t('button_chat');
4279                                    girlModalBtn.disabled = false;
4280                                    girlModalBtn.onclick = () => {
4281                                        // Открываем модальное окно выбора истории
4282                                        storyModal.dataset.girlId = String(girl.GirlId);
4283                                        openStoryModal(girl.GirlName);
4284                                    };
4285                                }
4286                                
4287                                updateUI();
4288                            } else {
4289                                tg.HapticFeedback.notificationOccurred('error');
4290                                tg.showAlert('Недостаточно средств!');
4291                                await fetchCurrency();
4292                                updateUI();
4293                            }
4294                        } catch {
4295                            tg.showAlert('Ошибка при покупке. Попробуйте позже.');
4296                        }
4297                    } else if (girl && girl.Bought) {
4298                        tg.showAlert('Already bought!');
4299                    }
4300                } else if (type === 'pack') {
4301                    // Логика покупки паков теперь обрабатывается через кнопку Upgrade
4302                    // Эта ветка больше не используется
4303                }
4304                
4305                updateUI();
4306            }
4307
4308            // --- Init & Event Listeners ---
4309            navButtons.girls.addEventListener('click', () => switchPage('girls'));
4310
4311            navButtons.lollipops.addEventListener('click', () => switchPage('lollipops'));
4312            
4313            // Back button on lollipops page
4314            const backButton = document.getElementById('back-button');
4315            if (backButton) {
4316                backButton.addEventListener('click', () => switchPage('girls'));
4317            }
4318            
4319            // Обработчики для свитчера стилей удалены
4320            
4321            // Добавляем обработчик для кнопки с плюсиком в панели валют
4322            const addCurrencyBtn = document.querySelector('.add-currency-btn');
4323            if (addCurrencyBtn) {
4324                addCurrencyBtn.addEventListener('click', () => switchPage('lollipops'));
4325            }
4326            
4327            document.querySelector('.container').addEventListener('click', handleBuy);
4328            
4329            async function handleUpgradeAction() {
4330                try {
4331                    console.log('[Upgrade] action');
4332                    if (isPaymentInProgress) { console.log('[Upgrade] blocked: payment in progress'); return; }
4333                    // Если ничего не выбрано — выберем последнюю карточку по умолчанию
4334                    if (!selectedPackId && Array.isArray(lollipopPacks) && lollipopPacks.length > 0) {
4335                        const fallbackPack = lollipopPacks[lollipopPacks.length - 1];
4336                        const cardToSelect = document.querySelector(`[data-id="${fallbackPack.id}"][data-type="pack"]`);
4337                        if (cardToSelect) togglePackSelection(cardToSelect, fallbackPack.id);
4338                    }
4339                    if (!selectedPackId) {
4340                        tg.showAlert('Please select a subscription first.');
4341                        return;
4342                    }
4343                    const pack = lollipopPacks.find(p => String(p.id) === String(selectedPackId));
4344                    console.log('[Upgrade] selected pack:', pack);
4345                    if (pack) {
4346                        await handlePackPurchase(pack);
4347                    } else {
4348                        tg.showAlert('Subscription not found.');
4349                    }
4350                } catch (e) {
4351                    console.error('[Upgrade] handler error', e);
4352                }
4353            }
4354
4355            // Обработчик для кнопки Upgrade
4356            const upgradeButtonEl = document.getElementById('upgrade-button');
4357            if (upgradeButtonEl) {
4358                upgradeButtonEl.addEventListener('click', handleUpgradeAction);
4359            }
4360
4361            // Обновление баланса после успешной оплаты через Telegram Stars
4362            tg.onEvent('invoicePaid', async () => {
4363                await fetchCurrency();
4364                updateUI();
4365                isPaymentInProgress = false;
4366            });
4367            // Обработка закрытия окна оплаты (для обратной связи)
4368            tg.onEvent('invoiceClosed', async (data) => {
4369                try {
4370                    if (data && data.status === 'paid') {
4371                        await fetchCurrency();
4372                        updateUI();
4373                    } else if (data && data.status === 'failed') {
4374                        tg.showAlert('Payment failed. Please try again.');
4375                    }
4376                } catch {}
4377                isPaymentInProgress = false;
4378            });
4379
4380            // --- Модальное окно девушки ---
4381            const girlModalBg = document.createElement('div');
4382            girlModalBg.id = 'girl-modal-bg';
4383            document.body.appendChild(girlModalBg);
4384            const girlModal = document.createElement('div');
4385            girlModal.id = 'girl-modal';
4386            girlModal.innerHTML = `
4387                <div class="girl-modal-inner">
4388                    <div class="girl-modal-photo-container">
4389                        <div class="girl-modal-photo-loading">
4390                            <div class="photo-loading-spinner"></div>
4391                        </div>
4392                        <img class="girl-modal-photo" src="" alt="" style="display: none;">
4393                    </div>
4394                    <div class="girl-modal-fade"></div>
4395                    <div class="girl-modal-content">
4396                        <div class="girl-modal-name"></div>
4397                        <div class="girl-modal-desc"></div>
4398                        <div class="girl-modal-loyalty">
4399                            <div class="girl-modal-loyalty-top">
4400                                <span class="girl-modal-points"></span>
4401                                <span class="girl-modal-upgrade"></span>
4402                            </div>
4403                            <div class="girl-modal-loyalty-bar">
4404                                <div class="girl-modal-loyalty-fill"></div>
4405                            </div>
4406                            <div class="girl-modal-loyalty-bottom">
4407                                <span class="girl-modal-loyalty-current"></span>
4408                                <span class="girl-modal-loyalty-next"></span>
4409                            </div>
4410                            <div class="girl-modal-loyalty-text"></div>
4411                        </div>
4412                        <div class="girl-modal-btns-row">
4413                            <button class="girl-modal-close" title="Close">
4414                                <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>
4415                            </button>
4416                            <button class="girl-modal-btn"></button>
4417                        </div>
4418                    </div>
4419                </div>
4420            `;
4421            document.body.appendChild(girlModal);
4422            const girlModalCloseBtn = girlModal.querySelector('.girl-modal-close');
4423            const girlModalPhoto = girlModal.querySelector('.girl-modal-photo');
4424            const girlModalName = girlModal.querySelector('.girl-modal-name');
4425            const girlModalDesc = girlModal.querySelector('.girl-modal-desc');
4426            const girlModalLoyaltyCurrent = girlModal.querySelector('.girl-modal-loyalty-current');
4427            const girlModalLoyaltyNext = girlModal.querySelector('.girl-modal-loyalty-next');
4428            const girlModalLoyaltyFill = girlModal.querySelector('.girl-modal-loyalty-fill');
4429            const girlModalLoyaltyText = girlModal.querySelector('.girl-modal-loyalty-text');
4430            const girlModalBtn = girlModal.querySelector('.girl-modal-btn');
4431            const girlModalPoints = girlModal.querySelector('.girl-modal-points');
4432            const girlModalUpgrade = girlModal.querySelector('.girl-modal-upgrade');
4433
4434            // --- Модальное окно выбора истории ---
4435            const storyModalBg = document.createElement('div');
4436            storyModalBg.id = 'story-modal-bg';
4437            storyModalBg.style.cssText = `
4438                position: fixed;
4439                left: 0; top: 0; right: 0; bottom: 0;
4440                z-index: 4000;
4441                background: rgba(0,0,0,0.7);
4442                display: none;
4443            `;
4444            document.body.appendChild(storyModalBg);
4445
4446            const storyModal = document.createElement('div');
4447            storyModal.id = 'story-modal';
4448            storyModal.style.cssText = `
4449                position: fixed;
4450                left: 50%; top: 50%;
4451                transform: translate(-50%, -50%);
4452                z-index: 4100;
4453                background: #131313;
4454                border-radius: 28px;
4455                box-shadow: 0 8px 40px 0 #000a;
4456                min-width: 300px;
4457                max-width: 90vw;
4458                padding: 32px 24px;
4459                display: none;
4460                flex-direction: column;
4461                align-items: stretch;
4462                border: 1.5px solid #212121;
4463            `;
4464            storyModal.innerHTML = `
4465                <div style="text-align: center; margin-bottom: 24px;">
4466                    <div style="font-size: 1.25em; font-weight: bold; color: #fff; margin-bottom: 8px;">Выберите историю</div>
4467                    <div style="color: #bfaed1; font-size: 1em;">Выберите историю для начала чата</div>
4468                </div>
4469                <div id="story-options" style="display: flex; flex-direction: column; gap: 16px;">
4470                    <button class="story-option" data-story="massage" style="
4471                        background: linear-gradient(90deg, #a084ee 0%, #d8b4fe 100%);
4472                        color: #fff;
4473                        border: none;
4474                        border-radius: 16px;
4475                        padding: 20px;
4476                        font-size: 1.1em;
4477                        font-weight: bold;
4478                        cursor: pointer;
4479                        transition: transform 0.2s, box-shadow 0.2s;
4480                        text-align: left;
4481                        display: flex;
4482                        align-items: center;
4483                        gap: 16px;
4484                    ">
4485                        <div style="
4486                            width: 48px;
4487                            height: 48px;
4488                            background: rgba(255, 255, 255, 0.2);
4489                            border-radius: 12px;
4490                            display: flex;
4491                            align-items: center;
4492                            justify-content: center;
4493                            font-size: 1.5em;
4494                        ">💆‍♀️</div>
4495                        <div>
4496                            <div style="font-weight: bold; margin-bottom: 4px;">История в массажке</div>
4497                            <div style="font-size: 0.9em; opacity: 0.8;">Начните чат с массажем</div>
4498                        </div>
4499                    </button>
4500                </div>
4501                <button class="story-modal-close" style="
4502                    position: absolute;
4503                    right: 16px; top: 16px;
4504                    background: #111;
4505                    color: #fff;
4506                    width: 40px;
4507                    height: 40px;
4508                    border-radius: 12px;
4509                    display: flex;
4510                    align-items: center;
4511                    justify-content: center;
4512                    cursor: pointer;
4513                    border: none;
4514                    font-weight: bold;
4515                    font-size: 1.2em;
4516                    transition: background 0.2s;
4517                ">✕</button>
4518            `;
4519            document.body.appendChild(storyModal);
4520
4521            const storyModalCloseBtn = storyModal.querySelector('.story-modal-close');
4522            const storyOptions = storyModal.querySelectorAll('.story-option');
4523
4524            // Функции для работы с модальным окном выбора истории
4525            function openStoryModal(girlName) {
4526                storyModalBg.style.display = 'block';
4527                storyModal.style.display = 'flex';
4528            }
4529
4530            function closeStoryModal() {
4531                storyModalBg.style.display = 'none';
4532                storyModal.style.display = 'none';
4533            }
4534
4535            // Обработчик выбора истории
4536            function handleStorySelection(storyType, girlId) {
4537                closeStoryModal();
4538                closeGirlModal();
4539                
4540                // Выполняем логику открытия чата (прошлый ф
4540ункционал кнопки "Chat")
4541                console.log('Sending request to /openchat for girlId:', girlId, 'with story:', storyType);
4542                
4543                if (!user.id || !girlId) {
4544                    console.error('Error: user.id or girlId is empty');
4545                    tg.showAlert('Error: insufficient data to open chat');
4546                    return;
4547                }
4548                
4549                // Функция для закрытия мини-аппа
4550                const closeMiniApp = () => {
4551                    console.log('Пытаемся закрыть мини-апп...');
4552                    
4553                    // Метод 1: Основной метод Telegram WebApp
4554                    try {
4555                        if (window.Telegram && window.Telegram.WebApp) {
4556                            window.Telegram.WebApp.close();
4557                            console.log('Мини-апп закрыт через window.Telegram.WebApp.close()');
4558                            return true;
4559                        }
4560                    } catch (e) {
4561                        console.log('window.Telegram.WebApp.close() не сработал:', e);
4562                    }
4563                    
4564                    // Метод 2: Через переменную tg
4565                    try {
4566                        if (tg && typeof tg.close === 'function') {
4567                            tg.close();
4568                            console.log('Мини-апп закрыт через tg.close()');
4569                            return true;
4570                        }
4571                    } catch (e) {
4572                        console.log('tg.close() не сработал:', e);
4573                    }
4574                    
4575                    // Метод 3: Попытка закрыть окно браузера
4576                    try {
4577                        window.close();
4578                        console.log('Попытка закрыть через window.close()');
4579                        return true;
4580                    } catch (e) {
4581                        console.log('window.close() не сработал:', e);
4582                    }
4583                    
4584                    // Метод 4: Попытка через Telegram Bot API
4585                    try {
4586                        if (window.Telegram && window.Telegram.WebApp && window.Telegram.WebApp.MainButton) {
4587                            window.Telegram.WebApp.MainButton.hide();
4588                            window.Telegram.WebApp.close();
4589                            console.log('Мини-апп закрыт через MainButton.hide() + close()');
4590                            return true;
4591                        }
4592                    } catch (e) {
4593                        console.log('MainButton метод не сработал:', e);
4594                    }
4595                    
4596                    console.log('Все методы закрытия не сработали');
4597                    return false;
4598                };
4599                
4600                // Отправляем запрос на сервер
4601                try {
4602                    console.log('Sending request to /openchat...');
4603                    
4604                    // Отправляем запрос без ожидания ответа (fire and forget)
4605                    fetch(`${API_BASE}/openchat?user=${user.id}&girlName=${encodeURIComponent(girlId)}`)
4606                        .then(response => {
4607                            console.log('Server response received:', response.status);
4608                            if (response.ok) {
4609                                tg.HapticFeedback.notificationOccurred('success');
4610                            } else {
4611                                tg.HapticFeedback.notificationOccurred('error');
4612                            }
4613                        })
4614                        .catch(error => {
4615                            console.error('Ошибка при отправке запроса:', error);
4616                            tg.HapticFeedback.notificationOccurred('error');
4617                        });
4618                    
4619                    // Сразу открываем ссылку на бота
4620                    console.log('Открываем ссылку на бота...');
4621                    try {
4622                        tg.openTelegramLink('https://t.me/CandyAIGirlsBot');
4623                    } catch (e) {
4624                        console.log('tg.openTelegramLink() не сработал:', e);
4625                    }
4626                    
4627                    // Закрываем мини-апп с небольшой задержкой
4628                    setTimeout(() => {
4629                        closeMiniApp();
4630                    }, 500);
4631                    
4632                } catch (error) {
4633                    console.error('Ошибка при обработке:', error);
4634                    tg.HapticFeedback.notificationOccurred('error');
4635                    
4636                    // В случае ошибки все равно пытаемся открыть ссылку и закрыть
4637                    try {
4638                        tg.openTelegramLink('https://t.me/CandyAIGirlsBot');
4639                    } catch (e) {
4640                        console.log('Не удалось открыть ссылку на бота:', e);
4641                    }
4642                    
4643                    // Закрываем мини-апп даже при ошибке
4644                    setTimeout(() => {
4645                        closeMiniApp();
4646                    }, 500);
4647                }
4648            }
4649
4650            // Добавляем обработчики событий для модального окна выбора истории
4651            storyModalCloseBtn.addEventListener('click', closeStoryModal);
4652            storyModalBg.addEventListener('click', closeStoryModal);
4653            
4654            storyOptions.forEach(option => {
4655                option.addEventListener('click', () => {
4656                    const storyType = option.dataset.story;
4657                    const girlId = storyModal.dataset.girlId;
4658                    handleStorySelection(storyType, girlId);
4659                });
4660                
4661                // Добавляем hover эффекты
4662                option.addEventListener('mouseenter', () => {
4663                    option.style.transform = 'scale(1.02)';
4664                    option.style.boxShadow = '0 4px 20px rgba(160, 132, 238, 0.3)';
4665                });
4666                
4667                option.addEventListener('mouseleave', () => {
4668                    option.style.transform = 'scale(1)';
4669                    option.style.boxShadow = 'none';
4670                });
4671            });
4672
4673            function openGirlModal(girl) {
4674                document.body.style.overflow = 'hidden';
4675
4676                // Debug logging to check photo data
4677                console.log('Opening modal for girl:', girl.GirlName);
4678
4679                // Получаем элементы модального окна
4680                const girlModalPhotoContainer = girlModal.querySelector('.girl-modal-photo-container');
4681                const girlModalPhotoLoading = girlModal.querySelector('.girl-modal-photo-loading');
4682                const girlModalPhoto = girlModal.querySelector('.girl-modal-photo');
4683
4684                // Используем локальную фотографию для GirlId < 1000, иначе из кэша/индикатор
4685                if (Number(girl.GirlId) < 1000) {
4686                    girlModalPhoto.src = `Photos/${encodeURIComponent(girl.GirlName)}.jpg`;
4687                    girlModalPhoto.style.display = 'block';
4688                    girlModalPhotoLoading.style.display = 'none';
4689                } else if (girlsPhotos.has(girl.GirlId)) {
4690                    const photo = girlsPhotos.get(girl.GirlId);
4691                    girlModalPhoto.src = `data:image/jpeg;base64,${photo}`;
4692                    girlModalPhoto.style.display = 'block';
4693                    girlModalPhotoLoading.style.display = 'none';
4694                } else {
4695                    // Показываем индикатор загрузки
4696                    girlModalPhotoLoading.style.display = 'flex';
4697                    girlModalPhoto.style.display = 'none';
4698                    girlModalPhoto.src = ''; // Очищаем src
4699                }
4700                
4701                girlModalPhoto.onerror = function() { 
4702                    this.onerror=null; 
4703                    this.src='https://placehold.co/300x220/9C27B0/FFFFFF?text='+encodeURIComponent(girl.GirlName); 
4704                };
4705                girlModalName.textContent = girl.GirlName;
4706                girlModalDesc.textContent = girl.DetailedDescription || '';
4707                
4708                // Устанавливаем атрибуты для идентификации девушки
4709                girlModalBtn.dataset.girlId = String(girl.GirlId);
4710                storyModal.dataset.girlId = String(girl.GirlId);
4711                
4712                // Обновляем строку лояльности
4713                const currentLoyalty = girl.CurrentLoyaltyPoints || 0;
4714                const maxLoyalty = girl.MaxLoyaltyPoints || 10;
4715                const loyaltyPercentage = maxLoyalty > 0 ? (currentLoyalty / maxLoyalty) * 100 : 0;
4716                
4717                // Top row: points (left) and upgrade (right)
4718                if (girlModalPoints) {
4719                    girlModalPoints.textContent = `${currentLoyalty} / ${maxLoyalty}`;
4720                }
4721                if (girlModalUpgrade) {
4722                    const giftsLeft = Number(user.gifts) || 0;
4723                    girlModalUpgrade.textContent = `🎁 Upgrade (${giftsLeft}) ⬆️`;
4724                    girlModalUpgrade.onclick = async () => {
4725                        // Optimistic UI update if user has gifts
4726                        const revert = { did: false, prevGifts: Number(user.gifts) || 0, prevPoints: null };
4727                        const giftsValueEl = document.querySelector('#user-balance .currency-panel .currency-item:nth-child(2) .currency-value');
4728                        const parsePoints = () => {
4729                            const txt = girlModalPoints && girlModalPoints.textContent ? girlModalPoints.textContent : '0 / 0';
4730                            const m = txt.match(/\s*(\d+)\s*\/\s*(\d+)\s*/);
4731                            if (!m) return { cur: 0, max: 0 };
4732                            return { cur: parseInt(m[1], 10) || 0, max: parseInt(m[2], 10) || 0 };
4733                        };
4734                        const applyPoints = (cur, max) => {
4735                            if (girlModalPoints) girlModalPoints.textContent = `${cur} / ${max}`;
4736                            const percent = max > 0 ? Math.min(100, Math.max(0, (cur / max) * 100)) : 0;
4737                            if (girlModalLoyaltyFill) girlModalLoyaltyFill.style.width = percent + '%';
4738                        };
4739                        const doOptimistic = () => {
4740                            if ((Number(user.gifts) || 0) <= 0) return false;
4741                            // save current
4742                            const { cur, max } = parsePoints();
4743                            revert.prevPoints = { cur, max };
4744                            // gifts--
4745                            user.gifts = Math.max(0, (Number(user.gifts) || 0) - 1);
4746                            if (giftsValueEl) giftsValueEl.textContent = String(user.gifts);
4747                            if (girlModalUpgrade) girlModalUpgrade.textContent = `🎁 Upgrade (${Number(user.gifts) || 0}) ⬆️`;
4748                            // points++ (cap at max)
4749                            const newCur = Math.min(max, cur + 1);
4750                            applyPoints(newCur, max);
4751                            // update girlsData cache
4752                            const idx = Array.isArray(girlsData) ? girlsData.findIndex(g => g.GirlName === girl.GirlName) : -1;
4753                            if (idx >= 0) {
4754                                const prev = girlsData[idx].CurrentLoyaltyPoints || 0;
4755                                girlsData[idx].CurrentLoyaltyPoints = Math.min(girlsData[idx].MaxLoyaltyPoints || 10, prev + 1);
4756                            }
4757                            revert.did = true;
4758                            return true;
4759                        };
4760                        const undoOptimistic = () => {
4761                            if (!revert.did) return;
4762                            // revert gifts
4763                            user.gifts = revert.prevGifts;
4764                            if (giftsValueEl) giftsValueEl.textContent = String(user.gifts);
4765                            if (girlModalUpgrade) girlModalUpgrade.textContent = `🎁 Upgrade (${Number(user.gifts) || 0}) ⬆️`;
4766                            // revert points
4767                            if (revert.prevPoints) applyPoints(revert.prevPoints.cur, revert.prevPoints.max);
4768                        };
4769                        // do optimistic update
4770                        doOptimistic();
4771                        try {
4772                            const url = `${API_BASE}/sendgift?user=${user.id}&girl=${encodeURIComponent(girl.GirlId)}`;
4773                            const { resp, json, text } = await debugFetch(url);
4774                            const norm = (v) => {
4775                                if (typeof v !== 'string') return '';
4776                                let s = v.trim().toLowerCase();
4777                                // strip single or double surrounding quotes if present
4778                                s = s.replace(/^['"]|['"]$/g, '');
4779                                return s;
4780                            };
4781                            let ok = false;
4782                            if (resp.ok) {
4783                                if (json) {
4784                                    if (typeof json === 'string') {
4785                                        const s = norm(json);
4786                                        ok = (s === 'success' || s === 'true');
4787                                    } else {
4788                                        ok = !!(json.success === true || json.Success === true || json.success === 'success' || json.Success === 'success');
4789                                    }
4790                                } else if (typeof text === 'string') {
4791                                    const s = norm(text);
4792                                    ok = (s === 'success' || s === 'true');
4793                                }
4794                            }
4795                            if (ok) {
4796                                // Refresh gifts and girl data
4797                                await fetchCurrency();
4798                                updateUI();
4799                                // Try to get updated girl data
4800                                try {
4801                                    const { resp: gResp, json: girlsJson } = await debugFetch(`${API_BASE}/girls?user=${user.id}`);
4802                                    if (gResp.ok && Array.isArray(girlsJson)) {
4803                                        girlsData = girlsJson;
4804                                        const updated = girlsData.find(g => g.GirlName === girl.GirlName) || girl;
4805                                        // Recompute modal fields
4806                                        const currentLoyalty = updated.CurrentLoyaltyPoints || 0;
4807                                        const maxLoyalty = updated.MaxLoyaltyPoints || 10;
4808                                        const loyaltyPercentage = maxLoyalty > 0 ? (currentLoyalty / maxLoyalty) * 100 : 0;
4809                                        if (girlModalPoints) girlModalPoints.textContent = `${currentLoyalty} / ${maxLoyalty}`;
4810                                        if (girlModalUpgrade) girlModalUpgrade.textContent = t('modal_girl_upgrade').replace('{0}', Number(user.gifts) || 0);
4811                                        if (girlModalLoyaltyCurrent) girlModalLoyaltyCurrent.textContent = updated.CurrentLoyaltyLevel || t('character_unknown');
4812                                        if (girlModalLoyaltyNext) girlModalLoyaltyNext.textContent = updated.NextLoyaltyLevel || t('character_unknown');
4813                                        if (girlModalLoyaltyFill) girlModalLoyaltyFill.style.width = loyaltyPercentage + '%';
4814                                    }
4815                                } catch {}
4816                                if (tg && tg.HapticFeedback) tg.HapticFeedback.notificationOccurred('success');
4817                            } else {
4818                                // revert optimistic UI on failure
4819                                undoOptimistic();
4820                                if (tg && tg.HapticFeedback) tg.HapticFeedback.notificationOccurred('error');
4821                            }
4822                        } catch (e) {
4823                            undoOptimistic();
4824                            if (tg && tg.HapticFeedback) tg.HapticFeedback.notificationOccurred('error');
4825                        }
4826                    };
4827                }
4828
4829                // Bottom row: current (left) and next (right)
4830                girlModalLoyaltyCurrent.textContent = girl.CurrentLoyaltyLevel || t('character_unknown');
4831                girlModalLoyaltyNext.textContent = girl.NextLoyaltyLevel || t('character_unknown');
4832                girlModalLoyaltyFill.style.width = loyaltyPercentage + '%';
4833                girlModalLoyaltyText.textContent = '';
4834                if (girl.Bought) {
4835                    girlModalBtn.textContent = t('button_chat');
4836                    girlModalBtn.disabled = false;
4837                    girlModalBtn.onclick = async () => {
4838                        try {
4839                            // Отправляем запрос для открытия чата (fire-and-forget)
4840                            fetch(`${API_BASE}/openchat?user=${user.id}&girlName=${encodeURIComponent(girl.GirlId)}`).catch(() => {});
4841                        } catch {}
4842                        // Открываем чат бота
4843                        try { tg.openTelegramLink('https://t.me/CandyAIGirlsBot'); } catch {}
4844                        // Закрываем мини-апп с небольшой задержкой
4845                        setTimeout(() => {
4846                            try { if (tg && typeof tg.close === 'function') tg.close(); } catch {}
4847                            try { window.close(); } catch {}
4848                        }, 300);
4849                    };
4850                } else {
4851                    girlModalBtn.innerHTML = `<span style=\"font-size:1.1em;\">${girl.Price} 🍬</span>`;
4852                    girlModalBtn.disabled = !user.lollipops || user.lollipops < girl.Price;
4853                    girlModalBtn.onclick = () => {
4854                        if (user.lollipops < girl.Price) {
4855                            closeGirlModal();
4856                            switchPage('lollipops');
4857                        } else {
4858                            // Покупка девушки
4859                            handleBuy({ target: { dataset: { id: girl.GirlName, type: 'girl' }, classList: { contains: () => true } } });
4860                        }
4861                    };
4862                }
4863                girlModalBg.style.display = 'block';
4864                girlModal.style.display = 'flex';
4865            }
4866            function closeGirlModal() {
4867                document.body.style.overflow = '';
4868                girlModalBg.style.display = 'none';
4869                girlModal.style.display = 'none';
4870            }
4871            girlModalCloseBtn.onclick = closeGirlModal;
4872            girlModalBg.onclick = closeGirlModal;
4873
4874            // --- Анимация scale только для карточек девушек ---
4875            document.addEventListener('mousedown', function(e) {
4876                if (!e.target || typeof e.target.closest !== 'function') return;
4877                const card = e.target.closest('.item-card');
4878                if (card && card.classList.contains('girl-card') && !e.target.closest('.buy-button')) {
4879                    card.classList.add('scaling');
4880                }
4881            });
4882            document.addEventListener('mouseup', function(e) {
4883                if (!e.target || typeof e.target.closest !== 'function') return;
4884                const card = e.target.closest('.item-card');
4885                if (card && card.classList.contains('girl-card')) card.classList.remove('scaling');
4886            });
4887            document.addEventListener('mouseleave', function(e) {
4888                if (!e.target || typeof e.target.closest !== 'function') return;
4889                const card = e.target.closest('.item-card');
4890                if (card && card.classList.contains('girl-card')) card.classList.remove('scaling');
4891            });
4892            document.addEventListener('touchstart', function(e) {
4893                if (!e.target || typeof e.target.closest !== 'function') return;
4894                const card = e.target.closest('.item-card');
4895                if (card && card.classList.contains('girl-card') && !e.target.closest('.buy-button')) {
4896                    card.classList.add('scaling');
4897                }
4898            }, {passive: true});
4899            document.addEventListener('touchend', function(e) {
4900                if (!e.target || typeof e.target.closest !== 'function') return;
4901                const card = e.target.closest('.item-card');
4902                if (card && card.classList.contains('girl-card')) card.classList.remove('scaling');
4903            });
4904
4905            // --- Автоматическое уменьшение шрифта описания, чтобы текст влезал ---
4906            function fitDescFont() {
4907                // Shrink only non-girl card descriptions
4908                document.querySelectorAll('.item-card:not(.girl-card) .item-desc').forEach(desc => {
4909                    desc.style.fontSize = '';
4910                    let size = 0.98;
4911                    const maxHeight = parseFloat(getComputedStyle(desc).lineHeight) * 2;
4912                    while (desc.scrollHeight > desc.clientHeight && size > 0.65) {
4913                        size -= 0.04;
4914                        desc.style.fontSize = size + 'em';
4915                    }
4916                });
4917            }
4918            // Вызываем после рендера карточек
4919            const origRenderGirlsShop = renderGirlsShop;
4920            renderGirlsShop = function() {
4921                origRenderGirlsShop();
4922                // Ensure girl's description uses stylesheet value
4923                document.querySelectorAll('.item-card.girl-card .item-desc').forEach(desc => {
4924                    desc.style.fontSize = '';
4925                });
4926                fitDescFont();
4927                // Пересчитываем высоту описания сразу и с небольшой задержкой (для загрузки изображений)
4928                if (typeof adjustGirlDescriptions === 'function') {
4929                    adjustGirlDescriptions();
4930                    setTimeout(adjustGirlDescriptions, 80);
4931                }
4932                // Инициализация ленивой загрузки для локальных фото
4933                if (typeof initLocalGirlLazyLoading === 'function') {
4934                    initLocalGirlLazyLoading();
4935                }
4936            };
4937 
4938            const origRenderLollipopsShop = renderLollipopsShop;
4939            renderLollipopsShop = function() { origRenderLollipopsShop(); fitDescFont(); };
4940
4941            // initializeStore and switchPage are now called after localization is ready (see above)
4942
4943            // --- Daily Bonus Modal ---
4944            const dailyBonusBlur = document.createElement('div');
4945            dailyBonusBlur.id = 'daily-bonus-blur';
4946            document.body.appendChild(dailyBonusBlur);
4947            const dailyBonusModal = document.createElement('div');
4948            dailyBonusModal.id = 'daily-bonus-modal';
4949            dailyBonusModal.innerHTML = `
4950                <button class="close-x" aria-label="${t('button_close')}">×</button>
4951                <div class="title">${t('modal_dailyBonus_title')}</div>
4952                <div class="claim-info">${t('modal_dailyBonus_info')}</div>
4953                <div class="claim-timer" id="daily-bonus-timer"></div>
4954                <button id="daily-claim-btn" class="btn btn-primary"><span>🎁</span> ${t('button_claim')}</button>
4955                <button id="daily-upgrade-btn" class="btn btn-secondary"><span>⚡</span> ${t('button_upgrade')}</button>
4956            `;
4957            document.body.appendChild(dailyBonusModal);
4958            const dailyClaimBtn = dailyBonusModal.querySelector('#daily-claim-btn');
4959            const dailyUpgradeBtn = dailyBonusModal.querySelector('#daily-upgrade-btn');
4960            const dailyCloseX = dailyBonusModal.querySelector('.close-x');
4961            const dailyTimerEl = dailyBonusModal.querySelector('#daily-bonus-timer');
4962            const getDailyBonusBtn = () => document.getElementById('daily-bonus-btn');
4963             let dailyIntervalId = null;
4964             let bonusClaimable = false;
4965
4966            function openDailyBonusModal() {
4967                // Update texts in case language changed
4968                if (typeof updateModalTexts === 'function') {
4969                    updateModalTexts();
4970                }
4971                dailyBonusBlur.style.display = 'block';
4972                dailyBonusModal.style.display = 'flex';
4973                document.body.style.overflow = 'hidden';
4974            }
4975            function closeDailyBonusModal() {
4976                dailyBonusBlur.style.display = 'none';
4977                dailyBonusModal.style.display = 'none';
4978                document.body.style.overflow = '';
4979            }
4980
4981            function formatHHMMSS(totalSeconds) {
4982                const sign = totalSeconds < 0 ? '-' : '';
4983                const secs = Math.max(0, Math.floor(totalSeconds));
4984                const h = String(Math.floor(secs / 3600)).padStart(2, '0');
4985                const m = String(Math.floor((secs % 3600) / 60)).padStart(2, '0');
4986                const s = String(secs % 60).padStart(2, '0');
4987                return `${sign}${h}:${m}:${s}`;
4988            }
4989
4990            async function refreshDailyBonusState() {
4991                try {
4992                    const { resp, text, json } = await debugFetch(`${API_BASE}/dailybonusremainingtime?user=${user.id}`);
4993                    if (!resp.ok) throw new Error('dailybonusremainingtime failed');
4994                    // Expect format like "-2.01:00:00.0007613" or "00:30:10.123"
4995                    // Parse sign and extract hh:mm:ss
4996                    let rawValue = undefined;
4997                    if (typeof text === 'string' && text.length > 0) {
4998                        rawValue = text;
4999                    } else if (typeof json === 'string') {
5000                        rawValue = json;
5001                    } else {
5002                        rawValue = '';
5003                    }
5004                    let raw = String(rawValue);
5005                    raw = raw.trim();
5006                    const isNegative = raw.startsWith('-');
5007                    const timePart = raw.replace(/^[+-]?/, '');
5008                    // Split by '.' to drop milliseconds
5009                    const main = timePart.split('.')[0];
5010                    // main can be d.hh:mm:ss or hh:mm:ss
5011                    let parts = main.split(':');
5012                    let hours = 0, minutes = 0, seconds = 0;
5013                    if (parts.length === 3) {
5014                        // Handle possible day as prefix in hours (d.hh)
5015                        const hPart = parts[0];
5016                        if (hPart.includes('.')) {
5017                            const [daysStr, hoursStr] = hPart.split('.');
5018                            hours = parseInt(daysStr, 10) * 24 + parseInt(hoursStr, 10);
5019                        } else {
5020                            hours = parseInt(hPart, 10);
5021                        }
5022                        minutes = parseInt(parts[1], 10);
5023                        seconds = parseInt(parts[2], 10);
5024                    }
5025                    const totalSeconds = (hours * 3600 + minutes * 60 + seconds) * (isNegative ? -1 : 1);
5026                    bonusClaimable = totalSeconds <= 0;
5027                    if (bonusClaimable) {
5028                        dailyTimerEl.textContent = '';
5029                        dailyClaimBtn.disabled = false;
5030                        const btn = getDailyBonusBtn();
5031                        if (btn) btn.classList.add('claimable', 'wobble');
5032                    } else {
5033                        dailyClaimBtn.disabled = true;
5034                        if (getDailyBonusBtn()) { getDailyBonusBtn().classList.remove('claimable'); getDailyBonusBtn().classList.remove('wobble'); }
5035                        // Show timer only if 0 < remaining <= 24h
5036                        if (totalSeconds > 0 && totalSeconds <= 86400) {
5037                            dailyTimerEl.textContent = formatHHMMSS(totalSeconds);
5038                        } else {
5039                            dailyTimerEl.textContent = '';
5040                        }
5041                        // Start countdown
5042                        if (dailyIntervalId) clearInterval(dailyIntervalId);
5043                        let remaining = totalSeconds;
5044                        dailyIntervalId = setInterval(() => {
5045                            remaining -= 1;
5046                            if (remaining <= 0) {
5047                                clearInterval(dailyIntervalId);
5048                                dailyIntervalId = null;
5049                                // When reaches zero, refresh to switch to claimable state and show 00:00:00
5050                                refreshDailyBonusState();
5051                            } else {
5052                                if (remaining > 0 && remaining <= 86400) {
5053                                    dailyTimerEl.textContent = formatHHMMSS(remaining);
5054                                } else {
5055                                    dailyTimerEl.textContent = '';
5056                                }
5057                            }
5058                        }, 1000);
5059                    }
5060                } catch (e) {
5061                    dailyTimerEl.textContent = '';
5062                    dailyClaimBtn.disabled = true;
5063                    if (getDailyBonusBtn()) { getDailyBonusBtn().classList.remove('claimable'); getDailyBonusBtn().classList.remove('wobble'); }
5064                }
5065            }
5066
5067            async function claimDailyBonus() {
5068                try {
5069                    const { resp, json, text } = await debugFetch(`${API_BASE}/claimdailybonus?user=${user.id}`);
5070                    const ok = resp.ok && ((typeof json === 'boolean' && json) || (typeof text === 'string' && text.trim().toLowerCase() === 'true'));
5071                    if (ok) {
5072                        dailyClaimBtn.disabled = true;
5073                        // Animation feedback
5074                        const anim = document.createElement('div');
5075                        anim.className = 'bonus-claimed-anim';
5076                        anim.textContent = '🎁 +10 Gifts';
5077                        document.body.appendChild(anim);
5078                        setTimeout(() => anim.remove(), 1000);
5079                        // Refresh balances
5080                        await fetchCurrency();
5081                        updateUI();
5082                        closeDailyBonusModal();
5083                        // Update state again (cooldown)
5084                        setTimeout(refreshDailyBonusState, 300);
5085                    } else {
5086                        tg.HapticFeedback.notificationOccurred('error');
5087                    }
5088                } catch (e) {
5089                    tg.HapticFeedback.notificationOccurred('error');
5090                }
5091            }
5092
5093            // Wire events
5094            const bindDailyBonusBtn = () => {
5095                const btn = getDailyBonusBtn();
5096                if (btn && !btn._bound) {
5097                    btn.addEventListener('click', async () => {
5098                        openDailyBonusModal();
5099                        await refreshDailyBonusState();
5100                    });
5101                    btn._bound = true;
5102                }
5103            };
5104            bindDailyBonusBtn();
5105            dailyCloseX.addEventListener('click', closeDailyBonusModal);
5106            dailyBonusBlur.addEventListener('click', closeDailyBonusModal);
5107            dailyUpgradeBtn.addEventListener('click', () => {
5108                closeDailyBonusModal();
5109                switchPage('lollipops');
5110            });
5111            dailyClaimBtn.addEventListener('click', async () => {
5112                if (!dailyClaimBtn.disabled) {
5113                    await claimDailyBonus();
5114                }
5115            });
5116            // Initial state fetch (to set wobble if available)
5117            refreshDailyBonusState();
5118
5119            // Delegated handler on balance container to be resilient to re-renders
5120            if (userBalanceEl && !userBalanceEl._dailyBound) {
5121                userBalanceEl.addEventListener('click', async (ev) => {
5122                    const target = ev.target && (ev.target.id === 'daily-bonus-btn' ? ev.target : ev.target.closest && ev.target.closest('#daily-bonus-btn'));
5123                    if (target) {
5124                        openDailyBonusModal();
5125                        await refreshDailyBonusState();
5126                    }
5127                });
5128                userBalanceEl._dailyBound = true;
5129            }
5130
5131            function adjustGirlDescriptions() {
5132                const cards = document.querySelectorAll('.item-card.girl-card');
5133                cards.forEach(card => {
5134                    const descEl = card.querySelector('.item-desc');
5135                    const relEl = card.querySelector('.girl-relationship-level');
5136                    if (!descEl || !relEl) return;
5137                    // Reset previous constraint to measure correctly
5138                    descEl.style.maxHeight = '';
5139                    const descRect = descEl.getBoundingClientRect();
5140                    const relRect = relEl.getBoundingClientRect();
5141                    const gap = 2; // minimal spacing between text and status
5142                    const computed = window.getComputedStyle(descEl);
5143                    const lineHeight = parseFloat(computed.lineHeight) || 20;
5144                    const fourLines = lineHeight * 4;
5145                    const available = Math.max(0, (relRect.top - descRect.top) - gap);
5146                    const maxHeightPx = Math.max(0, Math.min(available, fourLines));
5147                    descEl.style.maxHeight = maxHeightPx + 'px';
5148                });
5149            }
5150
5151            // Recalculate on resize/orientation changes and when page fully loaded
5152            window.addEventListener('resize', adjustGirlDescriptions);
5153            window.addEventListener('load', () => {
5154                // Delay a tick to ensure layout is final
5155                setTimeout(adjustGirlDescriptions, 0);
5156            });
5157
5158            // Create-character modal
5159            const createModalBlur = document.createElement('div');
5160            createModalBlur.id = 'create-modal-blur';
5161            document.body.appendChild(createModalBlur);
5162            const createModal = document.createElement('div');
5163            createModal.id = 'create-modal';
5164            createModal.innerHTML = `
5165                <div class="title">${t('modal_create_title')}</div>
5166                <div class="desc">${t('modal_create_desc')}</div>
5167                <div class="btns">
5168                    <button class="btn close">${t('button_close')}</button>
5169                    <button class="btn upgrade">Upgrade</button>
5170                </div>
5171            `;
5172            document.body.appendChild(createModal);
5173            const createCloseBtn = createModal.querySelector('.close');
5174            const createUpgradeBtn = createModal.querySelector('.upgrade');
5175            const openCreateModal = () => { 
5176                // Update texts in case language changed
5177                if (typeof updateModalTexts === 'function') {
5178                    updateModalTexts();
5179                }
5180                switchPage('character-creation'); 
5181            };
5182            const closeCreateModal = () => { createModalBlur.style.display = 'none'; createModal.style.display = 'none'; };
5183            createCloseBtn.addEventListener('click', closeCreateModal);
5184            createModalBlur.addEventListener('click', closeCreateModal);
5185            createUpgradeBtn.addEventListener('click', () => { closeCreateModal(); switchPage('lollipops'); });
5186            
5187            // Style selection handlers
5188            const styleCards = document.querySelectorAll('.style-card');
5189            let selectedStyle = null;
5190            
5191            styleCards.forEach(card => {
5192                card.addEventListener('click', () => {
5193                    // Remove selected class from all cards
5194                    styleCards.forEach(c => c.classList.remove('selected'));
5195                    
5196                    // Add selected class to clicked card
5197                    card.classList.add('selected');
5198                    
5199                    // Store selected style
5200                    selectedStyle = card.dataset.style;
5201                    console.log('Selected style:', selectedStyle);
5202                    
5203                    // Update ethnicity images based on selected style
5204                    updateEthnicityImages(selectedStyle);
5205                    
5206                    // Enable Next button
5207                    const nextBtn = document.querySelector('#page-character-creation .nav-next');
5208                    if (nextBtn) {
5209                        nextBtn.disabled = false;
5210                    }
5211                });
5212            });
5213            
5214            // Step 2 selection handlers
5215            let selectedEthnicity = null;
5216            let selectedAge = null;
5217            let selectedEyeColor = null;
5218            
5219            // Step 3 selection handlers
5220            let selectedHairStyle = null;
5221            let selectedHairColor = null;
5222            
5223            // Ethnicity selection
5224            const ethnicityCards = document.querySelectorAll('.ethnicity-card');
5225            ethnicityCards.forEach(card => {
5226                card.addEventListener('click', () => {
5227                    ethnicityCards.forEach(c => c.classList.remove('selected'));
5228                    card.classList.add('selected');
5229                    selectedEthnicity = card.dataset.ethnicity;
5230                    console.log('Selected ethnicity:', selectedEthnicity);
5231                    checkStep2Completion();
5232                });
5233            });
5234            
5235            // Age selection
5236            const ageCards = document.querySelectorAll('.age-card');
5237            ageCards.forEach(card => {
5238                card.addEventListener('click', () => {
5239                    ageCards.forEach(c => c.classList.remove('selected'));
5240                    card.classList.add('selected');
5241                    selectedAge = card.dataset.age;
5242                    console.log('Selected age:', selectedAge);
5243                    checkStep2Completion();
5244                });
5245            });
5246            
5247            // Eye color selection
5248            const eyeColorCards = document.querySelectorAll('.eye-color-card');
5249            eyeColorCards.forEach(card => {
5250                card.addEventListener('click', () => {
5251                    eyeColorCards.forEach(c => c.classList.remove('selected'));
5252                    card.classList.add('selected');
5253                    selectedEyeColor = card.dataset.eyeColor;
5254                    console.log('Selected eye color:', selectedEyeColor);
5255                    checkStep2Completion();
5256                });
5257            });
5258            
5259            // Function to update ethnicity images based on selected style
5260            function updateEthnicityImages(style) {
5261                const ethnicityImages = document.querySelectorAll('.ethnicity-image');
5262                ethnicityImages.forEach(img => {
5263                    const ethnicity = img.closest('.ethnicity-card').dataset.ethnicity;
5264                    img.src = `Photos/Creation/${style}/${ethnicity}.jpg`;
5265                });
5266            }
5267            
5268            // Update hair style images for step 3 based on selected style
5269            function updateHairStyleImages(style) {
5270                const hairImgs = document.querySelectorAll('.hair-style-image');
5271                hairImgs.forEach(img => {
5272                    const hair = img.closest('.hair-style-card').dataset.hair;
5273                    // Folder names per requirement: realistic / anime
5274                    const folder = style === 'realistic' || style === 'real' ? 'realistic' : 'anime';
5275                    img.src = `Photos/Creation/${folder}/${hair}.jpg`;
5276                });
5277            }
5278            
5279            // Function to check if all step 2 selections are made
5280            function checkStep2Completion() {
5281                const nextBtn = document.querySelector('#page-character-creation-step2 .nav-next');
5282                if (nextBtn && selectedEthnicity && selectedAge && selectedEyeColor) {
5283                    nextBtn.disabled = false;
5284                } else if (nextBtn) {
5285                    nextBtn.disabled = true;
5286                }
5287            }
5288            
5289            // Navigation button handlers
5290            const navBackBtns = document.querySelectorAll('.nav-back');
5291            const navNextBtns = document.querySelectorAll('.nav-next');
5292            
5293            navBackBtns.forEach(btn => {
5294                btn.addEventListener('click', () => {
5295                    if (currentPage === 'character-creation') {
5296                        switchPage('girls');
5297                    } else if (currentPage === 'character-creation-step2') {
5298                        switchPage('character-creation');
5299                    } else if (currentPage === 'character-creation-step3') {
5300                        switchPage('character-creation-step2');
5301                    }
5302                });
5303            });
5304            
5305            navNextBtns.forEach(btn => {
5306                btn.addEventListener('click', () => {
5307                    if (currentPage === 'character-creation') {
5308                        if (!btn.disabled && selectedStyle) {
5309                            switchPage('character-creation-step2');
5310                        }
5311                    } else if (currentPage === 'character-creation-step2') {
5312                        if (!btn.disabled && selectedEthnicity && selectedAge && selectedEyeColor) {
5313                            // Before moving to step 3, ensure hair images reflect selected style
5314                            updateHairStyleImages(selectedStyle || currentStyle || 'realistic');
5315                            switchPage('character-creation-step3');
5316                        }
5317                    } else if (currentPage === 'character-creation-step3') {
5318                        if (!btn.disabled && selectedHairStyle && selectedHairColor) {
5319                            // Prepare step 4 images and go to step 4
5320                            updateStep4Images(selectedStyle || currentStyle || 'realistic');
5321                            switchPage('character-creation-step4');
5322                        }
5323                    } else if (currentPage === 'character-creation-step4') {
5324                        if (!btn.disabled && selectedBodyType && selectedBreastSize && selectedButtSize) {
5325                            switchPage('character-creation-step5');
5326                            // When entering step 5, fit descriptions
5327                            fitPersonalityDescriptions();
5328                        }
5329                    } else if (currentPage === 'character-creation-step5') {
5330                        if (!btn.disabled && selectedPersonality) {
5331                            switchPage('character-creation-step6');
5332                        }
5333                    } else if (currentPage === 'character-creation-step6') {
5334                        if (!btn.disabled && selectedRelationship
5334) {
5335                            updateSummaryPage();
5336                            switchPage('character-creation-summary');
5337                        }
5338                    }
5339                });
5340            });
5341
5342            // Back from step 4 to step 3 and from step 5 to step 4 and from step 6 to step 5
5343            navBackBtns.forEach(btn => {
5344                btn.addEventListener('click', () => {
5345                    if (currentPage === 'character-creation-step4') {
5346                        switchPage('character-creation-step3');
5347                    } else if (currentPage === 'character-creation-step5') {
5348                        switchPage('character-creation-step4');
5349                    } else if (currentPage === 'character-creation-step6') {
5350                        switchPage('character-creation-step5');
5351                    } else if (currentPage === 'character-creation-summary') {
5352                        switchPage('character-creation-step6');
5353                    }
5354                });
5355            });
5356
5357            // Step 4 state
5358            let selectedBodyType = null;
5359            let selectedBreastSize = null;
5360            let selectedButtSize = null;
5361
5362            // Update step 4 images based on selected style
5363            function updateStep4Images(style) {
5364                const folder = (style === 'realistic' || style === 'real') ? 'realistic' : 'anime';
5365                // Body type
5366                document.querySelectorAll('.body-type-card').forEach(card => {
5367                    const key = card.dataset.body;
5368                    const img = card.querySelector('.body-type-image');
5369                    img.src = `Photos/Creation/${folder}/${key}.jpg`;
5370                });
5371                // Breast size (note: filenames for butt/breast per spec)
5372                document.querySelectorAll('.breast-size-card').forEach(card => {
5373                    const key = card.dataset.breast;
5374                    const img = card.querySelector('.breast-size-image');
5375                    img.src = `Photos/Creation/${folder}/breast_${key}.jpg`;
5376                });
5377                // Butt size
5378                document.querySelectorAll('.butt-size-card').forEach(card => {
5379                    const key = card.dataset.butt;
5380                    const img = card.querySelector('.butt-size-image');
5381                    img.src = `Photos/Creation/${folder}/butt_${key}.jpg`;
5382                });
5383            }
5384
5385            // Step 4 selection handlers
5386            const bodyCards = document.querySelectorAll('.body-type-card');
5387            bodyCards.forEach(card => {
5388                card.addEventListener('click', () => {
5389                    bodyCards.forEach(c => c.classList.remove('selected'));
5390                    card.classList.add('selected');
5391                    selectedBodyType = card.dataset.body;
5392                    checkStep4Completion();
5393                });
5394            });
5395            const breastCards = document.querySelectorAll('.breast-size-card');
5396            breastCards.forEach(card => {
5397                card.addEventListener('click', () => {
5398                    breastCards.forEach(c => c.classList.remove('selected'));
5399                    card.classList.add('selected');
5400                    selectedBreastSize = card.dataset.breast;
5401                    checkStep4Completion();
5402                });
5403            });
5404            const buttCards = document.querySelectorAll('.butt-size-card');
5405            buttCards.forEach(card => {
5406                card.addEventListener('click', () => {
5407                    buttCards.forEach(c => c.classList.remove('selected'));
5408                    card.classList.add('selected');
5409                    selectedButtSize = card.dataset.butt;
5410                    checkStep4Completion();
5411                });
5412            });
5413
5414            function checkStep4Completion() {
5415                const nextBtn = document.querySelector('#page-character-creation-step4 .nav-next');
5416                if (nextBtn && selectedBodyType && selectedBreastSize && selectedButtSize) {
5417                    nextBtn.disabled = false;
5418                } else if (nextBtn) {
5419                    nextBtn.disabled = true;
5420                }
5421            }
5422
5423            // Ensure personality description fits card (shrinks font down to a limit)
5424            function fitPersonalityDescriptions() {
5425                const cards = document.querySelectorAll('#page-character-creation-step5 .personality-card');
5426                cards.forEach(card => {
5427                    const desc = card.querySelector('.personality-desc');
5428                    if (!desc) return;
5429                    desc.style.fontSize = '';
5430                    let size = 0.95; // em
5431                    const minSize = 0.72;
5432                    // Allow up to ~5 lines worth of space based on card height
5433                    const maxHeight = Math.max(60, card.clientHeight - 72); // leave space for emoji+title+gaps
5434                    while (desc.scrollHeight > Math.min(maxHeight, 110) && size > minSize) {
5435                        size -= 0.03;
5436                        desc.style.fontSize = size + 'em';
5437                    }
5438                });
5439            }
5440
5441            // Step 5 state and selection
5442            let selectedPersonality = null;
5443            const personalityCards = document.querySelectorAll('.personality-card');
5444            personalityCards.forEach(card => {
5445                card.addEventListener('click', () => {
5446                    personalityCards.forEach(c => c.classList.remove('selected'));
5447                    card.classList.add('selected');
5448                    selectedPersonality = card.dataset.personality;
5449                    const nextBtn = document.querySelector('#page-character-creation-step5 .nav-next');
5450                    if (nextBtn) nextBtn.disabled = !selectedPersonality;
5451                });
5452            });
5453
5454            // Step 6: relationship selection
5455            let selectedRelationship = null;
5456            const relationshipCards = document.querySelectorAll('.relationship-card');
5457            relationshipCards.forEach(card => {
5458                card.addEventListener('click', () => {
5459                    relationshipCards.forEach(c => c.classList.remove('selected'));
5460                    card.classList.add('selected');
5461                    selectedRelationship = card.dataset.relationship;
5462                    const nextBtn = document.querySelector('#page-character-creation-step6 .nav-next');
5463                    if (nextBtn) nextBtn.disabled = !selectedRelationship;
5464                });
5465            });
5466
5467            // Update summary page with all selected choices
5468            function updateSummaryPage() {
5469                // Clear and render each summary card with either image+overlay or centered text
5470                const titleize = (s) =>
5470 s ? s.replace(/_/g, ' ').split(' ').map(w => w.charAt(0).toUpperCase()+w.slice(1)).join(' ') : 'Not selected';
5471                const folderForStyle = (style) => (style === 'realistic' || style === 'real') ? 'realistic' : 'anime';
5472                const folder = folderForStyle(selectedStyle || 'realistic');
5473
5474                const setImageCard = (id, imgPath, labelText) => {
5475                    const el = document.getElementById(id);
5476                    if (!el) return;
5477                    el.innerHTML = '';
5478                    if (imgPath) {
5479                        const img = document.createElement('img');
5480                        img.src = imgPath;
5481                        el.appendChild(img);
5482                        const overlay = document.createElement('div');
5483                        overlay.className = 'summary-overlay';
5484                        overlay.textContent = labelText;
5485                        el.appendChild(overlay);
5486                    } else {
5487                        const center = document.createElement('div');
5488                        center.className = 'summary-text';
5489                        center.textContent = labelText || 'Not selected';
5490                        el.appendChild(center);
5491                    }
5492                };
5493
5494                // Style (image)
5495                setImageCard('summary-style', selectedStyle ? `Photos/Creation/${folder}/style.jpg` : null, titleize(selectedStyle));
5496                // Ethnicity (image)
5497                setImageCard('summary-ethnicity', selectedEthnicity ? `Photos/Creation/${folder}/${selectedEthnicity}.jpg` : null, titleize(selectedEthnicity));
5498                // Age (text only)
5499                setImageCard('summary-age', null, titleize(selectedAge));
5500                // Eye color (image)
5501                const eyeMap = { brown: 'eyeBrown.jpg', blue: 'eyeBlue.jpg', green: 'eyeGreen.jpg' };
5502                setImageCard('summary-eye-color', selectedEyeColor ? `Photos/Creation/${eyeMap[selectedEyeColor] || ''}` : null, titleize(selectedEyeColor));
5503                // Hair style (image)
5504                setImageCard('summary-hair-style', selectedHairStyle ? `Photos/Creation/${folder}/${selectedHairStyle}.jpg` : null, titleize(selectedHairStyle));
5505                // Hair color (with background color)
5506                const hairColorEl = document.getElementById('summary-hair-color');
5507                if (hairColorEl) {
5508                    hairColorEl.innerHTML = '';
5509                    const center = document.createElement('div');
5510                    center.className = 'summary-text';
5511                    center.textContent = titleize(selectedHairColor);
5512                    hairColorEl.appendChild(center);
5513                    
5514                    // Apply background color based on selection
5515                    const colorMap = {
5516                        blonde: '#f7e07b',
5517                        brunette: '#6b4f3a',
5518                        black: '#111',
5519                        red: '#d14b4b',
5520                        pink: '#ff6fb7',
5521                        white: '#f0f0f0',
5522                        blue: '#4a7bd1',
5523                        green: '#3aa55d',
5524                        purple: '#7c4dff',
5525                        multicolor: 'linear-gradient(90deg, #ff2a2a 0%, #7a2aff 50%, #7fff2a 100%)'
5526                    };
5527                    const bgColor = colorMap[selectedHairColor] || '#121212';
5528                    hairColorEl.style.background = bgColor;
5529                    hairColorEl.style.color = ['white', 'black', 'red', 'blue', 'green', 'purple'].includes(selectedHairColor) ? '#fff' : '#000';
5530                }
5531                // Body type (image)
5532                setImageCard('summary-body-type', selectedBodyType ? `Photos/Creation/${folder}/${selectedBodyType}.jpg` : null, titleize(selectedBodyType));
5533                // Breast size (image)
5534                setImageCard('summary-breast-size', selectedBreastSize ? `Photos/Creation/${folder}/breast_${selectedBreastSize}.jpg` : null, titleize(selectedBreastSize));
5535                // Butt size (image)
5536                setImageCard('summary-butt-size', selectedButtSize ? `Photos/Creation/${folder}/butt_${selectedButtSize}.jpg` : null, titleize(selectedButtSize));
5537                // Personality (with emoji)
5538                const personalityEl = document.getElementById('summary-personality');
5539                if (personalityEl) {
5540                    personalityEl.innerHTML = '';
5541                    const container = document.createElement('div');
5542                    container.className = 'summary-text';
5543                    container.style.display = 'flex';
5544                    container.style.flexDirection = 'column';
5545                    container.style.alignItems = 'center';
5546                    container.style.gap = '4px';
5547                    
5548                    const emojiMap = {
5549                        caregiver: '🤱',
5550                        sage: '🧙',
5551                        innocent: '🌼',
5552                        jester: '🎭',
5553                        temptress: '😈',
5554                        dominant: '🦁',
5555                        submissive: '🙇',
5556                        lover: '💘',
5557                        nympho: '🔥',
5558                        mean: '🧊',
5559                        confidant: '🤝',
5560                        experimenter: '🧪'
5561                    };
5562                    
5563                    const emoji = document.createElement('div');
5564                    emoji.textContent = emojiMap[selectedPersonality] || '';
5565                    emoji.style.fontSize = '1.2em';
5566                    
5567                    const text = document.createElement('div');
5568                    text.textContent = titleize(selectedPersonality);
5569                    text.style.fontSize = '0.8em';
5570                    
5571                    container.appendChild(emoji);
5572                    container.appendChild(text);
5573                    personalityEl.appendChild(container);
5574                }
5575                // Relationship (with emoji)
5576                const relationshipEl = document.getElementById('summary-relationship');
5577                if (relationshipEl) {
5578                    relationshipEl.innerHTML = '';
5579                    const container = document.createElement('div');
5580                    container.className = 'summary-text';
5581                    container.style.display = 'flex';
5582                    container.style.flexDirection = 'column';
5583                    container.style.alignItems = 'center';
5584                    container.style.gap = '4px';
5585                    
5586                    const emojiMap = {
5587                        stranger: '🕵️‍♂️',
5588                        school_mate: '🎒',
5589                        colleague: '💼',
5590                        mentor: '🧑‍🏫',
5591                        girlfriend: '💖',
5592                        sex_friend: '🔥',
5593                        wife: '💍',
5594                        mistress: '👠',
5595                        friend: '🤝',
5596                        best_friend: '🌟',
5597                        step_sister: '👧',
5598                        step_mom: '👩‍👧'
5599                    };
5600                    
5601                    const emoji = document.createElement('div');
5602                    emoji.textContent = emojiMap[selectedRelationship] || '';
5603                    emoji.style.fontSize = '1.2em';
5604                    
5605                    const text = document.createElement('div');
5606                    text.textContent = titleize(selectedRelationship
5606);
5607                    text.style.fontSize = '0.8em';
5608                    
5609                    container.appendChild(emoji);
5610                    container.appendChild(text);
5611                    relationshipEl.appendChild(container);
5612                }
5613            }
5614
5615            // Handle "Bring To Life" button
5616            const bringToLifeBtn = document.querySelector('.nav-bring-to-life');
5617            const creationStatusModal = document.getElementById('creation-status-modal');
5618            const creationStatusMessage = document.getElementById('creation-status-message');
5619            const creationStatusBtn = document.getElementById('creation-status-btn');
5620            const progressBar = document.getElementById('progress-bar');
5621            const progressText = document.getElementById('progress-text');
5622            const progressContainer = document.getElementById('progress-container');
5623            
5624            // Initialize creation modal texts
5625            const creationStatusTitle = document.querySelector('.creation-status-title');
5626            if (creationStatusTitle) {
5627                creationStatusTitle.textContent = t('modal_create_title');
5628            }
5629            if (creationStatusBtn) {
5630                creationStatusBtn.textContent = t('button_close');
5631            }
5632            
5633            if (bringToLifeBtn) {
5634                bringToLifeBtn.addEventListener('click', async () => {
5635                    // Block button for 3 seconds
5636                    bringToLifeBtn.disabled = true;
5637                    bringToLifeBtn.style.opacity = '0.5';
5638                    bringToLifeBtn.style.cursor = 'not-allowed';
5639                    
5640                    setTimeout(() => {
5641                        bringToLifeBtn.disabled = false;
5642                        bringToLifeBtn.style.opacity = '1';
5643                        bringToLifeBtn.style.cursor = 'pointer';
5644                    }, 3000);
5645                    
5646                    try {
5647                        // First check subscription status
5648                        const subscriptionResponse = await fetch(`${API_BASE}/subscription?user=${user.id}`);
5649                        const subscriptionStatus = await subscriptionResponse.text(); // Get plain text response
5650                        
5651                        // If subscription is None or Bronze, show upgrade modal
5652                        if (subscriptionStatus === 'None' || subscriptionStatus === 'Bronze') {
5653                            // Update texts in case language changed
5654                            if (typeof updateModalTexts === 'function') {
5655                                updateModalTexts();
5656                            }
5657                            const createModalBlur = document.getElementById('create-modal-blur');
5658                            const createModal = document.getElementById('create-modal');
5659                            if (createModalBlur && createModal) {
5660                                createModalBlur.style.display = 'block';
5661                                createModal.style.display = 'block';
5662                            }
5663                            return;
5664                        }
5665                        
5666                        // If subscription is Silver or Gold, proceed with character creation
5667                        if (subscriptionStatus === 'Silver' || subscriptionStatus === 'Gold') {
5668                            // Update texts in case language changed
5669                            if (typeof updateModalTexts === 'function') {
5670                                updateModalTexts();
5671                            }
5672                            // Show modal with progress bar
5673                            creationStatusMessage.textContent = t('shop_loading_characters');
5674                            creationStatusBtn.style.display = 'none';
5675                            progressContainer.style.display = 'block';
5676                            creationStatusModal.style.display = 'flex';
5677                            
5678                            // Reset progress bar
5679                            progressBar.style.width = '0%';
5680                            progressText.textContent = '0%';
5681                            
5682                            // Start progress animation (10 seconds to 99%)
5683                            let progress = 0;
5684                            const progressInterval = setInterval(() => {
5685                                progress += 1;
5686                                if (progress <= 99) {
5687                                    progressBar.style.width = progress + '%';
5688                                    progressText.textContent = progress + '%';
5689                                } else {
5690                                    clearInterval(progressInterval);
5691                                }
5692                            }, 100); // 100ms intervals for smooth animation
5693                            
5694                            try {
5695                                // Collect all user selections with quoted string values
5696                                const params = new URLSearchParams({
5697                                    style: `"${selectedStyle || ''}"`,
5698                                    ethnicity: `"${selectedEthnicity || ''}"`,
5699                                    age: `"${selectedAge || ''}"`,
5700                                    eyecolor: `"${selectedEyeColor || ''}"`,
5701                                    hairstyle: `"${selectedHairStyle || ''}"`,
5702                                    haircolor: `"${selectedHairColor || ''}"`,
5703                                    bodytype: `"${selectedBodyType || ''}"`,
5704                                    breastsize: `"${selectedBreastSize || ''}"`,
5705                                    buttsize: `"${selectedButtSize || ''}"`,
5706                                    personality: `"${selectedPersonality || ''}"`,
5707                                    relationship: `"${selectedRelationship || ''}"`
5708                                });
5709
5710                                // Send request to create girl
5711                                const response = await fetch(`${API_BASE}/creategirl?user=${user.id}&${params.toString()}`);
5712                                const result = await response.json();
5713
5714                                // Stop progress animation and complete to 100%
5715                                clearInterval(progressInterval);
5716                                progressBar.style.width = '100%';
5717                                progressText.textContent = '100%';
5718                                
5719                                // Hide progress bar and update message
5720                                setTimeout(() => {
5721                                    progressContainer.style.display = 'none';
5722                                    
5723                                    // Update modal with result
5724                                    if (result.success) {
5725                                        creationStatusMessage.textContent = t('alert_alreadyBought');
5726                                    } else {
5727                                        creationStatusMessage.textContent = t('error_purchase');
5728                                    }
5729                                    
5730                                    // Show OK button
5731                                    creationStatusBtn.style.display = 'block';
5732                                }, 500);
5733                                
5734                            } catch (error) {
5735                                console.error('Error creating girl:', error);
5736                                
5737                                // Stop progress animation
5738                                clearInterval(progressInterval);
5739                                progressContainer.style.display = 'none';
5740                                creationStatusMessage.textContent = t('error_purchase');
5741                                creationStatusBtn.style.display = 'block';
5742                            }
5743                        }
5744                        
5745                    } catch (error) {
5746                        console.error('Error checking subscription:', error);
5747                        // If subscription check fails, show upgrade modal as fallback
5748                        const createModalBlur = document.getElementById('create-modal-blur');
5749                        const createModal = document.getElementById('create-modal');
5750                        if (createModalBlur && createModal) {
5751                            createModalBlur.style.display = 'block';
5752                            createModal.style.display = 'block';
5753                        }
5754                    }
5755                });
5756            }
5757            
5758            // Handle OK button click
5759            if (creationStatusBtn) {
5760                creationStatusBtn.addEventListener('click', async () => {
5761                    creationStatusModal.style.display = 'none';
5762
5763                    // Refresh girls list and photos
5764                    showLoadingScreen();
5765                    try {
5766                        // Обновляем список девушек
5767                        await refreshGirlsData();
5768                        
5769                        // Обновляем фотографии
5770                        girlsPhotosLoaded = false; // Сбрасываем флаг чтобы перезагрузить фотографии
5771                        await loadGirlsPhotos();
5772                        
5773                        // Пересоздаем карточки девушек
5774                        renderGirlsShop();
5775                    } catch (error) {
5776                        console.error('Failed to refresh girls list:', error);
5777                    }
5778                    hideLoadingScreen();
5779
5780                    switchPage('girls');
5781                });
5782            }
5783
5784            // Keep emoji/title sizes proportional to card size
5785            function updateRelationshipCardSizes() {
5786                document.querySelectorAll('.relationship-card').forEach(card => {
5787                    const rect = card.getBoundingClientRect();
5788                    // card is square via padding-top; width is size
5789                    const size = Math.max(60, Math.min(160, rect.width));
5790                    card.style.setProperty('--rel-card-size', size + 'px');
5791                });
5792            }
5793            // Run when entering step 6 and on resize
5794            const observer = new ResizeObserver(() => updateRelationshipCardSizes());
5795            document.querySelectorAll('.relationship-card').forEach(card => observer.observe(card));
5796            // Also call on navigation into step 6
5797            const origSwitchPage = switchPage;
5798            switchPage = function(name) {
5799                origSwitchPage(name);
5800                if (name === 'character-creation-step6') {
5801                    setTimeout(updateRelationshipCardSizes, 0);
5802                }
5803            };
5804
5805            // Hair style selection (step 3)
5806            const hairStyleCards = document.querySelectorAll('.hair-style-card');
5807            hairStyleCards.forEach(card => {
5808                card.addEventListener('click', () => {
5809                    hairStyleCards.forEach(c => c.classList.remove('selected'));
5810                    card.classList.add('selected');
5811                    selectedHairStyle = card.dataset.hair;
5812                    checkStep3Completion();
5813                });
5814            });
5815
5816            // Hair color selection (step 3)
5817            const hairColorCards = document.querySelectorAll('.hair-color-card');
5818            hairColorCards.forEach(card => {
5819                card.addEventListener('click', () => {
5820                    hairColorCards.forEach(c => c.classList.remove('selected'));
5821                    card.classList.add('selected');
5822                    selectedHairColor = card.dataset.hairColor;
5823                    checkStep3Completion();
5824                });
5825            });
5826
5827            function checkStep3Completion() {
5828                const nextBtn = document.querySelector('#page-character-creation-step3 .nav-next');
5829                if (nextBtn && selectedHairStyle && selectedHairColor) {
5830                    nextBtn.disabled = false;
5831                } else if (nextBtn) {
5832                    nextBtn.disabled = true;
5833                }
5834            }
5835        });
5836    </script>
5836
5837</body>
5838</html> 

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.