@mblinkov/whats-missing 20.0.49 → 20.0.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Game.tsx DELETED
@@ -1,1185 +0,0 @@
1
- import { useState, useEffect, useMemo, useRef } from "react";
2
- import { themes } from "./themes";
3
- import { styles } from "./Game.styles";
4
- import type { Theme } from "./themes";
5
-
6
- type ImageItem = { src: string; name: string };
7
- type RoundResult = {
8
- round: number;
9
- answer: string;
10
- correct: string;
11
- result: "correct" | "almost" | "wrong";
12
- };
13
-
14
- // ✅ базовый reset
15
- const globalReset = () => {
16
- const style = document.createElement("style");
17
- style.id = "whats-missing-reset"; // ✅ Добавляем ID для удаления
18
-
19
- style.textContent = `
20
- #whats-missing-root, #whats-missing-root * {
21
- box-sizing: border-box;
22
- font-family: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
23
- }
24
- #whats-missing-root img {
25
- max-width: 100%;
26
- height: auto;
27
- display: block;
28
- user-select: none;
29
- }
30
- html, body {
31
- margin: 0 !important;
32
- padding: 0 !important;
33
- width: 100% !important;
34
- height: 100% !important;
35
- overflow: hidden !important;
36
- zoom: 1 !important; /* ✅ защита от подзума */
37
- }
38
- #root {
39
- margin: 0 !important;
40
- padding: 0 !important;
41
- width: 100% !important;
42
- height: 100% !important;
43
- overflow: hidden !important;
44
- }
45
- `;
46
-
47
- // ✅ Удаляем старый стиль, если он есть
48
- const existingStyle = document.getElementById("whats-missing-reset");
49
- if (existingStyle) {
50
- existingStyle.remove();
51
- }
52
-
53
- document.head.appendChild(style);
54
- };
55
-
56
- // простая функция сравнения
57
- const levenshtein = (a: string, b: string) => {
58
- const dp = Array.from({ length: a.length + 1 }, () => Array(b.length + 1).fill(0));
59
- for (let i = 0; i <= a.length; i++) dp[i][0] = i;
60
- for (let j = 0; j <= b.length; j++) dp[0][j] = j;
61
- for (let i = 1; i <= a.length; i++) {
62
- for (let j = 1; j <= b.length; j++) {
63
- dp[i][j] =
64
- a[i - 1] === b[j - 1]
65
- ? dp[i - 1][j - 1]
66
- : Math.min(dp[i - 1][j - 1], dp[i][j - 1], dp[i - 1][j]) + 1;
67
- }
68
- }
69
- return dp[a.length][b.length];
70
- };
71
-
72
- // ✅ Preload utilities
73
- const preloadImage = (src: string): Promise<HTMLImageElement> => {
74
- return new Promise((resolve) => {
75
- // ✅ Проверяем, не загружена ли уже картинка
76
- const img = new Image();
77
- img.onload = () => resolve(img);
78
- img.onerror = () => resolve(img); // Continue even on error, но img все равно создан
79
- img.src = src;
80
- });
81
- };
82
-
83
- const preloadImages = async (urls: string[], signal?: AbortSignal): Promise<Map<string, HTMLImageElement>> => {
84
- const imageMap = new Map<string, HTMLImageElement>();
85
- const promises = urls.map(async (url) => {
86
- const img = await preloadImage(url);
87
- imageMap.set(url, img);
88
- });
89
- await Promise.allSettled(promises);
90
- return imageMap;
91
- };
92
-
93
- export default function Game({
94
- gameCubeSize,
95
- screenHeight,
96
- screenWidth,
97
- }: {
98
- gameCubeSize?: number;
99
- screenHeight?: number;
100
- screenWidth?: number;
101
- }) {
102
- const containerRef = useRef<HTMLDivElement>(null);
103
-
104
- useEffect(() => {
105
- globalReset();
106
- return () => {
107
- // ✅ Восстанавливаем overflow на html и body
108
- document.documentElement.style.overflow = "";
109
- document.body.style.overflow = "";
110
-
111
- // ✅ Удаляем наш style элемент
112
- const style = document.getElementById("whats-missing-reset");
113
- if (style) {
114
- style.remove();
115
- }
116
-
117
- // ✅ Cancel any ongoing preloads
118
- if (abortController.current) {
119
- abortController.current.abort();
120
- }
121
- };
122
- }, []);
123
-
124
- const [theme, setTheme] = useState<Theme | null>(null);
125
- const [files, setFiles] = useState<ImageItem[]>([]);
126
- const [rounds, setRounds] = useState(4);
127
- const [started, setStarted] = useState(false);
128
- const [currentRound, setCurrentRound] = useState(1);
129
- const [hiddenIndex, setHiddenIndex] = useState<number | null>(null);
130
- const [phase, setPhase] = useState<"ready" | "memorize" | "guess">("ready");
131
- const [readyTime, setReadyTime] = useState(10);
132
- const [memorizeTime, setMemorizeTime] = useState(10);
133
- const [timeLeft, setTimeLeft] = useState(20);
134
- const [score, setScore] = useState(0);
135
- const [finished, setFinished] = useState(false);
136
- const [inputValue, setInputValue] = useState("");
137
- const [answered, setAnswered] = useState(false);
138
- const [animating, setAnimating] = useState(false);
139
- const [result, setResult] = useState<"correct" | "almost" | "wrong" | null>(null);
140
- const [resultsTable, setResultsTable] = useState<RoundResult[]>([]);
141
- const [usedHidden, setUsedHidden] = useState<string[]>([]);
142
- const [isMobile, setIsMobile] = useState(false);
143
- const [scale, setScale] = useState(1);
144
- const [containerSize, setContainerSize] = useState<number | null>(null);
145
- const [isDesktopLayout, setIsDesktopLayout] = useState(false);
146
- const [isIPadMiniPortrait, setIsIPadMiniPortrait] = useState(false);
147
- const [isIPadMiniLandscape, setIsIPadMiniLandscape] = useState(false);
148
- const [isIPadAirPortrait, setIsIPadAirPortrait] = useState(false);
149
- const [isIPadAirLandscape, setIsIPadAirLandscape] = useState(false);
150
- const [isSurfaceDuoPortrait, setIsSurfaceDuoPortrait] = useState(false);
151
- const [isSurfaceDuoLandscape, setIsSurfaceDuoLandscape] = useState(false);
152
- const [isIPadProPortrait, setIsIPadProPortrait] = useState(false);
153
- const [isIPadProLandscape, setIsIPadProLandscape] = useState(false);
154
- const [isHorizontalLayout, setIsHorizontalLayout] = useState(false);
155
- const [isWideScreen, setIsWideScreen] = useState(false);
156
-
157
- // ✅ Система предзагрузки изображений
158
- const preloadedUrls = useRef<Set<string>>(new Set());
159
- const preloadedImages = useRef<Map<string, HTMLImageElement>>(new Map());
160
- const abortController = useRef<AbortController | null>(null);
161
-
162
- // ✅ адаптив под мобилки, планшеты и десктоп
163
- useEffect(() => {
164
- const resize = () => {
165
- const width = screenWidth ?? window.innerWidth;
166
- const height = screenHeight ?? window.innerHeight;
167
- const mobile = width < 768 || (width === 926 && height === 428) || (width === 932 && height === 430); // iPhone 14 Pro Max в landscape тоже считается мобильным
168
- const isLandscape = (width > height && mobile) || (width === 926 && height === 428) || (width === 932 && height === 430); // iPhone 14 Pro Max в landscape
169
- const isSmallHeight = height < 700; // Nest Hub, маленькие экраны
170
- const isWideScreen = width / height > 1.8; // ✅ Широкие экраны
171
-
172
- // Определяем iPhone до 14 Pro Max в landscape режиме
173
- // iPhone 14 Pro Max: 926x428 (landscape)
174
- // iPhone 13 Pro Max: 926x428 (landscape)
175
- // iPhone 12 Pro Max: 926x428 (landscape)
176
- // iPhone 11 Pro Max: 896x414 (landscape)
177
- // iPhone XR: 896x414 (landscape)
178
- // iPhone XS Max: 896x414 (landscape)
179
- // iPhone X: 812x375 (landscape)
180
- // iPhone 8 Plus: 736x414 (landscape)
181
- // iPhone 8: 667x375 (landscape)
182
- // iPhone SE: 667x375 (landscape)
183
-
184
- // iPhone XR: 896x414 (landscape)
185
- const isIPhoneXRLandscape = isLandscape && width === 896 && height === 414;
186
-
187
- // iPhone 12 Pro: 844x390 (landscape)
188
- const isIPhone12ProLandscape = isLandscape && width === 844 && height === 390;
189
-
190
- // Разрешение 1366x766 - ноутбуки и небольшие десктопы
191
- const is1366x766 = width === 1366 && height === 766;
192
-
193
- // Разрешение 1366x768 - ноутбуки и небольшие десктопы
194
- const is1366x768 = width === 1366 && height === 768;
195
-
196
- // Разрешение 1280x720 - ноутбуки и небольшие десктопы
197
- const is1280x720 = width === 1280 && height === 720;
198
-
199
- // Разрешение 1440x900 - ноутбуки и небольшие десктопы
200
- const is1440x900 = width === 1440 && height === 900;
201
-
202
- // iPad Mini/Air размеры
203
- // iPad Mini: 768x1024 (portrait), 1024x768 (landscape) - Chrome DevTools размеры
204
- // iPad Air: 820x1180 (portrait), 1180x820 (landscape)
205
- const isIPadMiniPortrait = width === 768 && height === 1024;
206
- const isIPadMiniLandscape = width === 1024 && height === 768;
207
- const isIPadAirPortrait = width === 820 && height === 1180;
208
- const isIPadAirLandscape = width === 1180 && height === 820;
209
-
210
- // Surface DUO размеры
211
- // Surface DUO: 540x720 (portrait), 720x540 (landscape)
212
- const isSurfaceDuoPortrait = width === 540 && height === 720;
213
- const isSurfaceDuoLandscape = width === 720 && height === 540;
214
-
215
- // iPad Pro размеры
216
- // iPad Pro: 1024x1366 (portrait), 1366x1024 (landscape)
217
- const isIPadProPortrait = width === 1024 && height === 1366;
218
- const isIPadProLandscape = width === 1366 && height === 1024;
219
-
220
- // Популярные разрешения для горизонтального расположения кнопки Check
221
- const desktopLayout = width >= 1200 && height >= 600 && !mobile;
222
- setIsDesktopLayout(desktopLayout);
223
-
224
- // Установка состояний для iPad и Surface DUO
225
- setIsIPadMiniPortrait(isIPadMiniPortrait);
226
- setIsIPadMiniLandscape(isIPadMiniLandscape);
227
- setIsIPadAirPortrait(isIPadAirPortrait);
228
- setIsIPadAirLandscape(isIPadAirLandscape);
229
- setIsSurfaceDuoPortrait(isSurfaceDuoPortrait);
230
- setIsSurfaceDuoLandscape(isSurfaceDuoLandscape);
231
- setIsIPadProPortrait(isIPadProPortrait);
232
- setIsIPadProLandscape(isIPadProLandscape);
233
-
234
- // ✅ Вычисляем горизонтальный layout ОДИН РАЗ
235
- const isHorizontal =
236
- (mobile && width > height) ||
237
- mobile || // ✅ ВСЕ мобильные устройства (включая portrait)
238
- height < 700 ||
239
- isWideScreen || // ✅ Широкие экраны
240
- (width === 1366 && height === 766) ||
241
- (width === 1366 && height === 768) ||
242
- (width === 1280 && height === 720) ||
243
- (width === 1440 && height === 900) ||
244
- isIPadMiniPortrait ||
245
- isIPadMiniLandscape ||
246
- isIPadAirPortrait ||
247
- isIPadAirLandscape ||
248
- isSurfaceDuoPortrait ||
249
- isSurfaceDuoLandscape ||
250
- isIPadProPortrait ||
251
- isIPadProLandscape ||
252
- isDesktopLayout;
253
- setIsHorizontalLayout(isHorizontal);
254
-
255
- const isOldIPhoneLandscape = isLandscape && height <= 428; // до iPhone 14 Pro Max включительно
256
-
257
- // treat only phones as "mobile" so tablets use the desktop (square/centered) layout
258
- setIsMobile(mobile);
259
-
260
- // ✅ Используем gameCubeSize от родительского сайта, но с защитой от слишком маленьких размеров
261
- if (mobile) {
262
- // Мобилки: используем переданный gameCubeSize или полную ширину
263
- setContainerSize(gameCubeSize && gameCubeSize >= 320 ? gameCubeSize : null);
264
- setScale(1);
265
- } else if (isSmallHeight) {
266
- // Маленькие экраны: используем переданный gameCubeSize или полную высоту
267
- setContainerSize(gameCubeSize && gameCubeSize >= 400 ? gameCubeSize : null);
268
- setScale(1);
269
- } else if (isWideScreen) {
270
- // ✅ Широкие экраны: используем стандартный размер но уменьшаем масштаб картинок
271
- const minSize = 400;
272
- const maxSize = 1200;
273
- const finalSize = gameCubeSize
274
- ? Math.max(minSize, Math.min(maxSize, gameCubeSize))
275
- : Math.min(1000, Math.min(width, height) * 0.9);
276
- setContainerSize(finalSize);
277
- setScale(0.85); // Уменьшаем масштаб картинок на 15%
278
- } else {
279
- // Десктопы: используем переданный gameCubeSize с разумными ограничениями
280
- const minSize = 400;
281
- const maxSize = 1200;
282
- const finalSize = gameCubeSize
283
- ? Math.max(minSize, Math.min(maxSize, gameCubeSize))
284
- : Math.min(1000, Math.min(width, height) * 0.9);
285
- setContainerSize(finalSize);
286
- setScale(1);
287
- }
288
- };
289
- resize();
290
- window.addEventListener("resize", resize);
291
- return () => window.removeEventListener("resize", resize);
292
- }, [screenWidth, screenHeight, gameCubeSize]);
293
-
294
- const getRandomSix = (arr: ImageItem[]) =>
295
- [...arr].sort(() => Math.random() - 0.5).slice(0, 6);
296
-
297
- // ✅ Функция предзагрузки темы
298
- const startThemePreload = (themeName: Theme) => {
299
- // Cancel previous preload
300
- if (abortController.current) {
301
- abortController.current.abort();
302
- }
303
-
304
- // Create new controller
305
- abortController.current = new AbortController();
306
-
307
- // Get theme images and start preloading
308
- const themeImages = themes[themeName];
309
- const urls = themeImages.map(item => item.src);
310
-
311
- preloadImages(urls, abortController.current.signal).then((imageMap) => {
312
- // Mark as preloaded
313
- urls.forEach(url => {
314
- preloadedUrls.current.add(url);
315
- if (imageMap.has(url)) {
316
- preloadedImages.current.set(url, imageMap.get(url)!);
317
- }
318
- });
319
- }).catch(() => {
320
- // Ignore abort errors
321
- });
322
- };
323
-
324
- const startGame = () => {
325
- if (!theme) return;
326
- const selected = getRandomSix(themes[theme]);
327
- setFiles(selected);
328
- setStarted(true);
329
- setFinished(false);
330
- setCurrentRound(1);
331
- setScore(0);
332
- setResultsTable([]);
333
- setUsedHidden([]);
334
-
335
- // ✅ Preload current round images
336
- const urls = selected.map(item => item.src);
337
- preloadImages(urls, abortController.current?.signal).then((imageMap) => {
338
- urls.forEach(url => {
339
- preloadedUrls.current.add(url);
340
- if (imageMap.has(url)) {
341
- preloadedImages.current.set(url, imageMap.get(url)!);
342
- }
343
- });
344
- }).catch(() => {
345
- // Ignore abort errors
346
- });
347
-
348
- startRound(selected, [], true);
349
- };
350
-
351
- const startRound = (images = files, used: string[] = usedHidden, isFirst = false) => {
352
- const roundSet = getRandomSix(images.length ? images : themes[theme!]);
353
- let idx = Math.floor(Math.random() * roundSet.length);
354
- let candidate = roundSet[idx].name;
355
- let attempts = 0;
356
- while (used.includes(candidate) && attempts < 20) {
357
- idx = Math.floor(Math.random() * roundSet.length);
358
- candidate = roundSet[idx].name;
359
- attempts++;
360
- }
361
- setFiles(roundSet);
362
- setHiddenIndex(idx);
363
- setUsedHidden([...used, candidate]);
364
- setAnswered(false);
365
- setInputValue("");
366
- setTimeLeft(20);
367
- setResult(null);
368
-
369
- // ✅ Preload next round images in background
370
- if (theme && !isFirst) {
371
- const nextPool = getRandomSix(themes[theme].filter(item => !used.includes(item.name)));
372
- const nextUrls = nextPool.map(item => item.src);
373
- preloadImages(nextUrls, abortController.current?.signal).then((imageMap) => {
374
- nextUrls.forEach(url => {
375
- preloadedUrls.current.add(url);
376
- if (imageMap.has(url)) {
377
- preloadedImages.current.set(url, imageMap.get(url)!);
378
- }
379
- });
380
- }).catch(() => {
381
- // Ignore abort errors
382
- });
383
- }
384
-
385
- if (isFirst) {
386
- setPhase("ready");
387
- setReadyTime(10); // Увеличено до 10 секунд для VPN/медленных соединений
388
- setMemorizeTime(10);
389
- } else {
390
- setPhase("memorize");
391
- setMemorizeTime(10);
392
- }
393
- };
394
-
395
- useEffect(() => {
396
- if (!started || finished || answered) return;
397
- if (phase === "ready") {
398
- if (readyTime <= 0) setPhase("memorize");
399
- else {
400
- const t = setTimeout(() => setReadyTime((r) => r - 1), 1000);
401
- return () => clearTimeout(t);
402
- }
403
- }
404
- if (phase === "memorize") {
405
- if (memorizeTime <= 0) setPhase("guess");
406
- else {
407
- const t = setTimeout(() => setMemorizeTime((m) => m - 1), 1000);
408
- return () => clearTimeout(t);
409
- }
410
- }
411
- if (phase === "guess") {
412
- if (timeLeft <= 0) {
413
- setAnswered(true);
414
- setResult("wrong");
415
- const correct = files[hiddenIndex!].name;
416
- setResultsTable((prev) => [
417
- ...prev,
418
- { round: currentRound, answer: inputValue, correct, result: "wrong" },
419
- ]);
420
- return;
421
- }
422
- const t = setTimeout(() => setTimeLeft((s) => s - 1), 1000);
423
- return () => clearTimeout(t);
424
- }
425
- }, [phase, readyTime, memorizeTime, timeLeft, started, finished, answered, files, hiddenIndex, currentRound, inputValue]);
426
-
427
- const checkAnswer = () => {
428
- if (hiddenIndex === null || animating) return;
429
- const correct = files[hiddenIndex].name;
430
- const userAnswer = inputValue.toLowerCase().trim();
431
- let roundResult: "correct" | "almost" | "wrong" = "wrong";
432
- if (userAnswer === correct) {
433
- setScore((s) => s + 1);
434
- setResult("correct");
435
- roundResult = "correct";
436
- } else if (levenshtein(userAnswer, correct) === 1) {
437
- setScore((s) => s + 0.5);
438
- setResult("almost");
439
- roundResult = "almost";
440
- } else {
441
- setResult("wrong");
442
- roundResult = "wrong";
443
- }
444
- setResultsTable((prev) => [...prev, { round: currentRound, answer: userAnswer, correct, result: roundResult }]);
445
- setAnimating(true);
446
- setTimeout(() => {
447
- setAnimating(false);
448
- setAnswered(true);
449
- }, 600);
450
- };
451
-
452
- const nextRound = () =>
453
- currentRound < rounds ? (setCurrentRound((r) => r + 1), startRound()) : setFinished(true);
454
-
455
- const exitGame = () => {
456
- // ✅ Cancel any ongoing preloads
457
- if (abortController.current) {
458
- abortController.current.abort();
459
- }
460
-
461
- setStarted(false);
462
- setFinished(false);
463
- setTheme(null);
464
- };
465
-
466
- const MemoizedLogo = useMemo(
467
- () => {
468
- // Скрываем логотип на мобильных устройствах в landscape режиме и на малых экранах
469
- if ((isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700) {
470
- return null;
471
- }
472
-
473
- return (
474
- // ensure logo is positioned inside the square container
475
- <div style={{ ...styles.gmLogoFixed, position: "absolute", top: 16, left: 16, zIndex: 30 }}>
476
- <picture>
477
- <source
478
- srcSet={window.origin + "/cloud/speakid/games/whatsmissing/logo.svg"}
479
- type="image/svg+xml"
480
- />
481
- <img
482
- src={window.origin + "/cloud/speakid/games/whatsmissing/logo.png"}
483
- alt="SPEAKID Logo"
484
- style={styles.gmLogoImg}
485
- loading="lazy"
486
- />
487
- </picture>
488
- </div>
489
- );
490
- },
491
- [isMobile]
492
- );
493
-
494
- return (
495
- <div
496
- ref={containerRef}
497
- style={{
498
- width: "100%",
499
- height: "100%",
500
- display: "flex",
501
- justifyContent: "center",
502
- alignItems: "center",
503
- background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
504
- transition: "background 0.3s ease",
505
- overflow: "hidden",
506
- position: "absolute",
507
- top: 0,
508
- left: 0,
509
- right: 0,
510
- bottom: 0
511
- }}
512
- >
513
- <div
514
- style={{
515
- width: isMobile ? "100%" : (containerSize || gameCubeSize || 1000),
516
- height: isMobile ? "100%" : (containerSize || gameCubeSize || 1000),
517
- display: "flex",
518
- justifyContent: "center",
519
- alignItems: "center",
520
- overflow: "hidden",
521
- borderRadius: isMobile ? 0 : "20px",
522
- background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
523
- boxShadow: isMobile ? "none" : "0 0 40px rgba(0,0,0,0.1)",
524
- margin: isMobile ? "0 auto" : "unset",
525
- position: "relative", // needed so absolute logo is inside the square
526
- transform: `scale(${scale})`, // ✅ Применяем масштаб для широких экранов
527
- }}
528
- >
529
- <div
530
- style={{
531
- transform: "none",
532
- width: "100%",
533
- height: "100%",
534
- display: "flex",
535
- justifyContent: "center",
536
- alignItems: "center",
537
- }}
538
- >
539
- <div id="whats-missing-root">
540
- {!isMobile && MemoizedLogo}
541
- {/* ====== ИГРОВАЯ ЛОГИКА ====== */}
542
- {!theme && !started && (
543
- <div style={styles.gmCenterScreen}>
544
- <h1 style={styles.gmHeadline1}>WHAT'S MISSING?</h1>
545
- <p style={styles.gmBodyM}>Select a theme:</p>
546
- <div style={{ display: "flex", gap: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "8px" : "16px" }}>
547
- {["animals", "food", "toys"].map((t) => (
548
- <button key={t} style={{
549
- ...styles.gmButton,
550
- padding: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "8px 12px" : "12px 24px",
551
- fontSize: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "12px" : "16px",
552
- minWidth: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "70px" : "auto"
553
- }} onClick={() => {
554
- setTheme(t as Theme);
555
- startThemePreload(t as Theme);
556
- }}>
557
- {t === "animals" ? "🐶 Animals" : t === "food" ? "🍎 Food" : "🧸 Toys"}
558
- </button>
559
- ))}
560
- </div>
561
- <div style={{ marginTop: 24 }}>
562
- <p style={styles.gmBodyS}>Choose number of rounds:</p>
563
- <div style={{ display: "flex", gap: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "6px" : "12px", marginTop: 8 }}>
564
- {[3, 4, 5].map((n) => (
565
- <button
566
- key={n}
567
- style={{
568
- ...styles.gmButton,
569
- ...(rounds === n ? styles.gmButtonActive : {}),
570
- padding: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "6px 10px" : "12px 24px",
571
- fontSize: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "12px" : "16px",
572
- minWidth: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "40px" : "auto"
573
- }}
574
- onClick={() => setRounds(n)}
575
- >
576
- {n}
577
- </button>
578
- ))}
579
- </div>
580
- </div>
581
- </div>
582
- )}
583
- {theme && !started && (
584
- <div style={styles.gmCenterScreen}>
585
- <h1 style={styles.gmHeadline1}>Theme selected: {theme}</h1>
586
- <p style={styles.gmBodyM}>Rounds: {rounds}</p>
587
- <button style={{
588
- ...styles.gmButton,
589
- padding: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "8px 16px" : "12px 24px",
590
- fontSize: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "14px" : "16px",
591
- minWidth: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "120px" : "auto"
592
- }} onClick={startGame}>
593
- ▶ Start game
594
- </button>
595
- </div>
596
- )}
597
- {finished && (
598
- <div style={styles.gmCenterScreen}>
599
- <h1 style={{
600
- ...styles.gmHeadline1,
601
- marginTop: (isMobile && window.innerWidth > window.innerHeight) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) || isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape ? "0px" : styles.gmHeadline1.marginTop,
602
- marginBottom: (isMobile && window.innerWidth > window.innerHeight) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) || isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape ? "2px" : styles.gmHeadline1.marginBottom
603
- }}>Results</h1>
604
- <h2 style={{
605
- ...styles.gmHeadline3,
606
- marginTop: (isMobile && window.innerWidth > window.innerHeight) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) || isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape ? "0px" : styles.gmHeadline3.marginTop,
607
- marginBottom: (isMobile && window.innerWidth > window.innerHeight) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) || isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape ? "2px" : styles.gmHeadline3.marginBottom
608
- }}>
609
- Your score: {score} / {rounds}
610
- </h2>
611
- <p style={{
612
- ...styles.gmBodyM,
613
- color: "#10b981",
614
- marginTop: (isMobile && window.innerWidth > window.innerHeight) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) || isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape ? "0px" : "12px",
615
- marginBottom: (isMobile && window.innerWidth > window.innerHeight) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) || isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape ? "2px" : styles.gmBodyM.marginBottom
616
- }}>Yahoo! You did it! 🍬✨</p>
617
- <table style={{
618
- ...styles.gmTable,
619
- marginTop: (isMobile && window.innerWidth > window.innerHeight) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) || isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape ? "0px" : "20px",
620
- marginBottom: (isMobile && window.innerWidth > window.innerHeight) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) || isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape ? "4px" : "32px"
621
- }}>
622
- <thead>
623
- <tr>
624
- <th>Round</th>
625
- <th>Your Answer</th>
626
- <th>Correct</th>
627
- <th>Result</th>
628
- </tr>
629
- </thead>
630
- <tbody>
631
- {resultsTable.map((r, i) => (
632
- <tr key={i}>
633
- <td style={styles.gmTableCell}>{r.round}</td>
634
- <td style={styles.gmTableCell}>{r.answer || "—"}</td>
635
- <td style={styles.gmTableCell}>{r.correct}</td>
636
- <td style={styles.gmTableCell}>
637
- {r.result === "correct"
638
- ? "✔ Correct"
639
- : r.result === "almost"
640
- ? "◐ Almost (0.5)"
641
- : "✘ Wrong"}
642
- </td>
643
- </tr>
644
- ))}
645
- </tbody>
646
- </table>
647
- <div style={{
648
- display: "flex",
649
- gap: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "6px" : "12px",
650
- marginTop: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "2px" : (window.innerWidth === 1366 && window.innerHeight === 766) || (window.innerWidth === 1366 && window.innerHeight === 768) || (window.innerWidth === 1280 && window.innerHeight === 720) || (window.innerWidth === 1440 && window.innerHeight === 900) || isDesktopLayout ? "12px" : "24px"
651
- }}>
652
- <button style={{
653
- ...styles.gmButton,
654
- padding: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "6px 10px" : "12px 24px",
655
- fontSize: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "12px" : "16px",
656
- minWidth: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "80px" : "auto"
657
- }} onClick={startGame}>
658
- 🔁 Play again
659
- </button>
660
- <button style={{
661
- ...styles.gmButton,
662
- padding: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "6px 10px" : "12px 24px",
663
- fontSize: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "12px" : "16px",
664
- minWidth: (isMobile && window.innerWidth > window.innerHeight) || (isMobile && window.innerWidth <= 375 && window.innerHeight <= 667) || (window.innerWidth === 896 && window.innerHeight === 414) || (window.innerWidth === 844 && window.innerHeight === 390) || (window.innerWidth === 926 && window.innerHeight === 428) || (window.innerWidth === 932 && window.innerHeight === 430) ? "80px" : "auto"
665
- }} onClick={exitGame}>
666
- ⬅️ Choose theme
667
- </button>
668
- </div>
669
- </div>
670
- )}
671
- {started && !finished && (
672
- <div style={styles.gmGameLayout}>
673
- <div
674
- style={{
675
- minHeight: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
676
- ? "45px" // iPhone SE: еще более компактная высота
677
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
678
- ? "45px" // iPhone до 14 Pro Max в landscape: такая же компактная как SE
679
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
680
- ? "45px" // iPhone XR в landscape: такая же компактная как SE
681
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
682
- ? "45px" // iPhone 12 Pro в landscape: такая же компактная как SE
683
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
684
- ? "45px" // iPhone 14 Pro Max в landscape: такая же компактная как SE
685
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700
686
- ? "60px" // iPhone landscape и малые экраны: компактная высота
687
- : "160px",
688
- display: "flex",
689
- flexDirection: "column",
690
- justifyContent: "center",
691
- alignItems: "center",
692
- paddingTop: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
693
- ? "8px" // iPhone SE: поднимаем таймер еще выше
694
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
695
- ? "8px" // iPhone до 14 Pro Max в landscape: поднимаем еще выше
696
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
697
- ? "8px" // iPhone XR в landscape: поднимаем еще выше
698
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
699
- ? "8px" // iPhone 12 Pro в landscape: поднимаем еще выше
700
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
701
- ? "8px" // iPhone 14 Pro Max в landscape: поднимаем еще выше
702
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700
703
- ? "15px" // iPhone landscape и малые экраны: поднимаем выше
704
- : "40px"
705
- }}
706
- >
707
- {phase === "ready" && (
708
- <>
709
- <h1 style={{ ...styles.gmHeadline1, color: "#ec4c44" }}>GET READY</h1>
710
- <div style={styles.gmHourglass}>⏳</div>
711
- </>
712
- )}
713
- {phase === "memorize" && (
714
- <p style={{ ...styles.gmBodyM, color: "#10b981" }}>
715
- MEMORIZE ({memorizeTime})
716
- </p>
717
- )}
718
- {phase === "guess" && !answered && (
719
- <p style={styles.gmBodyM}>⏳ Time left: {timeLeft}s</p>
720
- )}
721
- </div>
722
- {phase !== "ready" && (
723
- <div
724
- style={{
725
- ...styles.gmGrid,
726
- gridTemplateColumns: isMobile && window.innerWidth > window.innerHeight
727
- ? "repeat(3, 1fr)" // mobile landscape: 3 колонки
728
- : isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
729
- ? "repeat(3, 1fr)" // iPhone SE: 3 колонки для лучшего использования пространства
730
- : isMobile
731
- ? "repeat(2, 1fr)" // mobile portrait: 2 колонки
732
- : window.innerHeight < 700
733
- ? "repeat(3, 1fr)" // Nest Hub и малые экраны: 3 колонки
734
- : "repeat(3, 210px)", // desktop: 3 колонки фиксированного размера
735
- gridAutoRows: isMobile && window.innerWidth > window.innerHeight
736
- ? "120px" // mobile landscape: меньшая высота
737
- : isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
738
- ? "100px" // iPhone SE: очень компактная высота
739
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
740
- ? "100px" // iPhone XR в landscape: такая же компактная как SE
741
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
742
- ? "100px" // iPhone 12 Pro в landscape: такая же компактная как SE
743
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
744
- ? "100px" // iPhone 14 Pro Max в landscape: такая же компактная как SE
745
- : isMobile
746
- ? "150px" // mobile portrait: стандартная высота
747
- : window.innerHeight < 700
748
- ? "140px" // Nest Hub: компактная высота
749
- : (typeof window !== "undefined" && window.devicePixelRatio >= 1.25 && window.devicePixelRatio <= 1.5) // Среднее масштабирование (125%-150%)
750
- ? "240px" // Больше высота для экранов с масштабированием
751
- : "210px", // desktop: стандартная высота
752
- gap: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
753
- ? "12px" // iPhone SE: больше отступов
754
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
755
- ? "12px" // iPhone XR в landscape: такие же отступы как SE
756
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
757
- ? "12px" // iPhone 12 Pro в landscape: такие же отступы как SE
758
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
759
- ? "12px" // iPhone 14 Pro Max в landscape: такие же отступы как SE
760
- : isMobile || window.innerHeight < 700
761
- ? "8px"
762
- : (typeof window !== "undefined" && window.devicePixelRatio >= 1.25 && window.devicePixelRatio <= 1.5) // Среднее масштабирование (125%-150%)
763
- ? "24px" // Больше отступы для экранов с масштабированием
764
- : "20px",
765
- justifyItems: "center",
766
- maxWidth: isMobile && window.innerWidth > window.innerHeight
767
- ? "90%" // mobile landscape: используем больше ширины
768
- : isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
769
- ? "95%" // iPhone SE: используем почти всю ширину
770
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
771
- ? "95%" // iPhone XR в landscape: используем почти всю ширину как SE
772
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
773
- ? "95%" // iPhone 12 Pro в landscape: используем почти всю ширину как SE
774
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
775
- ? "95%" // iPhone 14 Pro Max в landscape: используем почти всю ширину как SE
776
- : "100%",
777
- padding: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
778
- ? "8px" // iPhone SE: минимальные внутренние отступы
779
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
780
- ? "8px" // iPhone XR в landscape: минимальные отступы как SE
781
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
782
- ? "8px" // iPhone 12 Pro в landscape: минимальные отступы как SE
783
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
784
- ? "8px" // iPhone 14 Pro Max в landscape: минимальные отступы как SE
785
- : (typeof window !== "undefined" && window.devicePixelRatio >= 1.25 && window.devicePixelRatio <= 1.5) // Среднее масштабирование (125%-150%)
786
- ? "20px" // Дополнительные отступы для экранов с масштабированием
787
- : "16px",
788
- }}
789
- >
790
- {files.map((file, i) => {
791
- const isHidden =
792
- hiddenIndex === i && phase === "guess" && !answered;
793
- return (
794
- <div
795
- key={i}
796
- style={{
797
- width: "100%",
798
- height: "100%",
799
- borderRadius: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
800
- ? "6px" // iPhone SE: меньшие скругления
801
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
802
- ? "6px" // iPhone XR в landscape: меньшие скругления как SE
803
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
804
- ? "6px" // iPhone 12 Pro в landscape: меньшие скругления как SE
805
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
806
- ? "6px" // iPhone 14 Pro Max в landscape: меньшие скругления как SE
807
- : "12px",
808
- overflow: "hidden",
809
- boxShadow: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
810
- ? "0 1px 4px rgba(0,0,0,0.1)" // iPhone SE: меньшие тени
811
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
812
- ? "0 1px 4px rgba(0,0,0,0.1)" // iPhone XR в landscape: меньшие тени как SE
813
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
814
- ? "0 1px 4px rgba(0,0,0,0.1)" // iPhone 12 Pro в landscape: меньшие тени как SE
815
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
816
- ? "0 1px 4px rgba(0,0,0,0.1)" // iPhone 14 Pro Max в landscape: меньшие тени как SE
817
- : "0 4px 12px rgba(0,0,0,0.15)",
818
- transition: "all 0.3s ease",
819
- cursor: "pointer",
820
- ...(result === "correct" && hiddenIndex === i
821
- ? {
822
- boxShadow: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
823
- ? "0 0 15px #10b981"
824
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
825
- ? "0 0 15px #10b981" // iPhone XR в landscape: такие же тени как SE
826
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
827
- ? "0 0 15px #10b981" // iPhone 12 Pro в landscape: такие же тени как SE
828
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
829
- ? "0 0 15px #10b981" // iPhone 14 Pro Max в landscape: такие же тени как SE
830
- : "0 0 20px #10b981",
831
- transform: "scale(1.03)"
832
- }
833
- : {}),
834
- ...(result === "wrong" && hiddenIndex === i
835
- ? {
836
- boxShadow: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
837
- ? "0 0 15px #ef4444"
838
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
839
- ? "0 0 15px #ef4444" // iPhone XR в landscape: такие же тени как SE
840
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
841
- ? "0 0 15px #ef4444" // iPhone 12 Pro в landscape: такие же тени как SE
842
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
843
- ? "0 0 15px #ef4444" // iPhone 14 Pro Max в landscape: такие же тени как SE
844
- : "0 0 20px #ef4444",
845
- transform: "scale(1.03)"
846
- }
847
- : {}),
848
- }}
849
- >
850
- {!isHidden && (() => {
851
- // ✅ Используем уже загруженный объект Image чтобы браузер взял из кеша
852
- const preloadedImg = preloadedImages.current.get(file.src);
853
- // Используем src из уже загруженного объекта или оригинальный URL
854
- const imgSrc = preloadedImg?.complete && preloadedImg.src
855
- ? preloadedImg.src
856
- : file.src;
857
-
858
- return (
859
- <img
860
- key={`${file.src}-${preloadedImg?.complete ? 'loaded' : 'pending'}`}
861
- src={imgSrc}
862
- alt={file.name}
863
- fetchPriority="high"
864
- loading="eager"
865
- decoding="async"
866
- style={{
867
- width: "100%",
868
- height: "100%",
869
- objectFit: "cover",
870
- }}
871
- />
872
- );
873
- })()}
874
- </div>
875
- );
876
- })}
877
- </div>
878
- )}
879
- <div style={{
880
- marginTop: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
881
- ? "1px" // iPhone SE: еще более минимальный отступ
882
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
883
- ? "1px" // iPhone до 14 Pro Max в landscape: такой же как SE
884
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
885
- ? "1px" // iPhone XR в landscape: такой же как SE
886
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
887
- ? "1px" // iPhone 12 Pro в landscape: такой же как SE
888
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
889
- ? "1px" // iPhone 14 Pro Max в landscape: такой же как SE
890
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700
891
- ? "4px" // iPhone landscape и малые экраны: минимальный отступ
892
- : "16px",
893
- height: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
894
- ? "40px" // iPhone SE: еще более компактная высота
895
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
896
- ? "40px" // iPhone до 14 Pro Max в landscape: такая же как SE
897
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
898
- ? "40px" // iPhone XR в landscape: такая же как SE
899
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
900
- ? "40px" // iPhone 12 Pro в landscape: такая же как SE
901
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
902
- ? "40px" // iPhone 14 Pro Max в landscape: такая же как SE
903
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700
904
- ? "50px" // iPhone landscape и малые экраны: компактная высота
905
- : "80px"
906
- }}>
907
- {phase === "guess" && !answered && (
908
- <div style={{
909
- display: "flex",
910
- flexDirection: isHorizontalLayout ? "row" : "column",
911
- gap: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
912
- ? "3px" // iPhone SE: еще более минимальный отступ
913
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
914
- ? "3px" // iPhone до 14 Pro Max в landscape: такой же как SE
915
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
916
- ? "3px" // iPhone XR в landscape: такой же как SE
917
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
918
- ? "3px" // iPhone 12 Pro в landscape: такой же как SE
919
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
920
- ? "3px" // iPhone 14 Pro Max в landscape: такой же как SE
921
- : (window.innerWidth === 1366 && window.innerHeight === 766) // 1366x766
922
- ? "8px" // 1366x766: отступ между инпутом и кнопкой
923
- : (window.innerWidth === 1366 && window.innerHeight === 768) // 1366x768
924
- ? "8px" // 1366x768: отступ между инпутом и кнопкой
925
- : (window.innerWidth === 1280 && window.innerHeight === 720) // 1280x720
926
- ? "8px" // 1280x720: отступ между инпутом и кнопкой
927
- : (window.innerWidth === 1440 && window.innerHeight === 900) // 1440x900
928
- ? "8px" // 1440x900: отступ между инпутом и кнопкой
929
- : isDesktopLayout // Десктопные разрешения
930
- ? "8px" // Десктопные разрешения: отступ между инпутом и кнопкой
931
- : isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape
932
- ? "8px" // iPad и Surface DUO: отступ между инпутом и кнопкой
933
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700 ? "6px" : "12px",
934
- alignItems: "center",
935
- justifyContent: "center",
936
- width: "100%",
937
- maxWidth: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
938
- ? "270px" // iPhone SE: еще более компактная ширина
939
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
940
- ? "270px" // iPhone до 14 Pro Max в landscape: такая же как SE
941
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
942
- ? "270px" // iPhone XR в landscape: такая же как SE
943
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
944
- ? "270px" // iPhone 12 Pro в landscape: такая же как SE
945
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
946
- ? "270px" // iPhone 14 Pro Max в landscape: такая же как SE
947
- : (window.innerWidth === 1366 && window.innerHeight === 766) // 1366x766
948
- ? "400px" // 1366x766: ширина контейнера
949
- : (window.innerWidth === 1366 && window.innerHeight === 768) // 1366x768
950
- ? "400px" // 1366x768: ширина контейнера
951
- : (window.innerWidth === 1280 && window.innerHeight === 720) // 1280x720
952
- ? "400px" // 1280x720: ширина контейнера
953
- : (window.innerWidth === 1440 && window.innerHeight === 900) // 1440x900
954
- ? "400px" // 1440x900: ширина контейнера
955
- : isDesktopLayout // Десктопные разрешения
956
- ? "400px" // Десктопные разрешения: ширина контейнера
957
- : isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape
958
- ? "400px" // iPad и Surface DUO: ширина контейнера
959
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700 ? "400px" : "300px"
960
- }}>
961
- <>
962
- <input
963
- type="text"
964
- placeholder="Type the missing word"
965
- value={inputValue}
966
- onChange={(e) => setInputValue(e.target.value)}
967
- style={{
968
- ...styles.gmInput,
969
- width: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
970
- ? "170px" // iPhone SE: еще более компактная ширина
971
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
972
- ? "170px" // iPhone до 14 Pro Max в landscape: такая же как SE
973
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
974
- ? "170px" // iPhone XR в landscape: такая же как SE
975
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
976
- ? "170px" // iPhone 12 Pro в landscape: такая же как SE
977
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
978
- ? "170px" // iPhone 14 Pro Max в landscape: такая же как SE
979
- : (window.innerWidth === 1366 && window.innerHeight === 766) // 1366x766
980
- ? "250px" // 1366x766: ширина инпута
981
- : (window.innerWidth === 1366 && window.innerHeight === 768) // 1366x768
982
- ? "250px" // 1366x768: ширина инпута
983
- : (window.innerWidth === 1280 && window.innerHeight === 720) // 1280x720
984
- ? "250px" // 1280x720: ширина инпута
985
- : (window.innerWidth === 1440 && window.innerHeight === 900) // 1440x900
986
- ? "250px" // 1440x900: ширина инпута
987
- : isDesktopLayout // Десктопные разрешения
988
- ? "250px" // Десктопные разрешения: ширина инпута
989
- : isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape
990
- ? "250px" // iPad и Surface DUO: ширина инпута
991
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700 ? "250px" : "auto",
992
- padding: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
993
- ? "5px 6px" // iPhone SE: еще более компактный padding
994
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
995
- ? "5px 6px" // iPhone до 14 Pro Max в landscape: такой же как SE
996
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
997
- ? "5px 6px" // iPhone XR в landscape: такой же как SE
998
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
999
- ? "5px 6px" // iPhone 12 Pro в landscape: такой же как SE
1000
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
1001
- ? "5px 6px" // iPhone 14 Pro Max в landscape: такой же как SE
1002
- : (window.innerWidth === 1366 && window.innerHeight === 766) // 1366x766
1003
- ? "10px 12px" // 1366x766: padding инпута
1004
- : (window.innerWidth === 1366 && window.innerHeight === 768) // 1366x768
1005
- ? "10px 12px" // 1366x768: padding инпута
1006
- : (window.innerWidth === 1280 && window.innerHeight === 720) // 1280x720
1007
- ? "10px 12px" // 1280x720: padding инпута
1008
- : (window.innerWidth === 1440 && window.innerHeight === 900) // 1440x900
1009
- ? "10px 12px" // 1440x900: padding инпута
1010
- : isDesktopLayout // Десктопные разрешения
1011
- ? "10px 12px" // Десктопные разрешения: padding инпута
1012
- : isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape
1013
- ? "10px 12px" // iPad и Surface DUO: padding инпута
1014
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700 ? "10px 12px" : "12px 16px",
1015
- fontSize: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
1016
- ? "10px" // iPhone SE: еще меньший шрифт
1017
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
1018
- ? "10px" // iPhone до 14 Pro Max в landscape: такой же как SE
1019
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
1020
- ? "11px" // iPhone XR в landscape: компактный шрифт
1021
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
1022
- ? "10px" // iPhone 12 Pro в landscape: такой же как SE
1023
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
1024
- ? "10px" // iPhone 14 Pro Max в landscape: такой же как SE
1025
- : (window.innerWidth === 1366 && window.innerHeight === 766) // 1366x766
1026
- ? "14px" // 1366x766: размер шрифта инпута
1027
- : (window.innerWidth === 1366 && window.innerHeight === 768) // 1366x768
1028
- ? "14px" // 1366x768: размер шрифта инпута
1029
- : (window.innerWidth === 1280 && window.innerHeight === 720) // 1280x720
1030
- ? "14px" // 1280x720: размер шрифта инпута
1031
- : (window.innerWidth === 1440 && window.innerHeight === 900) // 1440x900
1032
- ? "14px" // 1440x900: размер шрифта инпута
1033
- : isDesktopLayout // Десктопные разрешения
1034
- ? "14px" // Десктопные разрешения: размер шрифта инпута
1035
- : isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape
1036
- ? "14px" // iPad и Surface DUO: размер шрифта инпута
1037
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700 ? "14px" : "16px",
1038
- flex: isHorizontalLayout ? "1" : "none"
1039
- }}
1040
- />
1041
- <button
1042
- style={{
1043
- ...styles.gmButton,
1044
- marginLeft: isHorizontalLayout ? "8px" : "0",
1045
- padding: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
1046
- ? "5px 8px" // iPhone SE: еще более компактный padding
1047
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
1048
- ? "6px 10px" // iPhone до 14 Pro Max в landscape: компактный padding
1049
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
1050
- ? "6px 10px" // iPhone XR в landscape: компактный padding
1051
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
1052
- ? "6px 10px" // iPhone 12 Pro в landscape: компактный padding
1053
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
1054
- ? "6px 10px" // iPhone 14 Pro Max в landscape: компактный padding
1055
- : (window.innerWidth === 1366 && window.innerHeight === 766) // 1366x766
1056
- ? "10px 16px" // 1366x766: padding кнопки Check
1057
- : (window.innerWidth === 1366 && window.innerHeight === 768) // 1366x768
1058
- ? "10px 16px" // 1366x768: padding кнопки Check
1059
- : (window.innerWidth === 1280 && window.innerHeight === 720) // 1280x720
1060
- ? "10px 16px" // 1280x720: padding кнопки Check
1061
- : (window.innerWidth === 1440 && window.innerHeight === 900) // 1440x900
1062
- ? "10px 16px" // 1440x900: padding кнопки Check
1063
- : isDesktopLayout // Десктопные разрешения
1064
- ? "10px 16px" // Десктопные разрешения: padding кнопки Check
1065
- : isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape
1066
- ? "10px 16px" // iPad и Surface DUO: padding кнопки Check
1067
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700 ? "10px 16px" : "12px 24px",
1068
- fontSize: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
1069
- ? "10px" // iPhone SE: еще меньший шрифт
1070
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
1071
- ? "11px" // iPhone до 14 Pro Max в landscape: компактный шрифт
1072
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
1073
- ? "11px" // iPhone XR в landscape: компактный шрифт
1074
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
1075
- ? "11px" // iPhone 12 Pro в landscape: компактный шрифт
1076
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
1077
- ? "11px" // iPhone 14 Pro Max в landscape: компактный шрифт
1078
- : (window.innerWidth === 1366 && window.innerHeight === 766) // 1366x766
1079
- ? "14px" // 1366x766: размер шрифта кнопки Check
1080
- : (window.innerWidth === 1366 && window.innerHeight === 768) // 1366x768
1081
- ? "14px" // 1366x768: размер шрифта кнопки Check
1082
- : (window.innerWidth === 1280 && window.innerHeight === 720) // 1280x720
1083
- ? "14px" // 1280x720: размер шрифта кнопки Check
1084
- : (window.innerWidth === 1440 && window.innerHeight === 900) // 1440x900
1085
- ? "14px" // 1440x900: размер шрифта кнопки Check
1086
- : isDesktopLayout // Десктопные разрешения
1087
- ? "14px" // Десктопные разрешения: размер шрифта кнопки Check
1088
- : isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape
1089
- ? "14px" // iPad и Surface DUO: размер шрифта кнопки Check
1090
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700 ? "14px" : "16px",
1091
- minWidth: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
1092
- ? "45px" // iPhone SE: еще более компактная ширина
1093
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
1094
- ? "55px" // iPhone до 14 Pro Max в landscape: компактная ширина
1095
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
1096
- ? "55px" // iPhone XR в landscape: компактная ширина
1097
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
1098
- ? "55px" // iPhone 12 Pro в landscape: компактная ширина
1099
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
1100
- ? "55px" // iPhone 14 Pro Max в landscape: компактная ширина
1101
- : (window.innerWidth === 1366 && window.innerHeight === 766) // 1366x766
1102
- ? "80px" // 1366x766: минимальная ширина кнопки Check
1103
- : (window.innerWidth === 1366 && window.innerHeight === 768) // 1366x768
1104
- ? "80px" // 1366x768: минимальная ширина кнопки Check
1105
- : (window.innerWidth === 1280 && window.innerHeight === 720) // 1280x720
1106
- ? "80px" // 1280x720: минимальная ширина кнопки Check
1107
- : (window.innerWidth === 1440 && window.innerHeight === 900) // 1440x900
1108
- ? "80px" // 1440x900: минимальная ширина кнопки Check
1109
- : isDesktopLayout // Десктопные разрешения
1110
- ? "80px" // Десктопные разрешения: минимальная ширина кнопки Check
1111
- : isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape
1112
- ? "80px" // iPad и Surface DUO: минимальная ширина кнопки Check
1113
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700 ? "80px" : "100px",
1114
- flexShrink: 0
1115
- }}
1116
- onClick={checkAnswer}
1117
- disabled={animating}
1118
- >
1119
- {animating ? "..." : "Check"}
1120
- </button>
1121
- </>
1122
- </div>
1123
- )}
1124
- {answered && (
1125
- <button style={{
1126
- ...styles.gmButton,
1127
- padding: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
1128
- ? "5px 8px" // iPhone SE: еще более компактный padding
1129
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
1130
- ? "6px 10px" // iPhone до 14 Pro Max в landscape: компактный padding
1131
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
1132
- ? "6px 10px" // iPhone XR в landscape: компактный padding
1133
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
1134
- ? "6px 10px" // iPhone 12 Pro в landscape: компактный padding
1135
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
1136
- ? "6px 10px" // iPhone 14 Pro Max в landscape: компактный padding
1137
- : (window.innerWidth === 1366 && window.innerHeight === 766) // 1366x766
1138
- ? "10px 16px" // 1366x766: padding кнопки Next round
1139
- : (window.innerWidth === 1366 && window.innerHeight === 768) // 1366x768
1140
- ? "10px 16px" // 1366x768: padding кнопки Next round
1141
- : (window.innerWidth === 1280 && window.innerHeight === 720) // 1280x720
1142
- ? "10px 16px" // 1280x720: padding кнопки Next round
1143
- : (window.innerWidth === 1440 && window.innerHeight === 900) // 1440x900
1144
- ? "10px 16px" // 1440x900: padding кнопки Next round
1145
- : isDesktopLayout // Десктопные разрешения
1146
- ? "10px 16px" // Десктопные разрешения: padding кнопки Next round
1147
- : isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape
1148
- ? "10px 16px" // iPad и Surface DUO: padding кнопки Next round
1149
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700 ? "10px 16px" : "12px 24px",
1150
- fontSize: isMobile && window.innerWidth <= 375 && window.innerHeight <= 667
1151
- ? "10px" // iPhone SE: еще меньший шрифт
1152
- : (isMobile && window.innerWidth > window.innerHeight && window.innerHeight <= 428)
1153
- ? "11px" // iPhone до 14 Pro Max в landscape: компактный шрифт
1154
- : (window.innerWidth === 896 && window.innerHeight === 414) // iPhone XR
1155
- ? "11px" // iPhone XR в landscape: компактный шрифт
1156
- : (window.innerWidth === 844 && window.innerHeight === 390) // iPhone 12 Pro
1157
- ? "11px" // iPhone 12 Pro в landscape: компактный шрифт
1158
- : (window.innerWidth === 926 && window.innerHeight === 428) // iPhone 14 Pro Max
1159
- ? "11px" // iPhone 14 Pro Max в landscape: компактный шрифт
1160
- : (window.innerWidth === 1366 && window.innerHeight === 766) // 1366x766
1161
- ? "14px" // 1366x766: размер шрифта кнопки Next round
1162
- : (window.innerWidth === 1366 && window.innerHeight === 768) // 1366x768
1163
- ? "14px" // 1366x768: размер шрифта кнопки Next round
1164
- : (window.innerWidth === 1280 && window.innerHeight === 720) // 1280x720
1165
- ? "14px" // 1280x720: размер шрифта кнопки Next round
1166
- : (window.innerWidth === 1440 && window.innerHeight === 900) // 1440x900
1167
- ? "14px" // 1440x900: размер шрифта кнопки Next round
1168
- : isDesktopLayout // Десктопные разрешения
1169
- ? "14px" // Десктопные разрешения: размер шрифта кнопки Next round
1170
- : isIPadMiniPortrait || isIPadMiniLandscape || isIPadAirPortrait || isIPadAirLandscape || isSurfaceDuoPortrait || isSurfaceDuoLandscape || isIPadProPortrait || isIPadProLandscape
1171
- ? "14px" // iPad и Surface DUO: размер шрифта кнопки Next round
1172
- : (isMobile && window.innerWidth > window.innerHeight) || window.innerHeight < 700 ? "14px" : "16px"
1173
- }} onClick={nextRound}>
1174
- Next round
1175
- </button>
1176
- )}
1177
- </div>
1178
- </div>
1179
- )}
1180
- </div>
1181
- </div>
1182
- </div>
1183
- </div>
1184
- );
1185
- }