<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="https://matolanorbert.hu/wp-sitemap-index.xsl" ?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>https://matolanorbert.hu/wp-sitemap-posts-post-1.xml</loc></sitemap><sitemap><loc>https://matolanorbert.hu/wp-sitemap-posts-page-1.xml</loc></sitemap><sitemap><loc>https://matolanorbert.hu/wp-sitemap-taxonomies-category-1.xml</loc></sitemap><sitemap><loc>https://matolanorbert.hu/wp-sitemap-users-1.xml</loc></sitemap></sitemapindex>
        <style id="tf-head-css">
        .tf-world-item {
            display: inline-flex !important;
            align-items: center !important;
            justify-content: center !important;
            position: relative !important;
            margin: 4px 6px !important;
            padding: 0 !important;
            vertical-align: middle !important;
            user-select: none !important;
            transition: transform 0.2s ease-out, opacity 0.4s ease !important;
            z-index: 25 !important;
            pointer-events: auto !important;
            overflow: hidden !important;
        }
        .tf-world-item.tf-collected-hide {
            display: none !important;
        }
        .tf-world-item-inner {
            display: inline-flex !important;
            align-items: center !important;
            justify-content: center !important;
            position: relative !important;
            pointer-events: none !important;
        }
        .tf-world-emoji {
            font-size: 28px !important;
            line-height: 1 !important;
            display: inline-block !important;
            padding: 6px !important;
            filter: sepia(0.6) contrast(0.95) drop-shadow(1px 2px 2px rgba(27,17,11,0.35)) !important;
        }
        .tf-world-img {
            max-width: 120px !important;
            max-height: 120px !important;
            width: auto !important;
            height: auto !important;
            object-fit: contain !important;
            display: block !important;
        }

        /* Ráfolyó tinta réteg közvetlenül a képen */
        .tf-ink-overlay {
            position: absolute !important;
            inset: 0 !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            padding: 6px !important;
            box-sizing: border-box !important;
            pointer-events: none !important;
            z-index: 28 !important;
            text-align: center !important;
            background: radial-gradient(circle, rgba(227, 210, 179, 0.55) 0%, rgba(227, 210, 179, 0) 80%) !important;
            opacity: 0 !important;
        }
        .tf-ink-overlay.is-bleeding {
            animation: tfInkSoak 2.6s cubic-bezier(0.22, 1, 0.36, 1) forwards !important;
        }
        .tf-ink-text {
            font-family: "Estonia", cursive !important;
            font-size: 24px !important;
            line-height: 18px !important;
            color: #1b0f08 !important;
            text-shadow: 0 0 2px rgba(27, 15, 8, 0.75), 0 0 5px rgba(58, 30, 14, 0.45) !important;
            filter: url(#tf-ink-bleed-filter) !important;
            word-break: break-word !important;
        }
        @keyframes tfInkSoak {
            0%   { opacity: 0; filter: blur(6px) contrast(3); transform: scale(0.86); }
            25%  { opacity: 0.95; filter: blur(1.2px) contrast(1.8); transform: scale(1.01); }
            75%  { opacity: 1; filter: blur(0.3px) contrast(1.3); transform: scale(1.03); }
            100% { opacity: 0; filter: blur(2px); transform: scale(1.05); }
        }

        /* Organikus porréteg (minimum 75%-os leporolás) */
        .tf-dust-canvas {
            position: absolute !important;
            top: 0 !important;
            left: 0 !important;
            width: 100% !important;
            height: 100% !important;
            z-index: 30 !important;
            touch-action: none !important;
            pointer-events: auto !important;
        }

        @keyframes tfVintageFadeOut {
            0%   { transform: scale(1); opacity: 1; }
            100% { transform: scale(0.82); opacity: 0; }
        }
        .tf-collecting {
            animation: tfVintageFadeOut 0.4s ease forwards !important;
            pointer-events: none !important;
        }

        @keyframes tfSubtleShake {
            0%, 100% { transform: translateX(0) rotate(0deg); }
            25% { transform: translateX(-3px) rotate(-1.5deg); }
            50% { transform: translateX(3px) rotate(1.5deg); }
            75% { transform: translateX(-2px) rotate(-1deg); }
        }
        .tf-shake {
            animation: tfSubtleShake 0.3s ease !important;
        }

        /* Láthatatlan tinta */
        .tf-secret-ink {
            color: transparent !important;
            border-bottom: 1px dashed rgba(124, 105, 82, 0.4) !important;
            padding: 0 3px !important;
            transition: color 0.35s ease, text-shadow 0.35s ease !important;
        }
        .tf-secret-ink.tf-ink-revealed {
            color: #4a2511 !important;
            text-shadow: 0 0 4px rgba(132, 102, 53, 0.6) !important;
        }

        /* VINTAGE KÓDEX ([titkos_kodex]) */
        .tf-codex-embed {
            column-span: all !important;
            -webkit-column-span: all !important;
            break-inside: avoid !important;
            width: 100% !important;
            box-sizing: border-box !important;
            background: radial-gradient(circle at 50% 50%, #f1e6d2 25%, #dac8a8 78%, #bda580 100%) !important;
            border: 1px solid #4a3723 !important;
            box-shadow: inset 0 0 0 1px #8c7353, inset 0 0 16px rgba(62, 38, 21, 0.28) !important;
            padding: 8px !important;
            margin: 8px 0 !important;
            color: #1f140b !important;
            font-family: Georgia, "Times New Roman", Times, serif !important;
            text-align: left !important;
        }
        .tf-codex-top-banner {
            width: 100% !important;
            padding: 5px 8px !important;
            border: 1px solid #23170d !important;
            background: linear-gradient(180deg, #3d2d1e 0%, #4e3b28 50%, #382819 100%) !important;
            box-shadow: inset 0 0 0 1px #8c7353, inset 0 0 10px rgba(0,0,0,0.6) !important;
            display: flex !important;
            align-items: center !important;
            justify-content: space-between !important;
            flex-wrap: wrap !important;
            gap: 6px !important;
            box-sizing: border-box !important;
        }
        .tf-codex-top-title {
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 12.5px !important;
            color: #dfd0b8 !important;
            letter-spacing: 0.5px !important;
            margin: 0 !important;
        }
        .tf-codex-top-meta {
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 9.5px !important;
            color: #c8b28e !important;
            display: flex !important;
            align-items: center !important;
            gap: 6px !important;
        }
        .tf-vintage-btn {
            background: #1b110b !important;
            border: 1px solid #846635 !important;
            color: #D1BC9D !important;
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 9.5px !important;
            letter-spacing: 0.5px !important;
            text-transform: uppercase !important;
            padding: 3px 9px !important;
            border-radius: 2px !important;
            display: inline-block !important;
            text-decoration: none !important;
        }
        .tf-vintage-btn:hover {
            background: #3e2615 !important;
            color: #f1e6d2 !important;
        }
        .tf-tabs {
            width: 100% !important;
            border-top: 1px solid #4a3723 !important;
            border-bottom: 1px solid #4a3723 !important;
            margin: 4px 0 6px 0 !important;
            padding: 2px 0 !important;
            display: flex !important;
            align-items: center !important;
            justify-content: space-around !important;
            box-sizing: border-box !important;
        }
        .tf-tab {
            background: transparent !important;
            border: none !important;
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 10px !important;
            color: #3d2d1e !important;
            padding: 2px 4px !important;
            text-transform: uppercase !important;
            outline: none !important;
        }
        .tf-tab.active {
            color: #7a1c1c !important;
            text-decoration: underline !important;
        }
        .tf-codex-viewport {
            position: relative !important;
            min-height: 150px !important;
            transition: opacity 0.18s ease !important;
        }
        .tf-codex-viewport.is-switching {
            opacity: 0.25 !important;
        }
        .tf-tab-panel { display: none !important; }
        .tf-tab-panel.active { display: block !important; }

        .tf-codex-list {
            display: flex !important;
            flex-direction: column !important;
        }
        .tf-codex-row {
            display: flex !important;
            align-items: center !important;
            gap: 8px !important;
            padding: 6px 2px !important;
            border-bottom: 1px solid rgba(74, 55, 35, 0.45) !important;
            text-align: left !important;
        }
        .tf-codex-row.unlocked:hover {
            background: rgba(132, 102, 53, 0.14) !important;
        }
        .tf-codex-thumb-box {
            width: 46px !important;
            height: 46px !important;
            flex-shrink: 0 !important;
            border: 1px #7C6952 dashed !important;
            background: #382416 !important;
            padding: 3px !important;
            box-sizing: border-box !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            overflow: hidden !important;
        }
        .tf-codex-thumb-box img {
            width: 100% !important;
            height: 100% !important;
            object-fit: cover !important;
            display: block !important;
        }
        .tf-codex-thumb-emoji {
            font-size: 20px !important;
            filter: sepia(0.55) !important;
        }
        .tf-codex-row.locked .tf-codex-thumb-box img,
        .tf-codex-row.locked .tf-codex-thumb-emoji {
            filter: brightness(0) invert(0.2) sepia(1) !important;
            opacity: 0.4 !important;
        }
        .tf-codex-row-text {
            flex: 1 !important;
            min-width: 0 !important;
        }
        .tf-codex-row-title {
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 11.5px !important;
            line-height: 13.5px !important;
            color: #1f140b !important;
            margin-bottom: 2px !important;
        }
        .tf-codex-row.locked .tf-codex-row-title {
            color: #5c442c !important;
        }
        .tf-codex-row-desc {
            font-family: "Estonia", cursive !important;
            font-size: 19px !important;
            line-height: 17px !important;
            color: #3d2d1e !important;
        }

        .tf-typewriter-box {
            background: #e3d2b3 !important;
            border: 1px solid #846635 !important;
            box-shadow: inset 0 0 12px rgba(62, 38, 21, 0.25) !important;
            padding: 12px !important;
            text-align: center !important;
            position: relative !important;
            overflow: hidden !important;
        }
        .tf-typewriter-box h4 {
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 11px !important;
            color: #3e2615 !important;
            letter-spacing: 1px !important;
            text-transform: uppercase !important;
            margin: 0 0 6px 0 !important;
        }
        .tf-secret-code-input {
            width: 100% !important;
            max-width: 170px !important;
            height: 24px !important;
            background: rgba(27, 17, 11, 0.08) !important;
            border: none !important;
            border-bottom: 1px solid #846635 !important;
            color: #1b110b !important;
            font-family: Georgia, "Times New Roman", Times, serif !important;
            font-size: 12px !important;
            text-align: center !important;
            margin: 4px auto 8px auto !important;
            padding: 2px 6px !important;
            display: block !important;
            box-sizing: border-box !important;
            outline: none !important;
            text-transform: uppercase !important;
        }

        /* FELUGRÓ PERGAMEN ABLAK */
        #tf-item-modal-overlay {
            position: absolute !important;
            top: 50px !important;
            left: 8px !important;
            width: 764px !important;
            height: 459px !important;
            background: rgba(18, 12, 8, 0.72) !important;
            z-index: 9999996 !important;
            display: none;
            align-items: center !important;
            justify-content: center !important;
            border-radius: 4px !important;
        }
        #tf-item-modal-overlay.is-open {
            display: flex !important;
        }
        .tf-modal-parchment {
            width: 340px !important;
            max-width: 90% !important;
            max-height: 390px !important;
            overflow-y: auto !important;
            background-color: #e3d2b3 !important;
            background-image: radial-gradient(ellipse at center, rgba(0,0,0,0) 45%, rgba(108, 72, 40, 0.38) 100%) !important;
            border: 1px solid #846635 !important;
            box-shadow: 0 16px 40px rgba(0, 0, 0, 0.85), inset 0 0 22px rgba(62, 38, 21, 0.35) !important;
            border-radius: 3px !important;
            padding: 18px 22px !important;
            box-sizing: border-box !important;
            position: relative !important;
            text-align: center !important;
            color: #1b110b !important;
            animation: tfModalPopIn 0.28s cubic-bezier(0.2, 0.8, 0.2, 1) forwards !important;
        }
        @keyframes tfModalPopIn {
            0%   { opacity: 0; transform: translateY(20px) scale(0.95); }
            100% { opacity: 1; transform: translateY(0) scale(1); }
        }
        .tf-modal-close {
            position: absolute !important;
            top: 8px !important;
            right: 10px !important;
            background: transparent !important;
            border: none !important;
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 14px !important;
            color: #4a3423 !important;
            padding: 2px 6px !important;
        }
        .tf-modal-close:hover {
            color: #7a1c1c !important;
        }
        .tf-modal-img-wrap {
            width: 96px !important;
            height: 96px !important;
            margin: 0 auto 10px auto !important;
            border: 1px #7C6952 dashed !important;
            background: #382416 !important;
            padding: 4px !important;
            box-sizing: border-box !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            box-shadow: 0 4px 10px rgba(0,0,0,0.4) !important;
        }
        .tf-modal-img-wrap img {
            width: 100% !important;
            height: 100% !important;
            object-fit: contain !important;
            display: block !important;
        }
        .tf-modal-img-wrap span {
            font-size: 42px !important;
            filter: sepia(0.5) !important;
        }
        .tf-modal-title {
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 15px !important;
            color: #23170d !important;
            margin: 0 0 8px 0 !important;
            padding-bottom: 5px !important;
            border-bottom: 1px solid rgba(132, 102, 53, 0.45) !important;
        }
        .tf-modal-desc {
            font-family: Georgia, "Times New Roman", Times, serif !important;
            font-size: 12px !important;
            line-height: 16px !important;
            color: #26170c !important;
            text-align: justify !important;
            margin-bottom: 12px !important;
        }
        .tf-modal-reward-box {
            border-top: 1px dashed #846635 !important;
            padding-top: 10px !important;
            margin-top: 8px !important;
            display: flex !important;
            flex-direction: column !important;
            align-items: center !important;
            gap: 8px !important;
        }
        .tf-modal-coupon {
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 11px !important;
            color: #7a1c1c !important;
            background: rgba(27, 17, 11, 0.08) !important;
            border: 1px dashed #7a1c1c !important;
            padding: 4px 10px !important;
        }
        .tf-rhythm-puzzle {
            background: #e3d2b3 !important;
            border: 1px solid #846635 !important;
            box-shadow: inset 0 0 10px rgba(62, 38, 21, 0.25) !important;
            padding: 8px 12px !important;
            display: inline-block !important;
            text-align: center !important;
            margin: 6px 0 !important;
        }
        .tf-rhythm-buttons {
            display: flex !important;
            gap: 6px !important;
            justify-content: center !important;
        }
        .tf-rhythm-btn {
            background: #382416 !important;
            border: 1px dashed #7C6952 !important;
            color: #dfd0b8 !important;
            font-size: 16px !important;
            padding: 4px 10px !important;
        }
        .tf-hidden { display: none !important; }
        </style>

        <svg width="0" height="0" style="position:fixed;top:-9999px;left:-9999px;width:0;height:0;pointer-events:none;overflow:hidden;" aria-hidden="true">
            <defs>
                <filter id="tf-ink-bleed-filter" x="-20%" y="-20%" width="140%" height="140%">
                    <feTurbulence type="fractalNoise" baseFrequency="0.045" numOctaves="3" result="noise"/>
                    <feDisplacementMap in="SourceGraphic" in2="noise" scale="2.8" xChannelSelector="R" yChannelSelector="G"/>
                </filter>
            </defs>
        </svg>

        <script id="tf-engine-js">
        (function() {
            if (window.TF_Engine_Loaded) return;
            window.TF_Engine_Loaded = true;

            const TF_Config = {"ajax_url":"https:\/\/matolanorbert.hu\/wp-admin\/admin-ajax.php","nonce":"ba70083317","is_logged_in":false,"items":{"36":{"id":36,"title":"R\u00e9gi R\u00e9zkulcs","type":"tool","emoji":"\ud83d\udddd\ufe0f","image":"","hint":"Valahol egy poros sarokban lapul...","reward_text":"Egy apr\u00f3, m\u00edves r\u00e9zkulcs. Ha k\u00e9zbe veszed a fi\u00f3kodban, kinyithatsz vele lepecs\u00e9telt l\u00e1dik\u00e1kat.","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"req_essence":1,"time_restriction":"any","is_lantern":false,"ink_clue":"Valahol egy poros sarokban lapul..."},"37":{"id":37,"title":"Viaszpecs\u00e9tes Bor\u00edt\u00e9k","type":"locked","emoji":"\u2709\ufe0f","image":"","hint":"Csak a R\u00e9gi R\u00e9zkulccsal nyithat\u00f3 fel.","reward_text":"A bor\u00edt\u00e9kban egy elfeledett k\u00e9zirat r\u00e9szlete \u00e9s egy titkos kupon lapult!","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"VARAZSLAT15","req_item_id":36,"req_fragments":[],"req_essence":1,"time_restriction":"any","is_lantern":false,"ink_clue":"Csak a R\u00e9gi R\u00e9zkulccsal nyithat\u00f3 fel."},"38":{"id":38,"title":"Holdf\u00e9ny L\u00e1mp\u00e1s","type":"tool","emoji":"\ud83c\udfee","image":"","hint":"F\u00e9nye l\u00e1that\u00f3v\u00e1 teszi a l\u00e1thatatlan tint\u00e1t.","reward_text":"Vedd k\u00e9zbe ezt a l\u00e1mp\u00e1st! Am\u00edg akt\u00edv, az eg\u00e9rmutat\u00f3d f\u00e9nyk\u00f6re felfedi a [titkos_tinta] elemeket az oldalon.","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"req_essence":1,"time_restriction":"any","is_lantern":true,"ink_clue":"F\u00e9nye l\u00e1that\u00f3v\u00e1 teszi a l\u00e1thatatlan tint\u00e1t."},"39":{"id":39,"title":"Hajnali Harmatcsepp","type":"daily","emoji":"\ud83d\udca7","image":"","hint":"Minden nap \u00fajragy\u0171jthet\u0151 esszencia.","reward_text":"Tiszta esszencia, amellyel az alv\u00f3 magokat \u00e9s gub\u00f3kat t\u00e1pl\u00e1lhatod a M\u0171helyben.","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"req_essence":1,"time_restriction":"any","is_lantern":false,"ink_clue":"Minden nap \u00fajragy\u0171jthet\u0151 esszencia."},"40":{"id":40,"title":"Alv\u00f3 Holdvir\u00e1g","type":"evolving","emoji":"\ud83c\udf31","image":"","hint":"3 csepp Hajnali Harmatra van sz\u00fcks\u00e9ge, hogy kivir\u00e1gozzon.","reward_text":"A Holdvir\u00e1g kiny\u00edlt! Ez\u00fcst\u00f6s szirmai k\u00f6z\u00f6tt egy \u0151si dallam csend\u00fcl fel.","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"req_essence":3,"time_restriction":"any","is_lantern":false,"ink_clue":"3 csepp Hajnali Harmatra van sz\u00fcks\u00e9ge, hogy kivir\u00e1gozzon."},"41":{"id":41,"title":"Az \u00cdr\u00f3asztal Titkos Rekesze","type":"code_locked","emoji":"\ud83d\udcdc","image":"https:\/\/matolanorbert.hu\/wp-content\/uploads\/2026\/06\/wall.png","hint":"\u00cdrd be a helyes jelsz\u00f3t (BAGOLY) a fi\u00f3kod \u00cdr\u00f3g\u00e9p\u00e9be!","reward_text":"A z\u00e1rszerkezet kattanva engedett! Megtal\u00e1ltad a rejtett napl\u00f3bejegyz\u00e9st.","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"req_essence":3,"time_restriction":"any","is_lantern":false,"ink_clue":"\u00cdrd be a helyes jelsz\u00f3t (BAGOLY) a fi\u00f3kod \u00cdr\u00f3g\u00e9p\u00e9be!"}}};
            const STORAGE_KEY = 'tf_guest_state_v2';
            const itemsDB = TF_Config.items || {};
            let userState = loadLocalState();

            function getEmptyState() {
                return { collected: [], evolved: [], feed_counts: {}, essence: 0, last_daily: '' };
            }

            function loadLocalState() {
                try {
                    const raw = localStorage.getItem(STORAGE_KEY);
                    if (raw) return Object.assign(getEmptyState(), JSON.parse(raw));
                } catch (e) {}
                return getEmptyState();
            }

            function saveLocalState(state) {
                userState = Object.assign(getEmptyState(), state);
                userState.collected = (userState.collected || []).map(Number);
                userState.evolved = (userState.evolved || []).map(Number);
                try {
                    localStorage.setItem(STORAGE_KEY, JSON.stringify(userState));
                } catch (e) {}
                refreshAllUI();
            }

            function triggerSfx(type, customUrl) {
                if (typeof window.playDeskSfx === 'function') {
                    if (customUrl) {
                        window.playDeskSfx(customUrl);
                        return;
                    }
                    if (type === 'collect') window.playDeskSfx('music/keyturn.mp3');
                    else if (type === 'locked') window.playDeskSfx('music/locked.mp3');
                    else if (type === 'turn') window.playDeskSfx('music/turn.mp3');
                    else if (type === 'open') window.playDeskSfx('music/book-open.mp3');
                    else if (type === 'close') window.playDeskSfx('music/book-close.mp3');
                    else if (type === 'dust') window.playDeskSfx('music/book.mp3');
                }
            }

            function cleanRawExcerpts() {
                document.querySelectorAll('.news-item-excerpt, .newspaper-body').forEach(el => {
                    if (el.innerHTML.indexOf('[titkos_') !== -1) {
                        el.innerHTML = el.innerHTML.replace(/\[titkos_[^\]]*\]/gi, '');
                    }
                });
            }

            function bleedInkOnElement(containerEl, text) {
                if (!containerEl || !text) return;
                let overlay = containerEl.querySelector('.tf-ink-overlay');
                if (!overlay) {
                    overlay = document.createElement('span');
                    overlay.className = 'tf-ink-overlay';
                    overlay.innerHTML = '<span class="tf-ink-text"></span>';
                    containerEl.appendChild(overlay);
                }
                const textNode = overlay.querySelector('.tf-ink-text');
                if (!textNode) return;

                textNode.textContent = text;
                overlay.classList.remove('is-bleeding');
                void overlay.offsetWidth;
                overlay.classList.add('is-bleeding');
            }

            function withPreservedScroll(fn) {
                const scrollStates = [];
                document.querySelectorAll('#ajax-stage .customScrollBox').forEach(box => {
                    const cont = box.querySelector('.container');
                    const drag = box.parentElement ? box.parentElement.querySelector('.dragger') : null;
                    scrollStates.push({
                        box: box,
                        cont: cont,
                        drag: drag,
                        contTop: cont ? cont.style.top : '0px',
                        dragTop: drag ? drag.style.top : '0px',
                        nativeScroll: box.scrollTop
                    });
                });

                const modalScrolls = [];
                document.querySelectorAll('#modal-dynamic-content > div').forEach(div => {
                    modalScrolls.push({ el: div, top: div.scrollTop });
                });

                fn();

                scrollStates.forEach(st => {
                    if (st.cont) st.cont.style.top = st.contTop;
                    if (st.drag) st.drag.style.top = st.dragTop;
                    if (st.box) st.box.scrollTop = st.nativeScroll;
                });
                modalScrolls.forEach(ms => {
                    ms.el.scrollTop = ms.top;
                });
            }

            function ensureItemModal() {
                let stage = document.getElementById('ajax-stage') || document.querySelector('.viewer-wrapper') || document.body;
                let modal = document.getElementById('tf-item-modal-overlay');
                if (modal && modal.parentElement !== stage) {
                    modal.remove();
                    modal = null;
                }
                if (!modal) {
                    modal = document.createElement('div');
                    modal.id = 'tf-item-modal-overlay';
                    modal.innerHTML = '<div class="tf-modal-parchment">'
                        + '<button type="button" class="tf-modal-close" title="Bezárás">✕</button>'
                        + '<div class="tf-modal-img-wrap" id="tf-modal-img"></div>'
                        + '<h3 class="tf-modal-title" id="tf-modal-title"></h3>'
                        + '<div class="tf-modal-desc" id="tf-modal-desc"></div>'
                        + '<div class="tf-modal-reward-box" id="tf-modal-rewards"></div>'
                        + '</div>';
                    stage.appendChild(modal);

                    modal.addEventListener('click', function(e) {
                        if (e.target === modal || e.target.closest('.tf-modal-close')) {
                            e.preventDefault();
                            e.stopPropagation();
                            triggerSfx('close');
                            modal.classList.remove('is-open');
                        }
                    });
                }
                return modal;
            }

            function openItemModal(item) {
                const modal = ensureItemModal();
                const isEvolved = item.type !== 'evolving' || userState.evolved.includes(Number(item.id));
                const fed = (userState.feed_counts && userState.feed_counts[item.id]) ? userState.feed_counts[item.id] : 0;

                const imgWrap = modal.querySelector('#tf-modal-img');
                imgWrap.innerHTML = item.image
                    ? '<img src="' + item.image + '" alt="" draggable="false">'
                    : '<span>' + item.emoji + '</span>';

                modal.querySelector('#tf-modal-title').textContent = item.title;
                modal.querySelector('#tf-modal-desc').textContent = isEvolved
                    ? (item.reward_text || 'Megtalált ereklye a gyűjteményedben.')
                    : 'Ez az ereklye még szunnyad. Tápláld Napi Esszenciával (' + fed + ' / ' + item.req_essence + '), hogy felfedje titkát.';

                const rewardsBox = modal.querySelector('#tf-modal-rewards');
                rewardsBox.innerHTML = '';

                if (!isEvolved) {
                    const feedBtn = document.createElement('button');
                    feedBtn.type = 'button';
                    feedBtn.className = 'tf-vintage-btn';
                    feedBtn.textContent = 'Táplálás Esszenciával (' + fed + '/' + item.req_essence + ')';
                    feedBtn.addEventListener('click', () => {
                        sendAction('feed', Number(item.id), {}, () => {
                            triggerSfx('collect');
                            openItemModal(itemsDB[item.id]);
                        });
                    });
                    rewardsBox.appendChild(feedBtn);
                } else {
                    if (item.audio_url) {
                        const audioWrap = document.createElement('div');
                        audioWrap.style.width = '100%';
                        audioWrap.innerHTML = '<audio controls src="' + item.audio_url + '" style="width:100%; height:28px;"></audio>';
                        rewardsBox.appendChild(audioWrap);
                    }
                    if (item.reward_link) {
                        const linkBtn = document.createElement('a');
                        linkBtn.href = item.reward_link;
                        linkBtn.target = '_blank';
                        linkBtn.className = 'tf-vintage-btn';
                        linkBtn.textContent = 'Jutalom Letöltése / Megnyitása';
                        rewardsBox.appendChild(linkBtn);
                    }
                    if (item.coupon_code) {
                        const codeEl = document.createElement('div');
                        codeEl.className = 'tf-modal-coupon';
                        codeEl.innerHTML = 'Jutalom Kód: <strong>' + item.coupon_code + '</strong>';
                        rewardsBox.appendChild(codeEl);
                    }
                }

                rewardsBox.style.display = rewardsBox.children.length === 0 ? 'none' : 'flex';
                triggerSfx('open');
                modal.classList.add('is-open');
            }

            function syncWithServer() {
                const formData = new FormData();
                formData.append('action', 'tf_sync_state');
                formData.append('nonce', TF_Config.nonce);
                formData.append('guest_state', JSON.stringify(userState));

                fetch(TF_Config.ajax_url, { method: 'POST', body: formData })
                    .then(r => r.json())
                    .then(res => {
                        if (res.success && res.data && res.data.state) {
                            saveLocalState(res.data.state);
                        }
                    })
                    .catch(() => refreshAllUI());
            }

            function sendAction(actionType, itemId, extra = {}, onSuccess = null, onError = null) {
                const formData = new FormData();
                formData.append('action', 'tf_action');
                formData.append('nonce', TF_Config.nonce);
                formData.append('action_type', actionType);
                formData.append('item_id', itemId);
                formData.append('client_state', JSON.stringify(userState));

                Object.keys(extra).forEach(k => formData.append(k, extra[k]));

                fetch(TF_Config.ajax_url, { method: 'POST', body: formData })
                    .then(r => r.json())
                    .then(res => {
                        if (res.success) {
                            saveLocalState(res.data.state);
                            if (onSuccess) onSuccess(res.data);
                        } else {
                            triggerSfx('locked');
                            if (onError) onError(res.data);
                        }
                    });
            }

            // Minimum 75%-os leporolás
            function initDustCanvases() {
                document.querySelectorAll('.tf-world-item[data-dust="1"]').forEach(wrapper => {
                    if (wrapper._tfDustCleared) return;
                    if (!wrapper.offsetParent && wrapper.offsetWidth === 0) return;

                    let canvas = wrapper.querySelector('.tf-dust-canvas');
                    if (!canvas) {
                        canvas = document.createElement('canvas');
                        canvas.className = 'tf-dust-canvas';
                        wrapper.appendChild(canvas);
                    }
                    if (canvas._tfBound) return;
                    canvas._tfBound = true;

                    const w = Math.max(wrapper.offsetWidth, 80);
                    const h = Math.max(wrapper.offsetHeight, 60);
                    canvas.width = w;
                    canvas.height = h;

                    const ctx = canvas.getContext('2d', { willReadFrequently: true });
                    ctx.globalCompositeOperation = 'source-over';

                    ctx.fillStyle = 'rgba(96, 78, 58, 0.97)';
                    ctx.fillRect(0, 0, w, h);

                    for (let i = 0; i < 90; i++) {
                        ctx.fillStyle = (i % 2 === 0) ? 'rgba(150, 130, 104, 0.7)' : 'rgba(62, 48, 34, 0.75)';
                        ctx.beginPath();
                        ctx.arc(Math.random() * w, Math.random() * h, 1.5 + Math.random() * 4, 0, Math.PI * 2);
                        ctx.fill();
                    }

                    ctx.globalCompositeOperation = 'destination-out';
                    let lastX = null;
                    let lastY = null;
                    let strokeCounter = 0;
                    const brushRadius = Math.max(11, Math.min(w, h) * 0.14);

                    function checkClearedPercentage() {
                        try {
                            const imgData = ctx.getImageData(0, 0, w, h).data;
                            let totalPixels = 0;
                            let clearedPixels = 0;
                            for (let i = 3; i < imgData.length; i += 16) {
                                totalPixels++;
                                if (imgData[i] < 90) clearedPixels++;
                            }
                            return totalPixels > 0 ? (clearedPixels / totalPixels) : 0;
                        } catch (err) {
                            return 0;
                        }
                    }

                    function wipe(x, y) {
                        if (wrapper._tfDustCleared) return;

                        ctx.lineCap = 'round';
                        ctx.lineJoin = 'round';
                        ctx.lineWidth = brushRadius * 2;

                        ctx.beginPath();
                        if (lastX !== null && lastY !== null && Math.hypot(x - lastX, y - lastY) < 45) {
                            ctx.moveTo(lastX, lastY);
                            ctx.lineTo(x, y);
                            ctx.stroke();
                        } else {
                            ctx.arc(x, y, brushRadius, 0, Math.PI * 2);
                            ctx.fill();
                        }
                        lastX = x;
                        lastY = y;

                        strokeCounter++;
                        if (strokeCounter % 5 === 0) {
                            if (checkClearedPercentage() >= 0.75 && !wrapper._tfDustCleared) {
                                wrapper._tfDustCleared = true;
                                triggerSfx('dust');
                                canvas.style.transition = 'opacity 0.35s ease';
                                canvas.style.opacity = '0';
                                setTimeout(() => canvas.remove(), 350);
                            }
                        }
                    }

                    canvas.addEventListener('mousemove', e => {
                        const rect = canvas.getBoundingClientRect();
                        wipe((e.clientX - rect.left) * (canvas.width / rect.width), (e.clientY - rect.top) * (canvas.height / rect.height));
                    });

                    canvas.addEventListener('mouseleave', () => {
                        lastX = null;
                        lastY = null;
                    });

                    canvas.addEventListener('touchmove', e => {
                        e.preventDefault();
                        const rect = canvas.getBoundingClientRect();
                        const t = e.touches[0];
                        wipe((t.clientX - rect.left) * (canvas.width / rect.width), (t.clientY - rect.top) * (canvas.height / rect.height));
                    }, { passive: false });
                });
            }

            function hasLanternInCollection() {
                return Object.values(itemsDB).some(it => it.is_lantern && userState.collected.includes(Number(it.id)));
            }

            document.addEventListener('click', function(e) {
                const worldItem = e.target.closest('.tf-world-item');
                if (worldItem) {
                    e.preventDefault();
                    e.stopPropagation();

                    if (worldItem.dataset.dust === '1' && !worldItem._tfDustCleared) {
                        worldItem.classList.remove('tf-shake');
                        void worldItem.offsetWidth;
                        worldItem.classList.add('tf-shake');
                        return;
                    }

                    const id = Number(worldItem.dataset.itemId);
                    const item = itemsDB[id];
                    if (!item) return;

                    if (item.type === 'code_locked') {
                        triggerSfx('turn');
                        bleedInkOnElement(worldItem, item.ink_clue || ' ? ? ? ');
                        return;
                    }

                    sendAction('collect', id, {}, () => {
                        triggerSfx('collect', item.sfx_url);
                        worldItem.classList.add('tf-collecting');
                        setTimeout(() => {
                            withPreservedScroll(() => {
                                document.querySelectorAll('.tf-world-item[data-item-id="' + id + '"]').forEach(el => {
                                    el.classList.remove('tf-collecting');
                                    el.classList.add('tf-collected-hide');
                                });
                            });
                        }, 400);
                    }, () => {
                        worldItem.classList.remove('tf-shake');
                        void worldItem.offsetWidth;
                        worldItem.classList.add('tf-shake');
                    });
                    return;
                }

                const resetBtn = e.target.closest('.tf-reset-btn');
                if (resetBtn) {
                    e.preventDefault();
                    e.stopPropagation();
                    triggerSfx('turn');
                    sendAction('reset_demo', 0, {}, () => {
                        localStorage.removeItem(STORAGE_KEY);
                        withPreservedScroll(() => {
                            document.querySelectorAll('.tf-world-item').forEach(el => {
                                el.classList.remove('tf-collected-hide', 'tf-collecting');
                                delete el._tfDustCleared;
                                const oldC = el.querySelector('.tf-dust-canvas');
                                if (oldC) oldC.remove();
                            });
                            initDustCanvases();
                            refreshAllUI();
                        });
                    });
                    return;
                }

                const tabBtn = e.target.closest('.tf-tab');
                if (tabBtn) {
                    e.preventDefault();
                    e.stopPropagation();
                    const embed = tabBtn.closest('.tf-codex-embed');
                    if (!embed || tabBtn.classList.contains('active')) return;

                    triggerSfx('turn');
                    const viewport = embed.querySelector('.tf-codex-viewport');
                    if (viewport) viewport.classList.add('is-switching');

                    setTimeout(() => {
                        withPreservedScroll(() => {
                            embed.querySelectorAll('.tf-tab, .tf-tab-panel').forEach(el => el.classList.remove('active'));
                            tabBtn.classList.add('active');
                            const targetPanel = embed.querySelector('.tf-tab-panel[data-panel="' + tabBtn.dataset.tab + '"]');
                            if (targetPanel) targetPanel.classList.add('active');
                        });
                        if (viewport) viewport.classList.remove('is-switching');
                    }, 150);
                    return;
                }

                const codeSubmit = e.target.closest('.tf-secret-code-submit');
                if (codeSubmit) {
                    e.preventDefault();
                    e.stopPropagation();
                    const box = codeSubmit.closest('.tf-typewriter-box');
                    const input = box.querySelector('.tf-secret-code-input');
                    const val = input ? input.value.trim() : '';
                    if (!val) return;

                    sendAction('unlock_code', 0, { code: val }, (resData) => {
                        triggerSfx('collect');
                        if (input) input.value = '';
                        bleedInkOnElement(box, val.toUpperCase());
                        if (resData && resData.unlocked_id && itemsDB[resData.unlocked_id]) {
                            setTimeout(() => openItemModal(itemsDB[resData.unlocked_id]), 900);
                        }
                    }, () => {
                        box.classList.remove('tf-shake');
                        void box.offsetWidth;
                        box.classList.add('tf-shake');
                    });
                    return;
                }
            });

            document.addEventListener('mousemove', e => {
                if (!hasLanternInCollection()) return;
                document.querySelectorAll('.tf-secret-ink').forEach(el => {
                    const rect = el.getBoundingClientRect();
                    const cx = rect.left + rect.width / 2;
                    const cy = rect.top + rect.height / 2;
                    if (Math.hypot(e.clientX - cx, e.clientY - cy) < 130) {
                        el.classList.add('tf-ink-revealed');
                    } else {
                        el.classList.remove('tf-ink-revealed');
                    }
                });
            });

            function refreshAllUI() {
                withPreservedScroll(() => {
                    cleanRawExcerpts();
                    const today = new Date().toISOString().slice(0, 10);

                    document.querySelectorAll('.tf-world-item').forEach(el => {
                        const id = Number(el.dataset.itemId);
                        const item = itemsDB[id];
                        if (!item) return;
                        if (item.type === 'daily') {
                            if (userState.last_daily === today) el.classList.add('tf-collected-hide');
                            else el.classList.remove('tf-collected-hide');
                        } else if (userState.collected.includes(id)) {
                            el.classList.add('tf-collected-hide');
                        } else {
                            el.classList.remove('tf-collected-hide');
                        }
                    });

                    document.querySelectorAll('.tf-secret-content-block').forEach(block => {
                        const reqId = Number(block.dataset.reqItem);
                        block.style.display = userState.collected.includes(reqId) ? 'block' : 'none';
                    });

                    const totalItems = Object.keys(itemsDB).length;
                    document.querySelectorAll('.tf-collected-counter').forEach(el => {
                        el.textContent = userState.collected.length + '/' + totalItems;
                    });
                    document.querySelectorAll('.tf-essence-count').forEach(el => {
                        el.textContent = userState.essence || 0;
                    });

                    renderCodexLists();
                    renderAlchemyPanels();
                });
            }

            function renderCodexLists() {
                document.querySelectorAll('.tf-codex-embed').forEach(embed => {
                    const list = embed.querySelector('.tf-codex-list');
                    if (!list) return;
                    list.innerHTML = '';

                    Object.values(itemsDB).forEach(item => {
                        const isUnlocked = userState.collected.includes(Number(item.id));
                        const isEvolved = item.type !== 'evolving' || userState.evolved.includes(Number(item.id));

                        const row = document.createElement('div');
                        row.className = 'tf-codex-row ' + (isUnlocked ? 'unlocked' : 'locked');

                        const thumbHtml = item.image
                            ? '<img src="' + item.image + '" alt="" draggable="false">'
                            : '<span class="tf-codex-thumb-emoji">' + item.emoji + '</span>';

                        row.innerHTML = '<div class="tf-codex-thumb-box">' + thumbHtml + '</div>'
                            + '<div class="tf-codex-row-text">'
                            + '<div class="tf-codex-row-title">' + (isUnlocked ? item.title : '? ? ?') + '</div>'
                            + '<div class="tf-codex-row-desc">' + (isUnlocked ? (isEvolved ? 'Megtekintés' : 'Alvó ereklye') : item.hint) + '</div>'
                            + '</div>';

                        if (isUnlocked) {
                            row.addEventListener('click', (e) => {
                                e.preventDefault();
                                e.stopPropagation();
                                openItemModal(item);
                            });
                        }
                        list.appendChild(row);
                    });
                });
            }

            function renderAlchemyPanels() {
                document.querySelectorAll('.tf-alchemy-list').forEach(container => {
                    container.innerHTML = '';
                    const craftables = Object.values(itemsDB).filter(it => it.type === 'craftable' || it.type === 'evolving');

                    if (craftables.length === 0) {
                        container.innerHTML = '<div class="tf-codex-row-desc">Nincsenek gondozásra váró ereklyék.</div>';
                        return;
                    }

                    craftables.forEach(item => {
                        const row = document.createElement('div');
                        row.className = 'tf-codex-row unlocked';

                        if (item.type === 'craftable') {
                            const alreadyCrafted = userState.collected.includes(Number(item.id));
                            const ownedCount = item.req_fragments.filter(fid => userState.collected.includes(Number(fid))).length;
                            row.innerHTML = '<div class="tf-codex-row-text">'
                                + '<div class="tf-codex-row-title">' + item.title + '</div>'
                                + '<div class="tf-codex-row-desc">Töredékek: ' + ownedCount + ' / ' + item.req_fragments.length + '</div>'
                                + '</div>'
                                + '<div>' + (alreadyCrafted ? '<span class="tf-codex-row-desc">Összeállítva</span>' : '<button type="button" class="tf-vintage-btn" data-craft="' + item.id + '">Összeillesztés</button>') + '</div>';
                        } else if (item.type === 'evolving') {
                            const isCollected = userState.collected.includes(Number(item.id));
                            const isEvolved = userState.evolved.includes(Number(item.id));
                            const fed = (userState.feed_counts && userState.feed_counts[item.id]) ? userState.feed_counts[item.id] : 0;

                            row.innerHTML = '<div class="tf-codex-row-text">'
                                + '<div class="tf-codex-row-title">' + item.title + '</div>'
                                + '<div class="tf-codex-row-desc">' + (isCollected ? ('Esszencia: ' + fed + ' / ' + item.req_essence) : 'Még nem találtad meg.') + '</div>'
                                + '</div>'
                                + '<div>' + (!isCollected ? '' : (isEvolved ? '<span class="tf-codex-row-desc">Kifejlődött</span>' : '<button type="button" class="tf-vintage-btn" data-feed="' + item.id + '">Táplálás</button>')) + '</div>';
                        }
                        container.appendChild(row);
                    });

                    container.querySelectorAll('[data-craft]').forEach(btn => {
                        btn.addEventListener('click', (e) => {
                            e.preventDefault();
                            e.stopPropagation();
                            const cid = Number(btn.dataset.craft);
                            sendAction('craft', cid, {}, () => {
                                triggerSfx('collect');
                                if (itemsDB[cid]) openItemModal(itemsDB[cid]);
                            });
                        });
                    });
                    container.querySelectorAll('[data-feed]').forEach(btn => {
                        btn.addEventListener('click', (e) => {
                            e.preventDefault();
                            e.stopPropagation();
                            const fid = Number(btn.dataset.feed);
                            sendAction('feed', fid, {}, (resData) => {
                                triggerSfx('collect');
                                if (resData && resData.state && resData.state.evolved.includes(fid) && itemsDB[fid]) {
                                    openItemModal(itemsDB[fid]);
                                }
                            });
                        });
                    });
                });
            }

            let observerTimeout = null;
            const observer = new MutationObserver((mutations) => {
                let shouldUpdate = false;
                for (let i = 0; i < mutations.length; i++) {
                    const m = mutations[i];
                    if (m.target && (m.target.closest('.tf-codex-embed') || m.target.closest('#tf-item-modal-overlay') || m.target.closest('.tf-world-item'))) {
                        continue;
                    }
                    if (m.addedNodes && m.addedNodes.length > 0) {
                        shouldUpdate = true;
                        break;
                    }
                }
                if (shouldUpdate) {
                    clearTimeout(observerTimeout);
                    observerTimeout = setTimeout(() => {
                        initDustCanvases();
                        refreshAllUI();
                    }, 90);
                }
            });

            function boot() {
                initDustCanvases();
                refreshAllUI();
                syncWithServer();
                if (document.body) {
                    observer.observe(document.body, { childList: true, subtree: true });
                }
            }

            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', boot);
            } else {
                boot();
            }
        })();
        </script>
        