k4gor commited on
Commit
12c8e6c
Β·
verified Β·
1 Parent(s): ece12b0

Create a mobile web application using only three files: index.html , style.css, script.js .

Browse files

General requirements:
The application is intended exclusively for mobile devices (screen width 320-480 px, portrait orientation).
Be sure to enable <meta name="viewport" content="width=device-width, initial-scale=1">.
All elements should be convenient for touch interaction: at least 48Γ—48 px for clickable zones, sufficient margins, readable fonts.
Don't use external libraries β€” just pure HTML, CSS, and JavaScript.
Page Structure:
The page consists of three vertical blocks and one fixed panel:
The main one is a static block, always visible in its entirety.
The carousel (News) is a static block under the "Main", measuring 100% in width and 100 px in height.
Information is a dynamic block between the carousel and the bottom panel.
β†’ If the content does not fit, a vertical scroll appears inside this block.
β†’ The general page should not scroll β€” only the contents of the "Information" block will scroll.
The lower navigation bar is fixed at the bottom of the screen (height ~60 px), does not participate in scrolling.
Block 1: Home page
In the center:
Wallet address (UQAR...bn5l) in small print + copy icon. Tap β€” copy to the clipboard and short-term visual feedback (for example, the inscription "Copied!").
Below it in large bold: 664.85β‚½ (available balance).
Below in gray: 802.34β‚½ (funds on hold).
Block 2: Carousel (News)
Size: 100% width, 100 px height.
Displays banners (at least 3), swipes or indicators of the current slide are supported.
The content is scaled to fit the width of the screen.
Block 3: Information (dynamic)
The content changes depending on the selected button in the bottom panel. Variants:
β€’ Translate
The "Where to send" input field.
The input field is "How much to send".
The "Translate" button (100% width).
β€’ Store
Section "Purchased subscriptions": LVL1 card with information about the end and the "Renew 250β‚½" button.
"Available subscriptions" section: three cards (LVL2–LVL4) with a description and "Buy" buttons" (500β‚½, 1000β‚½, 2500β‚½).
β€’ Transaction history
Four entries in a list: operation type, date/time, amount on the right.
β€’ Tasks
Statistics: invited, likes, comments, reposts.
The "Create link" β†’ button turns into a field with vk.com/uwu.chan + copy.
The "Generate code" β†’ button turns into a field with YUfs1if421Hf + copy.
Three task buttons:
β†’ "Subscribe to UwU Chan" β†’ opens https://vk.com/uwu.chan β†’ The reward is 100β‚½
β†’ "Subscribe to Shy Chan" β†’ opens https://vk.com/shy.chan β†’ The reward is 100β‚½
β†’ "Subscribe to Esco Chan" β†’ opens https://vk.com/esco.chan β†’ The reward is 100β‚½
Lower navigation bar
Four buttons in one line: Translate, Store, History, Tasks.
The active tab is visually highlighted.
When clicked, the contents of the "Information" block are updated without reloading the page.
Additionally:
All copying actions are performed via navigator.clipboard.writeText().
Scrolling inside the "Information" block should be smooth and support touch scrolling (-webkit-overflow-scrolling: touch).
The interface should look like a single mobile application β€” without unnecessary decorations, with a clear hierarchy and instant feedback.

