{"id":10,"date":"2026-05-16T23:10:08","date_gmt":"2026-05-16T23:10:08","guid":{"rendered":"https:\/\/czytanie.julsoft.pl\/?page_id=10"},"modified":"2026-05-16T23:21:48","modified_gmt":"2026-05-16T23:21:48","slug":"glowna","status":"publish","type":"page","link":"https:\/\/czytanie.julsoft.pl\/","title":{"rendered":"G\u0142\u00f3wna"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"10\" class=\"elementor elementor-10\">\n\t\t\t\t<div class=\"elementor-element elementor-element-628acca e-flex e-con-boxed e-con e-parent\" data-id=\"628acca\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7f95a2f elementor-widget elementor-widget-shortcode\" data-id=\"7f95a2f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">    <!-- Zale\u017cno\u015bci -->\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    <script src=\"https:\/\/unpkg.com\/react@18\/umd\/react.production.min.js\"><\/script>\n    <script src=\"https:\/\/unpkg.com\/react-dom@18\/umd\/react-dom.production.min.js\"><\/script>\n    <script src=\"https:\/\/unpkg.com\/@babel\/standalone\/babel.min.js\"><\/script>\n    <script src=\"https:\/\/unpkg.com\/lucide@latest\"><\/script>\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Nunito:wght@400;700;900&family=Baloo+2:wght@600;800&display=swap\" rel=\"stylesheet\">\n\n    <style>\n        .ncp-app { font-family: 'Nunito', sans-serif; touch-action: manipulation; user-select: none; }\n        .ncp-title { font-family: 'Baloo 2', cursive; }\n        .no-scrollbar::-webkit-scrollbar { display: none; }\n        .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }\n        \n        \/* Animacje *\/\n        @keyframes pop { 0% {transform: scale(0.8); opacity:0;} 100% {transform: scale(1); opacity:1;} }\n        .animate-pop { animation: pop 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards; }\n        @keyframes bounce-sm { 0%,100%{transform:translateY(0);} 50%{transform:translateY(-5px);} }\n        .animate-bounce-sm { animation: bounce-sm 2s infinite; }\n        \n        \/* Motywy T\u0142a *\/\n        .theme-kosmos { background: linear-gradient(to bottom, #0f2027, #203a43, #2c5364); color: white; }\n        .theme-dzungla { background: linear-gradient(to bottom, #11998e, #38ef7d); color: #064e3b; }\n        .theme-ocean { background: linear-gradient(to bottom, #2193b0, #6dd5ed); color: #0c4a6e; }\n        .theme-magia { background: linear-gradient(to bottom, #8A2387, #E94057, #F27121); color: white; }\n        .theme-bohaterowie { background: linear-gradient(to right, #ed213a, #93291e); color: white; }\n        .theme-zwierzaki { background: linear-gradient(to bottom, #f7b733, #fc4a1a); color: white; }\n        .theme-default { background: #f0f9ff; color: #1e293b; }\n\n        \/* Ukrywanie element\u00f3w gdy aplikacja zainstalowana (PWA) *\/\n        @media all and (display-mode: standalone) {\n            .pwa-hide { display: none !important; }\n        }\n    <\/style>\n\n    <div id=\"ncp-root\" class=\"w-full max-w-md mx-auto min-h-[100dvh] bg-white relative overflow-hidden shadow-2xl ncp-app flex flex-col\">\n        <div class=\"flex items-center justify-center h-full text-blue-500 font-bold animate-pulse\">\u0141adowanie przygody...<\/div>\n    <\/div>\n\n    <!-- Instalacja PWA -->\n    <div id=\"ncp-install-banner\" class=\"hidden pwa-hide fixed bottom-4 left-1\/2 -translate-x-1\/2 bg-white text-gray-800 p-4 rounded-2xl shadow-2xl z-50 w-11\/12 max-w-sm border-4 border-blue-500 flex items-center justify-between\">\n        <div class=\"flex items-center\">\n            <span class=\"text-4xl mr-3\">\ud83d\udcf1<\/span>\n            <div>\n                <p class=\"font-bold text-sm leading-tight\">Zainstaluj na telefonie!<\/p>\n                <p class=\"text-xs text-gray-500\">Dzia\u0142a szybciej i bez paska<\/p>\n            <\/div>\n        <\/div>\n        <button onclick=\"ncpInstallPWA()\" class=\"bg-blue-500 hover:bg-blue-600 text-white px-5 py-2 rounded-xl font-bold transition-colors\">Instaluj<\/button>\n    <\/div>\n\n    <script type=\"text\/babel\">\n        const { useState, useEffect, useRef } = React;\n        const API_URL = 'https:\/\/czytanie.julsoft.pl\/index.php?rest_route=\/ncp\/v1';\n\n        \/\/ --- DANE EDUKACYJNE ---\n        const LETTERS = \"A\u0104BC\u0106DE\u0118FGHIJKL\u0141MN\u0143O\u00d3PRS\u015aTUWYZ\u0179\u017b\".split(\"\");\n        \n        const ALPHABET_WORDS = [\n            { w: 'AUTO', img: '\ud83d\ude97' }, { w: 'ARBUZ', img: '\ud83c\udf49' },\n            { w: 'BALON', img: '\ud83c\udf88' }, { w: 'BUT', img: '\ud83d\udc5e' },\n            { w: 'CYTRYNA', img: '\ud83c\udf4b' }, { w: 'CIASTKO', img: '\ud83c\udf6a' },\n            { w: 'DOM', img: '\ud83c\udfe0' }, { w: 'DRZEWO', img: '\ud83c\udf33' },\n            { w: 'EKRAN', img: '\ud83d\udda5\ufe0f' }, { w: 'ELF', img: '\ud83e\udddd' },\n            { w: 'FARBY', img: '\ud83c\udfa8' }, { w: 'FOKA', img: '\ud83e\uddad' },\n            { w: 'G\u00d3RA', img: '\u26f0\ufe0f' }, { w: 'GRZYB', img: '\ud83c\udf44' },\n            { w: 'HELIKOPTER', img: '\ud83d\ude81' }, { w: 'HULAJNOGA', img: '\ud83d\udef4' },\n            { w: 'IG\u0141A', img: '\ud83e\udea1' }, { w: 'INDYK', img: '\ud83e\udd83' },\n            { w: 'JAB\u0141KO', img: '\ud83c\udf4e' }, { w: 'JAJKO', img: '\ud83e\udd5a' },\n            { w: 'KOT', img: '\ud83d\udc31' }, { w: 'KROWA', img: '\ud83d\udc04' },\n            { w: 'LODY', img: '\ud83c\udf66' }, { w: 'LI\u015a\u0106', img: '\ud83c\udf43' },\n            { w: 'MAMA', img: '\ud83d\udc69' }, { w: 'MOTYL', img: '\ud83e\udd8b' },\n            { w: 'NOS', img: '\ud83d\udc43' }, { w: 'NOGA', img: '\ud83e\uddb5' },\n            { w: 'OKO', img: '\ud83d\udc41\ufe0f' }, { w: 'OKNO', img: '\ud83e\ude9f' },\n            { w: 'PIES', img: '\ud83d\udc36' }, { w: 'PTAK', img: '\ud83d\udc26' },\n            { w: 'ROBOT', img: '\ud83e\udd16' }, { w: 'RYBA', img: '\ud83d\udc1f' },\n            { w: 'S\u0141O\u0143CE', img: '\u2600\ufe0f' }, { w: 'SOWA', img: '\ud83e\udd89' },\n            { w: 'TATA', img: '\ud83d\udc68' }, { w: 'TORT', img: '\ud83c\udf82' },\n            { w: 'UCHO', img: '\ud83d\udc42' }, { w: 'UL', img: '\ud83d\udc1d' },\n            { w: 'WODA', img: '\ud83d\udca7' }, { w: 'W\u0104\u017b', img: '\ud83d\udc0d' },\n            { w: 'ZAMEK', img: '\ud83c\udff0' }, { w: 'ZEGAR', img: '\u23f0' },\n            { w: '\u017bABA', img: '\ud83d\udc38' }, { w: '\u017bYRAFA', img: '\ud83e\udd92' },\n            \n            \/\/ Nowe s\u0142owa na polskie litery dopasowane do TTS lektora!\n            { w: 'B\u0104K', img: '\ud83d\udc1d' }, { w: 'M\u0104KA', img: '\ud83c\udf3e' },\n            { w: '\u0106MA', img: '\ud83e\udd8b' }, { w: 'G\u0118\u015a', img: '\ud83e\udeb6' },\n            { w: 'R\u0118KA', img: '\u270b' }, { w: '\u0141\u00d3D\u0179', img: '\u26f5' },\n            { w: '\u0141OPATA', img: '\ud83e\uddf9' }, { w: 'KO\u0143', img: '\ud83d\udc0e' },\n            { w: 'S\u0141O\u0143', img: '\ud83d\udc18' }, { w: '\u00d3SEMKA', img: '8\ufe0f\u20e3' },\n            { w: '\u015aLIMAK', img: '\ud83d\udc0c' }, { w: '\u015aWIECA', img: '\ud83d\udd6f\ufe0f' },\n            { w: '\u0179REBAK', img: '\ud83d\udc34' }, { w: '\u0179R\u00d3D\u0141O', img: '\u26f2' }\n        ];\n\n        const WORDS_SYL = [\n            { w: 'KOT', img: '\ud83d\udc31', syl: ['KO', 'T'] }, { w: 'PIES', img: '\ud83d\udc36', syl: ['PIES'] },\n            { w: 'DOM', img: '\ud83c\udfe0', syl: ['DOM'] }, { w: 'AUTO', img: '\ud83d\ude97', syl: ['AU', 'TO'] },\n            { w: 'MAMA', img: '\ud83d\udc69', syl: ['MA', 'MA'] }, { w: 'TATA', img: '\ud83d\udc68', syl: ['TA', 'TA'] },\n            { w: 'RYBA', img: '\ud83d\udc1f', syl: ['RY', 'BA'] }, { w: 'S\u0141O\u0143', img: '\ud83d\udc18', syl: ['S\u0141O\u0143'] }\n        ];\n\n        const THEMES = [\n            { id: 'kosmos', icon: '\ud83d\ude80', name: 'Kosmos' }, { id: 'dzungla', icon: '\ud83c\udf34', name: 'D\u017cungla' },\n            { id: 'ocean', icon: '\ud83c\udf0a', name: 'Ocean' }, { id: 'magia', icon: '\u2728', name: 'Magia' },\n            { id: 'bohaterowie', icon: '\ud83e\uddb8\u200d\u2642\ufe0f', name: 'Bohaterowie' }, { id: 'zwierzaki', icon: '\ud83d\udc3e', name: 'Zwierzaki' }\n        ];\n\n        const COLORS = [\n            { id: 'czerwony', hex: '#ef4444' }, { id: 'pomaranczowy', hex: '#f97316' },\n            { id: 'zolty', hex: '#eab308' }, { id: 'zielony', hex: '#22c55e' },\n            { id: 'niebieski', hex: '#3b82f6' }, { id: 'fioletowy', hex: '#a855f7' },\n            { id: 'rozowy', hex: '#ec4899' }, { id: 'brazowy', hex: '#8b5cf6' },\n            { id: 'czarny', hex: '#334155' }, { id: 'szary', hex: '#94a3b8' }\n        ];\n\n        const BADGES = [\n            { id: 'first_login', icon: '\ud83c\udf1f', name: 'Pierwszy krok', req: 'Za\u0142o\u017cenie konta' },\n            { id: 'letters_10', icon: '\ud83c\udd70\ufe0f', name: 'Znam litery', req: 'Przerobione litery' },\n            { id: 'quiz_master', icon: '\ud83c\udfc6', name: 'Mistrz Quiz\u00f3w', req: 'Rozwi\u0105zane quizy' },\n            { id: 'stars_50', icon: '\ud83d\udc51', name: 'Kr\u00f3l Gwiazdek', req: '50 Gwiazdek' }\n        ];\n\n        \/\/ --- HOOK TTS ---\n        const useTTS = () => {\n            const speak = (text, rate = 0.85) => {\n                window.speechSynthesis.cancel();\n                const u = new SpeechSynthesisUtterance(text);\n                u.lang = 'pl-PL';\n                u.rate = rate;\n                window.speechSynthesis.speak(u);\n            };\n            return speak;\n        };\n\n        \/\/ --- G\u0141\u00d3WNA APLIKACJA ---\n        const App = () => {\n            const [screen, setScreen] = useState('loading'); \/\/ loading, select_user, register, dashboard, lesson_letters, lesson_words, quiz\n            const [users, setUsers] = useState([]);\n            const [currentUser, setCurrentUser] = useState(null);\n            const [badgePopup, setBadgePopup] = useState(null);\n            \n            const speak = useTTS();\n\n            \/\/ \u0141adowanie dzieci\n            useEffect(() => {\n                fetch(`${API_URL}\/children`)\n                    .then(r => r.json())\n                    .then(data => {\n                        setUsers(data);\n                        \/\/ Auto-login z pami\u0119ci\n                        const savedId = localStorage.getItem('ncp_last_user');\n                        if (savedId) {\n                            const u = data.find(x => x.id == savedId);\n                            if(u) return loginUser(u);\n                        }\n                        setScreen('select_user');\n                        setTimeout(() => speak('Witaj! Wybierz sw\u00f3j profil, lub stw\u00f3rz nowy.'), 500);\n                    });\n            }, []);\n\n            \/\/ \u015aledzenie czasu (ping co 60 sekund)\n            useEffect(() => {\n                if(!currentUser) return;\n                const interval = setInterval(() => {\n                    fetch(`${API_URL}\/time`, {\n                        method: 'POST',\n                        headers: {'Content-Type': 'application\/json'},\n                        body: JSON.stringify({ child_id: currentUser.id, seconds: 60 })\n                    });\n                }, 60000);\n                return () => clearInterval(interval);\n            }, [currentUser]);\n\n            const loginUser = (user) => {\n                localStorage.setItem('ncp_last_user', user.id);\n                setCurrentUser(user);\n                setScreen('dashboard');\n                speak(`Cze\u015b\u0107 ${user.name}! Wybierz, co dzisiaj robimy.`);\n            };\n\n            const logout = () => {\n                localStorage.removeItem('ncp_last_user');\n                setCurrentUser(null);\n                setScreen('select_user');\n            };\n\n            const awardProgress = async (type, key, stars = 1) => {\n                const res = await fetch(`${API_URL}\/progress`, {\n                    method: 'POST',\n                    headers: {'Content-Type': 'application\/json'},\n                    body: JSON.stringify({ child_id: currentUser.id, item_type: type, item_key: key, add_stars: stars })\n                });\n                const data = await res.json();\n                setCurrentUser(prev => ({...prev, stars: data.stars}));\n                \n                \/\/ Sprawdzanie odznak\n                const earned = data.badges || [];\n                const checkBadge = async (badgeId) => {\n                    if(!earned.includes(badgeId)) {\n                        setBadgePopup(BADGES.find(b => b.id === badgeId));\n                        speak('Hura! Zdoby\u0142e\u015b now\u0105 odznak\u0119!');\n                        await fetch(`${API_URL}\/progress`, {\n                            method: 'POST', headers: {'Content-Type': 'application\/json'},\n                            body: JSON.stringify({ child_id: currentUser.id, item_type: 'badge', item_key: badgeId })\n                        });\n                    }\n                };\n\n                if (data.stars >= 50) checkBadge('stars_50');\n                if (type === 'badge' && key === 'quiz_master') checkBadge('quiz_master');\n            };\n\n            if (screen === 'loading') return <div className=\"flex-1 flex justify-center items-center\"><div className=\"w-16 h-16 border-8 border-blue-200 border-t-blue-500 rounded-full animate-spin\"><\/div><\/div>;\n            if (screen === 'select_user') return <UserSelect users={users} onSelect={loginUser} onNew={() => setScreen('register')} speak={speak} \/>;\n            if (screen === 'register') return <Register onRegistered={(u) => { setUsers([u, ...users]); loginUser(u); }} onCancel={() => setScreen('select_user')} speak={speak} \/>;\n            \n            \/\/ Kolory i motyw\n            const uiColor = COLORS.find(c => c.id === currentUser?.color)?.hex || '#3b82f6';\n            const themeClass = `theme-${currentUser?.theme || 'default'}`;\n\n            return (\n                <div className={`flex-1 flex flex-col ${themeClass} transition-colors duration-500`}>\n                    \n                    {\/* Header *\/}\n                    <div className=\"p-4 flex justify-between items-center bg-black\/10 backdrop-blur-sm z-10 shadow-sm\">\n                        <button onClick={logout} className=\"p-2 bg-white\/20 rounded-full hover:bg-white\/30\" onClick={() => {speak('Wylogowano'); logout();}}>\n                            <i data-lucide=\"log-out\" className=\"w-6 h-6\"><\/i>\n                        <\/button>\n                        <div className=\"flex items-center gap-3\">\n                            <div className=\"font-bold text-xl drop-shadow-md text-white\">\u2b50 {currentUser.stars}<\/div>\n                            <div className=\"w-10 h-10 rounded-full bg-white\/80 flex items-center justify-center text-2xl shadow-lg border-2 border-white\/50\">\n                                {currentUser.gender === 'dziewczynka' ? '\ud83d\udc67' : '\ud83d\udc66'}\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    {\/* Tre\u015b\u0107 *\/}\n                    <div className=\"flex-1 overflow-y-auto no-scrollbar p-4 flex flex-col\">\n                        {screen === 'dashboard' && <Dashboard user={currentUser} setScreen={setScreen} speak={speak} uiColor={uiColor} \/>}\n                        {screen === 'lesson_letters' && <LessonLetters setScreen={setScreen} speak={speak} uiColor={uiColor} award={awardProgress} \/>}\n                        {screen === 'lesson_words' && <LessonWords setScreen={setScreen} speak={speak} uiColor={uiColor} award={awardProgress} \/>}\n                        {screen === 'quiz' && <LessonQuiz setScreen={setScreen} speak={speak} uiColor={uiColor} award={awardProgress} \/>}\n                    <\/div>\n\n                    {\/* Popup Odznaki *\/}\n                    {badgePopup && (\n                        <div className=\"fixed inset-0 bg-black\/60 z-50 flex items-center justify-center p-4 backdrop-blur-sm\" onClick={() => setBadgePopup(null)}>\n                            <div className=\"bg-white rounded-3xl p-8 text-center animate-pop max-w-sm w-full border-8 border-yellow-400 text-gray-800\">\n                                <div className=\"text-6xl mb-4 animate-bounce-sm\">{badgePopup.icon}<\/div>\n                                <h2 className=\"text-3xl ncp-title text-yellow-500 mb-2\">Nowa Odznaka!<\/h2>\n                                <p className=\"text-2xl font-bold\">{badgePopup.name}<\/p>\n                                <button className=\"mt-6 w-full bg-blue-500 text-white text-xl py-3 rounded-2xl font-bold shadow-lg\" onClick={() => setBadgePopup(null)}>Super!<\/button>\n                            <\/div>\n                        <\/div>\n                    )}\n                <\/div>\n            );\n        };\n\n        \/\/ --- KOMPONENT: WYB\u00d3R U\u017bYTKOWNIKA ---\n        const UserSelect = ({users, onSelect, onNew, speak}) => (\n            <div className=\"flex-1 bg-blue-50 p-6 flex flex-col\">\n                <h1 className=\"text-4xl ncp-title text-center text-blue-600 my-8\">Kto dzisiaj gra?<\/h1>\n                <div className=\"grid grid-cols-2 gap-4 overflow-y-auto no-scrollbar pb-10\">\n                    <button onClick={() => { speak('Dodaj nowego gracza'); onNew(); }} className=\"bg-white border-4 border-dashed border-blue-300 rounded-3xl p-4 flex flex-col items-center justify-center gap-2 hover:bg-blue-100 transition active:scale-95 min-h-[140px]\">\n                        <span className=\"text-5xl text-blue-400\">+<\/span>\n                        <span className=\"font-bold text-blue-500\">Nowy profil<\/span>\n                    <\/button>\n                    {users.map(u => {\n                        const bg = COLORS.find(c => c.id === u.color)?.hex || '#ccc';\n                        return (\n                            <button key={u.id} onClick={() => onSelect(u)} className=\"bg-white rounded-3xl p-4 flex flex-col items-center gap-3 shadow-lg hover:shadow-xl active:scale-95 transition min-h-[140px]\" style={{borderBottom: `6px solid ${bg}`}}>\n                                <div className=\"w-16 h-16 rounded-full flex items-center justify-center text-4xl shadow-inner\" style={{backgroundColor: `${bg}33`}}>\n                                    {u.gender === 'dziewczynka' ? '\ud83d\udc67' : '\ud83d\udc66'}\n                                <\/div>\n                                <span className=\"font-bold text-gray-800 text-lg truncate w-full\">{u.name}<\/span>\n                            <\/button>\n                        )\n                    })}\n                <\/div>\n            <\/div>\n        );\n\n        \/\/ --- KOMPONENT: REJESTRACJA ---\n        const Register = ({onRegistered, onCancel, speak}) => {\n            const [step, setStep] = useState(1);\n            const [data, setData] = useState({ name: '', gender: '', theme: '', color: '' });\n\n            const next = (key, val, msg) => {\n                setData(p => ({...p, [key]: val}));\n                if(msg) speak(msg);\n                if(step < 4) setStep(step+1);\n                else submit({...data, [key]: val});\n            };\n\n            const submit = async (finalData) => {\n                const res = await fetch(`${API_URL}\/children`, {\n                    method: 'POST', headers: {'Content-Type': 'application\/json'}, body: JSON.stringify(finalData)\n                });\n                const r = await res.json();\n                onRegistered({id: r.id, ...finalData, stars: 0, time_spent: 0});\n            };\n\n            return (\n                <div className=\"flex-1 bg-white p-6 flex flex-col\">\n                    <button onClick={onCancel} className=\"self-start text-gray-400 p-2 active:scale-90\"><i data-lucide=\"arrow-left\" className=\"w-8 h-8\"><\/i><\/button>\n                    \n                    <div className=\"flex-1 flex flex-col justify-center items-center text-center animate-pop\">\n                        {step === 1 && (\n                            <div className=\"w-full\">\n                                <h2 className=\"text-3xl ncp-title text-gray-800 mb-6\" onClick={()=>speak('Jak masz na imi\u0119?')}>Jak masz na imi\u0119? \ud83c\udfa4<\/h2>\n                                <input type=\"text\" value={data.name} onChange={e=>setData({...data, name: e.target.value})} className=\"w-full text-center text-3xl p-4 border-4 border-blue-200 rounded-2xl outline-none focus:border-blue-500 font-bold mb-6\" placeholder=\"Wpisz imi\u0119...\" \/>\n                                <button onClick={() => { if(data.name.trim().length > 1) next('name', data.name, 'Jeste\u015b ch\u0142opcem czy dziewczynk\u0105?'); else speak('Wpisz swoje imi\u0119'); }} className=\"w-full bg-blue-500 text-white text-2xl py-4 rounded-2xl font-bold shadow-xl active:scale-95 transition-transform\">Dalej \u27a1\ufe0f<\/button>\n                            <\/div>\n                        )}\n                        {step === 2 && (\n                            <div className=\"w-full\">\n                                <h2 className=\"text-3xl ncp-title text-gray-800 mb-6\" onClick={()=>speak('Jeste\u015b ch\u0142opcem czy dziewczynk\u0105?')}>Kim jeste\u015b?<\/h2>\n                                <div className=\"grid grid-cols-2 gap-4\">\n                                    <button onClick={()=>next('gender', 'dziewczynka', 'Wybierz sw\u00f3j ulubiony \u015bwiat')} className=\"bg-pink-50 border-4 border-pink-200 rounded-3xl p-6 text-6xl hover:bg-pink-100 active:scale-95 transition-transform\">\ud83d\udc67<\/button>\n                                    <button onClick={()=>next('gender', 'chlopiec', 'Wybierz sw\u00f3j ulubiony \u015bwiat')} className=\"bg-blue-50 border-4 border-blue-200 rounded-3xl p-6 text-6xl hover:bg-blue-100 active:scale-95 transition-transform\">\ud83d\udc66<\/button>\n                                <\/div>\n                            <\/div>\n                        )}\n                        {step === 3 && (\n                            <div className=\"w-full\">\n                                <h2 className=\"text-3xl ncp-title text-gray-800 mb-6\" onClick={()=>speak('Wybierz sw\u00f3j \u015bwiat')}>Wybierz sw\u00f3j \u015bwiat \ud83c\udf0d<\/h2>\n                                <div className=\"grid grid-cols-2 gap-3\">\n                                    {THEMES.map(t => (\n                                        <button key={t.id} onClick={()=>next('theme', t.id, 'Jaki jest tw\u00f3j ulubiony kolor?')} className=\"bg-gray-50 border-2 border-gray-200 rounded-2xl p-4 flex flex-col items-center active:scale-95 transition-transform\">\n                                            <span className=\"text-4xl\">{t.icon}<\/span><span className=\"font-bold mt-2 text-gray-700\">{t.name}<\/span>\n                                        <\/button>\n                                    ))}\n                                <\/div>\n                            <\/div>\n                        )}\n                        {step === 4 && (\n                            <div className=\"w-full\">\n                                <h2 className=\"text-3xl ncp-title text-gray-800 mb-6\" onClick={()=>speak('Wybierz sw\u00f3j ulubiony kolor')}>Ulubiony kolor \ud83c\udfa8<\/h2>\n                                <div className=\"grid grid-cols-5 gap-3\">\n                                    {COLORS.map(c => (\n                                        <button key={c.id} onClick={()=>next('color', c.id, 'Gotowe!')} className=\"w-14 h-14 rounded-full mx-auto shadow-md active:scale-90 border-4 border-white ring-2 ring-gray-200 transition-transform\" style={{backgroundColor: c.hex}}><\/button>\n                                    ))}\n                                <\/div>\n                            <\/div>\n                        )}\n                    <\/div>\n                <\/div>\n            );\n        };\n\n        \/\/ --- KOMPONENT: DASHBOARD ---\n        const Dashboard = ({user, setScreen, speak, uiColor}) => {\n            return (\n                <div className=\"flex-1 flex flex-col justify-center gap-4 animate-pop\">\n                    <button onClick={() => { speak('Poznaj litery'); setScreen('lesson_letters'); }} className=\"bg-white\/90 backdrop-blur rounded-3xl p-6 flex items-center gap-4 shadow-xl active:scale-95 transition-transform border-b-8\" style={{borderColor: uiColor}}>\n                        <div className=\"w-20 h-20 rounded-2xl flex items-center justify-center text-5xl\" style={{background: `${uiColor}22`}}>\ud83d\udd24<\/div>\n                        <div className=\"text-left flex-1\">\n                            <h3 className=\"text-2xl font-bold text-gray-800 ncp-title\">Litery i s\u0142owa<\/h3>\n                            <p className=\"text-gray-600 font-bold\">Poznaj alfabet i obrazki<\/p>\n                        <\/div>\n                    <\/button>\n                    \n                    <button onClick={() => { speak('Czytaj s\u0142owa'); setScreen('lesson_words'); }} className=\"bg-white\/90 backdrop-blur rounded-3xl p-6 flex items-center gap-4 shadow-xl active:scale-95 transition-transform border-b-8\" style={{borderColor: uiColor}}>\n                        <div className=\"w-20 h-20 rounded-2xl flex items-center justify-center text-5xl\" style={{background: `${uiColor}22`}}>\ud83d\udcda<\/div>\n                        <div className=\"text-left flex-1\">\n                            <h3 className=\"text-2xl font-bold text-gray-800 ncp-title\">Sylaby<\/h3>\n                            <p className=\"text-gray-600 font-bold\">Sk\u0142adaj s\u0142owa z sylab<\/p>\n                        <\/div>\n                    <\/button>\n\n                    <button onClick={() => { speak('Rozwi\u0105zuj quizy'); setScreen('quiz'); }} className=\"bg-white\/90 backdrop-blur rounded-3xl p-6 flex items-center gap-4 shadow-xl active:scale-95 transition-transform border-b-8\" style={{borderColor: uiColor}}>\n                        <div className=\"w-20 h-20 rounded-2xl flex items-center justify-center text-5xl\" style={{background: `${uiColor}22`}}>\ud83c\udfc6<\/div>\n                        <div className=\"text-left flex-1\">\n                            <h3 className=\"text-2xl font-bold text-gray-800 ncp-title\">Gra Quizowa<\/h3>\n                            <p className=\"text-gray-600 font-bold\">Zdob\u0105d\u017a wi\u0119cej gwiazdek!<\/p>\n                        <\/div>\n                    <\/button>\n                <\/div>\n            );\n        };\n\n        \/\/ --- KOMPONENT: LEKCJA LITER I S\u0141\u00d3W Z DANYMI LITERAMI ---\n        const LessonLetters = ({setScreen, speak, uiColor, award}) => {\n            const [idx, setIdx] = useState(0);\n            const letter = LETTERS[idx];\n\n            \/\/ Funkcja znajduj\u0105ca s\u0142owa zawieraj\u0105ce liter\u0119 (priorytet: s\u0142owa zaczynaj\u0105ce si\u0119 na liter\u0119)\n            const getWordsForLetter = (ltr) => {\n                let matches = ALPHABET_WORDS.filter(w => w.w.includes(ltr));\n                \/\/ Sortuj tak, by te zaczynaj\u0105ce si\u0119 na liter\u0119 by\u0142y pierwsze\n                matches.sort((a, b) => {\n                    const aStarts = a.w.startsWith(ltr) ? 0 : 1;\n                    const bStarts = b.w.startsWith(ltr) ? 0 : 1;\n                    return aStarts - bStarts;\n                });\n                return matches.slice(0, 2); \/\/ Zwraca 2 s\u0142owa do pokazu\n            };\n\n            const wordExamples = getWordsForLetter(letter);\n\n            const handleSpeakLetter = () => {\n                \/\/ Precyzyjne, sp\u00f3jne z wy\u015bwietlanym obrazkiem opisy g\u0142osowe dla specjalnych polskich liter!\n                const map = {\n                    '\u0104': '\u0105 jak w s\u0142owie b\u0105k',\n                    '\u0106': '\u0107 jak w s\u0142owie \u0107ma',\n                    '\u0118': '\u0119 jak w s\u0142owie g\u0119\u015b',\n                    '\u0141': '\u0142 jak w s\u0142owie \u0142\u00f3d\u017a',\n                    '\u0143': '\u0144 jak w s\u0142owie ko\u0144',\n                    '\u00d3': '\u00f3 jak w s\u0142owie \u00f3semka',\n                    '\u015a': '\u015b jak w s\u0142owie \u015blimak',\n                    '\u0179': '\u017a jak w s\u0142owie \u017arebak',\n                    '\u017b': '\u017c jak w s\u0142owie \u017caba'\n                };\n                speak(map[letter] || `Litera ${letter}`);\n            };\n\n            useEffect(() => { handleSpeakLetter(); }, [idx]);\n\n            const next = () => {\n                award('letter', letter, 1);\n                speak('Brawo!');\n                setIdx((idx + 1) % LETTERS.length);\n            };\n\n            \/\/ Renderuje s\u0142owo z podkre\u015blon\u0105 liter\u0105\n            const renderHighlightedWord = (wordText) => {\n                return wordText.split('').map((char, i) => {\n                    if (char === letter) {\n                        return <span key={i} className=\"font-black border-b-4 mx-[1px]\" style={{borderColor: uiColor, color: uiColor}}>{char}<\/span>\n                    }\n                    return <span key={i} className=\"text-gray-700\">{char}<\/span>\n                });\n            };\n\n            return (\n                <div className=\"flex-1 bg-white rounded-3xl shadow-xl p-6 flex flex-col items-center justify-center relative animate-pop border-4\" style={{borderColor: uiColor}}>\n                    <button onClick={() => setScreen('dashboard')} className=\"absolute top-4 left-4 p-2 bg-gray-100 rounded-full text-gray-500 active:scale-90\"><i data-lucide=\"x\" className=\"w-6 h-6\"><\/i><\/button>\n                    \n                    <div className=\"text-[120px] font-black leading-none drop-shadow-lg ncp-title my-4 cursor-pointer\" style={{color: uiColor}} onClick={handleSpeakLetter}>\n                        {letter}\n                    <\/div>\n                    <p className=\"text-gray-400 font-bold text-lg mb-4\">Wielka i ma\u0142a: {letter} {letter.toLowerCase()}<\/p>\n\n                    {\/* S\u0142owa demonstracyjne *\/}\n                    <div className=\"w-full flex flex-col gap-3 flex-1 overflow-y-auto no-scrollbar justify-center mb-4\">\n                        {wordExamples.length > 0 ? wordExamples.map((item, i) => (\n                            <button key={i} onClick={() => speak(item.w)} className=\"bg-gray-50 border border-gray-100 p-3 rounded-2xl flex items-center justify-center gap-4 w-full shadow-sm active:scale-95 transition-transform\">\n                                <span className=\"text-5xl\">{item.img}<\/span>\n                                <span className=\"text-3xl font-bold ncp-title tracking-wider\">{renderHighlightedWord(item.w)}<\/span>\n                            <\/button>\n                        )) : (\n                            <div className=\"text-gray-400 text-center font-bold\">Brak s\u0142\u00f3w na t\u0119 liter\u0119.<\/div>\n                        )}\n                    <\/div>\n\n                    <div className=\"flex gap-4 w-full mt-auto\">\n                        <button onClick={handleSpeakLetter} className=\"flex-1 bg-gray-100 py-4 rounded-2xl text-4xl active:scale-95 shadow-md\">\ud83d\udd0a<\/button>\n                        <button onClick={next} className=\"flex-[2] text-white text-2xl font-bold py-4 rounded-2xl active:scale-95 shadow-lg flex items-center justify-center gap-2\" style={{backgroundColor: uiColor}}>\n                            Dalej <i data-lucide=\"arrow-right\" className=\"w-6 h-6\"><\/i>\n                        <\/button>\n                    <\/div>\n                <\/div>\n            );\n        };\n\n        \/\/ --- KOMPONENT: LEKCJA SYLAB (S\u0141\u00d3W) ---\n        const LessonWords = ({setScreen, speak, uiColor, award}) => {\n            const [idx, setIdx] = useState(0);\n            const [sylIdx, setSylIdx] = useState(0);\n            const word = WORDS_SYL[idx];\n\n            useEffect(() => { setSylIdx(0); speak(word.w); }, [idx]);\n\n            const checkSyl = (s, i) => {\n                if(i === sylIdx) {\n                    speak(s);\n                    if(sylIdx + 1 === word.syl.length) {\n                        setTimeout(() => { speak('Wspaniale!'); award('word', word.w, 3); setIdx((idx+1)%WORDS_SYL.length); }, 1000);\n                    } else {\n                        setSylIdx(sylIdx + 1);\n                    }\n                } else {\n                    speak('Spr\u00f3buj inn\u0105 sylab\u0119');\n                }\n            };\n\n            return (\n                <div className=\"flex-1 bg-white rounded-3xl shadow-xl p-6 flex flex-col items-center justify-center relative animate-pop border-4\" style={{borderColor: uiColor}}>\n                    <button onClick={() => setScreen('dashboard')} className=\"absolute top-4 left-4 p-2 bg-gray-100 rounded-full text-gray-500 active:scale-90\"><i data-lucide=\"x\" className=\"w-6 h-6\"><\/i><\/button>\n                    \n                    <div className=\"text-8xl mb-6 animate-bounce-sm cursor-pointer\" onClick={() => speak(word.w)}>{word.img}<\/div>\n                    \n                    <div className=\"flex flex-wrap justify-center gap-3 mb-12 w-full\">\n                        {word.syl.map((s, i) => (\n                            <button key={i} onClick={() => checkSyl(s, i)} className={`px-6 py-4 rounded-2xl text-4xl font-bold border-b-8 active:scale-95 transition-all ${i < sylIdx ? 'bg-green-100 text-green-600 border-green-300' : 'bg-gray-100 text-gray-700 border-gray-300'}`}>\n                                {s}\n                            <\/button>\n                        ))}\n                    <\/div>\n\n                    <p className=\"text-gray-500 font-bold mb-4\" onClick={() => speak('Zbuduj s\u0142owo naciskaj\u0105c sylaby')}>Dotknij sylaby po kolei \ud83d\udc47<\/p>\n                <\/div>\n            );\n        };\n\n        \/\/ --- KOMPONENT: QUIZ (10 PYTA\u0143 Z PODSUMOWANIEM I NAGRODAMI) ---\n        const LessonQuiz = ({setScreen, speak, uiColor, award}) => {\n            const [level, setLevel] = useState(null); \/\/ null = menu, 1, 2, 3\n            const [question, setQuestion] = useState(null);\n            const [questionIndex, setQuestionIndex] = useState(0); \/\/ 0 do 9 (10 pyta\u0144)\n            const [quizScore, setQuizScore] = useState(0);\n            const [quizCompleted, setQuizCompleted] = useState(false);\n            const [isFeedbackLocked, setIsFeedbackLocked] = useState(false);\n            const [selectedAnswer, setSelectedAnswer] = useState(null);\n\n            \/\/ Generuje pytanie\n            const generateQuestion = (lvl, currentIdx) => {\n                setSelectedAnswer(null);\n                setIsFeedbackLocked(false);\n\n                if (lvl === 1) {\n                    \/\/ Poziom 1: Znajd\u017a podan\u0105 liter\u0119 (spo\u015br\u00f3d 3)\n                    const correct = LETTERS[Math.floor(Math.random() * LETTERS.length)];\n                    let options = [correct];\n                    while (options.length < 3) {\n                        const r = LETTERS[Math.floor(Math.random() * LETTERS.length)];\n                        if (!options.includes(r)) options.push(r);\n                    }\n                    options.sort(() => Math.random() - 0.5);\n                    speak(`Pytanie ${currentIdx + 1}. Gdzie jest litera ${correct}?`);\n                    setQuestion({ type: 'find_letter', correct, options, text: `Znajd\u017a liter\u0119: ${correct}` });\n                } \n                else if (lvl === 2) {\n                    \/\/ Poziom 2: Jaka to litera ze s\u0142uchu? (spo\u015br\u00f3d 6 opcji)\n                    const correct = LETTERS[Math.floor(Math.random() * LETTERS.length)];\n                    let options = [correct];\n                    while (options.length < 6) {\n                        const r = LETTERS[Math.floor(Math.random() * LETTERS.length)];\n                        if (!options.includes(r)) options.push(r);\n                    }\n                    options.sort(() => Math.random() - 0.5);\n                    speak(`Pytanie ${currentIdx + 1}. Naci\u015bnij liter\u0119 ${correct}`);\n                    setQuestion({ type: 'listen_letter', correct, options, text: 'Pos\u0142uchaj i wybierz liter\u0119:' });\n                }\n                else if (lvl === 3) {\n                    \/\/ Poziom 3: Jaka to pierwsza litera s\u0142owa?\n                    const wordObj = ALPHABET_WORDS[Math.floor(Math.random() * ALPHABET_WORDS.length)];\n                    const correct = wordObj.w.charAt(0);\n                    let options = [correct];\n                    while (options.length < 4) {\n                        const r = LETTERS[Math.floor(Math.random() * LETTERS.length)];\n                        if (!options.includes(r)) options.push(r);\n                    }\n                    options.sort(() => Math.random() - 0.5);\n                    speak(`Pytanie ${currentIdx + 1}. Jak\u0105 liter\u0105 zaczyna si\u0119 s\u0142owo ${wordObj.w}?`);\n                    setQuestion({ type: 'missing_letter', correct, options, wordObj, text: `Jak\u0105 liter\u0105 zaczyna si\u0119 s\u0142owo?` });\n                }\n            };\n\n            const startQuiz = (lvl) => {\n                setLevel(lvl);\n                setQuestionIndex(0);\n                setQuizScore(0);\n                setQuizCompleted(false);\n                generateQuestion(lvl, 0);\n            };\n\n            const checkAnswer = (ans) => {\n                if (isFeedbackLocked) return;\n                setIsFeedbackLocked(true);\n                setSelectedAnswer(ans);\n\n                if (ans === question.correct) {\n                    speak('Dobrze! Super!');\n                    setQuizScore(prev => prev + 1);\n                } else {\n                    speak(`Oj, to litera ${question.correct}.`);\n                }\n\n                \/\/ Czas na zapoznanie si\u0119 z feedbackiem, potem kolejne pytanie\n                setTimeout(() => {\n                    if (questionIndex < 9) {\n                        const nextIdx = questionIndex + 1;\n                        setQuestionIndex(nextIdx);\n                        generateQuestion(level, nextIdx);\n                    } else {\n                        \/\/ Zako\u0144czenie quizu\n                        const totalAwardStars = quizScore * level * 2;\n                        award('badge', 'quiz_master'); \/\/ Odznaka Mistrza Quiz\u00f3w!\n                        award('quiz_stars', `complete_lvl_${level}`, totalAwardStars); \/\/ Nagroda gwiazdkowa\n                        setQuizCompleted(true);\n                        speak(`Wspaniale! Uko\u0144czy\u0142e\u015b quiz. Tw\u00f3j wynik to ${quizScore} na 10 punkt\u00f3w. Zdobywasz ${totalAwardStars} gwiazdek!`);\n                    }\n                }, 2000);\n            };\n\n            \/\/ Widok menu quiz\u00f3w\n            if (!level) {\n                return (\n                    <div className=\"flex-1 bg-white rounded-3xl shadow-xl p-6 flex flex-col relative animate-pop border-4\" style={{borderColor: uiColor}}>\n                        <button onClick={() => setScreen('dashboard')} className=\"absolute top-4 left-4 p-2 bg-gray-100 rounded-full text-gray-500 active:scale-90\"><i data-lucide=\"arrow-left\" className=\"w-6 h-6\"><\/i><\/button>\n                        <h2 className=\"text-3xl font-bold text-center mt-12 mb-8 ncp-title\" style={{color: uiColor}}>Wybierz Quiz<\/h2>\n                        <div className=\"flex flex-col gap-4\">\n                            <button onClick={() => startQuiz(1)} className=\"bg-green-100 border-2 border-green-300 text-green-700 p-5 rounded-2xl font-bold text-2xl active:scale-95 transition-transform flex items-center justify-between\">\n                                <span>1. \u0141atwy<\/span> <span>\ud83d\udfe2<\/span>\n                            <\/button>\n                            <button onClick={() => startQuiz(2)} className=\"bg-yellow-100 border-2 border-yellow-300 text-yellow-700 p-5 rounded-2xl font-bold text-2xl active:scale-95 transition-transform flex items-center justify-between\">\n                                <span>2. \u015aredni<\/span> <span>\ud83d\udfe1<\/span>\n                            <\/button>\n                            <button onClick={() => startQuiz(3)} className=\"bg-red-100 border-2 border-red-300 text-red-700 p-5 rounded-2xl font-bold text-2xl active:scale-95 transition-transform flex items-center justify-between\">\n                                <span>3. Trudny<\/span> <span>\ud83d\udd34<\/span>\n                            <\/button>\n                        <\/div>\n                    <\/div>\n                );\n            }\n\n            \/\/ Widok uko\u0144czonego quizu (Podsumowanie)\n            if (quizCompleted) {\n                return (\n                    <div className=\"flex-1 bg-white rounded-3xl shadow-xl p-6 flex flex-col items-center justify-center text-center relative animate-pop border-4\" style={{borderColor: uiColor}}>\n                        <div className=\"text-7xl mb-4 animate-bounce-sm\">\ud83c\udfc6<\/div>\n                        <h2 className=\"text-3xl font-bold ncp-title text-gray-800 mb-2\">Quiz Uko\u0144czony!<\/h2>\n                        <p className=\"text-xl text-gray-500 mb-6\">Tw\u00f3j pi\u0119kny wynik to:<\/p>\n                        \n                        <div className=\"text-6xl font-black mb-6 ncp-title\" style={{color: uiColor}}>\n                            {quizScore} \/ 10\n                        <\/div>\n\n                        <div className=\"bg-yellow-100 border-2 border-yellow-300 p-4 rounded-2xl mb-8 w-full\">\n                            <p className=\"font-bold text-yellow-700 text-lg\">\u2b50 Otrzymujesz: +{quizScore * level * 2} gwiazdek!<\/p>\n                            <p className=\"text-xs text-yellow-600 mt-1\">Oraz now\u0105 odznak\u0119 w Twoim profilu!<\/p>\n                        <\/div>\n\n                        <button onClick={() => setLevel(null)} className=\"w-full text-white text-xl font-bold py-4 rounded-2xl active:scale-95 shadow-lg transition-transform\" style={{backgroundColor: uiColor}}>\n                            Zagraj jeszcze raz!\n                        <\/button>\n                    <\/div>\n                );\n            }\n\n            \/\/ Widok gry quizowej\n            return (\n                <div className=\"flex-1 bg-white rounded-3xl shadow-xl p-6 flex flex-col items-center justify-center relative animate-pop border-4\" style={{borderColor: uiColor}}>\n                    <button onClick={() => setLevel(null)} className=\"absolute top-4 left-4 p-2 bg-gray-100 rounded-full text-gray-500 active:scale-90\"><i data-lucide=\"x\" className=\"w-6 h-6\"><\/i><\/button>\n                    \n                    {\/* Pasek Post\u0119pu Quizu (1 do 10) *\/}\n                    <div className=\"w-full flex justify-between text-xs font-bold text-gray-400 mb-2\">\n                        <span>Pytanie {questionIndex + 1} z 10<\/span>\n                        <span>Wynik: {quizScore} pkt<\/span>\n                    <\/div>\n                    <div className=\"w-full bg-gray-100 h-3 rounded-full overflow-hidden mb-6\">\n                        <div className=\"h-full transition-all duration-300 rounded-full\" style={{backgroundColor: uiColor, width: `${(questionIndex + 1) * 10}%`}}><\/div>\n                    <\/div>\n\n                    <h3 className=\"text-xl font-bold text-gray-500 mb-6 text-center\">{question.text}<\/h3>\n\n                    {\/* Dla poziomu 3 pokazujemy obrazek i s\u0142owo bez 1 litery *\/}\n                    {question.type === 'missing_letter' && (\n                        <div className=\"text-center mb-8\">\n                            <div className=\"text-8xl mb-2 animate-bounce-sm\">{question.wordObj.img}<\/div>\n                            <div className=\"text-4xl font-bold ncp-title tracking-widest text-gray-700\">\n                                <span className=\"text-gray-300 border-b-4 border-gray-300 inline-block w-8 text-center mr-1\">_<\/span>\n                                {question.wordObj.w.substring(1)}\n                            <\/div>\n                        <\/div>\n                    )}\n\n                    {\/* Dla poziomu 2 przycisk do powt\u00f3rzenia odtwarzania *\/}\n                    {question.type === 'listen_letter' && (\n                        <button onClick={() => speak(`Litera ${question.correct}`)} className=\"bg-blue-100 p-6 rounded-full text-5xl mb-8 active:scale-90 shadow-md\">\ud83d\udd0a<\/button>\n                    )}\n\n                    {\/* Dla poziomu 1 du\u017ca litera *\/}\n                    {question.type === 'find_letter' && (\n                        <div className=\"text-[100px] font-black ncp-title mb-6 leading-none cursor-pointer\" style={{color: uiColor}} onClick={() => speak(`Litera ${question.correct}`)}>{question.correct}<\/div>\n                    )}\n\n                    {\/* Odpowiedzi *\/}\n                    <div className=\"grid grid-cols-2 gap-4 w-full\">\n                        {question.options.map((opt, i) => {\n                            let btnBg = 'bg-gray-50 border-gray-200';\n                            let btnTextColor = '';\n                            \n                            if (selectedAnswer !== null) {\n                                if (opt === question.correct) {\n                                    btnBg = 'bg-green-100 border-green-500 text-green-700';\n                                } else if (opt === selectedAnswer) {\n                                    btnBg = 'bg-red-100 border-red-500 text-red-700';\n                                }\n                            }\n\n                            return (\n                                <button key={i} onClick={() => checkAnswer(opt)} disabled={isFeedbackLocked} className={`border-4 text-5xl font-black p-6 rounded-2xl active:scale-90 transition-all ncp-title shadow-sm ${btnBg}`} style={selectedAnswer === null ? {color: uiColor} : {}}>\n                                    {opt}\n                                <\/button>\n                            );\n                        })}\n                    <\/div>\n                <\/div>\n            );\n        };\n\n        \/\/ Renderowanie G\u0142\u00f3wne\n        const root = ReactDOM.createRoot(document.getElementById('ncp-root'));\n        root.render(<App \/>);\n\n        \/\/ Inicjalizacja ikon Lucide\n        setInterval(() => { if(window.lucide) lucide.createIcons(); }, 1000);\n    <\/script>\n\n    <script>\n        \/\/ PWA - Logika automatycznej instalacji w locie\n        let deferredPrompt;\n        \n        if ('serviceWorker' in navigator) {\n            window.addEventListener('load', () => { \n                navigator.serviceWorker.register('https:\/\/czytanie.julsoft.pl\/?ncp_pwa=sw').catch(()=>{}); \n            });\n        }\n\n        window.addEventListener('beforeinstallprompt', (e) => {\n            e.preventDefault();\n            deferredPrompt = e;\n            \n            \/\/ Pokazujemy baner tylko, je\u015bli gra nie jest uruchomiona w trybie pe\u0142noekranowym (standalone)\n            if (!window.matchMedia('(display-mode: standalone)').matches) {\n                const banner = document.getElementById('ncp-install-banner');\n                if(banner) banner.classList.remove('hidden');\n            }\n        });\n\n        function ncpInstallPWA() {\n            if (deferredPrompt) {\n                deferredPrompt.prompt();\n                deferredPrompt.userChoice.then((choiceResult) => {\n                    if (choiceResult.outcome === 'accepted') {\n                        document.getElementById('ncp-install-banner').classList.add('hidden');\n                    }\n                    deferredPrompt = null;\n                });\n            }\n        }\n    <\/script>\n    <\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-10","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/czytanie.julsoft.pl\/index.php?rest_route=\/wp\/v2\/pages\/10","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/czytanie.julsoft.pl\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/czytanie.julsoft.pl\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/czytanie.julsoft.pl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/czytanie.julsoft.pl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10"}],"version-history":[{"count":7,"href":"https:\/\/czytanie.julsoft.pl\/index.php?rest_route=\/wp\/v2\/pages\/10\/revisions"}],"predecessor-version":[{"id":18,"href":"https:\/\/czytanie.julsoft.pl\/index.php?rest_route=\/wp\/v2\/pages\/10\/revisions\/18"}],"wp:attachment":[{"href":"https:\/\/czytanie.julsoft.pl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}