speakid-hangman 1.0.9 → 1.0.11

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.
@@ -1 +1 @@
1
- {"version":3,"file":"speakid-hangman.cjs.js","sources":["../src/styles/style.ts","../src/components/HangmanLobbyGame.tsx"],"sourcesContent":["import { CSSProperties } from \"react\";\n\n// ===== Стили согласно визуальному гайдлайну: Onest, минималистичный, дружелюбный =====\n// Шрифт: Onest (Regular, Medium, SemiBold)\n// Стиль: Плоский, минималистичный, воздушный, без излишеств\n// Цвета: Мягкий контраст, дружелюбная палитра\n\nexport const styles: Record<string, CSSProperties> = {\n gmCenterScreen: {\n position: \"relative\",\n zIndex: 1,\n minHeight: \"100%\",\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"center\",\n textAlign: \"center\",\n color: \"#1f2937\", // colorTextPrimary\n padding: \"24px 16px\",\n boxSizing: \"border-box\",\n fontFamily: '\"Onest\", system-ui, -apple-system, \"Segoe UI\", Roboto, Arial, sans-serif',\n background: \"transparent\", // Прозрачный по умолчанию, переопределяется в компоненте\n },\n // Desktop: Headline 1 - Onest SemiBold 32px, line-height 110%\n gmHeadline1: {\n fontWeight: 600, // SemiBold\n fontSize: \"clamp(30px, 4vw, 32px)\", // Mobile 30px, Desktop 32px\n lineHeight: \"110%\",\n marginBottom: \"24px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Headline 2 - Onest Medium 24px, line-height 110%\n gmHeadline2: {\n fontWeight: 500, // Medium\n fontSize: \"24px\",\n lineHeight: \"110%\",\n marginBottom: \"16px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Headline 3 - Onest Medium 24px, line-height 110%\n // Mobile: Headline 3 - Onest Medium 16px, line-height 110%\n gmHeadline3: {\n fontWeight: 500, // Medium\n fontSize: \"clamp(16px, 2vw, 24px)\", // Mobile 16px, Desktop 24px\n lineHeight: \"110%\",\n marginBottom: \"12px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Body L - Onest Regular 18px, line-height 120%\n gmBodyL: {\n fontWeight: 400, // Regular\n fontSize: \"18px\",\n lineHeight: \"120%\",\n marginBottom: \"12px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Body M - Onest Regular 16px, line-height 120%\n // Mobile: Body M - Onest Regular 14px, line-height 120%\n gmBodyM: {\n fontWeight: 400, // Regular\n fontSize: \"clamp(14px, 1.5vw, 16px)\", // Mobile 14px, Desktop 16px\n lineHeight: \"120%\",\n marginBottom: \"8px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Body S - Onest Regular 14px, line-height 120%\n // Mobile: Body S - Onest Regular 12px, line-height 120%\n gmBodyS: {\n fontWeight: 400, // Regular\n fontSize: \"clamp(12px, 1.5vw, 14px)\", // Mobile 12px, Desktop 14px\n lineHeight: \"120%\",\n color: \"#6b7280\", // colorTextSecondary\n marginBottom: \"8px\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Button: Onest Regular 16px, line-height 100%\n gmButton: {\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 400, // Regular\n fontSize: \"16px\",\n lineHeight: \"100%\",\n padding: \"10px 16px\",\n borderRadius: \"8px\", // Более мягкие углы для минималистичного стиля\n border: \"1px solid #e5e7eb\", // colorSeparator\n background: \"#ec4c44\", // colorAccent (Default)\n color: \"#ffffff\", // colorTextContrast\n cursor: \"pointer\",\n boxShadow: \"none\", // Плоский стиль без теней\n transition: \"background-color 0.2s ease, opacity 0.2s ease, transform 0.1s ease\",\n margin: \"4px\",\n },\n gmButtonActive: {\n background: \"#333\", // colorAccent Active\n color: \"#fff\", // colorTextContrast\n boxShadow: \"none\", // Плоский стиль\n },\n gmButtonSecondary: {\n background: \"#f9f9f9\", // colorBackgroundAccent\n color: \"#1f2937\", // colorTextPrimary\n border: \"1px solid #e5e7eb\", // colorSeparator\n boxShadow: \"none\", // Плоский стиль\n },\n gmButtonGroup: {\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"8px\",\n justifyContent: \"center\",\n marginBottom: \"24px\",\n },\n gmWordDisplay: {\n fontSize: \"clamp(20px, 5vw, 28px)\",\n fontWeight: 500, // Medium\n letterSpacing: \"6px\",\n margin: \"32px 0\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n lineHeight: \"120%\",\n },\n gmGuessedLetters: {\n fontSize: \"clamp(12px, 1.5vw, 16px)\", // Body S / Body M\n color: \"#6b7280\", // colorTextSecondary\n marginTop: \"16px\",\n minHeight: \"24px\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n lineHeight: \"120%\",\n },\n gmStatusWin: {\n color: \"#10b981\", // colorTextPositive / colorIconPositive\n fontWeight: 500, // Medium\n fontSize: \"clamp(14px, 1.5vw, 18px)\", // Body M / Body L\n lineHeight: \"120%\",\n margin: \"16px 0\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n gmStatusLose: {\n color: \"#ec4c44\", // colorTextNegative / colorIconNegative\n fontWeight: 500, // Medium\n fontSize: \"clamp(14px, 1.5vw, 18px)\", // Body M / Body L\n lineHeight: \"120%\",\n margin: \"16px 0\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n gmInfoBox: {\n background: \"#f9f9f9\", // colorBackgroundAccent\n border: \"1px solid #e5e7eb\", // colorSeparator\n borderRadius: \"8px\", // Мягкие углы\n padding: \"16px\",\n marginBottom: \"24px\",\n maxWidth: \"500px\",\n width: \"100%\",\n boxShadow: \"none\", // Плоский стиль\n },\n gmSection: {\n marginBottom: \"32px\",\n width: \"100%\",\n maxWidth: \"500px\",\n },\n // ✅ Обновлено только для качества логотипа (размер как в magic-sentence)\n gmLogoFixed: {\n position: \"absolute\",\n top: \"24px\", // ✅ Увеличен отступ сверху для большего пространства\n left: \"24px\", // ✅ Увеличен отступ слева для большего пространства\n width: \"auto\",\n zIndex: 30, // ✅ Унифицирован zIndex для консистентности\n pointerEvents: \"none\",\n background: \"transparent\",\n transform: \"none\",\n willChange: \"auto\",\n },\n gmLogoImg: {\n height: \"28px\",\n width: \"auto\",\n background: \"transparent\",\n objectFit: \"contain\",\n imageRendering: \"auto\",\n transform: \"translateZ(0)\",\n backfaceVisibility: \"hidden\",\n WebkitFontSmoothing: \"antialiased\",\n display: \"block\",\n },\n gmLogoFallback: {\n height: \"28px\",\n width: \"auto\",\n background: \"transparent\",\n color: \"#ec4c44\",\n fontSize: \"16px\",\n fontWeight: 700,\n display: \"block\",\n },\n};\n\n// ===== Цветовая палитра для справки =====\n// colorTextPrimary: #1f2937\n// colorTextSecondary: #6b7280\n// colorTextNegative: #ec4c44\n// colorTextPositive: #10b981\n// colorBackgroundAccent: #f9f9f9\n// colorSeparator: #e5e7eb\n// colorAccent (Default): #ec4c44\n// colorAccent (Active): #333\n\n","import React, { useState, useEffect, useCallback, useMemo } from \"react\";\nimport { styles } from \"../styles/style\";\n\n// Компонент визуализации виселицы\nfunction HangmanDrawing({ \n mistakes, \n maxMistakes, \n size = 200 \n}: { \n mistakes: number; \n maxMistakes: number;\n size?: number;\n}) {\n // Адаптивные размеры SVG\n const svgWidth = size;\n const svgHeight = size * 1.25; // Соотношение 200:250\n const strokeWidth = Math.max(3, size / 100); // ✅ Увеличена минимальная толщина с 2 до 3 для лучшей видимости на маленьких экранах\n \n // Координаты (пропорциональные исходному размеру 200x250)\n const baseX1 = 10 * (svgWidth / 200);\n const baseY = 240 * (svgHeight / 250);\n const baseX2 = 150 * (svgWidth / 200);\n \n const poleX = 80 * (svgWidth / 200);\n const poleY1 = 20 * (svgHeight / 250);\n const poleY2 = 240 * (svgHeight / 250);\n \n const topX1 = 80 * (svgWidth / 200);\n const topY = 20 * (svgHeight / 250);\n const topX2 = 150 * (svgWidth / 200);\n \n const ropeX = 150 * (svgWidth / 200);\n const ropeY1 = 20 * (svgHeight / 250);\n const ropeY2 = 50 * (svgHeight / 250);\n \n const headCX = 150 * (svgWidth / 200);\n const headCY = 70 * (svgHeight / 250);\n const headR = 20 * (svgWidth / 200);\n \n const bodyX = 150 * (svgWidth / 200);\n const bodyY1 = 90 * (svgHeight / 250);\n const bodyY2 = 150 * (svgHeight / 250);\n \n const leftArmX1 = 150 * (svgWidth / 200);\n const leftArmY1 = 110 * (svgHeight / 250);\n const leftArmX2 = 130 * (svgWidth / 200);\n const leftArmY2 = 130 * (svgHeight / 250);\n \n const rightArmX1 = 150 * (svgWidth / 200);\n const rightArmY1 = 110 * (svgHeight / 250);\n const rightArmX2 = 170 * (svgWidth / 200);\n const rightArmY2 = 130 * (svgHeight / 250);\n \n const leftLegX1 = 150 * (svgWidth / 200);\n const leftLegY1 = 150 * (svgHeight / 250);\n const leftLegX2 = 130 * (svgWidth / 200);\n const leftLegY2 = 190 * (svgHeight / 250);\n \n const rightLegX1 = 150 * (svgWidth / 200);\n const rightLegY1 = 150 * (svgHeight / 250);\n const rightLegX2 = 170 * (svgWidth / 200);\n const rightLegY2 = 190 * (svgHeight / 250);\n\n // Цвет в зависимости от количества ошибок\n const getStrokeColor = () => {\n if (mistakes === 0) return \"#1f2937\"; // colorTextPrimary\n if (mistakes <= maxMistakes * 0.5) return \"#1f2937\"; // Окей\n if (mistakes <= maxMistakes * 0.75) return \"#f59e0b\"; // Предупреждение\n return \"#ec4c44\"; // colorTextNegative - опасно\n };\n\n const strokeColor = getStrokeColor();\n\n return (\n <svg \n width={svgWidth} \n height={svgHeight}\n viewBox=\"0 0 200 250\" // ✅ Добавлен viewBox для правильного масштабирования на iOS Safari\n style={{ \n display: \"block\",\n margin: \"0 auto\",\n overflow: \"visible\", // ✅ Для корректного отображения линий\n WebkitFontSmoothing: \"antialiased\", // ✅ Для лучшего рендеринга на iOS\n transform: \"translateZ(0)\", // ✅ Включение аппаратного ускорения на iOS\n }}\n >\n {/* Виселица рисуется пошагово с ошибками */}\n {/* 1-я ошибка: Основание */}\n {mistakes > 0 && (\n <line \n x1={baseX1} \n y1={baseY} \n x2={baseX2} \n y2={baseY} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 2-я ошибка: Стойка */}\n {mistakes > 1 && (\n <line \n x1={poleX} \n y1={poleY1} \n x2={poleX} \n y2={poleY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 3-я ошибка: Верхняя перекладина */}\n {mistakes > 2 && (\n <line \n x1={topX1} \n y1={topY} \n x2={topX2} \n y2={topY} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 4-я ошибка: Веревка */}\n {mistakes > 3 && (\n <line \n x1={ropeX} \n y1={ropeY1} \n x2={ropeX} \n y2={ropeY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 5-я ошибка: Голова */}\n {mistakes > 4 && (\n <circle \n cx={headCX} \n cy={headCY} \n r={headR} \n stroke={strokeColor} \n fill=\"none\" \n strokeWidth={strokeWidth}\n />\n )}\n \n {/* 6-я ошибка: Тело */}\n {mistakes > 5 && (\n <line \n x1={bodyX} \n y1={bodyY1} \n x2={bodyX} \n y2={bodyY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {/* Дополнительные части (если maxMistakes больше 6) */}\n {mistakes > 6 && (\n <line \n x1={leftArmX1} \n y1={leftArmY1} \n x2={leftArmX2} \n y2={leftArmY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {mistakes > 7 && (\n <line \n x1={rightArmX1} \n y1={rightArmY1} \n x2={rightArmX2} \n y2={rightArmY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {mistakes > 8 && (\n <line \n x1={leftLegX1} \n y1={leftLegY1} \n x2={leftLegX2} \n y2={leftLegY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {mistakes > 9 && (\n <line \n x1={rightLegX1} \n y1={rightLegY1} \n x2={rightLegX2} \n y2={rightLegY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n </svg>\n );\n}\n\nexport interface HangmanLobbyGameProps {\n gameCubeSize?: number;\n screenHeight?: number;\n screenWidth?: number;\n logoUrl?: string;\n showLogo?: boolean;\n baseURL?: string;\n}\n\nexport default function HangmanLobbyGame({\n gameCubeSize = 400,\n screenHeight = 800,\n screenWidth = 800,\n logoUrl,\n showLogo = true,\n baseURL,\n}: HangmanLobbyGameProps = {}) {\n const categories = {\n Professions: [\"teacher\", \"doctor\", \"nurse\", \"driver\", \"police\", \"firefighter\", \"cook\", \"waiter\", \"farmer\", \"builder\", \"singer\", \"actor\", \"dentist\", \"pilot\", \"vet\", \"artist\", \"cleaner\", \"student\", \"baker\", \"mechanic\"],\n Family: [\"mother\", \"father\", \"sister\", \"brother\", \"grandmother\", \"grandfather\", \"aunt\", \"uncle\", \"cousin\", \"baby\", \"parents\", \"children\", \"wife\", \"husband\", \"son\", \"daughter\", \"family\", \"twins\", \"relatives\"],\n \"Farm animals\": [\"cow\", \"pig\", \"horse\", \"sheep\", \"goat\", \"duck\", \"chicken\", \"rooster\", \"turkey\", \"goose\", \"rabbit\", \"mouse\", \"donkey\", \"bee\", \"hen\", \"lamb\", \"bull\", \"pony\"],\n Food: [\"apple\", \"banana\", \"bread\", \"cheese\", \"milk\", \"egg\", \"rice\", \"soup\", \"fish\", \"meat\", \"potato\", \"carrot\", \"tomato\", \"cucumber\", \"butter\", \"cake\", \"salad\", \"pasta\", \"pizza\", \"juice\"],\n Hobbies: [\"reading\", \"drawing\", \"painting\", \"dancing\", \"singing\", \"cooking\", \"swimming\", \"fishing\", \"running\", \"cycling\", \"skating\", \"writing\", \"camping\", \"photography\", \"hiking\", \"games\"],\n Christmas: [\"tree\", \"present\", \"gift\", \"santa\", \"snow\", \"snowman\", \"bell\", \"star\", \"lights\", \"card\", \"cookies\", \"elf\", \"sleigh\", \"reindeer\", \"candle\", \"stocking\"],\n Halloween: [\"pumpkin\", \"costume\", \"candy\", \"ghost\", \"witch\", \"spider\", \"bat\", \"skeleton\", \"mask\", \"monster\", \"mummy\", \"cat\", \"broom\", \"zombie\", \"trick\", \"treat\", \"candle\", \"night\", \"party\"],\n Sport: [\"football\", \"basketball\", \"tennis\", \"swimming\", \"running\", \"baseball\", \"skiing\", \"skating\", \"volleyball\", \"hockey\", \"golf\", \"boxing\", \"cycling\", \"rugby\", \"karate\", \"yoga\", \"surfing\", \"climbing\", \"dancing\", \"gym\", \"chess\"],\n \"Body parts\": [\"head\", \"hair\", \"eyes\", \"ears\", \"nose\", \"mouth\", \"teeth\", \"tongue\", \"neck\", \"shoulder\", \"arm\", \"hand\", \"finger\", \"leg\", \"knee\", \"foot\", \"toe\", \"back\", \"stomach\", \"heart\", \"legs\", \"nails\", \"chin\", \"beard\"],\n \"School subjects\": [\"math\", \"english\", \"history\", \"geography\", \"art\", \"music\", \"science\", \"biology\", \"chemistry\", \"physics\", \"pe\", \"literature\", \"drama\", \"design\", \"economics\"],\n Animals: [\"cat\", \"dog\", \"rabbit\", \"elephant\", \"lion\", \"tiger\", \"monkey\", \"bear\", \"fox\", \"wolf\", \"giraffe\", \"zebra\", \"crocodile\", \"dolphin\", \"whale\", \"shark\", \"frog\", \"parrot\", \"mouse\", \"penguin\", \"deer\", \"lizard\", \"turtle\", \"snake\"],\n Countries: [\"russia\", \"canada\", \"china\", \"japan\", \"france\", \"germany\", \"italy\", \"spain\", \"brazil\", \"india\", \"australia\", \"america\", \"england\", \"korea\", \"mexico\", \"egypt\", \"turkey\", \"vietnam\", \"norway\", \"finland\", \"thailand\", \"georgia\", \"kazakhstan\"],\n Clothes: [\"shirt\", \"dress\", \"skirt\", \"trousers\", \"jeans\", \"coat\", \"jacket\", \"sweater\", \"socks\", \"shoes\", \"boots\", \"hat\", \"scarf\", \"gloves\", \"shorts\", \"cap\", \"belt\", \"tie\", \"uniform\", \"pants\", \"underwear\"],\n Traveling: [\"ticket\", \"luggage\", \"suitcase\", \"airport\", \"flight\", \"passport\", \"visa\", \"map\", \"guide\", \"hotel\", \"reservation\", \"bus\", \"train\", \"taxi\", \"tourist\", \"sightseeing\", \"backpack\", \"journey\", \"adventure\", \"beach\", \"tour\", \"souvenir\"],\n Environment: [\"tree\", \"forest\", \"air\", \"water\", \"pollution\", \"recycle\", \"nature\", \"clean\", \"waste\", \"plastic\", \"energy\", \"animal\", \"climate\", \"earth\", \"ocean\", \"river\", \"planet\", \"save\", \"green\", \"environment\", \"litter\", \"organic\"],\n Space: [\"planet\", \"star\", \"sun\", \"moon\", \"astronaut\", \"rocket\", \"space\", \"galaxy\", \"universe\", \"telescope\", \"comet\", \"asteroid\", \"orbit\", \"gravity\", \"alien\", \"spaceship\", \"mars\", \"satellite\", \"sky\", \"eclipse\"],\n Devices: [\"computer\", \"laptop\", \"phone\", \"tablet\", \"tv\", \"keyboard\", \"mouse\", \"printer\", \"camera\", \"headphones\", \"charger\", \"screen\", \"watch\", \"microphone\", \"speaker\", \"console\", \"router\", \"battery\", \"cable\", \"remote\"],\n };\n\n const [stage, setStage] = useState<\"lobby\" | \"category\" | \"rounds\" | \"game\" | \"result\">(\"lobby\");\n const [category, setCategory] = useState<keyof typeof categories | \"\">(\"\");\n const [difficulty] = useState<\"Easy\" | \"Normal\" | \"Hard\">(\"Normal\"); // Фиксированная сложность\n const [rounds, setRounds] = useState(0); // 0 означает \"не выбрано\"\n const [currentRound, setCurrentRound] = useState(1);\n const [word, setWord] = useState(\"\");\n const [guessed, setGuessed] = useState<string[]>([]);\n const [mistakes, setMistakes] = useState(0);\n const [wins, setWins] = useState(0);\n const [roundResult, setRoundResult] = useState<\"win\" | \"lose\" | null>(null);\n const [containerSize, setContainerSize] = useState<number | null>(null);\n const [scale, setScale] = useState(1);\n const [usedWords, setUsedWords] = useState<string[]>([]); // Отслеживание использованных слов\n\n const maxMistakes = difficulty === \"Easy\" ? 8 : difficulty === \"Normal\" ? 6 : 4;\n\n // Вычисляем baseURL для изображений\n const imagesBaseURL = baseURL || (typeof window !== \"undefined\" && window.origin \n ? `${window.origin}/cloud/speakid/games/hangman`\n : \"/cloud/speakid/games/hangman\");\n\n // Определение мобильного устройства - используем window напрямую (как в magic-sentence)\n const [isMobile, setIsMobile] = useState(false);\n const [isNestHub, setIsNestHub] = useState(false);\n const [isLandscape, setIsLandscape] = useState(false); // ✅ Landscape режим на мобильных\n const [isMediumScreen, setIsMediumScreen] = useState(false); // ✅ Для разрешений 1200-1400 (включая 1366x768)\n\n // Адаптивные размеры относительно gameCubeSize согласно визуальному гайдлайну\n // Desktop базовые размеры: Headline 1 - 32px, Headline 2 - 24px, Body M - 16px, Button - 16px\n // Mobile базовые размеры: Headline 1 - 30px, Headline 3 - 16px, Body M - 14px\n const baseFontSize = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400; // базовый размер 400px\n const landscapeScale = isLandscape ? 0.8 : 1; // ✅ Уменьшаем на 20% в landscape\n const mediumScreenScale = isMediumScreen ? 0.9 : 1; // ✅ Уменьшаем на 10% для medium screens (1200-1400px)\n const combinedScale = landscapeScale * mediumScreenScale;\n return {\n headline1: isMobile \n ? Math.max(24, Math.min(30, 30 * fontSizeScale * combinedScale)) // Mobile: 30px\n : Math.max(28, Math.min(32, 32 * fontSizeScale * mediumScreenScale)), // Desktop: 32px\n headline2: Math.max(20, Math.min(28, 24 * fontSizeScale * combinedScale)), // Desktop: 24px\n headline3: isMobile\n ? Math.max(14, Math.min(18, 16 * fontSizeScale * combinedScale)) // Mobile: 16px\n : Math.max(20, Math.min(26, 24 * fontSizeScale * combinedScale)), // Desktop: 24px\n bodyL: Math.max(14, Math.min(20, 18 * fontSizeScale * combinedScale)), // Desktop: 18px\n bodyM: isMobile\n ? Math.max(12, Math.min(16, 14 * fontSizeScale * combinedScale)) // Mobile: 14px\n : Math.max(14, Math.min(18, 16 * fontSizeScale * combinedScale)), // Desktop: 16px\n bodyS: isMobile\n ? Math.max(10, Math.min(14, 12 * fontSizeScale * combinedScale)) // Mobile: 12px\n : Math.max(12, Math.min(16, 14 * fontSizeScale * combinedScale)), // Desktop: 14px\n wordDisplay: Math.max(18, Math.min(32, 26 * fontSizeScale * combinedScale)), // Адаптивный размер\n button: Math.max(12, Math.min(18, 16 * fontSizeScale * combinedScale)), // Desktop: 16px\n };\n }, [isMobile, containerSize, gameCubeSize, isLandscape, isMediumScreen]);\n\n // Адаптивные отступы и размеры (минималистичный стиль - мягкие углы)\n // Специальные настройки для Nest Hub (1024x600) и landscape режима\n const padding = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400;\n const landscapeScale = isLandscape ? 0.65 : 1; // ✅ Уменьшаем на 35% в landscape\n const mediumScreenScale = isMediumScreen ? 0.85 : 1; // ✅ Уменьшаем на 15% для medium screens (1200-1400px)\n if (isNestHub) {\n return Math.max(8, Math.min(12, 10 * fontSizeScale));\n }\n const basePadding = Math.max(12, Math.min(24, 16 * fontSizeScale));\n return basePadding * landscapeScale * mediumScreenScale;\n }, [isNestHub, containerSize, gameCubeSize, isLandscape, isMediumScreen]);\n const gap = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400;\n const landscapeScale = isLandscape ? 0.65 : 1; // ✅ Уменьшаем на 35% в landscape\n const mediumScreenScale = isMediumScreen ? 0.85 : 1; // ✅ Уменьшаем на 15% для medium screens (1200-1400px)\n if (isNestHub) {\n return Math.max(3, Math.min(6, 5 * fontSizeScale));\n }\n const baseGap = Math.max(4, Math.min(12, 8 * fontSizeScale));\n return baseGap * landscapeScale * mediumScreenScale;\n }, [isNestHub, containerSize, gameCubeSize, isLandscape, isMediumScreen]);\n const borderRadius = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400;\n const mediumScreenScale = isMediumScreen ? 0.9 : 1; // ✅ Уменьшаем на 10% для medium screens (1200-1400px)\n return Math.max(6, Math.min(10, 8 * fontSizeScale * mediumScreenScale));\n }, [containerSize, gameCubeSize, isMediumScreen]); // Мягкие углы для плоского стиля\n\n // Функции вдохновленные открытым кодом Hangman\n const isWordGuessed = (secretWord: string, lettersGuessed: string[]): boolean => {\n // Проверяем, все ли буквы слова угаданы\n return secretWord.split(\"\").every(letter => lettersGuessed.includes(letter));\n };\n\n const getGuessedWord = (secretWord: string, lettersGuessed: string[]): string => {\n // Возвращает строку с угаданными буквами и подчеркиваниями\n return secretWord\n .split(\"\")\n .map(letter => (lettersGuessed.includes(letter) ? letter : \"_\"))\n .join(\" \");\n };\n\n const getAvailableLetters = (lettersGuessed: string[]): string[] => {\n // Возвращает массив доступных букв (не угаданных)\n const alphabet = \"abcdefghijklmnopqrstuvwxyz\".split(\"\");\n return alphabet.filter(letter => !lettersGuessed.includes(letter));\n };\n\n const pickRandomCategory = (): keyof typeof categories => {\n const categoryKeys = Object.keys(categories) as Array<keyof typeof categories>;\n \n // Используем crypto.getRandomValues для более надежной случайности\n let randomIndex: number;\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n randomIndex = array[0] % categoryKeys.length;\n } else {\n // Fallback на Math.random если crypto недоступен\n randomIndex = Math.floor(Math.random() * categoryKeys.length);\n }\n \n return categoryKeys[randomIndex];\n };\n\n const pickRandomWord = (cat: keyof typeof categories, avoidWords: string[] = []): string => {\n if (!cat || !categories[cat]) {\n // Fallback если категория пустая или не существует\n const firstCategory = Object.keys(categories)[0] as keyof typeof categories;\n return categories[firstCategory]?.[0] || \"\";\n }\n \n const words = categories[cat];\n if (!words || words.length === 0) {\n // Fallback если слова пустые\n return \"\";\n }\n \n // Если есть доступные слова (не использованные), выбираем из них\n const availableWords = words.filter(w => !avoidWords.includes(w));\n const wordsToChooseFrom = availableWords.length > 0 ? availableWords : words;\n \n if (wordsToChooseFrom.length === 0) {\n return \"\";\n }\n \n // Используем crypto.getRandomValues для более надежной случайности\n // Преобразуем в дробное число от 0 до 1 для равномерного распределения\n let randomIndex: number;\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n // Преобразуем в дробное число от 0 до 1 для равномерного распределения\n const randomFloat = array[0] / 0xFFFFFFFF;\n randomIndex = Math.floor(randomFloat * wordsToChooseFrom.length);\n } else {\n // Fallback на Math.random если crypto недоступен\n randomIndex = Math.floor(Math.random() * wordsToChooseFrom.length);\n }\n \n return wordsToChooseFrom[randomIndex];\n };\n\n const startGame = () => {\n if (!category) return;\n setUsedWords([]); // Сбрасываем список использованных слов при новой игре\n const randomWord = pickRandomWord(category, []);\n if (!randomWord) {\n // Если не удалось выбрать слово, возвращаемся к выбору категории\n setStage(\"category\");\n return;\n }\n setWord(randomWord);\n setUsedWords([randomWord]); // Запоминаем первое слово\n setGuessed([]);\n setMistakes(0);\n setCurrentRound(1);\n setWins(0);\n setRoundResult(null);\n setStage(\"game\");\n };\n\n // Функция для обработки выбора буквы (используется и для клавиатуры, и для кликов)\n const handleLetterSelect = useCallback((letter: string) => {\n if (stage !== \"game\" || roundResult !== null) return;\n \n const lowerLetter = letter.toLowerCase();\n \n // Проверка: только буквы английского алфавита\n if (!/^[a-z]$/.test(lowerLetter)) return;\n \n // Проверяем, была ли буква уже угадана\n setGuessed((prevGuessed) => {\n if (prevGuessed.includes(lowerLetter)) {\n return prevGuessed;\n }\n \n // Добавляем букву в список угаданных\n return [...prevGuessed, lowerLetter];\n });\n \n // Проверяем, есть ли буква в текущем слове (используем функциональное обновление)\n setWord((currentWord) => {\n if (currentWord && !currentWord.includes(lowerLetter)) {\n setMistakes((m) => m + 1);\n }\n return currentWord;\n });\n }, [stage, roundResult]);\n\n const handleKey = useCallback((e: KeyboardEvent) => {\n handleLetterSelect(e.key);\n }, [handleLetterSelect]);\n\n useEffect(() => {\n if (stage === \"game\") {\n window.addEventListener(\"keydown\", handleKey);\n return () => window.removeEventListener(\"keydown\", handleKey);\n }\n }, [stage, handleKey]);\n\n // Используем функцию из открытого кода\n const masked = word ? getGuessedWord(word, guessed) : \"\";\n const isWin = word ? isWordGuessed(word, guessed) : false;\n // Игра проиграна когда виселица полностью нарисована (10 частей: основание, стойка, перекладина, веревка, голова, тело, левая рука, правая рука, левая нога, правая нога)\n const isLose = mistakes >= 10;\n const availableLetters = getAvailableLetters(guessed);\n\n // Функция для перехода к следующему раунду (вынесена для избежания дублирования)\n const moveToNextRound = useCallback(() => {\n if (!category || currentRound >= rounds) {\n setStage(\"result\");\n return;\n }\n \n setCurrentRound((r) => r + 1);\n setUsedWords((prev) => {\n const newWord = pickRandomWord(category as keyof typeof categories, prev);\n if (newWord) {\n setWord(newWord);\n return [...prev, newWord];\n }\n return prev;\n });\n setGuessed([]);\n setMistakes(0);\n setRoundResult(null);\n }, [category, currentRound, rounds]);\n\n useEffect(() => {\n if (isWin && roundResult === null) {\n setRoundResult(\"win\");\n setWins((w) => w + 1);\n \n const timer = setTimeout(() => {\n moveToNextRound();\n }, 2000);\n \n return () => clearTimeout(timer);\n }\n \n if (isLose && roundResult === null) {\n setRoundResult(\"lose\");\n \n const timer = setTimeout(() => {\n moveToNextRound();\n }, 2000);\n \n return () => clearTimeout(timer);\n }\n }, [isWin, isLose, roundResult, moveToNextRound]);\n\n const nextRound = () => {\n if (!category || currentRound >= rounds) {\n setStage(\"result\");\n return;\n }\n \n setCurrentRound((r) => r + 1);\n setUsedWords((prev) => {\n const newWord = pickRandomWord(category as keyof typeof categories, prev);\n if (newWord) {\n setWord(newWord);\n return [...prev, newWord]; // Добавляем новое слово в список использованных\n }\n return prev;\n });\n setGuessed([]);\n setMistakes(0);\n setRoundResult(null);\n };\n\n // ✅ Адаптив под мобилки, планшеты и десктоп (как в magic-sentence)\n useEffect(() => {\n const resize = () => {\n const width = window.innerWidth;\n const height = window.innerHeight;\n const mobile = width < 768 || (width === 926 && height === 428) || (width === 932 && height === 430);\n const isSmallHeight = height < 700;\n const isWideScreen = width / height > 1.8;\n const nestHub = width === 1024 && height === 600;\n const landscape = mobile && width > height; // ✅ Landscape режим на мобильных\n // ✅ Определение разрешений 1200-1400 (включая 1366x768)\n const mediumScreen = width >= 1200 && width <= 1400;\n \n setIsMobile(mobile);\n setIsNestHub(nestHub);\n setIsLandscape(landscape);\n setIsMediumScreen(mediumScreen);\n\n // ✅ Адаптивные размеры контейнера\n if (mobile) {\n // Мобильные устройства: используем 100% ширины/высоты\n setContainerSize(null);\n setScale(1);\n } else if (isSmallHeight) {\n // Маленькая высота: используем 100% ширины/высоты\n setContainerSize(null);\n setScale(1);\n } else {\n // Десктоп/планшет: рассчитываем оптимальный размер\n const minSize = 400;\n const maxSize = 1200;\n \n // Рассчитываем максимальный размер, который поместится на экране\n // Учитываем отступы (примерно 40px с каждой стороны) и минимальные размеры\n const availableWidth = width - 80; // Отступы по 40px с каждой стороны\n const availableHeight = height - 80;\n const maxAvailableSize = Math.min(availableWidth, availableHeight);\n \n // Если передан gameCubeSize, используем его, но не больше доступного размера\n let targetSize: number;\n if (gameCubeSize && gameCubeSize >= 320) {\n targetSize = Math.min(gameCubeSize, maxAvailableSize);\n } else {\n // Используем 90% от минимального размера экрана\n targetSize = Math.min(1000, maxAvailableSize * 0.9);\n }\n \n // Ограничиваем минимальным и максимальным размером\n const finalSize = Math.max(minSize, Math.min(maxSize, targetSize));\n setContainerSize(finalSize);\n \n // Для широких экранов уменьшаем масштаб\n if (isWideScreen) {\n setScale(0.85);\n } else {\n setScale(1);\n }\n }\n };\n resize();\n window.addEventListener(\"resize\", resize);\n return () => window.removeEventListener(\"resize\", resize);\n }, [gameCubeSize]);\n\n // SVG с детскими каракулями для фона (более резкие и яркие)\n const kidsDoodlesSvg = `\n <svg width=\"100%\" height=\"100%\" xmlns=\"http://www.w3.org/2000/svg\" style=\"position: absolute; top: 0; left: 0; pointer-events: none; opacity: 0.2;\">\n <!-- Каракули мелками и фломастерами -->\n \n <!-- Сердечко -->\n <path d=\"M 85% 15% Q 85% 10%, 90% 10% Q 95% 10%, 95% 15% Q 95% 20%, 90% 25% Q 85% 30%, 85% 15%\" \n fill=\"none\" stroke=\"#FF69B4\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \n <!-- Звезда -->\n <path d=\"M 10% 85% L 12% 80% L 14% 85% L 18% 85% L 13% 88% L 15% 92% L 10% 89% L 5% 92% L 7% 88% L 2% 85% Z\" \n fill=\"#FFA500\" stroke=\"#FF8C00\" stroke-width=\"1.5\"/>\n \n <!-- Волнистые линии (мелки) -->\n <path d=\"M 20% 25% Q 22% 23%, 24% 25% T 28% 25% T 32% 25%\" \n fill=\"none\" stroke=\"#FF6B6B\" stroke-width=\"3.5\" stroke-linecap=\"round\"/>\n <path d=\"M 60% 30% Q 62% 28%, 64% 30% T 68% 30% T 72% 30%\" \n fill=\"none\" stroke=\"#4ECDC4\" stroke-width=\"3.5\" stroke-linecap=\"round\"/>\n \n <!-- Спираль -->\n <path d=\"M 5% 45% Q 8% 42%, 10% 45% Q 12% 48%, 10% 50% Q 8% 52%, 5% 50% Q 3% 48%, 5% 45%\" \n fill=\"none\" stroke=\"#9B59B6\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \n <!-- Зигзаг -->\n <path d=\"M 88% 55% L 92% 50% L 94% 55% L 96% 50% L 98% 55%\" \n fill=\"none\" stroke=\"#E74C3C\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n \n <!-- Ромашка -->\n <circle cx=\"25%\" cy=\"70%\" r=\"15\" fill=\"none\" stroke=\"#FFD700\" stroke-width=\"2.5\"/>\n <circle cx=\"25%\" cy=\"70%\" r=\"8\" fill=\"#FFD700\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"22%\" y2=\"65%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"28%\" y2=\"65%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"22%\" y2=\"75%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"28%\" y2=\"75%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n \n <!-- Каляки-маляки (случайные линии) -->\n <path d=\"M 40% 20% Q 42% 22%, 40% 24% T 40% 28%\" \n fill=\"none\" stroke=\"#32CD32\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n <path d=\"M 50% 60% L 53% 57% L 55% 60% L 57% 57%\" \n fill=\"none\" stroke=\"#FF1493\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \n <!-- Еще волнистые линии -->\n <path d=\"M 35% 85% Q 37% 83%, 39% 85% T 43% 85% T 47% 85%\" \n fill=\"none\" stroke=\"#FF4500\" stroke-width=\"3.5\" stroke-linecap=\"round\"/>\n </svg>\n `;\n\n // Адаптивные стили для контента (без фиксированных размеров)\n // Определение планшета: ширина >= 768px и < 1024px (и не мобильный)\n const isTablet = !isMobile && typeof window !== \"undefined\" && window.innerWidth >= 768 && window.innerWidth < 1024;\n // Условие для отображения логотипа: не мобильный, showLogo включен, И (не экран игры ИЛИ планшет)\n const shouldShowLogo = !isMobile && showLogo && (stage !== \"game\" || isTablet);\n\n const containerStyle: React.CSSProperties = {\n ...styles.gmCenterScreen,\n width: \"100%\",\n height: \"100%\",\n padding: `${padding}px`,\n paddingTop: shouldShowLogo ? `${80}px` : `${padding}px`, // ✅ Резервируем больше места под логотип (24px top + 28px высота + 28px отступ)\n overflow: isMediumScreen ? \"hidden\" : \"auto\", // ✅ Для разрешений 1200-1400 убираем скролл\n position: \"relative\",\n boxSizing: \"border-box\",\n background: \"transparent\",\n };\n\n // Мемоизированный логотип (рендерится вне условных блоков)\n const MemoizedLogo = useMemo(\n () => {\n // Проверяем showLogo ПЕРЕД проверкой размеров экрана\n if (!shouldShowLogo) {\n return null;\n }\n \n // Скрываем логотип только на мобильных устройствах в landscape режиме\n // Убрали проверку height < 700, чтобы уважать проп showLogo на всех разрешениях\n const width = window.innerWidth;\n if (isMobile && width > window.innerHeight) {\n return null;\n }\n \n const logoBaseUrl = logoUrl || (typeof window !== \"undefined\" && window.origin \n ? `${window.origin}/cloud/speakid/games/hangman/logo`\n : \"/cloud/speakid/games/hangman/logo\");\n \n return (\n <div style={styles.gmLogoFixed}>\n <picture>\n <source\n srcSet={`${logoBaseUrl}.svg`}\n type=\"image/svg+xml\"\n />\n <img\n src={`${logoBaseUrl}.png`}\n alt=\"SPEAKID Logo\"\n style={styles.gmLogoImg}\n loading=\"lazy\"\n />\n </picture>\n </div>\n );\n },\n [isMobile, shouldShowLogo, logoUrl, stage]\n );\n\n // Общая структура рендеринга (как в magic-sentence)\n const renderContent = () => {\n // Начальный экран лобби\n if (stage === \"lobby\") {\n return (\n <>\n {MemoizedLogo}\n <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />\n <h1 style={{ \n ...styles.gmHeadline1, \n fontSize: `${baseFontSize.headline1}px`, \n marginBottom: `${gap * 3}px`,\n position: \"relative\",\n zIndex: 1,\n }}>\n HANGMAN\n </h1>\n <button\n onClick={() => setStage(\"category\")}\n style={{\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 500, // Medium для более заметности\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap * 1.2}px ${gap * 3}px`,\n borderRadius: `${borderRadius * 1.5}px`,\n position: \"relative\",\n zIndex: 1,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"#ec4c44\",\n color: \"#ffffff\",\n border: \"none\",\n cursor: \"pointer\",\n transition: \"background 0.2s ease, transform 0.1s ease\",\n boxShadow: \"0 2px 8px rgba(236, 76, 68, 0.2)\",\n minWidth: \"120px\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = \"#d43a32\";\n e.currentTarget.style.transform = \"translateY(-2px)\";\n e.currentTarget.style.boxShadow = \"0 4px 12px rgba(236, 76, 68, 0.3)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = \"#ec4c44\";\n e.currentTarget.style.transform = \"translateY(0)\";\n e.currentTarget.style.boxShadow = \"0 2px 8px rgba(236, 76, 68, 0.2)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.transform = \"translateY(0)\";\n }}\n >\n <svg\n width={`${baseFontSize.button * 1.3}px`}\n height={`${baseFontSize.button * 1.3}px`}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{ display: \"block\", marginRight: `${gap}px` }}\n >\n <path\n d=\"M8 5V19L19 12L8 5Z\"\n fill=\"#ffffff\"\n stroke=\"none\"\n />\n </svg>\n <span style={{ fontWeight: 500 }}>PLAY</span>\n </button>\n <div style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n zIndex: 0,\n }}>\n <img\n src={`${imagesBaseURL}/sun.png`}\n alt=\"Sun\"\n style={{\n position: \"absolute\",\n left: isMobile ? \"-10%\" : \"5%\",\n top: \"20%\",\n width: \"auto\",\n height: isMobile \n ? `${Math.min(window.innerHeight * 0.33, 200)}px`\n : `${Math.min((containerSize || gameCubeSize || 1000) * 0.33, 300)}px`,\n maxHeight: \"33vh\",\n objectFit: \"contain\",\n opacity: 0.6,\n }}\n />\n <img\n src={`${imagesBaseURL}/character.png`}\n alt=\"Hangman character\"\n style={{\n position: \"absolute\",\n right: isMobile ? \"5%\" : \"10%\",\n bottom: \"10%\",\n width: \"auto\",\n height: isMobile \n ? `${Math.min(window.innerHeight * 0.33, 200)}px`\n : `${Math.min((containerSize || gameCubeSize || 1000) * 0.33, 300)}px`,\n maxHeight: \"33vh\",\n objectFit: \"contain\",\n opacity: 0.6,\n }}\n />\n </div>\n </>\n );\n }\n\n // Экран выбора категории\n if (stage === \"category\") {\n return (\n <>\n {MemoizedLogo}\n <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />\n <button\n onClick={() => setStage(\"lobby\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n }}\n style={{\n ...styles.gmButton,\n ...styles.gmButtonSecondary,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n position: \"absolute\",\n top: \"60px\", // ✅ Под логотипом (24px top логотипа + 28px высота + 8px отступ)\n left: \"24px\", // ✅ Та же позиция что и логотип\n zIndex: 10,\n }}\n >\n ←\n </button>\n\n <div style={{ ...styles.gmButtonGroup, gap: `${gap}px`, marginBottom: `${gap * 3}px`, marginTop: `${gap * 4}px`, position: \"relative\", zIndex: 1 }}>\n {Object.keys(categories).map((cat) => {\n // Облачки с border вместо заливки\n return (\n <button\n key={cat}\n onClick={() => {\n setCategory(cat as keyof typeof categories);\n setStage(\"rounds\");\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\";\n e.currentTarget.style.borderColor = \"#1f2937\";\n e.currentTarget.style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n e.currentTarget.style.borderColor = \"#e5e7eb\";\n e.currentTarget.style.transform = \"scale(1)\";\n }}\n style={{\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 500,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap * 1.2}px ${gap * 2}px`,\n borderRadius: `${borderRadius * 2}px`, // Более округлые для облачков\n margin: `${gap / 2}px`,\n background: \"transparent\",\n border: \"2px solid #e5e7eb\",\n color: \"#1f2937\",\n cursor: \"pointer\",\n transition: \"background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease\",\n boxShadow: \"none\",\n }}\n >\n {cat}\n </button>\n );\n })}\n </div>\n </>\n );\n }\n\n // Экран выбора количества раундов\n if (stage === \"rounds\") {\n return (\n <>\n {MemoizedLogo}\n <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />\n <button\n onClick={() => setStage(\"category\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n }}\n style={{\n ...styles.gmButton,\n ...styles.gmButtonSecondary,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n position: \"absolute\",\n top: \"60px\", // ✅ Под логотипом (24px top логотипа + 28px высота + 8px отступ)\n left: \"24px\", // ✅ Та же позиция что и логотип\n zIndex: 10,\n }}\n >\n ←\n </button>\n\n <h1 style={{ ...styles.gmHeadline1, fontSize: `${baseFontSize.headline1}px`, marginBottom: `${gap * 2}px`, position: \"relative\", zIndex: 1 }}>\n Choose rounds\n </h1>\n\n <div style={{ ...styles.gmButtonGroup, gap: `${gap}px`, marginBottom: `${gap * 3}px`, position: \"relative\", zIndex: 1 }}>\n {[1, 3, 5].map((r) => {\n // Облачки с border вместо заливки\n return (\n <button\n key={r}\n onClick={() => {\n setRounds(r);\n startGame();\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\";\n e.currentTarget.style.borderColor = \"#1f2937\";\n e.currentTarget.style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n e.currentTarget.style.borderColor = \"#e5e7eb\";\n e.currentTarget.style.transform = \"scale(1)\";\n }}\n style={{\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 500,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap * 1.2}px ${gap * 2}px`,\n borderRadius: `${borderRadius * 2}px`, // Более округлые для облачков\n margin: `${gap / 2}px`,\n background: \"transparent\",\n border: \"2px solid #e5e7eb\",\n color: \"#1f2937\",\n cursor: \"pointer\",\n transition: \"background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease\",\n boxShadow: \"none\",\n }}\n >\n {r}\n </button>\n );\n })}\n </div>\n </>\n );\n }\n\n // Игровой экран\n if (stage === \"game\") {\n return (\n <>\n {MemoizedLogo}\n {!isLandscape && <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />} {/* ✅ Скрываем декоративные элементы в landscape */}\n <div style={{\n ...styles.gmInfoBox,\n padding: `${isLandscape ? gap * 0.6 : gap * 0.8}px`, // ✅ Уменьшаем padding в landscape\n marginBottom: `${isLandscape ? gap * 0.3 : gap * 0.5}px`, // ✅ Уменьшаем margin в landscape\n maxWidth: `${(containerSize || gameCubeSize) * 0.9}px`,\n }}>\n <h3 style={{ ...styles.gmHeadline3, fontSize: `${baseFontSize.headline3}px`, marginBottom: `${gap * 0.5}px` }}>\n Category: {category}\n </h3>\n <p style={{ ...styles.gmBodyM, fontSize: `${baseFontSize.bodyM}px`, marginBottom: `0px` }}>\n Round {currentRound} of {rounds}\n </p>\n </div>\n\n {word && (\n <p style={{\n ...styles.gmBodyS,\n fontSize: `${baseFontSize.bodyS}px`,\n marginTop: `${isLandscape ? gap * 0.3 : gap * 0.5}px`, // ✅ Уменьшаем margin в landscape\n marginBottom: `${isLandscape ? gap * 0.5 : gap}px`, // ✅ Уменьшаем margin в landscape\n }}>\n I am thinking of a word that is <strong>{word.length}</strong> letters long\n </p>\n )}\n\n {/* Визуализация виселицы */}\n <div style={{\n margin: `${isLandscape ? gap * 0.5 : gap}px 0`, // ✅ Уменьшаем margin в landscape\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}>\n <HangmanDrawing \n mistakes={mistakes} \n maxMistakes={maxMistakes}\n size={isNestHub \n ? Math.max(80, Math.min(110, (containerSize || gameCubeSize) * 0.16))\n : isMobile\n ? isLandscape\n ? Math.max(70, Math.min(120, Math.min(window.innerWidth * 0.25, window.innerHeight * 0.15))) // ✅ Уменьшаем на 25% в landscape\n : Math.max(100, Math.min(150, Math.min(window.innerWidth * 0.3, window.innerHeight * 0.2))) // ✅ Улучшенный расчет для мобильных\n : Math.max(100, Math.min(150, (containerSize || gameCubeSize) * 0.2))}\n />\n </div>\n\n <div style={{\n ...styles.gmWordDisplay,\n fontSize: `${Math.max(16, Math.min(24, baseFontSize.wordDisplay * 0.9))}px`,\n margin: `${isLandscape ? gap * 0.5 : gap}px 0`, // ✅ Уменьшаем margin в landscape\n letterSpacing: `${gap * 0.8}px`,\n minHeight: `${Math.max(16, Math.min(24, baseFontSize.wordDisplay * 0.9)) * 1.2}px`,\n }}>{masked || \"Loading...\"}</div>\n\n {/* Алфавит - вдохновлено getAvailableLetters */}\n <div style={{\n ...styles.gmInfoBox,\n padding: `${isLandscape ? gap * 0.6 : gap}px`, // ✅ Уменьшаем padding в landscape\n marginTop: `${isLandscape ? gap * 0.5 : gap}px`, // ✅ Уменьшаем margin в landscape\n marginBottom: `${isLandscape ? gap * 0.5 : gap}px`, // ✅ Уменьшаем margin в landscape\n maxWidth: `${(containerSize || gameCubeSize) * 0.95}px`,\n }}>\n <p style={{\n ...styles.gmBodyS,\n fontSize: `${baseFontSize.bodyS}px`,\n marginBottom: `${gap}px`,\n fontWeight: 500, // Medium\n }}>\n Available letters:\n </p>\n <div style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: `${gap / 3}px`,\n justifyContent: \"center\",\n fontSize: `${Math.max(9, Math.min(12, baseFontSize.bodyS * 0.75))}px`,\n fontFamily: '\"Onest\", system-ui, sans-serif',\n }}>\n {availableLetters.map((letter) => (\n <button\n key={letter}\n onClick={() => handleLetterSelect(letter)}\n disabled={roundResult !== null}\n onMouseEnter={(e) => {\n if (roundResult === null) {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n e.currentTarget.style.cursor = \"pointer\";\n }\n }}\n onMouseLeave={(e) => {\n if (roundResult === null) {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n e.currentTarget.style.cursor = \"pointer\";\n }\n }}\n style={{\n padding: `${gap / 4}px ${gap / 3}px`,\n borderRadius: `${borderRadius * 0.5}px`,\n background: \"#f9f9f9\",\n color: \"#1f2937\",\n border: \"1px solid #e5e7eb\",\n minWidth: `${Math.max(gap * 1.5, (containerSize || gameCubeSize) * 0.04)}px`,\n textAlign: \"center\",\n display: \"inline-block\",\n cursor: roundResult === null ? \"pointer\" : \"default\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontSize: `${Math.max(9, Math.min(12, baseFontSize.bodyS * 0.75))}px`,\n transition: \"background-color 0.2s ease\",\n }}\n >\n {letter}\n </button>\n ))}\n </div>\n </div>\n\n {/* Уже угаданные буквы */}\n {guessed.length > 0 && (\n <div style={{\n ...styles.gmGuessedLetters,\n fontSize: `${Math.max(10, Math.min(12, baseFontSize.bodyS * 0.85))}px`,\n marginTop: `${gap * 0.5}px`,\n marginBottom: `2px`,\n }}>\n <span style={{ color: \"#6b7280\" }}>\n Guessed letters: <strong>{guessed.join(\", \")}</strong>\n </span>\n </div>\n )}\n\n {roundResult === \"win\" && (\n <div style={{\n ...styles.gmStatusWin,\n fontSize: `${baseFontSize.bodyL}px`,\n margin: `2px 0`,\n }}>\n 🎉 You won this round!\n </div>\n )}\n\n {roundResult === \"lose\" && (\n <div style={{\n ...styles.gmStatusLose,\n fontSize: `${baseFontSize.bodyL}px`,\n margin: `2px 0`,\n }}>\n The hangman is complete! The word was: <strong>{word}</strong>\n </div>\n )}\n\n {roundResult !== null && currentRound < rounds && (\n <div style={{ marginTop: `2px`, marginBottom: `${gap}px` }}>\n <button\n onClick={nextRound}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#d43a32\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#ec4c44\";\n }}\n style={{\n ...styles.gmButton,\n fontSize: `${Math.max(11, Math.min(14, baseFontSize.button * 0.85))}px`,\n padding: `${gap * 0.6}px ${gap * 1.2}px`,\n borderRadius: `${borderRadius}px`,\n }}\n >\n NEXT\n </button>\n </div>\n )}\n\n {roundResult !== null && currentRound >= rounds && (\n <div style={{ marginTop: `2px`, marginBottom: `${gap}px` }}>\n <button\n onClick={() => setStage(\"result\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#d43a32\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#ec4c44\";\n }}\n style={{\n ...styles.gmButton,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n }}\n >\n View results\n </button>\n </div>\n )}\n\n {roundResult === null && guessed.length === 0 && (\n <p style={{\n ...styles.gmBodyS,\n fontSize: `${baseFontSize.bodyS}px`,\n marginTop: `${gap}px`,\n marginBottom: `${gap}px`,\n }}>\n Type a letter on your keyboard\n </p>\n )}\n </>\n );\n }\n\n // Экран результатов\n if (stage === \"result\") {\n return (\n <>\n {MemoizedLogo}\n <h1 style={{\n ...styles.gmHeadline1,\n fontSize: `${baseFontSize.headline1}px`,\n marginBottom: `${gap * 2}px`,\n }}>\n 🎊 Game Finished!\n </h1>\n <p style={{\n ...styles.gmBodyL,\n fontSize: `${baseFontSize.bodyL}px`,\n marginBottom: `${gap * 2}px`,\n }}>\n You guessed <strong>{wins}</strong> out of <strong>{rounds}</strong> words correctly.\n </p>\n \n <div style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: `${gap}px`,\n alignItems: \"center\",\n }}>\n <button\n onClick={() => {\n // Сбрасываем состояние и запускаем новую игру с той же категорией и раундами\n if (!category || rounds === 0) {\n setStage(\"lobby\");\n return;\n }\n \n setUsedWords([]);\n const randomWord = pickRandomWord(category as keyof typeof categories, []);\n if (randomWord) {\n setWord(randomWord);\n setUsedWords([randomWord]);\n setGuessed([]);\n setMistakes(0);\n setCurrentRound(1);\n setWins(0);\n setRoundResult(null);\n setStage(\"game\");\n }\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#d43a32\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#ec4c44\";\n }}\n style={{\n ...styles.gmButton,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n minWidth: \"200px\",\n }}\n >\n Play again\n </button>\n \n <button\n onClick={() => setStage(\"lobby\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n }}\n style={{\n ...styles.gmButton,\n ...styles.gmButtonSecondary,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n minWidth: \"200px\",\n }}\n >\n Exit\n </button>\n </div>\n </>\n );\n }\n\n return null;\n };\n\n // Единый return с трехуровневой структурой (как в magic-sentence)\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n background: \"transparent\",\n overflow: \"hidden\",\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0\n }}\n >\n <div\n style={{\n width: isMobile ? \"100%\" : (containerSize || gameCubeSize || 1000),\n height: isMobile ? \"100%\" : (containerSize || gameCubeSize || 1000),\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n overflow: \"hidden\",\n borderRadius: isMobile ? 0 : \"20px\",\n background: \"#ffffff\",\n boxShadow: isMobile ? \"none\" : \"0 0 40px rgba(0,0,0,0.1)\",\n margin: isMobile ? \"0 auto\" : \"unset\",\n position: \"relative\", // needed so absolute logo is inside the square\n transform: `scale(${scale})`,\n }}\n >\n <div\n style={{\n transform: \"translateZ(0)\",\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}\n >\n <div style={containerStyle}>\n {renderContent()}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\n"],"names":["styles","HangmanDrawing","mistakes","maxMistakes","size","svgWidth","svgHeight","strokeWidth","baseX1","baseY","baseX2","poleX","poleY1","poleY2","topX1","topY","topX2","ropeX","ropeY1","ropeY2","headCX","headCY","headR","bodyX","bodyY1","bodyY2","leftArmX1","leftArmY1","leftArmX2","leftArmY2","rightArmX1","rightArmY1","rightArmX2","rightArmY2","leftLegX1","leftLegY1","leftLegX2","leftLegY2","rightLegX1","rightLegY1","rightLegX2","rightLegY2","strokeColor","jsxs","jsx","HangmanLobbyGame","gameCubeSize","screenHeight","screenWidth","logoUrl","showLogo","baseURL","categories","stage","setStage","useState","category","setCategory","difficulty","rounds","setRounds","currentRound","setCurrentRound","word","setWord","guessed","setGuessed","setMistakes","wins","setWins","roundResult","setRoundResult","containerSize","setContainerSize","scale","setScale","usedWords","setUsedWords","imagesBaseURL","isMobile","setIsMobile","isNestHub","setIsNestHub","isLandscape","setIsLandscape","isMediumScreen","setIsMediumScreen","baseFontSize","useMemo","fontSizeScale","landscapeScale","mediumScreenScale","combinedScale","padding","gap","borderRadius","isWordGuessed","secretWord","lettersGuessed","letter","getGuessedWord","getAvailableLetters","pickRandomWord","cat","avoidWords","firstCategory","_a","words","availableWords","w","wordsToChooseFrom","randomIndex","array","randomFloat","startGame","randomWord","handleLetterSelect","useCallback","lowerLetter","prevGuessed","currentWord","m","handleKey","useEffect","masked","isWin","isLose","availableLetters","moveToNextRound","r","prev","newWord","timer","nextRound","resize","width","height","mobile","isSmallHeight","isWideScreen","nestHub","landscape","mediumScreen","availableWidth","availableHeight","maxAvailableSize","targetSize","finalSize","kidsDoodlesSvg","isTablet","shouldShowLogo","containerStyle","MemoizedLogo","logoBaseUrl","renderContent","Fragment","e"],"mappings":"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"}
1
+ {"version":3,"file":"speakid-hangman.cjs.js","sources":["../src/styles/style.ts","../src/components/HangmanLobbyGame.tsx"],"sourcesContent":["import { CSSProperties } from \"react\";\n\n// ===== Стили согласно визуальному гайдлайну: Onest, минималистичный, дружелюбный =====\n// Шрифт: Onest (Regular, Medium, SemiBold)\n// Стиль: Плоский, минималистичный, воздушный, без излишеств\n// Цвета: Мягкий контраст, дружелюбная палитра\n\nexport const styles: Record<string, CSSProperties> = {\n gmCenterScreen: {\n position: \"relative\",\n zIndex: 1,\n minHeight: \"100%\",\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"center\",\n textAlign: \"center\",\n color: \"#1f2937\", // colorTextPrimary\n padding: \"24px 16px\",\n boxSizing: \"border-box\",\n fontFamily: '\"Onest\", system-ui, -apple-system, \"Segoe UI\", Roboto, Arial, sans-serif',\n background: \"transparent\", // Прозрачный по умолчанию, переопределяется в компоненте\n },\n // Desktop: Headline 1 - Onest SemiBold 32px, line-height 110%\n gmHeadline1: {\n fontWeight: 600, // SemiBold\n fontSize: \"clamp(30px, 4vw, 32px)\", // Mobile 30px, Desktop 32px\n lineHeight: \"110%\",\n marginBottom: \"24px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Headline 2 - Onest Medium 24px, line-height 110%\n gmHeadline2: {\n fontWeight: 500, // Medium\n fontSize: \"24px\",\n lineHeight: \"110%\",\n marginBottom: \"16px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Headline 3 - Onest Medium 24px, line-height 110%\n // Mobile: Headline 3 - Onest Medium 16px, line-height 110%\n gmHeadline3: {\n fontWeight: 500, // Medium\n fontSize: \"clamp(16px, 2vw, 24px)\", // Mobile 16px, Desktop 24px\n lineHeight: \"110%\",\n marginBottom: \"12px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Body L - Onest Regular 18px, line-height 120%\n gmBodyL: {\n fontWeight: 400, // Regular\n fontSize: \"18px\",\n lineHeight: \"120%\",\n marginBottom: \"12px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Body M - Onest Regular 16px, line-height 120%\n // Mobile: Body M - Onest Regular 14px, line-height 120%\n gmBodyM: {\n fontWeight: 400, // Regular\n fontSize: \"clamp(14px, 1.5vw, 16px)\", // Mobile 14px, Desktop 16px\n lineHeight: \"120%\",\n marginBottom: \"8px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Body S - Onest Regular 14px, line-height 120%\n // Mobile: Body S - Onest Regular 12px, line-height 120%\n gmBodyS: {\n fontWeight: 400, // Regular\n fontSize: \"clamp(12px, 1.5vw, 14px)\", // Mobile 12px, Desktop 14px\n lineHeight: \"120%\",\n color: \"#6b7280\", // colorTextSecondary\n marginBottom: \"8px\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Button: Onest Regular 16px, line-height 100%\n gmButton: {\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 400, // Regular\n fontSize: \"16px\",\n lineHeight: \"100%\",\n padding: \"10px 16px\",\n borderRadius: \"8px\", // Более мягкие углы для минималистичного стиля\n border: \"1px solid #e5e7eb\", // colorSeparator\n background: \"#ec4c44\", // colorAccent (Default)\n color: \"#ffffff\", // colorTextContrast\n cursor: \"pointer\",\n boxShadow: \"none\", // Плоский стиль без теней\n transition: \"background-color 0.2s ease, opacity 0.2s ease, transform 0.1s ease\",\n margin: \"4px\",\n },\n gmButtonActive: {\n background: \"#333\", // colorAccent Active\n color: \"#fff\", // colorTextContrast\n boxShadow: \"none\", // Плоский стиль\n },\n gmButtonSecondary: {\n background: \"#f9f9f9\", // colorBackgroundAccent\n color: \"#1f2937\", // colorTextPrimary\n border: \"1px solid #e5e7eb\", // colorSeparator\n boxShadow: \"none\", // Плоский стиль\n },\n gmButtonGroup: {\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"8px\",\n justifyContent: \"center\",\n marginBottom: \"24px\",\n },\n gmWordDisplay: {\n fontSize: \"clamp(20px, 5vw, 28px)\",\n fontWeight: 500, // Medium\n letterSpacing: \"6px\",\n margin: \"32px 0\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n lineHeight: \"120%\",\n },\n gmGuessedLetters: {\n fontSize: \"clamp(12px, 1.5vw, 16px)\", // Body S / Body M\n color: \"#6b7280\", // colorTextSecondary\n marginTop: \"16px\",\n minHeight: \"24px\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n lineHeight: \"120%\",\n },\n gmStatusWin: {\n color: \"#10b981\", // colorTextPositive / colorIconPositive\n fontWeight: 500, // Medium\n fontSize: \"clamp(14px, 1.5vw, 18px)\", // Body M / Body L\n lineHeight: \"120%\",\n margin: \"16px 0\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n gmStatusLose: {\n color: \"#ec4c44\", // colorTextNegative / colorIconNegative\n fontWeight: 500, // Medium\n fontSize: \"clamp(14px, 1.5vw, 18px)\", // Body M / Body L\n lineHeight: \"120%\",\n margin: \"16px 0\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n gmInfoBox: {\n background: \"#f9f9f9\", // colorBackgroundAccent\n border: \"1px solid #e5e7eb\", // colorSeparator\n borderRadius: \"8px\", // Мягкие углы\n padding: \"16px\",\n marginBottom: \"24px\",\n maxWidth: \"500px\",\n width: \"100%\",\n boxShadow: \"none\", // Плоский стиль\n },\n gmSection: {\n marginBottom: \"32px\",\n width: \"100%\",\n maxWidth: \"500px\",\n },\n // ✅ Обновлено только для качества логотипа (размер как в magic-sentence)\n gmLogoFixed: {\n position: \"absolute\",\n top: \"24px\", // ✅ Увеличен отступ сверху для большего пространства\n left: \"24px\", // ✅ Увеличен отступ слева для большего пространства\n width: \"auto\",\n zIndex: 30, // ✅ Унифицирован zIndex для консистентности\n pointerEvents: \"none\",\n background: \"transparent\",\n transform: \"none\",\n willChange: \"auto\",\n },\n gmLogoImg: {\n height: \"28px\",\n width: \"auto\",\n background: \"transparent\",\n objectFit: \"contain\",\n imageRendering: \"auto\",\n transform: \"translateZ(0)\",\n backfaceVisibility: \"hidden\",\n WebkitFontSmoothing: \"antialiased\",\n display: \"block\",\n },\n gmLogoFallback: {\n height: \"28px\",\n width: \"auto\",\n background: \"transparent\",\n color: \"#ec4c44\",\n fontSize: \"16px\",\n fontWeight: 700,\n display: \"block\",\n },\n};\n\n// ===== Цветовая палитра для справки =====\n// colorTextPrimary: #1f2937\n// colorTextSecondary: #6b7280\n// colorTextNegative: #ec4c44\n// colorTextPositive: #10b981\n// colorBackgroundAccent: #f9f9f9\n// colorSeparator: #e5e7eb\n// colorAccent (Default): #ec4c44\n// colorAccent (Active): #333\n\n","import React, { useState, useEffect, useCallback, useMemo } from \"react\";\nimport { styles } from \"../styles/style\";\n\n// Компонент визуализации виселицы\nfunction HangmanDrawing({ \n mistakes, \n maxMistakes, \n size = 200 \n}: { \n mistakes: number; \n maxMistakes: number;\n size?: number;\n}) {\n // Адаптивные размеры SVG\n const svgWidth = size;\n const svgHeight = size * 1.25; // Соотношение 200:250\n const strokeWidth = Math.max(3, size / 100); // ✅ Увеличена минимальная толщина с 2 до 3 для лучшей видимости на маленьких экранах\n \n // Координаты (пропорциональные исходному размеру 200x250)\n const baseX1 = 10 * (svgWidth / 200);\n const baseY = 240 * (svgHeight / 250);\n const baseX2 = 150 * (svgWidth / 200);\n \n const poleX = 80 * (svgWidth / 200);\n const poleY1 = 20 * (svgHeight / 250);\n const poleY2 = 240 * (svgHeight / 250);\n \n const topX1 = 80 * (svgWidth / 200);\n const topY = 20 * (svgHeight / 250);\n const topX2 = 150 * (svgWidth / 200);\n \n const ropeX = 150 * (svgWidth / 200);\n const ropeY1 = 20 * (svgHeight / 250);\n const ropeY2 = 50 * (svgHeight / 250);\n \n const headCX = 150 * (svgWidth / 200);\n const headCY = 70 * (svgHeight / 250);\n const headR = 20 * (svgWidth / 200);\n \n const bodyX = 150 * (svgWidth / 200);\n const bodyY1 = 90 * (svgHeight / 250);\n const bodyY2 = 150 * (svgHeight / 250);\n \n const leftArmX1 = 150 * (svgWidth / 200);\n const leftArmY1 = 110 * (svgHeight / 250);\n const leftArmX2 = 130 * (svgWidth / 200);\n const leftArmY2 = 130 * (svgHeight / 250);\n \n const rightArmX1 = 150 * (svgWidth / 200);\n const rightArmY1 = 110 * (svgHeight / 250);\n const rightArmX2 = 170 * (svgWidth / 200);\n const rightArmY2 = 130 * (svgHeight / 250);\n \n const leftLegX1 = 150 * (svgWidth / 200);\n const leftLegY1 = 150 * (svgHeight / 250);\n const leftLegX2 = 130 * (svgWidth / 200);\n const leftLegY2 = 190 * (svgHeight / 250);\n \n const rightLegX1 = 150 * (svgWidth / 200);\n const rightLegY1 = 150 * (svgHeight / 250);\n const rightLegX2 = 170 * (svgWidth / 200);\n const rightLegY2 = 190 * (svgHeight / 250);\n\n // Цвет в зависимости от количества ошибок\n const getStrokeColor = () => {\n if (mistakes === 0) return \"#1f2937\"; // colorTextPrimary\n if (mistakes <= maxMistakes * 0.5) return \"#1f2937\"; // Окей\n if (mistakes <= maxMistakes * 0.75) return \"#f59e0b\"; // Предупреждение\n return \"#ec4c44\"; // colorTextNegative - опасно\n };\n\n const strokeColor = getStrokeColor();\n\n return (\n <svg \n width={svgWidth} \n height={svgHeight}\n viewBox=\"0 0 200 250\" // ✅ Добавлен viewBox для правильного масштабирования на iOS Safari\n style={{ \n display: \"block\",\n margin: \"0 auto\",\n overflow: \"visible\", // ✅ Для корректного отображения линий\n WebkitFontSmoothing: \"antialiased\", // ✅ Для лучшего рендеринга на iOS\n transform: \"translateZ(0)\", // ✅ Включение аппаратного ускорения на iOS\n }}\n >\n {/* Виселица рисуется пошагово с ошибками */}\n {/* 1-я ошибка: Основание */}\n {mistakes > 0 && (\n <line \n x1={baseX1} \n y1={baseY} \n x2={baseX2} \n y2={baseY} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 2-я ошибка: Стойка */}\n {mistakes > 1 && (\n <line \n x1={poleX} \n y1={poleY1} \n x2={poleX} \n y2={poleY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 3-я ошибка: Верхняя перекладина */}\n {mistakes > 2 && (\n <line \n x1={topX1} \n y1={topY} \n x2={topX2} \n y2={topY} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 4-я ошибка: Веревка */}\n {mistakes > 3 && (\n <line \n x1={ropeX} \n y1={ropeY1} \n x2={ropeX} \n y2={ropeY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 5-я ошибка: Голова */}\n {mistakes > 4 && (\n <circle \n cx={headCX} \n cy={headCY} \n r={headR} \n stroke={strokeColor} \n fill=\"none\" \n strokeWidth={strokeWidth}\n />\n )}\n \n {/* 6-я ошибка: Тело */}\n {mistakes > 5 && (\n <line \n x1={bodyX} \n y1={bodyY1} \n x2={bodyX} \n y2={bodyY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {/* Дополнительные части (если maxMistakes больше 6) */}\n {mistakes > 6 && (\n <line \n x1={leftArmX1} \n y1={leftArmY1} \n x2={leftArmX2} \n y2={leftArmY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {mistakes > 7 && (\n <line \n x1={rightArmX1} \n y1={rightArmY1} \n x2={rightArmX2} \n y2={rightArmY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {mistakes > 8 && (\n <line \n x1={leftLegX1} \n y1={leftLegY1} \n x2={leftLegX2} \n y2={leftLegY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {mistakes > 9 && (\n <line \n x1={rightLegX1} \n y1={rightLegY1} \n x2={rightLegX2} \n y2={rightLegY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n </svg>\n );\n}\n\nexport interface HangmanLobbyGameProps {\n gameCubeSize?: number;\n screenHeight?: number;\n screenWidth?: number;\n logoUrl?: string;\n showLogo?: boolean;\n baseURL?: string;\n}\n\nexport default function HangmanLobbyGame({\n gameCubeSize = 400,\n screenHeight = 800,\n screenWidth = 800,\n logoUrl,\n showLogo = true,\n baseURL,\n}: HangmanLobbyGameProps = {}) {\n const categories = {\n Professions: [\"teacher\", \"doctor\", \"nurse\", \"driver\", \"police\", \"firefighter\", \"cook\", \"waiter\", \"farmer\", \"builder\", \"singer\", \"actor\", \"dentist\", \"pilot\", \"vet\", \"artist\", \"cleaner\", \"student\", \"baker\", \"mechanic\"],\n Family: [\"mother\", \"father\", \"sister\", \"brother\", \"grandmother\", \"grandfather\", \"aunt\", \"uncle\", \"cousin\", \"baby\", \"parents\", \"children\", \"wife\", \"husband\", \"son\", \"daughter\", \"family\", \"twins\", \"relatives\"],\n \"Farm animals\": [\"cow\", \"pig\", \"horse\", \"sheep\", \"goat\", \"duck\", \"chicken\", \"rooster\", \"turkey\", \"goose\", \"rabbit\", \"mouse\", \"donkey\", \"bee\", \"hen\", \"lamb\", \"bull\", \"pony\"],\n Food: [\"apple\", \"banana\", \"bread\", \"cheese\", \"milk\", \"egg\", \"rice\", \"soup\", \"fish\", \"meat\", \"potato\", \"carrot\", \"tomato\", \"cucumber\", \"butter\", \"cake\", \"salad\", \"pasta\", \"pizza\", \"juice\"],\n Hobbies: [\"reading\", \"drawing\", \"painting\", \"dancing\", \"singing\", \"cooking\", \"swimming\", \"fishing\", \"running\", \"cycling\", \"skating\", \"writing\", \"camping\", \"photography\", \"hiking\", \"games\"],\n Christmas: [\"tree\", \"present\", \"gift\", \"santa\", \"snow\", \"snowman\", \"bell\", \"star\", \"lights\", \"card\", \"cookies\", \"elf\", \"sleigh\", \"reindeer\", \"candle\", \"stocking\"],\n Halloween: [\"pumpkin\", \"costume\", \"candy\", \"ghost\", \"witch\", \"spider\", \"bat\", \"skeleton\", \"mask\", \"monster\", \"mummy\", \"cat\", \"broom\", \"zombie\", \"trick\", \"treat\", \"candle\", \"night\", \"party\"],\n Sport: [\"football\", \"basketball\", \"tennis\", \"swimming\", \"running\", \"baseball\", \"skiing\", \"skating\", \"volleyball\", \"hockey\", \"golf\", \"boxing\", \"cycling\", \"rugby\", \"karate\", \"yoga\", \"surfing\", \"climbing\", \"dancing\", \"gym\", \"chess\"],\n \"Body parts\": [\"head\", \"hair\", \"eyes\", \"ears\", \"nose\", \"mouth\", \"teeth\", \"tongue\", \"neck\", \"shoulder\", \"arm\", \"hand\", \"finger\", \"leg\", \"knee\", \"foot\", \"toe\", \"back\", \"stomach\", \"heart\", \"legs\", \"nails\", \"chin\", \"beard\"],\n \"School subjects\": [\"math\", \"english\", \"history\", \"geography\", \"art\", \"music\", \"science\", \"biology\", \"chemistry\", \"physics\", \"pe\", \"literature\", \"drama\", \"design\", \"economics\"],\n Animals: [\"cat\", \"dog\", \"rabbit\", \"elephant\", \"lion\", \"tiger\", \"monkey\", \"bear\", \"fox\", \"wolf\", \"giraffe\", \"zebra\", \"crocodile\", \"dolphin\", \"whale\", \"shark\", \"frog\", \"parrot\", \"mouse\", \"penguin\", \"deer\", \"lizard\", \"turtle\", \"snake\"],\n Countries: [\"russia\", \"canada\", \"china\", \"japan\", \"france\", \"germany\", \"italy\", \"spain\", \"brazil\", \"india\", \"australia\", \"america\", \"england\", \"korea\", \"mexico\", \"egypt\", \"turkey\", \"vietnam\", \"norway\", \"finland\", \"thailand\", \"georgia\", \"kazakhstan\"],\n Clothes: [\"shirt\", \"dress\", \"skirt\", \"trousers\", \"jeans\", \"coat\", \"jacket\", \"sweater\", \"socks\", \"shoes\", \"boots\", \"hat\", \"scarf\", \"gloves\", \"shorts\", \"cap\", \"belt\", \"tie\", \"uniform\", \"pants\", \"underwear\"],\n Traveling: [\"ticket\", \"luggage\", \"suitcase\", \"airport\", \"flight\", \"passport\", \"visa\", \"map\", \"guide\", \"hotel\", \"reservation\", \"bus\", \"train\", \"taxi\", \"tourist\", \"sightseeing\", \"backpack\", \"journey\", \"adventure\", \"beach\", \"tour\", \"souvenir\"],\n Environment: [\"tree\", \"forest\", \"air\", \"water\", \"pollution\", \"recycle\", \"nature\", \"clean\", \"waste\", \"plastic\", \"energy\", \"animal\", \"climate\", \"earth\", \"ocean\", \"river\", \"planet\", \"save\", \"green\", \"environment\", \"litter\", \"organic\"],\n Space: [\"planet\", \"star\", \"sun\", \"moon\", \"astronaut\", \"rocket\", \"space\", \"galaxy\", \"universe\", \"telescope\", \"comet\", \"asteroid\", \"orbit\", \"gravity\", \"alien\", \"spaceship\", \"mars\", \"satellite\", \"sky\", \"eclipse\"],\n Devices: [\"computer\", \"laptop\", \"phone\", \"tablet\", \"tv\", \"keyboard\", \"mouse\", \"printer\", \"camera\", \"headphones\", \"charger\", \"screen\", \"watch\", \"microphone\", \"speaker\", \"console\", \"router\", \"battery\", \"cable\", \"remote\"],\n };\n\n const [stage, setStage] = useState<\"lobby\" | \"category\" | \"rounds\" | \"game\" | \"result\">(\"lobby\");\n const [category, setCategory] = useState<keyof typeof categories | \"\">(\"\");\n const [difficulty] = useState<\"Easy\" | \"Normal\" | \"Hard\">(\"Normal\"); // Фиксированная сложность\n const [rounds, setRounds] = useState(0); // 0 означает \"не выбрано\"\n const [currentRound, setCurrentRound] = useState(1);\n const [word, setWord] = useState(\"\");\n const [guessed, setGuessed] = useState<string[]>([]);\n const [mistakes, setMistakes] = useState(0);\n const [wins, setWins] = useState(0);\n const [roundResult, setRoundResult] = useState<\"win\" | \"lose\" | null>(null);\n const [containerSize, setContainerSize] = useState<number | null>(null);\n const [scale, setScale] = useState(1);\n const [usedWords, setUsedWords] = useState<string[]>([]); // Отслеживание использованных слов\n\n const maxMistakes = difficulty === \"Easy\" ? 8 : difficulty === \"Normal\" ? 6 : 4;\n\n // Вычисляем baseURL для изображений\n const imagesBaseURL = baseURL || (typeof window !== \"undefined\" && window.origin \n ? `${window.origin}/cloud/speakid/games/hangman`\n : \"/cloud/speakid/games/hangman\");\n\n // Определение мобильного устройства - используем window напрямую (как в magic-sentence)\n const [isMobile, setIsMobile] = useState(false);\n const [isNestHub, setIsNestHub] = useState(false);\n const [isLandscape, setIsLandscape] = useState(false); // ✅ Landscape режим на мобильных\n const [isMediumScreen, setIsMediumScreen] = useState(false); // ✅ Для разрешений 1200-1400 (включая 1366x768)\n\n // Адаптивные размеры относительно gameCubeSize согласно визуальному гайдлайну\n // Desktop базовые размеры: Headline 1 - 32px, Headline 2 - 24px, Body M - 16px, Button - 16px\n // Mobile базовые размеры: Headline 1 - 30px, Headline 3 - 16px, Body M - 14px\n const baseFontSize = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400; // базовый размер 400px\n const landscapeScale = isLandscape ? 0.8 : 1; // ✅ Уменьшаем на 20% в landscape\n const mediumScreenScale = isMediumScreen ? 0.9 : 1; // ✅ Уменьшаем на 10% для medium screens (1200-1400px)\n const combinedScale = landscapeScale * mediumScreenScale;\n return {\n headline1: isMobile \n ? Math.max(24, Math.min(30, 30 * fontSizeScale * combinedScale)) // Mobile: 30px\n : Math.max(28, Math.min(32, 32 * fontSizeScale * mediumScreenScale)), // Desktop: 32px\n headline2: Math.max(20, Math.min(28, 24 * fontSizeScale * combinedScale)), // Desktop: 24px\n headline3: isMobile\n ? Math.max(14, Math.min(18, 16 * fontSizeScale * combinedScale)) // Mobile: 16px\n : Math.max(20, Math.min(26, 24 * fontSizeScale * combinedScale)), // Desktop: 24px\n bodyL: Math.max(14, Math.min(20, 18 * fontSizeScale * combinedScale)), // Desktop: 18px\n bodyM: isMobile\n ? Math.max(12, Math.min(16, 14 * fontSizeScale * combinedScale)) // Mobile: 14px\n : Math.max(14, Math.min(18, 16 * fontSizeScale * combinedScale)), // Desktop: 16px\n bodyS: isMobile\n ? Math.max(10, Math.min(14, 12 * fontSizeScale * combinedScale)) // Mobile: 12px\n : Math.max(12, Math.min(16, 14 * fontSizeScale * combinedScale)), // Desktop: 14px\n wordDisplay: Math.max(18, Math.min(32, 26 * fontSizeScale * combinedScale)), // Адаптивный размер\n button: Math.max(12, Math.min(18, 16 * fontSizeScale * combinedScale)), // Desktop: 16px\n };\n }, [isMobile, containerSize, gameCubeSize, isLandscape, isMediumScreen]);\n\n // Адаптивные отступы и размеры (минималистичный стиль - мягкие углы)\n // Специальные настройки для Nest Hub (1024x600) и landscape режима\n const padding = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400;\n const landscapeScale = isLandscape ? 0.65 : 1; // ✅ Уменьшаем на 35% в landscape\n const mediumScreenScale = isMediumScreen ? 0.85 : 1; // ✅ Уменьшаем на 15% для medium screens (1200-1400px)\n if (isNestHub) {\n return Math.max(8, Math.min(12, 10 * fontSizeScale));\n }\n const basePadding = Math.max(12, Math.min(24, 16 * fontSizeScale));\n return basePadding * landscapeScale * mediumScreenScale;\n }, [isNestHub, containerSize, gameCubeSize, isLandscape, isMediumScreen]);\n const gap = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400;\n const landscapeScale = isLandscape ? 0.65 : 1; // ✅ Уменьшаем на 35% в landscape\n const mediumScreenScale = isMediumScreen ? 0.85 : 1; // ✅ Уменьшаем на 15% для medium screens (1200-1400px)\n if (isNestHub) {\n return Math.max(3, Math.min(6, 5 * fontSizeScale));\n }\n const baseGap = Math.max(4, Math.min(12, 8 * fontSizeScale));\n return baseGap * landscapeScale * mediumScreenScale;\n }, [isNestHub, containerSize, gameCubeSize, isLandscape, isMediumScreen]);\n const borderRadius = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400;\n const mediumScreenScale = isMediumScreen ? 0.9 : 1; // ✅ Уменьшаем на 10% для medium screens (1200-1400px)\n return Math.max(6, Math.min(10, 8 * fontSizeScale * mediumScreenScale));\n }, [containerSize, gameCubeSize, isMediumScreen]); // Мягкие углы для плоского стиля\n\n // Функции вдохновленные открытым кодом Hangman\n const isWordGuessed = (secretWord: string, lettersGuessed: string[]): boolean => {\n // Проверяем, все ли буквы слова угаданы\n return secretWord.split(\"\").every(letter => lettersGuessed.includes(letter));\n };\n\n const getGuessedWord = (secretWord: string, lettersGuessed: string[]): string => {\n // Возвращает строку с угаданными буквами и подчеркиваниями\n return secretWord\n .split(\"\")\n .map(letter => (lettersGuessed.includes(letter) ? letter : \"_\"))\n .join(\" \");\n };\n\n const getAvailableLetters = (lettersGuessed: string[]): string[] => {\n // Возвращает массив доступных букв (не угаданных)\n const alphabet = \"abcdefghijklmnopqrstuvwxyz\".split(\"\");\n return alphabet.filter(letter => !lettersGuessed.includes(letter));\n };\n\n const pickRandomCategory = (): keyof typeof categories => {\n const categoryKeys = Object.keys(categories) as Array<keyof typeof categories>;\n \n // Используем crypto.getRandomValues для более надежной случайности\n let randomIndex: number;\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n randomIndex = array[0] % categoryKeys.length;\n } else {\n // Fallback на Math.random если crypto недоступен\n randomIndex = Math.floor(Math.random() * categoryKeys.length);\n }\n \n return categoryKeys[randomIndex];\n };\n\n const pickRandomWord = (cat: keyof typeof categories, avoidWords: string[] = []): string => {\n if (!cat || !categories[cat]) {\n // Fallback если категория пустая или не существует\n const firstCategory = Object.keys(categories)[0] as keyof typeof categories;\n return categories[firstCategory]?.[0] || \"\";\n }\n \n const words = categories[cat];\n if (!words || words.length === 0) {\n // Fallback если слова пустые\n return \"\";\n }\n \n // Если есть доступные слова (не использованные), выбираем из них\n const availableWords = words.filter(w => !avoidWords.includes(w));\n const wordsToChooseFrom = availableWords.length > 0 ? availableWords : words;\n \n if (wordsToChooseFrom.length === 0) {\n return \"\";\n }\n \n // Используем crypto.getRandomValues для более надежной случайности\n // Преобразуем в дробное число от 0 до 1 для равномерного распределения\n let randomIndex: number;\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n // Преобразуем в дробное число от 0 до 1 для равномерного распределения\n const randomFloat = array[0] / 0xFFFFFFFF;\n randomIndex = Math.floor(randomFloat * wordsToChooseFrom.length);\n } else {\n // Fallback на Math.random если crypto недоступен\n randomIndex = Math.floor(Math.random() * wordsToChooseFrom.length);\n }\n \n return wordsToChooseFrom[randomIndex];\n };\n\n const startGame = () => {\n if (!category) return;\n setUsedWords([]); // Сбрасываем список использованных слов при новой игре\n const randomWord = pickRandomWord(category, []);\n if (!randomWord) {\n // Если не удалось выбрать слово, возвращаемся к выбору категории\n setStage(\"category\");\n return;\n }\n setWord(randomWord);\n setUsedWords([randomWord]); // Запоминаем первое слово\n setGuessed([]);\n setMistakes(0);\n setCurrentRound(1);\n setWins(0);\n setRoundResult(null);\n setStage(\"game\");\n };\n\n // Функция для обработки выбора буквы (используется и для клавиатуры, и для кликов)\n const handleLetterSelect = useCallback((letter: string) => {\n if (stage !== \"game\" || roundResult !== null) return;\n \n const lowerLetter = letter.toLowerCase();\n \n // Проверка: только буквы английского алфавита\n if (!/^[a-z]$/.test(lowerLetter)) return;\n \n // Проверяем, была ли буква уже угадана\n setGuessed((prevGuessed) => {\n if (prevGuessed.includes(lowerLetter)) {\n return prevGuessed;\n }\n \n // Добавляем букву в список угаданных\n return [...prevGuessed, lowerLetter];\n });\n \n // Проверяем, есть ли буква в текущем слове (используем функциональное обновление)\n setWord((currentWord) => {\n if (currentWord && !currentWord.includes(lowerLetter)) {\n setMistakes((m) => m + 1);\n }\n return currentWord;\n });\n }, [stage, roundResult]);\n\n const handleKey = useCallback((e: KeyboardEvent) => {\n handleLetterSelect(e.key);\n }, [handleLetterSelect]);\n\n useEffect(() => {\n if (stage === \"game\") {\n window.addEventListener(\"keydown\", handleKey);\n return () => window.removeEventListener(\"keydown\", handleKey);\n }\n }, [stage, handleKey]);\n\n // Используем функцию из открытого кода\n const masked = word ? getGuessedWord(word, guessed) : \"\";\n const isWin = word ? isWordGuessed(word, guessed) : false;\n // Игра проиграна когда виселица полностью нарисована (10 частей: основание, стойка, перекладина, веревка, голова, тело, левая рука, правая рука, левая нога, правая нога)\n const isLose = mistakes >= 10;\n const availableLetters = getAvailableLetters(guessed);\n\n // Функция для перехода к следующему раунду (вынесена для избежания дублирования)\n const moveToNextRound = useCallback(() => {\n if (!category || currentRound >= rounds) {\n setStage(\"result\");\n return;\n }\n \n setCurrentRound((r) => r + 1);\n setUsedWords((prev) => {\n const newWord = pickRandomWord(category as keyof typeof categories, prev);\n if (newWord) {\n setWord(newWord);\n return [...prev, newWord];\n }\n return prev;\n });\n setGuessed([]);\n setMistakes(0);\n setRoundResult(null);\n }, [category, currentRound, rounds]);\n\n useEffect(() => {\n if (isWin && roundResult === null) {\n setRoundResult(\"win\");\n setWins((w) => w + 1);\n \n const timer = setTimeout(() => {\n moveToNextRound();\n }, 2000);\n \n return () => clearTimeout(timer);\n }\n \n if (isLose && roundResult === null) {\n setRoundResult(\"lose\");\n \n const timer = setTimeout(() => {\n moveToNextRound();\n }, 2000);\n \n return () => clearTimeout(timer);\n }\n }, [isWin, isLose, roundResult, moveToNextRound]);\n\n const nextRound = () => {\n if (!category || currentRound >= rounds) {\n setStage(\"result\");\n return;\n }\n \n setCurrentRound((r) => r + 1);\n setUsedWords((prev) => {\n const newWord = pickRandomWord(category as keyof typeof categories, prev);\n if (newWord) {\n setWord(newWord);\n return [...prev, newWord]; // Добавляем новое слово в список использованных\n }\n return prev;\n });\n setGuessed([]);\n setMistakes(0);\n setRoundResult(null);\n };\n\n // ✅ Адаптив под мобилки, планшеты и десктоп (как в magic-sentence)\n useEffect(() => {\n const resize = () => {\n const width = window.innerWidth;\n const height = window.innerHeight;\n const mobile = width < 768 || (width === 926 && height === 428) || (width === 932 && height === 430);\n const isSmallHeight = height < 700;\n const isWideScreen = width / height > 1.8;\n const nestHub = width === 1024 && height === 600;\n const landscape = mobile && width > height; // ✅ Landscape режим на мобильных\n // ✅ Определение разрешений 1200-1400 (включая 1366x768)\n const mediumScreen = width >= 1200 && width <= 1400;\n \n setIsMobile(mobile);\n setIsNestHub(nestHub);\n setIsLandscape(landscape);\n setIsMediumScreen(mediumScreen);\n\n // ✅ Адаптивные размеры контейнера\n if (mobile) {\n // Мобильные устройства: используем 100% ширины/высоты\n setContainerSize(null);\n setScale(1);\n } else if (isSmallHeight) {\n // Маленькая высота: используем 100% ширины/высоты\n setContainerSize(null);\n setScale(1);\n } else {\n // Десктоп/планшет: рассчитываем оптимальный размер\n const minSize = 400;\n const maxSize = 1200;\n \n // Рассчитываем максимальный размер, который поместится на экране\n // Учитываем отступы (примерно 40px с каждой стороны) и минимальные размеры\n const availableWidth = width - 80; // Отступы по 40px с каждой стороны\n const availableHeight = height - 80;\n const maxAvailableSize = Math.min(availableWidth, availableHeight);\n \n // Если передан gameCubeSize, используем его, но не больше доступного размера\n let targetSize: number;\n if (gameCubeSize && gameCubeSize >= 320) {\n targetSize = Math.min(gameCubeSize, maxAvailableSize);\n } else {\n // Используем 90% от минимального размера экрана\n targetSize = Math.min(1000, maxAvailableSize * 0.9);\n }\n \n // Ограничиваем минимальным и максимальным размером\n const finalSize = Math.max(minSize, Math.min(maxSize, targetSize));\n setContainerSize(finalSize);\n \n // Для широких экранов уменьшаем масштаб\n if (isWideScreen) {\n setScale(0.85);\n } else {\n setScale(1);\n }\n }\n };\n resize();\n window.addEventListener(\"resize\", resize);\n return () => window.removeEventListener(\"resize\", resize);\n }, [gameCubeSize]);\n\n // SVG с детскими каракулями для фона (более резкие и яркие)\n const kidsDoodlesSvg = `\n <svg width=\"100%\" height=\"100%\" xmlns=\"http://www.w3.org/2000/svg\" style=\"position: absolute; top: 0; left: 0; pointer-events: none; opacity: 0.2;\">\n <!-- Каракули мелками и фломастерами -->\n \n <!-- Сердечко -->\n <path d=\"M 85% 15% Q 85% 10%, 90% 10% Q 95% 10%, 95% 15% Q 95% 20%, 90% 25% Q 85% 30%, 85% 15%\" \n fill=\"none\" stroke=\"#FF69B4\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \n <!-- Звезда -->\n <path d=\"M 10% 85% L 12% 80% L 14% 85% L 18% 85% L 13% 88% L 15% 92% L 10% 89% L 5% 92% L 7% 88% L 2% 85% Z\" \n fill=\"#FFA500\" stroke=\"#FF8C00\" stroke-width=\"1.5\"/>\n \n <!-- Волнистые линии (мелки) -->\n <path d=\"M 20% 25% Q 22% 23%, 24% 25% T 28% 25% T 32% 25%\" \n fill=\"none\" stroke=\"#FF6B6B\" stroke-width=\"3.5\" stroke-linecap=\"round\"/>\n <path d=\"M 60% 30% Q 62% 28%, 64% 30% T 68% 30% T 72% 30%\" \n fill=\"none\" stroke=\"#4ECDC4\" stroke-width=\"3.5\" stroke-linecap=\"round\"/>\n \n <!-- Спираль -->\n <path d=\"M 5% 45% Q 8% 42%, 10% 45% Q 12% 48%, 10% 50% Q 8% 52%, 5% 50% Q 3% 48%, 5% 45%\" \n fill=\"none\" stroke=\"#9B59B6\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \n <!-- Зигзаг -->\n <path d=\"M 88% 55% L 92% 50% L 94% 55% L 96% 50% L 98% 55%\" \n fill=\"none\" stroke=\"#E74C3C\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n \n <!-- Ромашка -->\n <circle cx=\"25%\" cy=\"70%\" r=\"15\" fill=\"none\" stroke=\"#FFD700\" stroke-width=\"2.5\"/>\n <circle cx=\"25%\" cy=\"70%\" r=\"8\" fill=\"#FFD700\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"22%\" y2=\"65%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"28%\" y2=\"65%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"22%\" y2=\"75%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"28%\" y2=\"75%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n \n <!-- Каляки-маляки (случайные линии) -->\n <path d=\"M 40% 20% Q 42% 22%, 40% 24% T 40% 28%\" \n fill=\"none\" stroke=\"#32CD32\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n <path d=\"M 50% 60% L 53% 57% L 55% 60% L 57% 57%\" \n fill=\"none\" stroke=\"#FF1493\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \n <!-- Еще волнистые линии -->\n <path d=\"M 35% 85% Q 37% 83%, 39% 85% T 43% 85% T 47% 85%\" \n fill=\"none\" stroke=\"#FF4500\" stroke-width=\"3.5\" stroke-linecap=\"round\"/>\n </svg>\n `;\n\n // Адаптивные стили для контента (без фиксированных размеров)\n // Определение планшета: ширина >= 768px и < 1024px (и не мобильный)\n const isTablet = !isMobile && typeof window !== \"undefined\" && window.innerWidth >= 768 && window.innerWidth < 1024;\n // Условие для отображения логотипа: не мобильный, showLogo включен, И (не экран игры ИЛИ планшет)\n const shouldShowLogo = !isMobile && showLogo && (stage !== \"game\" || isTablet);\n\n const containerStyle: React.CSSProperties = {\n ...styles.gmCenterScreen,\n width: \"100%\",\n height: \"100%\",\n padding: `${padding}px`,\n paddingTop: shouldShowLogo ? `${80}px` : `${padding}px`, // ✅ Резервируем больше места под логотип (24px top + 28px высота + 28px отступ)\n overflow: isMediumScreen ? \"hidden\" : \"auto\", // ✅ Для разрешений 1200-1400 убираем скролл\n position: \"relative\",\n boxSizing: \"border-box\",\n background: \"transparent\",\n };\n\n // Мемоизированный логотип (рендерится вне условных блоков)\n const MemoizedLogo = useMemo(\n () => {\n // Проверяем showLogo ПЕРЕД проверкой размеров экрана\n if (!shouldShowLogo) {\n return null;\n }\n \n // Скрываем логотип только на мобильных устройствах в landscape режиме\n // Убрали проверку height < 700, чтобы уважать проп showLogo на всех разрешениях\n const width = window.innerWidth;\n if (isMobile && width > window.innerHeight) {\n return null;\n }\n \n const logoBaseUrl = logoUrl || (typeof window !== \"undefined\" && window.origin \n ? `${window.origin}/cloud/speakid/games/hangman/logo`\n : \"/cloud/speakid/games/hangman/logo\");\n \n return (\n <div style={styles.gmLogoFixed}>\n <picture>\n <source\n srcSet={`${logoBaseUrl}.svg`}\n type=\"image/svg+xml\"\n />\n <img\n src={`${logoBaseUrl}.png`}\n alt=\"SPEAKID Logo\"\n style={styles.gmLogoImg}\n loading=\"lazy\"\n />\n </picture>\n </div>\n );\n },\n [isMobile, shouldShowLogo, logoUrl, stage]\n );\n\n // Общая структура рендеринга (как в magic-sentence)\n const renderContent = () => {\n // Начальный экран лобби\n if (stage === \"lobby\") {\n return (\n <>\n {MemoizedLogo}\n <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />\n <h1 style={{ \n ...styles.gmHeadline1, \n fontSize: `${baseFontSize.headline1}px`, \n marginBottom: `${gap * 3}px`,\n position: \"relative\",\n zIndex: 1,\n }}>\n HANGMAN\n </h1>\n <button\n onClick={() => setStage(\"category\")}\n style={{\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 500, // Medium для более заметности\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap * 1.2}px ${gap * 3}px`,\n borderRadius: `${borderRadius * 1.5}px`,\n position: \"relative\",\n zIndex: 1,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"#ec4c44\",\n color: \"#ffffff\",\n border: \"none\",\n cursor: \"pointer\",\n transition: \"background 0.2s ease, transform 0.1s ease\",\n boxShadow: \"0 2px 8px rgba(236, 76, 68, 0.2)\",\n minWidth: \"120px\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = \"#d43a32\";\n e.currentTarget.style.transform = \"translateY(-2px)\";\n e.currentTarget.style.boxShadow = \"0 4px 12px rgba(236, 76, 68, 0.3)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = \"#ec4c44\";\n e.currentTarget.style.transform = \"translateY(0)\";\n e.currentTarget.style.boxShadow = \"0 2px 8px rgba(236, 76, 68, 0.2)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.transform = \"translateY(0)\";\n }}\n >\n <svg\n width={`${baseFontSize.button * 1.3}px`}\n height={`${baseFontSize.button * 1.3}px`}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{ display: \"block\", marginRight: `${gap}px` }}\n >\n <path\n d=\"M8 5V19L19 12L8 5Z\"\n fill=\"#ffffff\"\n stroke=\"none\"\n />\n </svg>\n <span style={{ fontWeight: 500 }}>PLAY</span>\n </button>\n <div style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n zIndex: 0,\n }}>\n <img\n src={`${imagesBaseURL}/sun.png`}\n alt=\"Sun\"\n style={{\n position: \"absolute\",\n left: isMobile ? \"-10%\" : \"5%\",\n top: \"20%\",\n width: \"auto\",\n height: isMobile \n ? `${Math.min(window.innerHeight * 0.33, 200)}px`\n : `${Math.min((containerSize || gameCubeSize || 1000) * 0.33, 300)}px`,\n maxHeight: \"33vh\",\n objectFit: \"contain\",\n opacity: 0.6,\n }}\n />\n <img\n src={`${imagesBaseURL}/character.png`}\n alt=\"Hangman character\"\n style={{\n position: \"absolute\",\n right: isMobile ? \"5%\" : \"10%\",\n bottom: \"10%\",\n width: \"auto\",\n height: isMobile \n ? `${Math.min(window.innerHeight * 0.33, 200)}px`\n : `${Math.min((containerSize || gameCubeSize || 1000) * 0.33, 300)}px`,\n maxHeight: \"33vh\",\n objectFit: \"contain\",\n opacity: 0.6,\n }}\n />\n </div>\n </>\n );\n }\n\n // Экран выбора категории\n if (stage === \"category\") {\n return (\n <>\n {MemoizedLogo}\n <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />\n <button\n onClick={() => setStage(\"lobby\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n }}\n style={{\n ...styles.gmButton,\n ...styles.gmButtonSecondary,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n position: \"absolute\",\n top: \"60px\", // ✅ Под логотипом (24px top логотипа + 28px высота + 8px отступ)\n left: \"24px\", // ✅ Та же позиция что и логотип\n zIndex: 10,\n }}\n >\n ←\n </button>\n\n <div style={{ ...styles.gmButtonGroup, gap: `${gap}px`, marginBottom: `${gap * 3}px`, marginTop: `${gap * 4}px`, position: \"relative\", zIndex: 1 }}>\n {Object.keys(categories).map((cat) => {\n // Облачки с border вместо заливки\n return (\n <button\n key={cat}\n onClick={() => {\n setCategory(cat as keyof typeof categories);\n setStage(\"rounds\");\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\";\n e.currentTarget.style.borderColor = \"#1f2937\";\n e.currentTarget.style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n e.currentTarget.style.borderColor = \"#e5e7eb\";\n e.currentTarget.style.transform = \"scale(1)\";\n }}\n style={{\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 500,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap * 1.2}px ${gap * 2}px`,\n borderRadius: `${borderRadius * 2}px`, // Более округлые для облачков\n margin: `${gap / 2}px`,\n background: \"transparent\",\n border: \"2px solid #e5e7eb\",\n color: \"#1f2937\",\n cursor: \"pointer\",\n transition: \"background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease\",\n boxShadow: \"none\",\n }}\n >\n {cat}\n </button>\n );\n })}\n </div>\n </>\n );\n }\n\n // Экран выбора количества раундов\n if (stage === \"rounds\") {\n return (\n <>\n {MemoizedLogo}\n <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />\n <button\n onClick={() => setStage(\"category\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n }}\n style={{\n ...styles.gmButton,\n ...styles.gmButtonSecondary,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n position: \"absolute\",\n top: \"60px\", // ✅ Под логотипом (24px top логотипа + 28px высота + 8px отступ)\n left: \"24px\", // ✅ Та же позиция что и логотип\n zIndex: 10,\n }}\n >\n ←\n </button>\n\n <h1 style={{ ...styles.gmHeadline1, fontSize: `${baseFontSize.headline1}px`, marginBottom: `${gap * 2}px`, position: \"relative\", zIndex: 1 }}>\n Choose rounds\n </h1>\n\n <div style={{ ...styles.gmButtonGroup, gap: `${gap}px`, marginBottom: `${gap * 3}px`, position: \"relative\", zIndex: 1 }}>\n {[1, 3, 5].map((r) => {\n // Облачки с border вместо заливки\n return (\n <button\n key={r}\n onClick={() => {\n setRounds(r);\n startGame();\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\";\n e.currentTarget.style.borderColor = \"#1f2937\";\n e.currentTarget.style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n e.currentTarget.style.borderColor = \"#e5e7eb\";\n e.currentTarget.style.transform = \"scale(1)\";\n }}\n style={{\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 500,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap * 1.2}px ${gap * 2}px`,\n borderRadius: `${borderRadius * 2}px`, // Более округлые для облачков\n margin: `${gap / 2}px`,\n background: \"transparent\",\n border: \"2px solid #e5e7eb\",\n color: \"#1f2937\",\n cursor: \"pointer\",\n transition: \"background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease\",\n boxShadow: \"none\",\n }}\n >\n {r}\n </button>\n );\n })}\n </div>\n </>\n );\n }\n\n // Игровой экран\n if (stage === \"game\") {\n return (\n <>\n {MemoizedLogo}\n {!isLandscape && <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />} {/* ✅ Скрываем декоративные элементы в landscape */}\n <div style={{\n ...styles.gmInfoBox,\n padding: `${isLandscape ? gap * 0.6 : gap * 0.8}px`, // ✅ Уменьшаем padding в landscape\n marginBottom: `${isLandscape ? gap * 0.3 : gap * 0.5}px`, // ✅ Уменьшаем margin в landscape\n maxWidth: `${(containerSize || gameCubeSize) * 0.9}px`,\n textAlign: \"center\", // ✅ Центрируем текст по плашке\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}>\n <h3 style={{ ...styles.gmHeadline3, fontSize: `${baseFontSize.headline3}px`, marginBottom: `${gap * 0.2}px`, textAlign: \"center\" }}>\n Category: {category}\n </h3>\n <p style={{ ...styles.gmBodyM, fontSize: `${baseFontSize.bodyM}px`, marginBottom: `0px`, textAlign: \"center\" }}>\n Round {currentRound} of {rounds}\n </p>\n </div>\n\n {word && (\n <p style={{\n ...styles.gmBodyS,\n fontSize: `${baseFontSize.bodyS}px`,\n marginTop: `${isLandscape ? gap * 0.3 : gap * 0.5}px`, // ✅ Уменьшаем margin в landscape\n marginBottom: `${isLandscape ? gap * 0.5 : gap}px`, // ✅ Уменьшаем margin в landscape\n }}>\n I am thinking of a word that is <strong>{word.length}</strong> letters long\n </p>\n )}\n\n {/* Визуализация виселицы */}\n <div style={{\n margin: `${isLandscape ? gap * 0.5 : gap}px 0`, // ✅ Уменьшаем margin в landscape\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}>\n <HangmanDrawing \n mistakes={mistakes} \n maxMistakes={maxMistakes}\n size={isNestHub \n ? Math.max(80, Math.min(110, (containerSize || gameCubeSize) * 0.16))\n : isMobile\n ? isLandscape\n ? Math.max(70, Math.min(120, Math.min(window.innerWidth * 0.25, window.innerHeight * 0.15))) // ✅ Уменьшаем на 25% в landscape\n : Math.max(100, Math.min(150, Math.min(window.innerWidth * 0.3, window.innerHeight * 0.2))) // ✅ Улучшенный расчет для мобильных\n : Math.max(100, Math.min(150, (containerSize || gameCubeSize) * 0.2))}\n />\n </div>\n\n <div style={{\n ...styles.gmWordDisplay,\n fontSize: `${Math.max(16, Math.min(24, baseFontSize.wordDisplay * 0.9))}px`,\n margin: `${isLandscape ? gap * 0.5 : gap}px 0`, // ✅ Уменьшаем margin в landscape\n letterSpacing: `${gap * 0.8}px`,\n minHeight: `${Math.max(16, Math.min(24, baseFontSize.wordDisplay * 0.9)) * 1.2}px`,\n }}>{masked || \"Loading...\"}</div>\n\n {/* Алфавит - вдохновлено getAvailableLetters */}\n <div style={{\n ...styles.gmInfoBox,\n padding: `${isLandscape ? gap * 0.6 : gap}px`, // ✅ Уменьшаем padding в landscape\n marginTop: `${isLandscape ? gap * 0.5 : gap}px`, // ✅ Уменьшаем margin в landscape\n marginBottom: `${isLandscape ? gap * 0.5 : gap}px`, // ✅ Уменьшаем margin в landscape\n maxWidth: `${(containerSize || gameCubeSize) * 0.95}px`,\n }}>\n <div style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: `${gap / 3}px`,\n justifyContent: \"center\",\n alignItems: \"center\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n }}>\n {availableLetters.map((letter) => (\n <button\n key={letter}\n onClick={() => handleLetterSelect(letter)}\n disabled={roundResult !== null}\n onMouseEnter={(e) => {\n if (roundResult === null) {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n e.currentTarget.style.cursor = \"pointer\";\n }\n }}\n onMouseLeave={(e) => {\n if (roundResult === null) {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n e.currentTarget.style.cursor = \"pointer\";\n }\n }}\n style={{\n flex: \"1 1 auto\",\n padding: `${gap * 0.5}px ${gap * 0.4}px`,\n borderRadius: `${borderRadius * 0.5}px`,\n background: \"#f9f9f9\",\n color: \"#1f2937\",\n border: \"1px solid #e5e7eb\",\n minWidth: `${Math.max((containerSize || gameCubeSize) * 0.06, gap * 2)}px`,\n maxWidth: `${Math.max((containerSize || gameCubeSize) * 0.12, gap * 3)}px`,\n textAlign: \"center\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: roundResult === null ? \"pointer\" : \"default\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontSize: `${Math.max(14, Math.min(20, baseFontSize.bodyS * 1.2))}px`,\n fontWeight: 500,\n transition: \"background-color 0.2s ease\",\n }}\n >\n {letter.toUpperCase()}\n </button>\n ))}\n </div>\n </div>\n\n {/* Уже угаданные буквы */}\n {guessed.length > 0 && (\n <div style={{\n ...styles.gmGuessedLetters,\n fontSize: `${Math.max(10, Math.min(12, baseFontSize.bodyS * 0.85))}px`,\n marginTop: `${gap * 0.5}px`,\n marginBottom: `2px`,\n }}>\n <span style={{ color: \"#6b7280\" }}>\n Guessed letters: <strong>{guessed.join(\", \")}</strong>\n </span>\n </div>\n )}\n\n {roundResult === \"win\" && (\n <div style={{\n ...styles.gmStatusWin,\n fontSize: `${baseFontSize.bodyL}px`,\n margin: `2px 0`,\n }}>\n 🎉 You won this round!\n </div>\n )}\n\n {roundResult === \"lose\" && (\n <div style={{\n ...styles.gmStatusLose,\n fontSize: `${baseFontSize.bodyL}px`,\n margin: `2px 0`,\n }}>\n The hangman is complete! The word was: <strong>{word}</strong>\n </div>\n )}\n\n {roundResult !== null && currentRound < rounds && (\n <div style={{ marginTop: `2px`, marginBottom: `${gap}px` }}>\n <button\n onClick={nextRound}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#d43a32\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#ec4c44\";\n }}\n style={{\n ...styles.gmButton,\n fontSize: `${Math.max(11, Math.min(14, baseFontSize.button * 0.85))}px`,\n padding: `${gap * 0.6}px ${gap * 1.2}px`,\n borderRadius: `${borderRadius}px`,\n }}\n >\n NEXT\n </button>\n </div>\n )}\n\n {roundResult !== null && currentRound >= rounds && (\n <div style={{ marginTop: `2px`, marginBottom: `${gap}px` }}>\n <button\n onClick={() => setStage(\"result\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#d43a32\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#ec4c44\";\n }}\n style={{\n ...styles.gmButton,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n }}\n >\n View results\n </button>\n </div>\n )}\n\n {roundResult === null && guessed.length === 0 && (\n <p style={{\n ...styles.gmBodyS,\n fontSize: `${baseFontSize.bodyS}px`,\n marginTop: `${gap}px`,\n marginBottom: `${gap}px`,\n }}>\n Type a letter on your keyboard\n </p>\n )}\n </>\n );\n }\n\n // Экран результатов\n if (stage === \"result\") {\n return (\n <>\n {MemoizedLogo}\n <h1 style={{\n ...styles.gmHeadline1,\n fontSize: `${baseFontSize.headline1}px`,\n marginBottom: `${gap * 2}px`,\n }}>\n 🎊 Game Finished!\n </h1>\n <p style={{\n ...styles.gmBodyL,\n fontSize: `${baseFontSize.bodyL}px`,\n marginBottom: `${gap * 2}px`,\n }}>\n You guessed <strong>{wins}</strong> out of <strong>{rounds}</strong> words correctly.\n </p>\n \n <div style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: `${gap}px`,\n alignItems: \"center\",\n }}>\n <button\n onClick={() => {\n // Сбрасываем состояние и запускаем новую игру с той же категорией и раундами\n if (!category || rounds === 0) {\n setStage(\"lobby\");\n return;\n }\n \n setUsedWords([]);\n const randomWord = pickRandomWord(category as keyof typeof categories, []);\n if (randomWord) {\n setWord(randomWord);\n setUsedWords([randomWord]);\n setGuessed([]);\n setMistakes(0);\n setCurrentRound(1);\n setWins(0);\n setRoundResult(null);\n setStage(\"game\");\n }\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#d43a32\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#ec4c44\";\n }}\n style={{\n ...styles.gmButton,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n minWidth: \"200px\",\n }}\n >\n Play again\n </button>\n \n <button\n onClick={() => setStage(\"lobby\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n }}\n style={{\n ...styles.gmButton,\n ...styles.gmButtonSecondary,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n minWidth: \"200px\",\n }}\n >\n Exit\n </button>\n </div>\n </>\n );\n }\n\n return null;\n };\n\n // Единый return с трехуровневой структурой (как в magic-sentence)\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n background: \"transparent\",\n overflow: \"hidden\",\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0\n }}\n >\n <div\n style={{\n width: isMobile ? \"100%\" : (containerSize || gameCubeSize || 1000),\n height: isMobile ? \"100%\" : (containerSize || gameCubeSize || 1000),\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n overflow: \"hidden\",\n borderRadius: isMobile ? 0 : \"20px\",\n background: \"#ffffff\",\n boxShadow: isMobile ? \"none\" : \"0 0 40px rgba(0,0,0,0.1)\",\n margin: isMobile ? \"0 auto\" : \"unset\",\n position: \"relative\", // needed so absolute logo is inside the square\n transform: `scale(${scale})`,\n }}\n >\n <div\n style={{\n transform: \"translateZ(0)\",\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}\n >\n <div style={containerStyle}>\n {renderContent()}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\n"],"names":["styles","HangmanDrawing","mistakes","maxMistakes","size","svgWidth","svgHeight","strokeWidth","baseX1","baseY","baseX2","poleX","poleY1","poleY2","topX1","topY","topX2","ropeX","ropeY1","ropeY2","headCX","headCY","headR","bodyX","bodyY1","bodyY2","leftArmX1","leftArmY1","leftArmX2","leftArmY2","rightArmX1","rightArmY1","rightArmX2","rightArmY2","leftLegX1","leftLegY1","leftLegX2","leftLegY2","rightLegX1","rightLegY1","rightLegX2","rightLegY2","strokeColor","jsxs","jsx","HangmanLobbyGame","gameCubeSize","screenHeight","screenWidth","logoUrl","showLogo","baseURL","categories","stage","setStage","useState","category","setCategory","difficulty","rounds","setRounds","currentRound","setCurrentRound","word","setWord","guessed","setGuessed","setMistakes","wins","setWins","roundResult","setRoundResult","containerSize","setContainerSize","scale","setScale","usedWords","setUsedWords","imagesBaseURL","isMobile","setIsMobile","isNestHub","setIsNestHub","isLandscape","setIsLandscape","isMediumScreen","setIsMediumScreen","baseFontSize","useMemo","fontSizeScale","landscapeScale","mediumScreenScale","combinedScale","padding","gap","borderRadius","isWordGuessed","secretWord","lettersGuessed","letter","getGuessedWord","getAvailableLetters","pickRandomWord","cat","avoidWords","firstCategory","_a","words","availableWords","w","wordsToChooseFrom","randomIndex","array","randomFloat","startGame","randomWord","handleLetterSelect","useCallback","lowerLetter","prevGuessed","currentWord","m","handleKey","useEffect","masked","isWin","isLose","availableLetters","moveToNextRound","r","prev","newWord","timer","nextRound","resize","width","height","mobile","isSmallHeight","isWideScreen","nestHub","landscape","mediumScreen","availableWidth","availableHeight","maxAvailableSize","targetSize","finalSize","kidsDoodlesSvg","isTablet","shouldShowLogo","containerStyle","MemoizedLogo","logoBaseUrl","renderContent","Fragment","e"],"mappings":"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"}