opensource / chino-cartas.html
🌑
汉字 Flash Cards
Juego de tarjetas con estética oscura para aprender caracteres chinos básicos. Pistas visuales, pinyin y combinaciones de palabras.
🇨🇳 Chino · Mandarín HTML CSS JavaScript Flashcards Chinese MIT License
1 archivo 730 líneas MIT
Ver en AlpacaViajes Volver
chino-cartas.html 730 líneas
HTML · CSS · JavaScript
1 <!DOCTYPE html>
2 class="tok-tag"><htmlclass="tok-attr"> lang="es"class="tok-tag">>
3 class="tok-tag"><headclass="tok-attr">class="tok-tag">>
4 class="tok-tag"><metaclass="tok-attr"> charset="UTF-8"class="tok-tag">>
5 class="tok-tag"><metaclass="tok-attr"> name="viewport" content="width=device-width, initial-scale=1.0"class="tok-tag">>
6 class="tok-tag"><titleclass="tok-attr">class="tok-tag">>汉字 — Aprende Chinoclass="tok-tag"></titleclass="tok-attr">class="tok-tag">>
7 class="tok-tag"><linkclass="tok-attr"> href="class="tok-prop">https:class="tok-val">//fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;700&family=class="tok-prop">Quicksand:class="tok-val">wght@400;600;700&display=swap" rel="stylesheet"class="tok-tag">>
8 class="tok-tag"><styleclass="tok-attr">class="tok-tag">>
9 :root {
10 class="tok-prop">--bg: class="tok-val">#0d0d0d;
11 class="tok-prop">--surface: class="tok-val">#161616;
12 class="tok-prop">--card-front: class="tok-val">#1a1a2e;
13 class="tok-prop">--card-back: class="tok-val">#16213e;
14 class="tok-prop">--accent: class="tok-val">#e94560;
15 class="tok-prop">--gold: class="tok-val">#f5a623;
16 class="tok-prop">--text: class="tok-val">#f0f0f0;
17 class="tok-prop">--muted: class="tok-val">#888;
18 class="tok-prop">--green: class="tok-val">#4caf50;
19 class="tok-prop">--red: class="tok-val">#e94560;
20 class="tok-prop">--radius: class="tok-val">20px;
21 }
22
23 * { class="tok-prop">margin: class="tok-val">0; class="tok-prop">padding: class="tok-val">0; class="tok-prop">box-sizing: class="tok-val">border-box; }
24
25 body {
26 class="tok-prop">background: class="tok-val">class="tok-kw">var(--bg);
27 class="tok-prop">color: class="tok-val">class="tok-kw">var(--text);
28 class="tok-prop">font-family: class="tok-val">';Quicksand', sans-serif;
29 class="tok-prop">min-height: class="tok-val">100vh;
30 class="tok-prop">display: class="tok-val">flex;
31 class="tok-prop">flex-direction: class="tok-val">column;
32 class="tok-prop">align-items: class="tok-val">center;
33 class="tok-prop">justify-content: class="tok-val">flex-start;
34 class="tok-prop">padding: class="tok-val">30px 20px 60px;
35 class="tok-prop">overflow-x: class="tok-val">hidden;
36 }
37
38 /* Background decoration */
39 class="tok-prop">body:class="tok-val">:before {
40 class="tok-prop">content: class="tok-val">';';
41 class="tok-prop">position: class="tok-val">fixed;
42 class="tok-prop">top: class="tok-val">-200px; class="tok-prop">right: class="tok-val">-200px;
43 class="tok-prop">width: class="tok-val">600px; class="tok-prop">height: class="tok-val">600px;
44 class="tok-prop">background: class="tok-val">radial-gradient(circle, rgba(233,69,96,0.08) 0%, transparent 70%);
45 class="tok-prop">pointer-events: class="tok-val">none;
46 class="tok-prop">z-index: class="tok-val">0;
47 }
48 class="tok-prop">body:class="tok-val">:after {
49 class="tok-prop">content: class="tok-val">';';
50 class="tok-prop">position: class="tok-val">fixed;
51 class="tok-prop">bottom: class="tok-val">-200px; class="tok-prop">left: class="tok-val">-200px;
52 class="tok-prop">width: class="tok-val">500px; class="tok-prop">height: class="tok-val">500px;
53 class="tok-prop">background: class="tok-val">radial-gradient(circle, rgba(245,166,35,0.06) 0%, transparent 70%);
54 class="tok-prop">pointer-events: class="tok-val">none;
55 class="tok-prop">z-index: class="tok-val">0;
56 }
57
58 header {
59 class="tok-prop">text-align: class="tok-val">center;
60 class="tok-prop">margin-bottom: class="tok-val">30px;
61 class="tok-prop">position: class="tok-val">relative; class="tok-prop">z-index: class="tok-val">1;
62 }
63
64 .lang-badge {
65 class="tok-prop">display: class="tok-val">inline-block;
66 class="tok-prop">background: class="tok-val">class="tok-kw">var(--accent);
67 class="tok-prop">color: class="tok-val">white;
68 class="tok-prop">font-size: class="tok-val">11px;
69 class="tok-prop">font-weight: class="tok-val">700;
70 class="tok-prop">letter-spacing: class="tok-val">3px;
71 class="tok-prop">text-transform: class="tok-val">uppercase;
72 class="tok-prop">padding: class="tok-val">4px 14px;
73 class="tok-prop">border-radius: class="tok-val">20px;
74 class="tok-prop">margin-bottom: class="tok-val">10px;
75 }
76
77 h1 {
78 class="tok-prop">font-family: class="tok-val">';Noto Serif SC', serif;
79 class="tok-prop">font-size: class="tok-val">clamp(2rem, 6vw, 3.5rem);
80 class="tok-prop">color: class="tok-val">class="tok-kw">var(--text);
81 class="tok-prop">line-height: class="tok-val">1;
82 class="tok-prop">margin-bottom: class="tok-val">6px;
83 }
84
85 .subtitle {
86 class="tok-prop">color: class="tok-val">class="tok-kw">var(--muted);
87 class="tok-prop">font-size: class="tok-val">13px;
88 class="tok-prop">letter-spacing: class="tok-val">1px;
89 }
90
91 /* Progress */
92 .progress-wrap {
93 class="tok-prop">width: class="tok-val">100%;
94 class="tok-prop">max-width: class="tok-val">500px;
95 class="tok-prop">margin-bottom: class="tok-val">20px;
96 class="tok-prop">position: class="tok-val">relative; class="tok-prop">z-index: class="tok-val">1;
97 }
98
99 .progress-info {
100 class="tok-prop">display: class="tok-val">flex;
101 class="tok-prop">justify-content: class="tok-val">space-between;
102 class="tok-prop">font-size: class="tok-val">12px;
103 class="tok-prop">color: class="tok-val">class="tok-kw">var(--muted);
104 class="tok-prop">margin-bottom: class="tok-val">8px;
105 }
106
107 .progress-bar {
108 class="tok-prop">height: class="tok-val">4px;
109 class="tok-prop">background: class="tok-val">#2a2a2a;
110 class="tok-prop">border-radius: class="tok-val">4px;
111 class="tok-prop">overflow: class="tok-val">hidden;
112 }
113
114 .progress-fill {
115 class="tok-prop">height: class="tok-val">100%;
116 class="tok-prop">background: class="tok-val">linear-gradient(90deg, class="tok-kw">var(--accent), class="tok-kw">var(--gold));
117 class="tok-prop">border-radius: class="tok-val">4px;
118 class="tok-prop">transition: class="tok-val">width 0.4s ease;
119 }
120
121 .score-row {
122 class="tok-prop">display: class="tok-val">flex;
123 class="tok-prop">gap: class="tok-val">16px;
124 class="tok-prop">justify-content: class="tok-val">center;
125 class="tok-prop">margin-bottom: class="tok-val">24px;
126 class="tok-prop">position: class="tok-val">relative; class="tok-prop">z-index: class="tok-val">1;
127 }
128
129 .score-pill {
130 class="tok-prop">display: class="tok-val">flex;
131 class="tok-prop">align-items: class="tok-val">center;
132 class="tok-prop">gap: class="tok-val">6px;
133 class="tok-prop">background: class="tok-val">#1e1e1e;
134 class="tok-prop">border-radius: class="tok-val">30px;
135 class="tok-prop">padding: class="tok-val">6px 16px;
136 class="tok-prop">font-size: class="tok-val">13px;
137 class="tok-prop">font-weight: class="tok-val">600;
138 }
139
140 .score-pill .dot {
141 class="tok-prop">width: class="tok-val">8px; class="tok-prop">height: class="tok-val">8px;
142 class="tok-prop">border-radius: class="tok-val">50%;
143 }
144
145 .dot-green { class="tok-prop">background: class="tok-val">class="tok-kw">var(--green); }
146 .dot-red { class="tok-prop">background: class="tok-val">class="tok-kw">var(--red); }
147
148 /* CARD */
149 .card-area {
150 class="tok-prop">perspective: class="tok-val">1200px;
151 class="tok-prop">width: class="tok-val">320px;
152 class="tok-prop">height: class="tok-val">420px;
153 class="tok-prop">margin-bottom: class="tok-val">28px;
154 class="tok-prop">position: class="tok-val">relative; class="tok-prop">z-index: class="tok-val">1;
155 class="tok-prop">cursor: class="tok-val">pointer;
156 }
157
158 .card-inner {
159 class="tok-prop">width: class="tok-val">100%;
160 class="tok-prop">height: class="tok-val">100%;
161 class="tok-prop">position: class="tok-val">relative;
162 class="tok-prop">transform-style: class="tok-val">preserve-3d;
163 class="tok-prop">transition: class="tok-val">transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
164 }
165
166 .card-inner.flipped {
167 class="tok-prop">transform: class="tok-val">rotateY(180deg);
168 }
169
170 .card-face {
171 class="tok-prop">position: class="tok-val">absolute;
172 class="tok-prop">inset: class="tok-val">0;
173 class="tok-prop">border-radius: class="tok-val">class="tok-kw">var(--radius);
174 class="tok-prop">backface-visibility: class="tok-val">hidden;
175 class="tok-prop">display: class="tok-val">flex;
176 class="tok-prop">flex-direction: class="tok-val">column;
177 class="tok-prop">align-items: class="tok-val">center;
178 class="tok-prop">justify-content: class="tok-val">center;
179 class="tok-prop">padding: class="tok-val">30px;
180 class="tok-prop">border: class="tok-val">1px solid rgba(255,255,255,0.06);
181 }
182
183 .card-front {
184 class="tok-prop">background: class="tok-val">linear-gradient(145deg, #1a1a2e 0%, #0f0f1a 100%);
185 class="tok-prop">box-shadow: class="tok-val">0 20px 60px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.05);
186 }
187
188 .card-back {
189 class="tok-prop">background: class="tok-val">linear-gradient(145deg, #16213e 0%, #0a0f1e 100%);
190 class="tok-prop">box-shadow: class="tok-val">0 20px 60px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.05);
191 class="tok-prop">transform: class="tok-val">rotateY(180deg);
192 }
193
194 .card-level {
195 class="tok-prop">position: class="tok-val">absolute;
196 class="tok-prop">top: class="tok-val">18px; class="tok-prop">left: class="tok-val">18px;
197 class="tok-prop">font-size: class="tok-val">10px;
198 class="tok-prop">font-weight: class="tok-val">700;
199 class="tok-prop">letter-spacing: class="tok-val">2px;
200 class="tok-prop">color: class="tok-val">class="tok-kw">var(--accent);
201 class="tok-prop">text-transform: class="tok-val">uppercase;
202 }
203
204 .card-num {
205 class="tok-prop">position: class="tok-val">absolute;
206 class="tok-prop">top: class="tok-val">18px; class="tok-prop">right: class="tok-val">18px;
207 class="tok-prop">font-size: class="tok-val">11px;
208 class="tok-prop">color: class="tok-val">class="tok-kw">var(--muted);
209 }
210
211 .hint-emoji {
212 class="tok-prop">font-size: class="tok-val">72px;
213 class="tok-prop">margin-bottom: class="tok-val">16px;
214 class="tok-prop">filter: class="tok-val">drop-shadow(0 0 20px rgba(245,166,35,0.3));
215 class="tok-prop">animation: class="tok-val">float 3s ease-in-out infinite;
216 }
217
218 @keyframes float {
219 0%, 100% { class="tok-prop">transform: class="tok-val">translateY(0px); }
220 50% { class="tok-prop">transform: class="tok-val">translateY(-8px); }
221 }
222
223 .hint-text {
224 class="tok-prop">font-size: class="tok-val">14px;
225 class="tok-prop">color: class="tok-val">class="tok-kw">var(--muted);
226 class="tok-prop">text-align: class="tok-val">center;
227 class="tok-prop">line-height: class="tok-val">1.5;
228 class="tok-prop">font-style: class="tok-val">italic;
229 }
230
231 .tap-hint {
232 class="tok-prop">position: class="tok-val">absolute;
233 class="tok-prop">bottom: class="tok-val">20px;
234 class="tok-prop">font-size: class="tok-val">11px;
235 class="tok-prop">color: class="tok-val">rgba(255,255,255,0.2);
236 class="tok-prop">letter-spacing: class="tok-val">1px;
237 class="tok-prop">display: class="tok-val">flex;
238 class="tok-prop">align-items: class="tok-val">center;
239 class="tok-prop">gap: class="tok-val">6px;
240 }
241
242 .class="tok-prop">tap-hint:class="tok-val">:before, .tap-hint::after {
243 class="tok-prop">content: class="tok-val">';✦';
244 class="tok-prop">font-size: class="tok-val">8px;
245 }
246
247 /* Back face */
248 .char-main {
249 class="tok-prop">font-family: class="tok-val">';Noto Serif SC', serif;
250 class="tok-prop">font-size: class="tok-val">100px;
251 class="tok-prop">line-height: class="tok-val">1;
252 class="tok-prop">margin-bottom: class="tok-val">8px;
253 class="tok-prop">background: class="tok-val">linear-gradient(135deg, #fff 30%, class="tok-kw">var(--gold));
254 class="tok-prop">-webkit-background-clip: class="tok-val">text;
255 class="tok-prop">-webkit-text-fill-color: class="tok-val">transparent;
256 class="tok-prop">background-clip: class="tok-val">text;
257 class="tok-prop">filter: class="tok-val">drop-shadow(0 0 30px rgba(245,166,35,0.2));
258 }
259
260 .pinyin {
261 class="tok-prop">font-size: class="tok-val">22px;
262 class="tok-prop">color: class="tok-val">class="tok-kw">var(--gold);
263 class="tok-prop">font-weight: class="tok-val">600;
264 class="tok-prop">letter-spacing: class="tok-val">2px;
265 class="tok-prop">margin-bottom: class="tok-val">12px;
266 }
267
268 .meaning {
269 class="tok-prop">font-size: class="tok-val">18px;
270 class="tok-prop">color: class="tok-val">class="tok-kw">var(--text);
271 class="tok-prop">font-weight: class="tok-val">600;
272 class="tok-prop">margin-bottom: class="tok-val">6px;
273 }
274
275 .example {
276 class="tok-prop">font-size: class="tok-val">12px;
277 class="tok-prop">color: class="tok-val">class="tok-kw">var(--muted);
278 class="tok-prop">text-align: class="tok-val">center;
279 class="tok-prop">line-height: class="tok-val">1.6;
280 }
281
282 .example span {
283 class="tok-prop">color: class="tok-val">rgba(245,166,35,0.7);
284 }
285
286 /* Buttons */
287 .btn-row {
288 class="tok-prop">display: class="tok-val">flex;
289 class="tok-prop">gap: class="tok-val">16px;
290 class="tok-prop">position: class="tok-val">relative; class="tok-prop">z-index: class="tok-val">1;
291 class="tok-prop">margin-bottom: class="tok-val">20px;
292 }
293
294 .btn {
295 class="tok-prop">padding: class="tok-val">14px 32px;
296 class="tok-prop">border-radius: class="tok-val">50px;
297 class="tok-prop">border: class="tok-val">none;
298 class="tok-prop">font-family: class="tok-val">';Quicksand', sans-serif;
299 class="tok-prop">font-size: class="tok-val">14px;
300 class="tok-prop">font-weight: class="tok-val">700;
301 class="tok-prop">cursor: class="tok-val">pointer;
302 class="tok-prop">letter-spacing: class="tok-val">0.5px;
303 class="tok-prop">transition: class="tok-val">all 0.2s ease;
304 class="tok-prop">display: class="tok-val">flex;
305 class="tok-prop">align-items: class="tok-val">center;
306 class="tok-prop">gap: class="tok-val">8px;
307 }
308
309 .class="tok-prop">btn:class="tok-val">active { class="tok-prop">transform: class="tok-val">scale(0.95); }
310
311 .btn-yes {
312 class="tok-prop">background: class="tok-val">linear-gradient(135deg, #2d6a4f, #4caf50);
313 class="tok-prop">color: class="tok-val">white;
314 class="tok-prop">box-shadow: class="tok-val">0 8px 24px rgba(76,175,80,0.3);
315 }
316
317 .class="tok-prop">btn-yes:class="tok-val">hover {
318 class="tok-prop">box-shadow: class="tok-val">0 12px 32px rgba(76,175,80,0.45);
319 class="tok-prop">transform: class="tok-val">translateY(-2px);
320 }
321
322 .btn-no {
323 class="tok-prop">background: class="tok-val">linear-gradient(135deg, #7b1a2a, #e94560);
324 class="tok-prop">color: class="tok-val">white;
325 class="tok-prop">box-shadow: class="tok-val">0 8px 24px rgba(233,69,96,0.3);
326 }
327
328 .class="tok-prop">btn-no:class="tok-val">hover {
329 class="tok-prop">box-shadow: class="tok-val">0 12px 32px rgba(233,69,96,0.45);
330 class="tok-prop">transform: class="tok-val">translateY(-2px);
331 }
332
333 .btn-flip {
334 class="tok-prop">background: class="tok-val">linear-gradient(135deg, #2a2a2a, #3a3a3a);
335 class="tok-prop">color: class="tok-val">class="tok-kw">var(--text);
336 class="tok-prop">box-shadow: class="tok-val">0 8px 24px rgba(0,0,0,0.3);
337 class="tok-prop">border: class="tok-val">1px solid rgba(255,255,255,0.08);
338 }
339
340 .class="tok-prop">btn-flip:class="tok-val">hover {
341 class="tok-prop">background: class="tok-val">linear-gradient(135deg, #3a3a3a, #4a4a4a);
342 class="tok-prop">transform: class="tok-val">translateY(-2px);
343 }
344
345 .btn[disabled] {
346 class="tok-prop">opacity: class="tok-val">0.3;
347 class="tok-prop">cursor: class="tok-val">not-allowed;
348 class="tok-prop">transform: class="tok-val">none !important;
349 class="tok-prop">box-shadow: class="tok-val">none !important;
350 }
351
352 /* Result screen */
353 .result-screen {
354 class="tok-prop">display: class="tok-val">none;
355 class="tok-prop">flex-direction: class="tok-val">column;
356 class="tok-prop">align-items: class="tok-val">center;
357 class="tok-prop">text-align: class="tok-val">center;
358 class="tok-prop">position: class="tok-val">relative; class="tok-prop">z-index: class="tok-val">1;
359 class="tok-prop">animation: class="tok-val">fadeIn 0.5s ease;
360 }
361
362 @keyframes fadeIn {
363 from { class="tok-prop">opacity: class="tok-val">0; class="tok-prop">transform: class="tok-val">translateY(20px); }
364 to { class="tok-prop">opacity: class="tok-val">1; class="tok-prop">transform: class="tok-val">translateY(0); }
365 }
366
367 .result-screen.active { class="tok-prop">display: class="tok-val">flex; }
368
369 .result-emoji { class="tok-prop">font-size: class="tok-val">80px; class="tok-prop">margin-bottom: class="tok-val">20px; }
370
371 .result-title {
372 class="tok-prop">font-family: class="tok-val">';Noto Serif SC', serif;
373 class="tok-prop">font-size: class="tok-val">2rem;
374 class="tok-prop">margin-bottom: class="tok-val">8px;
375 }
376
377 .result-sub {
378 class="tok-prop">color: class="tok-val">class="tok-kw">var(--muted);
379 class="tok-prop">font-size: class="tok-val">14px;
380 class="tok-prop">margin-bottom: class="tok-val">30px;
381 class="tok-prop">line-height: class="tok-val">1.6;
382 }
383
384 .result-stats {
385 class="tok-prop">display: class="tok-val">flex;
386 class="tok-prop">gap: class="tok-val">30px;
387 class="tok-prop">margin-bottom: class="tok-val">30px;
388 }
389
390 .stat {
391 class="tok-prop">display: class="tok-val">flex;
392 class="tok-prop">flex-direction: class="tok-val">column;
393 class="tok-prop">align-items: class="tok-val">center;
394 class="tok-prop">gap: class="tok-val">4px;
395 }
396
397 .stat-num {
398 class="tok-prop">font-size: class="tok-val">2.5rem;
399 class="tok-prop">font-weight: class="tok-val">700;
400 class="tok-prop">line-height: class="tok-val">1;
401 }
402
403 .stat-label {
404 class="tok-prop">font-size: class="tok-val">11px;
405 class="tok-prop">color: class="tok-val">class="tok-kw">var(--muted);
406 class="tok-prop">text-transform: class="tok-val">uppercase;
407 class="tok-prop">letter-spacing: class="tok-val">1px;
408 }
409
410 .btn-restart {
411 class="tok-prop">background: class="tok-val">linear-gradient(135deg, class="tok-kw">var(--accent), #c0392b);
412 class="tok-prop">color: class="tok-val">white;
413 class="tok-prop">padding: class="tok-val">16px 40px;
414 class="tok-prop">font-size: class="tok-val">15px;
415 class="tok-prop">box-shadow: class="tok-val">0 12px 32px rgba(233,69,96,0.35);
416 }
417
418 .class="tok-prop">btn-restart:class="tok-val">hover {
419 class="tok-prop">transform: class="tok-val">translateY(-2px);
420 class="tok-prop">box-shadow: class="tok-val">0 16px 40px rgba(233,69,96,0.5);
421 }
422
423 /* Animations class="tok-kw">for correct/wrong */
424 @keyframes shake {
425 0%, 100% { class="tok-prop">transform: class="tok-val">translateX(0); }
426 20% { class="tok-prop">transform: class="tok-val">translateX(-10px); }
427 40% { class="tok-prop">transform: class="tok-val">translateX(10px); }
428 60% { class="tok-prop">transform: class="tok-val">translateX(-8px); }
429 80% { class="tok-prop">transform: class="tok-val">translateX(8px); }
430 }
431
432 @keyframes pulse-green {
433 0% { class="tok-prop">box-shadow: class="tok-val">0 20px 60px rgba(0,0,0,0.5); }
434 50% { class="tok-prop">box-shadow: class="tok-val">0 20px 60px rgba(76,175,80,0.4), 0 0 40px rgba(76,175,80,0.2); }
435 100% { class="tok-prop">box-shadow: class="tok-val">0 20px 60px rgba(0,0,0,0.5); }
436 }
437
438 .shake { class="tok-prop">animation: class="tok-val">shake 0.4s ease; }
439 .pulse-green .card-inner { class="tok-prop">animation: class="tok-val">pulse-green 0.5s ease; }
440
441 .game-area { class="tok-prop">position: class="tok-val">relative; class="tok-prop">z-index: class="tok-val">1; class="tok-prop">display: class="tok-val">flex; class="tok-prop">flex-direction: class="tok-val">column; class="tok-prop">align-items: class="tok-val">center; }
442 class="tok-tag"></styleclass="tok-attr">class="tok-tag">>
443 class="tok-tag"></headclass="tok-attr">class="tok-tag">>
444 class="tok-tag"><bodyclass="tok-attr">class="tok-tag">>
445
446 class="tok-tag"><headerclass="tok-attr">class="tok-tag">>
447 class="tok-tag"><divclass="tok-attr"> class="lang-badge"class="tok-tag">>🇨🇳 Chino Mandarínclass="tok-tag"></divclass="tok-attr">class="tok-tag">>
448 class="tok-tag"><h1class="tok-attr">class="tok-tag">>汉字卡片class="tok-tag"></h1class="tok-attr">class="tok-tag">>
449 class="tok-tag"><pclass="tok-attr"> class="subtitle"class="tok-tag">>Aprende con cartas · Nivel 1 · Caracteres básicosclass="tok-tag"></pclass="tok-attr">class="tok-tag">>
450 class="tok-tag"></headerclass="tok-attr">class="tok-tag">>
451
452 class="tok-tag"><divclass="tok-attr"> class="progress-wrap"class="tok-tag">>
453 class="tok-tag"><divclass="tok-attr"> class="progress-info"class="tok-tag">>
454 class="tok-tag"><spanclass="tok-attr"> id="prog-text"class="tok-tag">>Carta 1 de 10class="tok-tag"></spanclass="tok-attr">class="tok-tag">>
455 class="tok-tag"><spanclass="tok-attr"> id="prog-pct"class="tok-tag">>0%class="tok-tag"></spanclass="tok-attr">class="tok-tag">>
456 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
457 class="tok-tag"><divclass="tok-attr"> class="progress-bar"class="tok-tag">>
458 class="tok-tag"><divclass="tok-attr"> class="progress-fill" id="progress-fill" style="class="tok-prop">width:class="tok-val">0%";class="tok-tag">>class="tok-tag"></divclass="tok-attr">class="tok-tag">>
459 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
460 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
461
462 class="tok-tag"><divclass="tok-attr"> class="score-row"class="tok-tag">>
463 class="tok-tag"><divclass="tok-attr"> class="score-pill"class="tok-tag">>
464 class="tok-tag"><divclass="tok-attr"> class="dot dot-green"class="tok-tag">>class="tok-tag"></divclass="tok-attr">class="tok-tag">>
465 class="tok-tag"><spanclass="tok-attr"> id="score-yes"class="tok-tag">>0class="tok-tag"></spanclass="tok-attr">class="tok-tag">> correctas
466 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
467 class="tok-tag"><divclass="tok-attr"> class="score-pill"class="tok-tag">>
468 class="tok-tag"><divclass="tok-attr"> class="dot dot-red"class="tok-tag">>class="tok-tag"></divclass="tok-attr">class="tok-tag">>
469 class="tok-tag"><spanclass="tok-attr"> id="score-no"class="tok-tag">>0class="tok-tag"></spanclass="tok-attr">class="tok-tag">> a repasar
470 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
471 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
472
473 class="tok-tag"><divclass="tok-attr"> class="game-area" id="game-area"class="tok-tag">>
474 class="tok-tag"><divclass="tok-attr"> class="card-area" id="card-area" onclick="flipCard()"class="tok-tag">>
475 class="tok-tag"><divclass="tok-attr"> class="card-inner" id="card-inner"class="tok-tag">>
476
477 class="tok-tag"><divclass="tok-attr"> class="card-face card-front"class="tok-tag">>
478 class="tok-tag"><divclass="tok-attr"> class="card-level"class="tok-tag">>Pistaclass="tok-tag"></divclass="tok-attr">class="tok-tag">>
479 class="tok-tag"><divclass="tok-attr"> class="card-num" id="card-num"class="tok-tag">>1/10class="tok-tag"></divclass="tok-attr">class="tok-tag">>
480 class="tok-tag"><divclass="tok-attr"> class="hint-emoji" id="hint-emoji"class="tok-tag">>🔥class="tok-tag"></divclass="tok-attr">class="tok-tag">>
481 class="tok-tag"><divclass="tok-attr"> class="hint-text" id="hint-text"class="tok-tag">>"Calienta, ilumina,class="tok-tag"><brclass="tok-attr">class="tok-tag">>puede destruir o crear"class="tok-tag"></divclass="tok-attr">class="tok-tag">>
482 class="tok-tag"><divclass="tok-attr"> class="tap-hint"class="tok-tag">>toca para revelarclass="tok-tag"></divclass="tok-attr">class="tok-tag">>
483 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
484
485 class="tok-tag"><divclass="tok-attr"> class="card-face card-back"class="tok-tag">>
486 class="tok-tag"><divclass="tok-attr"> class="card-level"class="tok-tag">>Respuestaclass="tok-tag"></divclass="tok-attr">class="tok-tag">>
487 class="tok-tag"><divclass="tok-attr"> class="char-main" id="char-main"class="tok-tag">>火class="tok-tag"></divclass="tok-attr">class="tok-tag">>
488 class="tok-tag"><divclass="tok-attr"> class="pinyin" id="pinyin"class="tok-tag">>huǒclass="tok-tag"></divclass="tok-attr">class="tok-tag">>
489 class="tok-tag"><divclass="tok-attr"> class="meaning" id="meaning"class="tok-tag">>FUEGOclass="tok-tag"></divclass="tok-attr">class="tok-tag">>
490 class="tok-tag"><divclass="tok-attr"> class="example" id="example"class="tok-tag">>火山 (huǒshān) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Volcánclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>class="tok-tag"><brclass="tok-attr">class="tok-tag">>火车 (huǒchē) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Trenclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>class="tok-tag"></divclass="tok-attr">class="tok-tag">>
491 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
492
493 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
494 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
495
496 class="tok-tag"><divclass="tok-attr"> class="btn-row" id="btn-row"class="tok-tag">>
497 class="tok-tag"><buttonclass="tok-attr"> class="btn btn-no" id="btn-no" onclick="answer(false)" disabledclass="tok-tag">>✗ A repasarclass="tok-tag"></buttonclass="tok-attr">class="tok-tag">>
498 class="tok-tag"><buttonclass="tok-attr"> class="btn btn-flip" onclick="flipCard()"class="tok-tag">>↺ Voltearclass="tok-tag"></buttonclass="tok-attr">class="tok-tag">>
499 class="tok-tag"><buttonclass="tok-attr"> class="btn btn-yes" id="btn-yes" onclick="answer(true)" disabledclass="tok-tag">>✓ Lo sabíaclass="tok-tag"></buttonclass="tok-attr">class="tok-tag">>
500 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
501 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
502
503 class="tok-tag"><divclass="tok-attr"> class="result-screen" id="result-screen"class="tok-tag">>
504 class="tok-tag"><divclass="tok-attr"> class="result-emoji" id="result-emoji"class="tok-tag">>🎉class="tok-tag"></divclass="tok-attr">class="tok-tag">>
505 class="tok-tag"><divclass="tok-attr"> class="result-title" id="result-title"class="tok-tag">>¡Bien hecho!class="tok-tag"></divclass="tok-attr">class="tok-tag">>
506 class="tok-tag"><divclass="tok-attr"> class="result-sub" id="result-sub"class="tok-tag">>Completaste el mazo de hoyclass="tok-tag"></divclass="tok-attr">class="tok-tag">>
507 class="tok-tag"><divclass="tok-attr"> class="result-stats"class="tok-tag">>
508 class="tok-tag"><divclass="tok-attr"> class="stat"class="tok-tag">>
509 class="tok-tag"><divclass="tok-attr"> class="stat-num" id="res-yes" style="class="tok-prop">color:class="tok-val">class="tok-kw">var(--green)";class="tok-tag">>0class="tok-tag"></divclass="tok-attr">class="tok-tag">>
510 class="tok-tag"><divclass="tok-attr"> class="stat-label"class="tok-tag">>Correctasclass="tok-tag"></divclass="tok-attr">class="tok-tag">>
511 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
512 class="tok-tag"><divclass="tok-attr"> class="stat"class="tok-tag">>
513 class="tok-tag"><divclass="tok-attr"> class="stat-num" id="res-no" style="class="tok-prop">color:class="tok-val">class="tok-kw">var(--red)";class="tok-tag">>0class="tok-tag"></divclass="tok-attr">class="tok-tag">>
514 class="tok-tag"><divclass="tok-attr"> class="stat-label"class="tok-tag">>A repasarclass="tok-tag"></divclass="tok-attr">class="tok-tag">>
515 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
516 class="tok-tag"><divclass="tok-attr"> class="stat"class="tok-tag">>
517 class="tok-tag"><divclass="tok-attr"> class="stat-num" id="res-pct" style="class="tok-prop">color:class="tok-val">class="tok-kw">var(--gold)";class="tok-tag">>0%class="tok-tag"></divclass="tok-attr">class="tok-tag">>
518 class="tok-tag"><divclass="tok-attr"> class="stat-label"class="tok-tag">>Dominioclass="tok-tag"></divclass="tok-attr">class="tok-tag">>
519 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
520 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
521 class="tok-tag"><buttonclass="tok-attr"> class="btn btn-restart" onclick="restartGame()"class="tok-tag">>↺ Jugar de nuevoclass="tok-tag"></buttonclass="tok-attr">class="tok-tag">>
522 class="tok-tag"></divclass="tok-attr">class="tok-tag">>
523
524 class="tok-tag"><scriptclass="tok-attr">class="tok-tag">>
525 class="tok-kw">const cards = [
526 {
527 class="tok-prop">emoji: class="tok-val">';🔥',
528 class="tok-prop">hint: class="tok-val">';"Calienta, ilumina,class="tok-tag"><brclass="tok-attr">class="tok-tag">>puede destruir o crear"',
529 class="tok-prop">char: class="tok-val">';火',
530 class="tok-prop">pinyin: class="tok-val">';huǒ',
531 class="tok-prop">meaning: class="tok-val">';FUEGO',
532 class="tok-prop">example: class="tok-val">';火山 (huǒshān) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Volcánclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>class="tok-tag"><brclass="tok-attr">class="tok-tag">>火车 (huǒchē) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Trenclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>'
533 },
534 {
535 class="tok-prop">emoji: class="tok-val">';💧',
536 class="tok-prop">hint: class="tok-val">';"Transparente, vital,class="tok-tag"><brclass="tok-attr">class="tok-tag">>cae del cielo"',
537 class="tok-prop">char: class="tok-val">';水',
538 class="tok-prop">pinyin: class="tok-val">';shuǐ',
539 class="tok-prop">meaning: class="tok-val">';AGUA',
540 class="tok-prop">example: class="tok-val">';水果 (shuǐguǒ) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Frutaclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>class="tok-tag"><brclass="tok-attr">class="tok-tag">>水平 (shuǐpíng) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Nivel / Horizontalclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>'
541 },
542 {
543 class="tok-prop">emoji: class="tok-val">';⛰️',
544 class="tok-prop">hint: class="tok-val">';"Tres picos,class="tok-tag"><brclass="tok-attr">class="tok-tag">>muy alto, muy antiguo"',
545 class="tok-prop">char: class="tok-val">';山',
546 class="tok-prop">pinyin: class="tok-val">';shān',
547 class="tok-prop">meaning: class="tok-val">';MONTAÑA',
548 class="tok-prop">example: class="tok-val">';山水 (shānshuǐ) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Paisajeclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>class="tok-tag"><brclass="tok-attr">class="tok-tag">>火山 (huǒshān) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Volcánclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>'
549 },
550 {
551 class="tok-prop">emoji: class="tok-val">';🚶',
552 class="tok-prop">hint: class="tok-val">';"Dos piernas caminando,class="tok-tag"><brclass="tok-attr">class="tok-tag">>somos todos nosotros"',
553 class="tok-prop">char: class="tok-val">';人',
554 class="tok-prop">pinyin: class="tok-val">';rén',
555 class="tok-prop">meaning: class="tok-val">';PERSONA',
556 class="tok-prop">example: class="tok-val">';人口 (rénkǒu) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Poblaciónclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>class="tok-tag"><brclass="tok-attr">class="tok-tag">>人生 (rénshēng) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Vida humanaclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>'
557 },
558 {
559 class="tok-prop">emoji: class="tok-val">';☀️',
560 class="tok-prop">hint: class="tok-val">';"Redondo, brillante,class="tok-tag"><brclass="tok-attr">class="tok-tag">>aparece cada mañana"',
561 class="tok-prop">char: class="tok-val">';日',
562 class="tok-prop">pinyin: class="tok-val">';rì',
563 class="tok-prop">meaning: class="tok-val">';SOL / DÍA',
564 class="tok-prop">example: class="tok-val">';日本 (rìběn) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Japónclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>class="tok-tag"><brclass="tok-attr">class="tok-tag">>生日 (shēngrì) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Cumpleañosclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>'
565 },
566 {
567 class="tok-prop">emoji: class="tok-val">';🌙',
568 class="tok-prop">hint: class="tok-val">';"La luz de la noche,class="tok-tag"><brclass="tok-attr">class="tok-tag">>cambia de forma cada semana"',
569 class="tok-prop">char: class="tok-val">';月',
570 class="tok-prop">pinyin: class="tok-val">';yuè',
571 class="tok-prop">meaning: class="tok-val">';LUNA / MES',
572 class="tok-prop">example: class="tok-val">';月亮 (yuèliàng) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>La lunaclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>class="tok-tag"><brclass="tok-attr">class="tok-tag">>月饼 (yuèbǐng) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Pastel de lunaclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>'
573 },
574 {
575 class="tok-prop">emoji: class="tok-val">';🌳',
576 class="tok-prop">hint: class="tok-val">';"Raíces abajo,class="tok-tag"><brclass="tok-attr">class="tok-tag">>ramas arriba"',
577 class="tok-prop">char: class="tok-val">';木',
578 class="tok-prop">pinyin: class="tok-val">';mù',
579 class="tok-prop">meaning: class="tok-val">';ÁRBOL / MADERA',
580 class="tok-prop">example: class="tok-val">';木头 (mùtou) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Maderaclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>class="tok-tag"><brclass="tok-attr">class="tok-tag">>木耳 (mù\'ěr) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Hongo negroclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>'
581 },
582 {
583 class="tok-prop">emoji: class="tok-val">';👁️',
584 class="tok-prop">hint: class="tok-val">';"Con esto lees,class="tok-tag"><brclass="tok-attr">class="tok-tag">>con esto ves el mundo"',
585 class="tok-prop">char: class="tok-val">';目',
586 class="tok-prop">pinyin: class="tok-val">';mù',
587 class="tok-prop">meaning: class="tok-val">';OJO',
588 class="tok-prop">example: class="tok-val">';目标 (mùbiāo) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Objetivo / Metaclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>class="tok-tag"><brclass="tok-attr">class="tok-tag">>注目 (zhùmù) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Prestar atenciónclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>'
589 },
590 {
591 class="tok-prop">emoji: class="tok-val">';👄',
592 class="tok-prop">hint: class="tok-val">';"Hablas, comes,class="tok-tag"><brclass="tok-attr">class="tok-tag">>sonríes con esto"',
593 class="tok-prop">char: class="tok-val">';口',
594 class="tok-prop">pinyin: class="tok-val">';kǒu',
595 class="tok-prop">meaning: class="tok-val">';BOCA',
596 class="tok-prop">example: class="tok-val">';人口 (rénkǒu) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Poblaciónclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>class="tok-tag"><brclass="tok-attr">class="tok-tag">>出口 (chūkǒu) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Salida / Exportarclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>'
597 },
598 {
599 class="tok-prop">emoji: class="tok-val">';🌿',
600 class="tok-prop">hint: class="tok-val">';"Brota de la tierra,class="tok-tag"><brclass="tok-attr">class="tok-tag">>verde y pequeño"',
601 class="tok-prop">char: class="tok-val">';草',
602 class="tok-prop">pinyin: class="tok-val">';cǎo',
603 class="tok-prop">meaning: class="tok-val">';HIERBA / PASTO',
604 class="tok-prop">example: class="tok-val">';草地 (cǎodì) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Céspedclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>class="tok-tag"><brclass="tok-attr">class="tok-tag">>草莓 (cǎoméi) = class="tok-tag"><spanclass="tok-attr">class="tok-tag">>Fresaclass="tok-tag"></spanclass="tok-attr">class="tok-tag">>'
605 }
606 ];
607
608 class="tok-kw">let current = 0;
609 class="tok-kw">let flipped = false;
610 class="tok-kw">let scoreYes = 0;
611 class="tok-kw">let scoreNo = 0;
612 class="tok-kw">let shuffled = [];
613
614 class="tok-kw">function shuffle(arr) {
615 class="tok-kw">return [...arr].sort(() => Math.random() - 0.5);
616 }
617
618 class="tok-kw">function startGame() {
619 shuffled = shuffle(cards);
620 current = 0; scoreYes = 0; scoreNo = 0;
621 flipped = false;
622 document.getElementById('result-screen').classList.remove('active');
623 document.getElementById('game-area').style.display = 'flex';
624 updateScores();
625 loadCard(0);
626 }
627
628 class="tok-kw">function loadCard(idx) {
629 class="tok-kw">const c = shuffled[idx];
630 flipped = false;
631
632 class="tok-kw">const inner = document.getElementById('card-inner');
633 inner.classList.remove('flipped');
634
635 document.getElementById('hint-emoji').textContent = c.emoji;
636 document.getElementById('hint-text').innerHTML = c.hint;
637 document.getElementById('char-main').textContent = c.char;
638 document.getElementById('pinyin').textContent = c.pinyin;
639 document.getElementById('meaning').textContent = c.meaning;
640 document.getElementById('example').innerHTML = c.example;
641 document.getElementById('card-num').textContent = `${idx+1}/10`;
642
643 document.getElementById('btn-yes').disabled = true;
644 document.getElementById('btn-no').disabled = true;
645
646 // Progress
647 class="tok-kw">const pct = Math.round((idx / cards.length) * 100);
648 document.getElementById('progress-fill').style.width = pct + '%';
649 document.getElementById('prog-text').textContent = `Carta ${idx+1} de ${cards.length}`;
650 document.getElementById('prog-pct').textContent = pct + '%';
651 }
652
653 class="tok-kw">function flipCard() {
654 class="tok-kw">if (flipped) class="tok-kw">return;
655 flipped = true;
656 document.getElementById('card-inner').classList.add('flipped');
657 document.getElementById('btn-yes').disabled = false;
658 document.getElementById('btn-no').disabled = false;
659 }
660
661 class="tok-kw">function answer(knew) {
662 class="tok-kw">if (!flipped) class="tok-kw">return;
663 class="tok-kw">const area = document.getElementById('card-area');
664
665 class="tok-kw">if (knew) {
666 scoreYes++;
667 area.classList.add('pulse-green');
668 setTimeout(() => area.classList.remove('pulse-green'), 600);
669 } class="tok-kw">else {
670 scoreNo++;
671 area.classList.add('shake');
672 setTimeout(() => area.classList.remove('shake'), 500);
673 }
674
675 updateScores();
676 current++;
677
678 class="tok-kw">if (current >= shuffled.length) {
679 setTimeout(showResult, 400);
680 } class="tok-kw">else {
681 setTimeout(() => loadCard(current), 350);
682 }
683 }
684
685 class="tok-kw">function updateScores() {
686 document.getElementById('score-yes').textContent = scoreYes;
687 document.getElementById('score-no').textContent = scoreNo;
688 }
689
690 class="tok-kw">function showResult() {
691 document.getElementById('game-area').style.display = 'none';
692 class="tok-kw">const screen = document.getElementById('result-screen');
693 screen.classList.add('active');
694
695 class="tok-kw">const pct = Math.round((scoreYes / cards.length) * 100);
696 document.getElementById('res-yes').textContent = scoreYes;
697 document.getElementById('res-no').textContent = scoreNo;
698 document.getElementById('res-pct').textContent = pct + '%';
699
700 class="tok-kw">let emoji, title, sub;
701 class="tok-kw">if (pct === 100) {
702 emoji = '🏆'; title = '¡Perfecto!'; sub = '100% — ¡Eres un maestro del mandarín!';
703 } class="tok-kw">else class="tok-kw">if (pct >= 70) {
704 emoji = '🌟'; title = '¡Muy bien!'; sub = `Dominaste ${scoreYes} de ${cards.length} caracteres. ¡Sigue así!`;
705 } class="tok-kw">else class="tok-kw">if (pct >= 40) {
706 emoji = '💪'; title = '¡Buen intento!'; sub = `Vas por buen camino. Repasa los que fallaste.`;
707 } class="tok-kw">else {
708 emoji = '🌱'; title = '¡Apenas empiezas!'; sub = `Normal, es tu primera vez. ¡Vuélvelo a intentar!`;
709 }
710
711 document.getElementById('result-emoji').textContent = emoji;
712 document.getElementById('result-title').textContent = title;
713 document.getElementById('result-sub').textContent = sub;
714
715 // Progress to 100%
716 document.getElementById('progress-fill').style.width = '100%';
717 document.getElementById('prog-text').textContent = `¡Completado!`;
718 document.getElementById('prog-pct').textContent = '100%';
719 }
720
721 class="tok-kw">function restartGame() {
722 startGame();
723 }
724
725 // Start!
726 startGame();
727 class="tok-tag"></scriptclass="tok-attr">class="tok-tag">>
728 class="tok-tag"></bodyclass="tok-attr">class="tok-tag">>
729 class="tok-tag"></htmlclass="tok-attr">class="tok-tag">>
730