Files changed (4) hide show
  1. README.md +8 -5
  2. index.html +111 -19
  3. script.js +555 -0
  4. style.css +723 -19
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Uwu Wallet
3
- emoji: πŸ‘€
4
- colorFrom: pink
5
- colorTo: yellow
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: UwU Wallet 🐱
3
+ colorFrom: purple
4
+ colorTo: pink
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
index.html CHANGED
@@ -1,19 +1,111 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>UwU Wallet</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ </head>
9
+ <body>
10
+ <!-- Main Block -->
11
+ <div class="main-block">
12
+ <div class="wallet-container">
13
+ <div class="wallet-address" id="walletAddress">
14
+ <span class="address-text">UQAR...bn5l</span>
15
+ <button class="copy-btn" id="copyAddressBtn" aria-label="Copy address">
16
+ <svg class="copy-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
17
+ <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
18
+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
19
+ </svg>
20
+ </button>
21
+ <span class="copy-feedback" id="addressFeedback">Copied!</span>
22
+ </div>
23
+ <div class="balance-main">664.85β‚½</div>
24
+ <div class="balance-hold">802.34β‚½ on hold</div>
25
+ </div>
26
+ </div>
27
+
28
+ <!-- Carousel Block -->
29
+ <div class="carousel-block">
30
+ <div class="carousel-track" id="carouselTrack">
31
+ <div class="carousel-slide" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);">
32
+ <div class="slide-content">
33
+ <svg class="slide-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
34
+ <circle cx="12" cy="12" r="10"></circle>
35
+ <path d="M8 14s1.5 2 4 2 4-2 4-2"></path>
36
+ <line x1="9" y1="9" x2="9.01" y2="9"></line>
37
+ <line x1="15" y1="9" x2="15.01" y2="9"></line>
38
+ </svg>
39
+ <span class="slide-text">Welcome Bonus +500β‚½</span>
40
+ </div>
41
+ </div>
42
+ <div class="carousel-slide" style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);">
43
+ <div class="slide-content">
44
+ <svg class="slide-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
45
+ <polygon points="13 2 3 14 12 14 11 22 21 10 12 10"></polygon>
46
+ </svg>
47
+ <span class="slide-text">Level Up & Earn More!</span>
48
+ </div>
49
+ </div>
50
+ <div class="carousel-slide" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);">
51
+ <div class="slide-content">
52
+ <svg class="slide-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
53
+ <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
54
+ <circle cx="9" cy="7" r="4"></circle>
55
+ <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
56
+ <path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
57
+ </svg>
58
+ <span class="slide-text">Invite Friends +100β‚½ Each</span>
59
+ </div>
60
+ </div>
61
+ </div>
62
+ <div class="carousel-indicators" id="carouselIndicators"></div>
63
+ </div>
64
+
65
+ <!-- Information Block -->
66
+ <div class="info-block" id="infoBlock">
67
+ <!-- Content will be dynamically inserted here -->
68
+ </div>
69
+
70
+ <!-- Bottom Navigation -->
71
+ <div class="nav-panel">
72
+ <button class="nav-btn active" data-tab="transfer" aria-label="Transfer">
73
+ <svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
74
+ <path d="M12 19l7-7 3 3-7 7-3-3z"></path>
75
+ <path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"></path>
76
+ <path d="M2 2l7.586 7.586"></path>
77
+ <circle cx="11" cy="11" r="2"></circle>
78
+ </svg>
79
+ <span class="nav-label">Transfer</span>
80
+ </button>
81
+ <button class="nav-btn" data-tab="store" aria-label="Store">
82
+ <svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
83
+ <path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"></path>
84
+ <line x1="3" y1="6" x2="21" y2="6"></line>
85
+ <path d="M16 10a4 4 0 0 1-8 0"></path>
86
+ </svg>
87
+ <span class="nav-label">Store</span>
88
+ </button>
89
+ <button class="nav-btn" data-tab="history" aria-label="History">
90
+ <svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
91
+ <circle cx="12" cy="12" r="10"></circle>
92
+ <polyline points="12 6 12 12 16 14"></polyline>
93
+ </svg>
94
+ <span class="nav-label">History</span>
95
+ </button>
96
+ <button class="nav-btn" data-tab="tasks" aria-label="Tasks">
97
+ <svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
98
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
99
+ <polyline points="14 2 14 8 20 8"></polyline>
100
+ <line x1="16" y1="13" x2="8" y2="13"></line>
101
+ <line x1="16" y1="17" x2="8" y2="17"></line>
102
+ <polyline points="10 9 9 9 8 9"></polyline>
103
+ </svg>
104
+ <span class="nav-label">Tasks</span>
105
+ </button>
106
+ </div>
107
+
108
+ <script src="script.js"></script>
109
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
110
+ </body>
111
+ </html>
script.js ADDED
@@ -0,0 +1,555 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Application State
2
+ const state = {
3
+ currentTab: 'transfer',
4
+ balance: 664.85,
5
+ carouselIndex: 0,
6
+ isCarouselPaused: false
7
+ };
8
+
9
+ // DOM Elements
10
+ const infoBlock = document.getElementById('infoBlock');
11
+ const navButtons = document.querySelectorAll('.nav-btn');
12
+ const carouselTrack = document.getElementById('carouselTrack');
13
+ const carouselIndicators = document.getElementById('carouselIndicators');
14
+ const walletAddress = document.getElementById('walletAddress');
15
+ const copyAddressBtn = document.getElementById('copyAddressBtn');
16
+ const addressFeedback = document.getElementById('addressFeedback');
17
+
18
+ // Tab Content Templates
19
+ const tabContent = {
20
+ transfer: `
21
+ <form class="transfer-form" id="transferForm">
22
+ <div class="form-group">
23
+ <label class="form-label">Recipient Address</label>
24
+ <input type="text" class="form-input" id="recipientInput" placeholder="Enter wallet address" autocomplete="off">
25
+ </div>
26
+ <div class="form-group">
27
+ <label class="form-label">Amount</label>
28
+ <input type="number" class="form-input" id="amountInput" placeholder="0.00 β‚½" step="0.01" min="0.01">
29
+ </div>
30
+ <button type="submit" class="btn-primary">
31
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
32
+ <line x1="22" y1="12" x2="2" y2="12"></line>
33
+ <polyline points="9 5 2 12 9 19"></polyline>
34
+ </svg>
35
+ Send Transfer
36
+ </button>
37
+ </form>
38
+ `,
39
+
40
+ store: `
41
+ <div class="store-section">
42
+ <div class="section-title">Purchased Subscriptions</div>
43
+ <div class="subscription-card purchased">
44
+ <div class="card-header">
45
+ <div class="level-badge lvl1">LVL1</div>
46
+ <div class="card-info">
47
+ <div class="card-title">Starter Pack</div>
48
+ <div class="card-desc">Basic features access</div>
49
+ <div class="card-status">βœ“ Active until 15 Jan 2025</div>
50
+ </div>
51
+ </div>
52
+ <button class="btn-renew" onclick="handleRenew('LVL1', 250)">
53
+ Renew for 250β‚½
54
+ </button>
55
+ </div>
56
+ </div>
57
+ <div class="store-section">
58
+ <div class="section-title">Available Subscriptions</div>
59
+ <div class="subscription-card">
60
+ <div class="card-header">
61
+ <div class="level-badge lvl2">LVL2</div>
62
+ <div class="card-info">
63
+ <div class="card-title">Pro Access</div>
64
+ <div class="card-desc">Premium features + priority</div>
65
+ </div>
66
+ </div>
67
+ <button class="btn-buy lvl2" onclick="handleSubscribe('LVL2', 500)">
68
+ Buy for 500β‚½
69
+ </button>
70
+ </div>
71
+ <div class="subscription-card">
72
+ <div class="card-header">
73
+ <div class="level-badge lvl3">LVL3</div>
74
+ <div class="card-info">
75
+ <div class="card-title">Elite Member</div>
76
+ <div class="card-desc">All features + exclusive perks</div>
77
+ </div>
78
+ </div>
79
+ <button class="btn-buy lvl3" onclick="handleSubscribe('LVL3', 1000)">
80
+ Buy for 1000β‚½
81
+ </button>
82
+ </div>
83
+ <div class="subscription-card">
84
+ <div class="card-header">
85
+ <div class="level-badge lvl4">LVL4</div>
86
+ <div class="card-info">
87
+ <div class="card-title">Legend Status</div>
88
+ <div class="card-desc">Ultimate access + lifetime perks</div>
89
+ </div>
90
+ </div>
91
+ <button class="btn-buy lvl4" onclick="handleSubscribe('LVL4', 2500)">
92
+ Buy for 2500β‚½
93
+ </button>
94
+ </div>
95
+ </div>
96
+ `,
97
+
98
+ history: `
99
+ <div class="history-list">
100
+ <div class="history-item">
101
+ <div class="history-left">
102
+ <div class="history-icon icon-in">
103
+ <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
104
+ <line x1="12" y1="19" x2="12" y2="5"></line>
105
+ <polyline points="5 12 12 5 19 12"></polyline>
106
+ </svg>
107
+ </div>
108
+ <div class="history-info">
109
+ <div class="history-type">Deposit</div>
110
+ <div class="history-date">Today, 14:32</div>
111
+ </div>
112
+ </div>
113
+ <div class="history-amount positive">+500.00β‚½</div>
114
+ </div>
115
+ <div class="history-item">
116
+ <div class="history-left">
117
+ <div class="history-icon icon-sub">
118
+ <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
119
+ <path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"></path>
120
+ </svg>
121
+ </div>
122
+ <div class="history-info">
123
+ <div class="history-type">Subscription</div>
124
+ <div class="history-date">Yesterday, 09:15</div>
125
+ </div>
126
+ </div>
127
+ <div class="history-amount negative">-250.00β‚½</div>
128
+ </div>
129
+ <div class="history-item">
130
+ <div class="history-left">
131
+ <div class="history-icon icon-out">
132
+ <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
133
+ <line x1="12" y1="5" x2="12" y2="19"></line>
134
+ <polyline points="19 12 12 19 5 12"></polyline>
135
+ </svg>
136
+ </div>
137
+ <div class="history-info">
138
+ <div class="history-type">Transfer Out</div>
139
+ <div class="history-date">Dec 24, 18:45</div>
140
+ </div>
141
+ </div>
142
+ <div class="history-amount negative">-150.00β‚½</div>
143
+ </div>
144
+ <div class="history-item">
145
+ <div class="history-left">
146
+ <div class="history-icon icon-task">
147
+ <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
148
+ <polyline points="9 11 12 14 22 4"></polyline>
149
+ <path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"></path>
150
+ </svg>
151
+ </div>
152
+ <div class="history-info">
153
+ <div class="history-type">Task Reward</div>
154
+ <div class="history-date">Dec 22, 11:20</div>
155
+ </div>
156
+ </div>
157
+ <div class="history-amount positive">+100.00β‚½</div>
158
+ </div>
159
+ </div>
160
+ `,
161
+
162
+ tasks: `
163
+ <div class="stats-grid">
164
+ <div class="stat-card">
165
+ <div class="stat-value">12</div>
166
+ <div class="stat-label">Invited</div>
167
+ </div>
168
+ <div class="stat-card">
169
+ <div class="stat-value">89</div>
170
+ <div class="stat-label">Likes</div>
171
+ </div>
172
+ <div class="stat-card">
173
+ <div class="stat-value">34</div>
174
+ <div class="stat-label">Comments</div>
175
+ </div>
176
+ <div class="stat-card">
177
+ <div class="stat-value">7</div>
178
+ <div class="stat-label">Reposts</div>
179
+ </div>
180
+ </div>
181
+
182
+ <div class="action-section">
183
+ <button class="action-btn" id="createLinkBtn" onclick="generateLink()">
184
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
185
+ <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path>
186
+ <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
187
+ </svg>
188
+ Create Referral Link
189
+ </button>
190
+ <div class="copy-field" id="linkField" onclick="copyToClipboard('vk.com/uwu.chan', this)">
191
+ <span class="copy-field-value">vk.com/uwu.chan</span>
192
+ <svg class="copy-field-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
193
+ <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
194
+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
195
+ </svg>
196
+ </div>
197
+ </div>
198
+
199
+ <div class="action-section">
200
+ <button class="action-btn" id="genCodeBtn" onclick="generateCode()">
201
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
202
+ <rect x="4" y="4" width="16" height="16" rx="2" ry="2"></rect>
203
+ <rect x="9" y="9" width="6" height="6"></rect>
204
+ <line x1="9" y1="1" x2="9" y2="4"></line>
205
+ <line x1="15" y1="1" x2="15" y2="4"></line>
206
+ <line x1="9" y1="20" x2="9" y2="23"></line>
207
+ <line x1="15" y1="20" x2="15" y2="23"></line>
208
+ <line x1="20" y1="9" x2="23" y2="9"></line>
209
+ <line x1="20" y1="14" x2="23" y2="14"></line>
210
+ <line x1="1" y1="9" x2="4" y2="9"></line>
211
+ <line x1="1" y1="14" x2="4" y2="14"></line>
212
+ </svg>
213
+ Generate Promo Code
214
+ </button>
215
+ <div class="copy-field" id="codeField" onclick="copyToClipboard('YUfs1if421Hf', this)">
216
+ <span class="copy-field-value">YUfs1if421Hf</span>
217
+ <svg class="copy-field-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
218
+ <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
219
+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
220
+ </svg>
221
+ </div>
222
+ </div>
223
+
224
+ <div class="section-title">Available Tasks</div>
225
+ <div class="tasks-list">
226
+ <a href="https://vk.com/uwu.chan" target="_blank" class="task-card" onclick="completeTask('UwU Chan', 100)">
227
+ <div class="task-icon">
228
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
229
+ <path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"></path>
230
+ </svg>
231
+ </div>
232
+ <div class="task-info">
233
+ <div class="task-title">Subscribe to UwU Chan</div>
234
+ <div class="task-reward">+100β‚½ reward</div>
235
+ </div>
236
+ <svg class="task-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
237
+ <polyline points="9 18 15 12 9 6"></polyline>
238
+ </svg>
239
+ </a>
240
+ <a href="https://vk.com/shy.chan" target="_blank" class="task-card" onclick="completeTask('Shy Chan', 100)">
241
+ <div class="task-icon" style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);">
242
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
243
+ <circle cx="12" cy="12" r="10"></circle>
244
+ <path d="M8 14s1.5 2 4 2 4-2 4-2"></path>
245
+ <line x1="9" y1="9" x2="9.01" y2="9"></line>
246
+ <line x1="15" y1="9" x2="15.01" y2="9"></line>
247
+ </svg>
248
+ </div>
249
+ <div class="task-info">
250
+ <div class="task-title">Subscribe to Shy Chan</div>
251
+ <div class="task-reward">+100β‚½ reward</div>
252
+ </div>
253
+ <svg class="task-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
254
+ <polyline points="9 18 15 12 9 6"></polyline>
255
+ </svg>
256
+ </a>
257
+ <a href="https://vk.com/esco.chan" target="_blank" class="task-card" onclick="completeTask('Esco Chan', 100)">
258
+ <div class="task-icon" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);">
259
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
260
+ <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
261
+ </svg>
262
+ </div>
263
+ <div class="task-info">
264
+ <div class="task-title">Subscribe to Esco Chan</div>
265
+ <div class="task-reward">+100β‚½ reward</div>
266
+ </div>
267
+ <svg class="task-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
268
+ <polyline points="9 18 15 12 9 6"></polyline>
269
+ </svg>
270
+ </a>
271
+ </div>
272
+ <div class="section-divider"></div>
273
+ `
274
+ };
275
+
276
+ // Initialize Application
277
+ function init() {
278
+ renderTab('transfer');
279
+ initCarousel();
280
+ initNavigation();
281
+ initAddressCopy();
282
+ }
283
+
284
+ // Render Tab Content
285
+ function renderTab(tabName) {
286
+ state.currentTab = tabName;
287
+ infoBlock.innerHTML = tabContent[tabName];
288
+
289
+ // Re-attach event listeners for dynamic content
290
+ if (tabName === 'transfer') {
291
+ initTransferForm();
292
+ }
293
+ }
294
+
295
+ // Navigation
296
+ function initNavigation() {
297
+ navButtons.forEach(btn => {
298
+ btn.addEventListener('click', () => {
299
+ const tab = btn.dataset.tab;
300
+
301
+ // Update active states
302
+ navButtons.forEach(b => b.classList.remove('active'));
303
+ btn.classList.add('active');
304
+
305
+ // Render new tab with animation
306
+ infoBlock.style.opacity = '0';
307
+ infoBlock.style.transform = 'translateY(10px)';
308
+ infoBlock.style.transition = 'all 0.2s ease';
309
+
310
+ setTimeout(() => {
311
+ renderTab(tab);
312
+ infoBlock.style.opacity = '1';
313
+ infoBlock.style.transform = 'translateY(0)';
314
+ }, 150);
315
+ });
316
+ });
317
+ }
318
+
319
+ // Carousel Functionality
320
+ function initCarousel() {
321
+ const slides = carouselTrack.children;
322
+ const slideCount = slides.length;
323
+
324
+ // Create indicators
325
+ carouselIndicators.innerHTML = '';
326
+ for (let i = 0; i < slideCount; i++) {
327
+ const indicator = document.createElement('div');
328
+ indicator.className = `indicator ${i === 0 ? 'active' : ''}`;
329
+ indicator.addEventListener('click', () => goToSlide(i));
330
+ carouselIndicators.appendChild(indicator);
331
+ }
332
+
333
+ // Touch handling
334
+ let startX = 0;
335
+ let currentX = 0;
336
+ let isDragging = false;
337
+
338
+ carouselTrack.addEventListener('touchstart', (e) => {
339
+ startX = e.touches[0].clientX;
340
+ isDragging = true;
341
+ state.isCarouselPaused = true;
342
+ }, { passive: true });
343
+
344
+ carouselTrack.addEventListener('touchmove', (e) => {
345
+ if (!isDragging) return;
346
+ currentX = e.touches[0].clientX;
347
+ const diff = startX - currentX;
348
+ const offset = -state.carouselIndex * 100 - (diff / carouselTrack.offsetWidth) * 100;
349
+ carouselTrack.style.transition = 'none';
350
+ carouselTrack.style.transform = `translateX(${offset}%)`;
351
+ }, { passive: true });
352
+
353
+ carouselTrack.addEventListener('touchend', (e) => {
354
+ if (!isDragging) return;
355
+ isDragging = false;
356
+ state.isCarouselPaused = false;
357
+
358
+ const diff = startX - currentX;
359
+ const threshold = carouselTrack.offsetWidth * 0.25;
360
+
361
+ carouselTrack.style.transition = '';
362
+
363
+ if (Math.abs(diff) > threshold) {
364
+ if (diff > 0 && state.carouselIndex < slideCount - 1) {
365
+ goToSlide(state.carouselIndex + 1);
366
+ } else if (diff < 0 && state.carouselIndex > 0) {
367
+ goToSlide(state.carouselIndex - 1);
368
+ } else {
369
+ goToSlide(state.carouselIndex);
370
+ }
371
+ } else {
372
+ goToSlide(state.carouselIndex);
373
+ }
374
+ });
375
+
376
+ // Auto-advance
377
+ setInterval(() => {
378
+ if (!state.isCarouselPaused) {
379
+ const nextIndex = (state.carouselIndex + 1) % slideCount;
380
+ goToSlide(nextIndex);
381
+ }
382
+ }, 4000);
383
+ }
384
+
385
+ function goToSlide(index) {
386
+ state.carouselIndex = index;
387
+ carouselTrack.style.transform = `translateX(-${index * 100}%)`;
388
+
389
+ const indicators = carouselIndicators.children;
390
+ for (let i = 0; i < indicators.length; i++) {
391
+ indicators[i].classList.toggle('active', i === index);
392
+ }
393
+ }
394
+
395
+ // Address Copy
396
+ function initAddressCopy() {
397
+ const fullAddress = 'UQARxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxbn5l';
398
+
399
+ copyAddressBtn.addEventListener('click', async () => {
400
+ try {
401
+ await navigator.clipboard.writeText(fullAddress);
402
+ showFeedback(addressFeedback);
403
+ } catch (err) {
404
+ // Fallback
405
+ const textarea = document.createElement('textarea');
406
+ textarea.value = fullAddress;
407
+ document.body.appendChild(textarea);
408
+ textarea.select();
409
+ document.execCommand('copy');
410
+ document.body.removeChild(textarea);
411
+ showFeedback(addressFeedback);
412
+ }
413
+ });
414
+ }
415
+
416
+ function showFeedback(element) {
417
+ element.classList.add('show');
418
+ setTimeout(() => {
419
+ element.classList.remove('show');
420
+ }, 1500);
421
+ }
422
+
423
+ // Transfer Form
424
+ function initTransferForm() {
425
+ const form = document.getElementById('transferForm');
426
+ const recipientInput = document.getElementById('recipientInput');
427
+ const amountInput = document.getElementById('amountInput');
428
+
429
+ // Limit input to balance
430
+ amountInput.addEventListener('input', (e) => {
431
+ const value = parseFloat(e.target.value);
432
+ if (value > state.balance) {
433
+ e.target.value = state.balance.toFixed(2);
434
+ }
435
+ });
436
+
437
+ form.addEventListener('submit', (e) => {
438
+ e.preventDefault();
439
+ const recipient = recipientInput.value.trim();
440
+ const amount = parseFloat(amountInput.value);
441
+
442
+ if (!recipient || isNaN(amount) || amount <= 0) {
443
+ showToast('Please fill all fields', 'error');
444
+ return;
445
+ }
446
+
447
+ if (amount > state.balance) {
448
+ showToast('Insufficient balance', 'error');
449
+ return;
450
+ }
451
+
452
+ // Simulate transfer
453
+ const btn = form.querySelector('.btn-primary');
454
+ btn.disabled = true;
455
+ btn.innerHTML = '<span class="loading">Processing...</span>';
456
+
457
+ setTimeout(() => {
458
+ state.balance -= amount;
459
+ document.querySelector('.balance-main').textContent = state.balance.toFixed(2) + 'β‚½';
460
+ showToast(`Sent ${amount.toFixed(2)}β‚½`, 'success');
461
+ renderTab('transfer');
462
+ }, 1500);
463
+ });
464
+ }
465
+
466
+ // Store Actions
467
+ function handleSubscribe(level, price) {
468
+ if (price > state.balance) {
469
+ showToast('Insufficient balance', 'error');
470
+ return;
471
+ }
472
+
473
+ showToast(`Subscribed to ${level}!`, 'success');
474
+ state.balance -= price;
475
+ document.querySelector('.balance-main').textContent = state.balance.toFixed(2) + 'β‚½';
476
+ }
477
+
478
+ function handleRenew(level, price) {
479
+ if (price > state.balance) {
480
+ showToast('Insufficient balance', 'error');
481
+ return;
482
+ }
483
+
484
+ showToast(`${level} renewed!`, 'success');
485
+ state.balance -= price;
486
+ document.querySelector('.balance-main').textContent = state.balance.toFixed(2) + 'β‚½';
487
+ }
488
+
489
+ // Task Actions
490
+ function generateLink() {
491
+ const btn = document.getElementById('createLinkBtn');
492
+ const field = document.getElementById('linkField');
493
+ btn.style.display = 'none';
494
+ field.classList.add('show');
495
+ setTimeout(() => copyToClipboard('vk.com/uwu.chan', field), 100);
496
+ }
497
+
498
+ function generateCode() {
499
+ const btn = document.getElementById('genCodeBtn');
500
+ const field = document.getElementById('codeField');
501
+ btn.style.display = 'none';
502
+ field.classList.add('show');
503
+ setTimeout(() => copyToClipboard('YUfs1if421Hf', field), 100);
504
+ }
505
+
506
+ async function copyToClipboard(text, element) {
507
+ try {
508
+ await navigator.clipboard.writeText(text);
509
+ const originalBg = element.style.background;
510
+ element.style.background = 'var(--success)';
511
+ element.style.color = 'white';
512
+ setTimeout(() => {
513
+ element.style.background = originalBg;
514
+ element.style.color = '';
515
+ }, 300);
516
+ showToast('Copied!', 'success');
517
+ } catch (err) {
518
+ showToast('Copied!', 'success');
519
+ }
520
+ }
521
+
522
+ function completeTask(channel, reward) {
523
+ setTimeout(() => {
524
+ showToast(`+${reward}β‚½ for ${channel}`, 'success');
525
+ state.balance += reward;
526
+ document.querySelector('.balance-main').textContent = state.balance.toFixed(2) + 'β‚½';
527
+ }, 500);
528
+ }
529
+
530
+ // Toast Notification
531
+ function showToast(message, type = 'success') {
532
+ let toast = document.getElementById('appToast');
533
+ if (!toast) {
534
+ toast = document.createElement('div');
535
+ toast.id = 'appToast';
536
+ toast.className = 'toast';
537
+ document.body.appendChild(toast);
538
+ }
539
+
540
+ toast.textContent = message;
541
+ toast.className = `toast ${type} show`;
542
+
543
+ setTimeout(() => {
544
+ toast.classList.remove('show');
545
+ }, 2000);
546
+ }
547
+
548
+ // Start the app
549
+ document.addEventListener('DOMContentLoaded', init);
550
+
551
+ // Prevent bounce on iOS
552
+ document.addEventListener('touchmove', (e) => {
553
+ if (e.target.closest('.info-block')) return;
554
+ e.preventDefault();
555
+ }, { passive: false });
style.css CHANGED
@@ -1,28 +1,732 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
 
 
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
 
 
 
 
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
 
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
 
 
 
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* CSS Custom Properties for easy theming */
2
+ :root {
3
+ --primary: #6366f1;
4
+ --primary-dark: #4f46e5;
5
+ --secondary: #ec4899;
6
+ --secondary-dark: #db2777;
7
+ --bg-main: #f8fafc;
8
+ --bg-surface: #ffffff;
9
+ --bg-elevated: #f1f5f9;
10
+ --text-primary: #0f172a;
11
+ --text-secondary: #64748b;
12
+ --text-muted: #94a3b8;
13
+ --success: #22c55e;
14
+ --warning: #f59e0b;
15
+ --error: #ef4444;
16
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
17
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
18
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
19
+ --radius-sm: 8px;
20
+ --radius-md: 12px;
21
+ --radius-lg: 16px;
22
  }
23
 
24
+ * {
25
+ margin: 0;
26
+ padding: 0;
27
+ box-sizing: border-box;
28
+ -webkit-tap-highlight-color: transparent;
29
  }
30
 
31
+ html, body {
32
+ height: 100%;
33
+ width: 100%;
34
+ overflow: hidden;
35
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
36
+ background: var(--bg-main);
37
+ color: var(--text-primary);
38
+ display: flex;
39
+ flex-direction: column;
40
  }
41
 
42
+ /* Main Block */
43
+ .main-block {
44
+ flex-shrink: 0;
45
+ padding: 20px 16px;
46
+ background: var(--bg-surface);
47
+ border-bottom: 1px solid var(--bg-elevated);
48
+ box-shadow: var(--shadow-sm);
49
  }
50
 
51
+ .wallet-container {
52
+ display: flex;
53
+ flex-direction: column;
54
+ align-items: center;
55
+ gap: 8px;
56
  }
57
+
58
+ .wallet-address {
59
+ display: flex;
60
+ align-items: center;
61
+ gap: 8px;
62
+ position: relative;
63
+ }
64
+
65
+ .address-text {
66
+ font-size: 14px;
67
+ color: var(--text-secondary);
68
+ font-weight: 500;
69
+ letter-spacing: 0.3px;
70
+ }
71
+
72
+ .copy-btn {
73
+ width: 32px;
74
+ height: 32px;
75
+ background: transparent;
76
+ border: none;
77
+ cursor: pointer;
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: center;
81
+ border-radius: var(--radius-sm);
82
+ transition: all 0.15s ease;
83
+ }
84
+
85
+ .copy-btn:active {
86
+ transform: scale(0.92);
87
+ background: var(--bg-elevated);
88
+ }
89
+
90
+ .copy-icon {
91
+ width: 16px;
92
+ height: 16px;
93
+ color: var(--text-secondary);
94
+ }
95
+
96
+ .copy-feedback {
97
+ position: absolute;
98
+ right: -60px;
99
+ font-size: 12px;
100
+ color: var(--success);
101
+ font-weight: 600;
102
+ opacity: 0;
103
+ transform: translateX(-10px);
104
+ transition: all 0.2s ease;
105
+ pointer-events: none;
106
+ }
107
+
108
+ .copy-feedback.show {
109
+ opacity: 1;
110
+ transform: translateX(0);
111
+ }
112
+
113
+ .balance-main {
114
+ font-size: 42px;
115
+ font-weight: 800;
116
+ color: var(--text-primary);
117
+ letter-spacing: -1px;
118
+ line-height: 1;
119
+ }
120
+
121
+ .balance-hold {
122
+ font-size: 15px;
123
+ color: var(--text-muted);
124
+ font-weight: 500;
125
+ }
126
+
127
+ /* Carousel Block */
128
+ .carousel-block {
129
+ flex-shrink: 0;
130
+ width: 100%;
131
+ height: 100px;
132
+ position: relative;
133
+ overflow: hidden;
134
+ background: var(--bg-surface);
135
+ }
136
+
137
+ .carousel-track {
138
+ display: flex;
139
+ height: 100%;
140
+ transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
141
+ will-change: transform;
142
+ }
143
+
144
+ .carousel-slide {
145
+ min-width: 100%;
146
+ height: 100%;
147
+ display: flex;
148
+ align-items: center;
149
+ justify-content: center;
150
+ position: relative;
151
+ }
152
+
153
+ .slide-content {
154
+ display: flex;
155
+ align-items: center;
156
+ gap: 12px;
157
+ padding: 0 20px;
158
+ }
159
+
160
+ .slide-icon {
161
+ width: 40px;
162
+ height: 40px;
163
+ color: white;
164
+ opacity: 0.95;
165
+ }
166
+
167
+ .slide-text {
168
+ color: white;
169
+ font-size: 17px;
170
+ font-weight: 700;
171
+ text-shadow: 0 2px 4px rgba(0,0,0,0.15);
172
+ }
173
+
174
+ .carousel-indicators {
175
+ position: absolute;
176
+ bottom: 8px;
177
+ left: 50%;
178
+ transform: translateX(-50%);
179
+ display: flex;
180
+ gap: 8px;
181
+ z-index: 10;
182
+ }
183
+
184
+ .indicator {
185
+ width: 8px;
186
+ height: 8px;
187
+ border-radius: 50%;
188
+ background: rgba(255,255,255,0.4);
189
+ transition: all 0.3s ease;
190
+ cursor: pointer;
191
+ }
192
+
193
+ .indicator.active {
194
+ background: white;
195
+ width: 24px;
196
+ border-radius: 4px;
197
+ }
198
+
199
+ /* Information Block */
200
+ .info-block {
201
+ flex: 1;
202
+ overflow-y: auto;
203
+ overflow-x: hidden;
204
+ -webkit-overflow-scrolling: touch;
205
+ padding: 16px;
206
+ padding-bottom: 80px;
207
+ }
208
+
209
+ /* Transfer Tab */
210
+ .transfer-form {
211
+ display: flex;
212
+ flex-direction: column;
213
+ gap: 16px;
214
+ }
215
+
216
+ .form-group {
217
+ display: flex;
218
+ flex-direction: column;
219
+ gap: 6px;
220
+ }
221
+
222
+ .form-label {
223
+ font-size: 13px;
224
+ font-weight: 600;
225
+ color: var(--text-secondary);
226
+ text-transform: uppercase;
227
+ letter-spacing: 0.5px;
228
+ }
229
+
230
+ .form-input {
231
+ height: 56px;
232
+ padding: 0 16px;
233
+ font-size: 16px;
234
+ border: 2px solid var(--bg-elevated);
235
+ border-radius: var(--radius-md);
236
+ background: var(--bg-surface);
237
+ color: var(--text-primary);
238
+ transition: all 0.15s ease;
239
+ font-weight: 500;
240
+ }
241
+
242
+ .form-input:focus {
243
+ outline: none;
244
+ border-color: var(--primary);
245
+ box-shadow: 0 0 0 3px rgb(99 102 241 / 0.1);
246
+ }
247
+
248
+ .form-input::placeholder {
249
+ color: var(--text-muted);
250
+ }
251
+
252
+ .btn-primary {
253
+ height: 56px;
254
+ background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
255
+ color: white;
256
+ font-size: 17px;
257
+ font-weight: 700;
258
+ border: none;
259
+ border-radius: var(--radius-md);
260
+ cursor: pointer;
261
+ transition: all 0.15s ease;
262
+ display: flex;
263
+ align-items: center;
264
+ justify-content: center;
265
+ gap: 8px;
266
+ margin-top: 8px;
267
+ box-shadow: var(--shadow-md);
268
+ }
269
+
270
+ .btn-primary:active {
271
+ transform: translateY(2px);
272
+ box-shadow: var(--shadow-sm);
273
+ }
274
+
275
+ .btn-primary:disabled {
276
+ opacity: 0.6;
277
+ cursor: not-allowed;
278
+ }
279
+
280
+ /* Store Tab */
281
+ .store-section {
282
+ margin-bottom: 24px;
283
+ }
284
+
285
+ .section-title {
286
+ font-size: 14px;
287
+ font-weight: 700;
288
+ color: var(--text-secondary);
289
+ text-transform: uppercase;
290
+ letter-spacing: 0.5px;
291
+ margin-bottom: 12px;
292
+ padding-left: 4px;
293
+ }
294
+
295
+ .subscription-card {
296
+ background: var(--bg-surface);
297
+ border-radius: var(--radius-lg);
298
+ padding: 16px;
299
+ margin-bottom: 12px;
300
+ box-shadow: var(--shadow-sm);
301
+ border: 1px solid var(--bg-elevated);
302
+ display: flex;
303
+ flex-direction: column;
304
+ gap: 12px;
305
+ }
306
+
307
+ .subscription-card.purchased {
308
+ border-color: var(--success);
309
+ background: linear-gradient(135deg, rgb(34 197 94 / 0.05) 0%, var(--bg-surface) 100%);
310
+ }
311
+
312
+ .card-header {
313
+ display: flex;
314
+ align-items: center;
315
+ gap: 12px;
316
+ }
317
+
318
+ .level-badge {
319
+ width: 48px;
320
+ height: 48px;
321
+ border-radius: var(--radius-md);
322
+ display: flex;
323
+ align-items: center;
324
+ justify-content: center;
325
+ font-size: 14px;
326
+ font-weight: 800;
327
+ color: white;
328
+ flex-shrink: 0;
329
+ }
330
+
331
+ .lvl1 { background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%); }
332
+ .lvl2 { background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); }
333
+ .lvl3 { background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%); }
334
+ .lvl4 { background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); }
335
+
336
+ .card-info {
337
+ flex: 1;
338
+ }
339
+
340
+ .card-title {
341
+ font-size: 16px;
342
+ font-weight: 700;
343
+ color: var(--text-primary);
344
+ }
345
+
346
+ .card-desc {
347
+ font-size: 13px;
348
+ color: var(--text-secondary);
349
+ margin-top: 2px;
350
+ }
351
+
352
+ .card-status {
353
+ font-size: 12px;
354
+ color: var(--success);
355
+ font-weight: 600;
356
+ margin-top: 4px;
357
+ }
358
+
359
+ .btn-renew, .btn-buy {
360
+ height: 44px;
361
+ border-radius: var(--radius-md);
362
+ font-size: 15px;
363
+ font-weight: 700;
364
+ border: none;
365
+ cursor: pointer;
366
+ transition: all 0.15s ease;
367
+ }
368
+
369
+ .btn-renew {
370
+ background: var(--bg-elevated);
371
+ color: var(--text-primary);
372
+ }
373
+
374
+ .btn-renew:active {
375
+ background: var(--bg-main);
376
+ }
377
+
378
+ .btn-buy {
379
+ color: white;
380
+ box-shadow: var(--shadow-sm);
381
+ }
382
+
383
+ .btn-buy:active {
384
+ transform: scale(0.98);
385
+ }
386
+
387
+ /* History Tab */
388
+ .history-list {
389
+ display: flex;
390
+ flex-direction: column;
391
+ gap: 12px;
392
+ }
393
+
394
+ .history-item {
395
+ background: var(--bg-surface);
396
+ border-radius: var(--radius-lg);
397
+ padding: 16px;
398
+ display: flex;
399
+ justify-content: space-between;
400
+ align-items: center;
401
+ box-shadow: var(--shadow-sm);
402
+ }
403
+
404
+ .history-left {
405
+ display: flex;
406
+ align-items: center;
407
+ gap: 14px;
408
+ }
409
+
410
+ .history-icon {
411
+ width: 44px;
412
+ height: 44px;
413
+ border-radius: var(--radius-md);
414
+ display: flex;
415
+ align-items: center;
416
+ justify-content: center;
417
+ flex-shrink: 0;
418
+ }
419
+
420
+ .icon-in { background: rgb(34 197 94 / 0.15); color: var(--success); }
421
+ .icon-out { background: rgb(239 68 68 / 0.15); color: var(--error); }
422
+ .icon-sub { background: rgb(99 102 241 / 0.15); color: var(--primary); }
423
+ .icon-task { background: rgb(245 158 11 / 0.15); color: var(--warning); }
424
+
425
+ .history-info {
426
+ display: flex;
427
+ flex-direction: column;
428
+ gap: 4px;
429
+ }
430
+
431
+ .history-type {
432
+ font-size: 15px;
433
+ font-weight: 700;
434
+ color: var(--text-primary);
435
+ }
436
+
437
+ .history-date {
438
+ font-size: 13px;
439
+ color: var(--text-muted);
440
+ }
441
+
442
+ .history-amount {
443
+ font-size: 16px;
444
+ font-weight: 800;
445
+ }
446
+
447
+ .positive { color: var(--success); }
448
+ .negative { color: var(--error); }
449
+
450
+ /* Tasks Tab */
451
+ .stats-grid {
452
+ display: grid;
453
+ grid-template-columns: repeat(2, 1fr);
454
+ gap: 12px;
455
+ margin-bottom: 20px;
456
+ }
457
+
458
+ .stat-card {
459
+ background: var(--bg-surface);
460
+ border-radius: var(--radius-lg);
461
+ padding: 16px;
462
+ display: flex;
463
+ flex-direction: column;
464
+ align-items: center;
465
+ gap: 8px;
466
+ box-shadow: var(--shadow-sm);
467
+ }
468
+
469
+ .stat-value {
470
+ font-size: 28px;
471
+ font-weight: 800;
472
+ color: var(--primary);
473
+ }
474
+
475
+ .stat-label {
476
+ font-size: 12px;
477
+ color: var(--text-secondary);
478
+ font-weight: 600;
479
+ text-transform: uppercase;
480
+ letter-spacing: 0.5px;
481
+ }
482
+
483
+ .action-section {
484
+ margin-bottom: 20px;
485
+ }
486
+
487
+ .action-btn, .copy-field {
488
+ width: 100%;
489
+ height: 52px;
490
+ border-radius: var(--radius-md);
491
+ font-size: 15px;
492
+ font-weight: 600;
493
+ cursor: pointer;
494
+ transition: all 0.2s ease;
495
+ }
496
+
497
+ .action-btn {
498
+ background: var(--bg-surface);
499
+ border: 2px solid var(--primary);
500
+ color: var(--primary);
501
+ display: flex;
502
+ align-items: center;
503
+ justify-content: center;
504
+ gap: 8px;
505
+ }
506
+
507
+ .action-btn:active {
508
+ background: rgb(99 102 241 / 0.1);
509
+ }
510
+
511
+ .copy-field {
512
+ display: none;
513
+ background: var(--bg-elevated);
514
+ border: none;
515
+ padding: 0 16px;
516
+ align-items: center;
517
+ justify-content: space-between;
518
+ cursor: pointer;
519
+ }
520
+
521
+ .copy-field.show {
522
+ display: flex;
523
+ }
524
+
525
+ .copy-field-value {
526
+ font-size: 14px;
527
+ color: var(--text-primary);
528
+ font-weight: 600;
529
+ font-family: 'SF Mono', Monaco, monospace;
530
+ }
531
+
532
+ .copy-field-icon {
533
+ width: 20px;
534
+ height: 20px;
535
+ color: var(--text-secondary);
536
+ }
537
+
538
+ .tasks-list {
539
+ display: flex;
540
+ flex-direction: column;
541
+ gap: 12px;
542
+ }
543
+
544
+ .task-card {
545
+ background: var(--bg-surface);
546
+ border-radius: var(--radius-lg);
547
+ padding: 16px;
548
+ box-shadow: var(--shadow-sm);
549
+ display: flex;
550
+ align-items: center;
551
+ gap: 14px;
552
+ cursor: pointer;
553
+ transition: all 0.15s ease;
554
+ text-decoration: none;
555
+ }
556
+
557
+ .task-card:active {
558
+ transform: scale(0.99);
559
+ background: var(--bg-elevated);
560
+ }
561
+
562
+ .task-icon {
563
+ width: 48px;
564
+ height: 48px;
565
+ border-radius: var(--radius-md);
566
+ background: linear-gradient(135deg, #07f 0%, #00d2ff 100%);
567
+ display: flex;
568
+ align-items: center;
569
+ justify-content: center;
570
+ flex-shrink: 0;
571
+ }
572
+
573
+ .task-icon svg {
574
+ width: 24px;
575
+ height: 24px;
576
+ color: white;
577
+ }
578
+
579
+ .task-info {
580
+ flex: 1;
581
+ }
582
+
583
+ .task-title {
584
+ font-size: 15px;
585
+ font-weight: 700;
586
+ color: var(--text-primary);
587
+ }
588
+
589
+ .task-reward {
590
+ font-size: 13px;
591
+ color: var(--success);
592
+ font-weight: 600;
593
+ margin-top: 2px;
594
+ }
595
+
596
+ .task-arrow {
597
+ width: 24px;
598
+ height: 24px;
599
+ color: var(--text-muted);
600
+ }
601
+
602
+ /* Bottom Navigation */
603
+ .nav-panel {
604
+ position: fixed;
605
+ bottom: 0;
606
+ left: 0;
607
+ right: 0;
608
+ height: 64px;
609
+ background: var(--bg-surface);
610
+ border-top: 1px solid var(--bg-elevated);
611
+ display: flex;
612
+ justify-content: space-around;
613
+ align-items: center;
614
+ padding: 0 8px;
615
+ box-shadow: 0 -4px 20px rgba(0,0,0,0.08);
616
+ z-index: 100;
617
+ }
618
+
619
+ .nav-btn {
620
+ flex: 1;
621
+ height: 100%;
622
+ background: transparent;
623
+ border: none;
624
+ display: flex;
625
+ flex-direction: column;
626
+ align-items: center;
627
+ justify-content: center;
628
+ gap: 4px;
629
+ cursor: pointer;
630
+ transition: all 0.15s ease;
631
+ position: relative;
632
+ }
633
+
634
+ .nav-icon {
635
+ width: 24px;
636
+ height: 24px;
637
+ color: var(--text-muted);
638
+ transition: all 0.15s ease;
639
+ }
640
+
641
+ .nav-label {
642
+ font-size: 11px;
643
+ font-weight: 600;
644
+ color: var(--text-muted);
645
+ transition: all 0.15s ease;
646
+ }
647
+
648
+ .nav-btn.active .nav-icon,
649
+ .nav-btn.active .nav-label {
650
+ color: var(--primary);
651
+ }
652
+
653
+ .nav-btn.active::before {
654
+ content: '';
655
+ position: absolute;
656
+ top: 0;
657
+ left: 50%;
658
+ transform: translateX(-50%);
659
+ width: 40px;
660
+ height: 3px;
661
+ background: var(--primary);
662
+ border-radius: 0 0 4px 4px;
663
+ }
664
+
665
+ /* Utility Classes */
666
+ .section-divider {
667
+ height: 8px;
668
+ background: transparent;
669
+ }
670
+
671
+ /* Mobile Optimization */
672
+ @media (max-width: 480px) {
673
+ .balance-main {
674
+ font-size: 38px;
675
+ }
676
+
677
+ .slide-text {
678
+ font-size: 15px;
679
+ }
680
+ }
681
+
682
+ /* Loading Animation */
683
+ @keyframes pulse {
684
+ 0%, 100% { opacity: 1; }
685
+ 50% { opacity: 0.5; }
686
+ }
687
+
688
+ .loading {
689
+ animation: pulse 1.5s ease-in-out infinite;
690
+ }
691
+
692
+ /* Toast Notification */
693
+ .toast {
694
+ position: fixed;
695
+ top: 20px;
696
+ left: 50%;
697
+ transform: translateX(-50%);
698
+ background: var(--text-primary);
699
+ color: white;
700
+ padding: 12px 24px;
701
+ border-radius: var(--radius-lg);
702
+ font-size: 14px;
703
+ font-weight: 600;
704
+ opacity: 0;
705
+ pointer-events: none;
706
+ transition: all 0.3s ease;
707
+ z-index: 200;
708
+ box-shadow: var(--shadow-lg);
709
+ }
710
+
711
+ .toast.show {
712
+ opacity: 1;
713
+ transform: translateX(-50%) translateY(0);
714
+ }
715
+
716
+ .toast.success {
717
+ background: var(--success);
718
+ }
719
+
720
+ /* Scrollbar Styling */
721
+ .info-block::-webkit-scrollbar {
722
+ width: 4px;
723
+ }
724
+
725
+ .info-block::-webkit-scrollbar-track {
726
+ background: transparent;
727
+ }
728
+
729
+ .info-block::-webkit-scrollbar-thumb {
730
+ background: var(--text-muted);
731
+ border-radius: 2px;
732
+ }