<?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-hidden { display: none !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; cursor:pointer !important; }
        .tf-vintage-btn:hover { background:#3e2615 !important; color:#f1e6d2 !important; }

        /* Világban heverő felvehető tárgyak */
        .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; }
        .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); } }
        .tf-wax-seal { position:absolute !important; inset:0 !important; display:flex !important; align-items:center !important; justify-content:center !important; z-index:29 !important; pointer-events:auto !important; cursor:pointer !important; transition:transform 0.18s ease, opacity 0.35s ease !important; }
        .tf-wax-svg { width:54px !important; height:54px !important; filter:drop-shadow(0 3px 5px rgba(18, 8, 4, 0.7)) !important; transition:transform 0.15s ease !important; }
        .tf-wax-outer { fill:#7c1919 !important; stroke:#4d0d0d !important; stroke-width:3px !important; } .tf-wax-inner { fill:#641212 !important; stroke:#a83232 !important; stroke-width:1.5px !important; stroke-dasharray:3,2 !important; } .tf-wax-emblem { fill:#d4af37 !important; font-size:22px !important; font-family:Georgia, serif !important; user-select:none !important; }
        .tf-crack { fill:none !important; stroke:#1b0707 !important; stroke-width:2.2px !important; stroke-linecap:round !important; stroke-linejoin:round !important; opacity:0 !important; transition:opacity 0.15s ease !important; }
        .tf-wax-seal[data-cracks="1"] .tf-crack-1 { opacity:0.85 !important; } .tf-wax-seal[data-cracks="2"] .tf-crack-1, .tf-wax-seal[data-cracks="2"] .tf-crack-2 { opacity:0.95 !important; } .tf-wax-seal[data-cracks="2"] .tf-wax-svg { transform:scale(0.95) rotate(-4deg) !important; }
        .tf-wax-seal.is-shattering { transform:scale(1.28) rotate(8deg) !important; opacity:0 !important; pointer-events:none !important; }
        .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; }

        /* Vizuális Szertár (Polcok és Asztal) */
        .tf-szertar-wrapper { width:100% !important; max-width:800px !important; margin:20px auto !important; background:radial-gradient(circle at 50% 50%, #2f2219 0%, #170f0a 100%) !important; border:8px solid #1a100a !important; border-radius:4px !important; box-shadow:inset 0 0 40px rgba(0,0,0,0.9), 0 10px 30px rgba(0,0,0,0.7) !important; position:relative !important; overflow:hidden !important; display:flex !important; flex-direction:column !important; font-family:Georgia, serif !important; }
        .tf-shelf-container { flex:1 !important; display:flex !important; flex-direction:column !important; justify-content:space-evenly !important; padding:20px 10px 0 10px !important; gap:30px !important; min-height:240px !important; }
        .tf-shelf-row { display:flex !important; flex-wrap:wrap !important; justify-content:center !important; align-items:flex-end !important; gap:16px !important; padding-bottom:8px !important; border-bottom:12px solid #3c2415 !important; box-shadow:0 6px 6px -4px rgba(0,0,0,0.8), inset 0 -3px 0 rgba(0,0,0,0.3) !important; position:relative !important; min-height:60px !important; }
        .tf-shelf-row::after { content:"" !important; position:absolute !important; bottom:-12px !important; left:0 !important; right:0 !important; height:12px !important; background:linear-gradient(90deg, rgba(0,0,0,0.4) 0%, transparent 10%, transparent 90%, rgba(0,0,0,0.4) 100%) !important; pointer-events:none !important; }
        
        .tf-placed-item { position:relative !important; display:inline-flex !important; align-items:flex-end !important; justify-content:center !important; width:50px !important; height:50px !important; cursor:pointer !important; filter:drop-shadow(0 5px 4px rgba(0,0,0,0.65)) !important; transition:transform 0.15s ease !important; user-select:none !important; touch-action:none !important; }
        .tf-placed-item:hover { transform:scale(1.1) translateY(-2px) !important; filter:drop-shadow(0 8px 6px rgba(0,0,0,0.75)) !important; }
        .tf-placed-item img { max-width:100% !important; max-height:100% !important; object-fit:contain !important; pointer-events:none !important; display:block !important; }
        .tf-placed-item .tf-emoji-icon { font-size:36px !important; line-height:1 !important; pointer-events:none !important; filter:sepia(0.5) !important; }
        .tf-placed-item .tf-qty-badge { position:absolute !important; bottom:-4px !important; right:-6px !important; font-family:"Uncial Antiqua", Georgia, serif !important; font-size:11px !important; font-weight:bold !important; color:#fff !important; text-shadow:0 0 4px #000, 0 0 2px #000 !important; pointer-events:none !important; }
        .tf-placed-item.is-draggable-tool { cursor:grab !important; }
        .tf-placed-item.is-drop-target { filter:drop-shadow(0 0 10px #d4af37) !important; transform:scale(1.15) !important; }

        .tf-worktable-container { background:linear-gradient(180deg, #442a18 0%, #2b1a0f 100%) !important; border-top:2px solid #1a100a !important; box-shadow:0 -10px 20px rgba(0,0,0,0.6) !important; padding:15px 10px !important; display:flex !important; justify-content:space-around !important; align-items:flex-end !important; position:relative !important; min-height:100px !important; }
        
        .tf-mortar { width:65px !important; height:55px !important; background:radial-gradient(ellipse at top, #777 0%, #444 100%) !important; border-radius:10px 10px 30px 30px !important; box-shadow:inset 0 4px 6px rgba(0,0,0,0.5), 0 6px 10px rgba(0,0,0,0.6) !important; position:relative !important; display:flex !important; justify-content:center !important; align-items:flex-end !important; padding-bottom:5px !important; cursor:pointer !important; }
        .tf-mortar.is-drop-target { filter:drop-shadow(0 0 12px #d4af37) !important; }
        .tf-mortar-pestle { position:absolute !important; width:14px !important; height:45px !important; background:linear-gradient(90deg, #999 0%, #aaa 50%, #777 100%) !important; border-radius:6px !important; top:-20px !important; right:15px !important; transform-origin:bottom center !important; transform:rotate(15deg) !important; transition:transform 0.1s ease !important; box-shadow:2px 2px 4px rgba(0,0,0,0.5) !important; pointer-events:none !important; opacity:0; }
        .tf-mortar.has-item .tf-mortar-pestle { opacity:1; }
        .tf-mortar.is-smashing .tf-mortar-pestle { transform:rotate(0deg) translateY(10px) !important; }
        .tf-mortar-content { font-size:24px !important; line-height:1 !important; pointer-events:none !important; }
        
        .tf-cauldron { width:110px !important; height:85px !important; background:radial-gradient(circle at 30% 30%, #444 0%, #111 100%) !important; border-radius:10px 10px 50px 50px !important; box-shadow:inset 0 8px 10px rgba(0,0,0,0.8), 0 8px 15px rgba(0,0,0,0.7) !important; position:relative !important; display:flex !important; justify-content:center !important; align-items:flex-start !important; cursor:pointer !important; }
        .tf-cauldron::before { content:"" !important; position:absolute !important; top:-6px !important; left:-5px !important; right:-5px !important; height:12px !important; border-radius:50% !important; border:4px solid #222 !important; box-sizing:border-box !important; }
        .tf-cauldron.is-drop-target { filter:drop-shadow(0 0 15px #d4af37) !important; }
        .tf-cauldron-liquid { position:absolute !important; top:0 !important; left:6px !important; right:6px !important; height:20px !important; border-radius:50% !important; background:rgba(30, 30, 30, 0.9) !important; transition:background 0.5s ease !important; box-shadow:inset 0 0 10px rgba(0,0,0,0.8) !important; pointer-events:none !important; }
        .tf-cauldron-bubbles { position:absolute !important; top:-15px !important; width:100% !important; text-align:center !important; font-size:16px !important; pointer-events:none !important; opacity:0; transition:opacity 0.3s ease !important; }
        .tf-cauldron.has-items .tf-cauldron-bubbles { opacity:1 !important; animation:tfFloat 2s infinite ease-in-out !important; }
        @keyframes tfFloat { 0%, 100% { transform:translateY(0); } 50% { transform:translateY(-8px); } }
        
        .tf-essence-vial { width:30px !important; height:50px !important; background:linear-gradient(180deg, rgba(255,255,255,0.4) 0%, rgba(200,220,255,0.2) 100%) !important; border:2px solid rgba(255,255,255,0.6) !important; border-radius:4px 4px 12px 12px !important; position:relative !important; box-shadow:0 4px 6px rgba(0,0,0,0.5), inset 0 -15px 20px rgba(100,150,255,0.4) !important; display:flex !important; align-items:center !important; justify-content:center !important; cursor:grab !important; touch-action:none !important; }
        .tf-essence-vial::before { content:"" !important; position:absolute !important; top:-8px !important; left:6px !important; width:14px !important; height:6px !important; background:#5c3a21 !important; border-radius:2px !important; }
        .tf-essence-count { font-family:"Uncial Antiqua", Georgia, serif !important; font-size:14px !important; color:#fff !important; text-shadow:0 0 4px #000, 0 0 2px #000 !important; font-weight:bold !important; pointer-events:none !important; }
        .tf-essence-vial.is-empty { opacity:0.5 !important; cursor:not-allowed !important; filter:grayscale(1) !important; }

        .tf-cauldron-stir-btn, .tf-cauldron-pour-btn { position:absolute !important; top:40% !important; left:50% !important; transform:translate(-50%, -50%) !important; z-index:10 !important; font-family:"Uncial Antiqua", Georgia, serif !important; font-size:11px !important; padding:4px 8px !important; border-radius:3px !important; border:1px solid #d4af37 !important; background:rgba(40,20,10,0.9) !important; color:#d4af37 !important; cursor:pointer !important; text-transform:uppercase !important; box-shadow:0 4px 8px rgba(0,0,0,0.8) !important; }
        .tf-cauldron-pour-btn { top:70% !important; border-color:#8a2424 !important; color:#ffaaaa !important; }

        /* Lebegő Drag Ikon */
        #tf-drag-ghost { position:fixed !important; top:-200px; left:-200px; width:50px !important; height:50px !important; margin-left:-25px !important; margin-top:-25px !important; pointer-events:none !important; z-index:9999999 !important; display:none; align-items:center !important; justify-content:center !important; filter:drop-shadow(0 10px 15px rgba(0,0,0,0.75)) !important; }
        #tf-drag-ghost.is-dragging { display:flex !important; }
        #tf-drag-ghost img { width:100% !important; height:100% !important; object-fit:contain !important; }
        #tf-drag-ghost span { font-size:36px !important; line-height:1 !important; }

        /* Önálló Rejtvények (Kriptex, Mérleg, Asztrolábium) */
        .tf-standalone-puzzle { background:#e3d2b3 !important; border:2px solid #846635 !important; box-shadow:inset 0 0 15px rgba(62,38,21,0.3), 0 6px 12px rgba(0,0,0,0.4) !important; padding:16px !important; margin:16px auto !important; text-align:center !important; border-radius:4px !important; max-width:320px !important; position:relative !important; overflow:hidden !important; font-family:Georgia, serif !important; }
        .tf-puzzle-title { font-family:"Uncial Antiqua", Georgia, serif !important; font-size:14px !important; color:#3e2615 !important; margin:0 0 12px 0 !important; text-transform:uppercase !important; letter-spacing:1px !important; border-bottom:1px solid rgba(132,102,53,0.4) !important; padding-bottom:6px !important; }
        
        .tf-cryptex-assembly { display:inline-flex !important; gap:4px !important; background:linear-gradient(180deg, #1e130b 0%, #382416 50%, #1e130b 100%) !important; border:2px solid #846635 !important; padding:8px 12px !important; border-radius:4px !important; margin-bottom:12px !important; user-select:none !important; box-shadow:inset 0 0 10px rgba(0,0,0,0.8) !important; }
        .tf-cryptex-wheel { width:28px !important; height:60px !important; background:linear-gradient(180deg, #5a4224 0%, #c8a464 25%, #f3e0b5 50%, #c8a464 75%, #5a4224 100%) !important; border-left:1px solid #3a2612 !important; border-right:1px solid #3a2612 !important; box-shadow:inset 0 8px 8px rgba(0,0,0,0.6), inset 0 -8px 8px rgba(0,0,0,0.6) !important; display:flex !important; flex-direction:column !important; align-items:center !important; justify-content:space-between !important; padding:2px 0 !important; box-sizing:border-box !important; cursor:ns-resize !important; touch-action:none !important; border-radius:2px !important; position:relative !important; }
        .tf-cryptex-wheel::before { content:"" !important; position:absolute !important; top:19px !important; left:0 !important; right:0 !important; height:22px !important; border-top:1px solid rgba(122,28,28,0.5) !important; border-bottom:1px solid rgba(122,28,28,0.5) !important; pointer-events:none !important; }
        .tf-wheel-prev, .tf-wheel-next { font-size:10px !important; line-height:16px !important; color:rgba(35,23,13,0.5) !important; pointer-events:none !important; }
        .tf-wheel-curr { font-family:"Uncial Antiqua", Georgia, serif !important; font-size:15px !important; line-height:20px !important; font-weight:bold !important; color:#1b0f08 !important; pointer-events:none !important; }

        .tf-merleg-structure { position:relative !important; height:120px !important; margin:10px auto !important; width:220px !important; }
        .tf-merleg-base { position:absolute !important; bottom:0 !important; left:50% !important; transform:translateX(-50%) !important; width:20px !important; height:100px !important; background:linear-gradient(90deg, #b8860b 0%, #daa520 50%, #b8860b 100%) !important; border-radius:4px 4px 0 0 !important; border:1px solid #6b4c06 !important; box-shadow:2px 2px 6px rgba(0,0,0,0.4) !important; }
        .tf-merleg-base::after { content:"" !important; position:absolute !important; bottom:0 !important; left:-20px !important; width:60px !important; height:10px !important; background:#5a4224 !important; border-radius:4px !important; }
        .tf-merleg-arm { position:absolute !important; top:20px !important; left:10px !important; right:10px !important; height:6px !important; background:#846635 !important; border:1px solid #3e2615 !important; border-radius:3px !important; transform-origin:center center !important; transition:transform 0.4s cubic-bezier(0.4, 0, 0.2, 1) !important; display:flex !important; justify-content:space-between !important; z-index:2 !important; }
        .tf-merleg-pan-left, .tf-merleg-pan-right { position:relative !important; width:40px !important; height:6px !important; background:#b8860b !important; border-radius:0 0 20px 20px !important; top:6px !important; display:flex !important; flex-wrap:wrap-reverse !important; align-content:flex-start !important; justify-content:center !important; padding-top:4px !important; gap:2px !important; min-height:10px !important; }
        .tf-merleg-pan-left::before, .tf-merleg-pan-right::before { content:"" !important; position:absolute !important; top:-40px !important; left:19px !important; width:2px !important; height:40px !important; background:#846635 !important; }
        .tf-merleg-pan-right.is-drop-target { filter:drop-shadow(0 0 8px #d4af37) !important; }
        .tf-merleg-inventory { display:flex !important; justify-content:center !important; gap:8px !important; margin-top:20px !important; min-height:40px !important; padding:10px !important; background:rgba(62,38,21,0.1) !important; border-radius:4px !important; border:1px dashed rgba(132,102,53,0.4) !important; }
        .tf-weight-item { width:24px !important; height:24px !important; background:radial-gradient(circle, #555 0%, #222 100%) !important; border:2px solid #111 !important; border-radius:50% 50% 2px 2px !important; color:#fff !important; font-size:11px !important; font-family:monospace !important; display:flex !important; align-items:center !important; justify-content:center !important; cursor:grab !important; touch-action:none !important; box-shadow:0 3px 5px rgba(0,0,0,0.5) !important; }
        .tf-weight-item.is-placed { position:relative !important; top:0 !important; left:0 !important; cursor:pointer !important; margin:1px !important; }
        .tf-merleg-target-weight { width:28px !important; height:28px !important; background:radial-gradient(circle, #ffd700 0%, #daa520 100%) !important; border-radius:50% !important; border:2px solid #b8860b !important; display:flex !important; align-items:center !important; justify-content:center !important; font-size:16px !important; color:#fff !important; font-weight:bold !important; }
        .tf-merleg-target-weight::after { content:"⚜" !important; }

        .tf-astrolabe-rings { position:relative !important; width:160px !important; height:160px !important; margin:10px auto !important; border-radius:50% !important; background:radial-gradient(circle, #1a100a 0%, #3e2615 100%) !important; box-shadow:inset 0 0 20px #000, 0 8px 16px rgba(0,0,0,0.6) !important; border:4px solid #846635 !important; display:flex !important; align-items:center !important; justify-content:center !important; }
        .tf-astro-ring { position:absolute !important; border-radius:50% !important; border:2px dashed rgba(212,175,55,0.4) !important; transition:transform 0.3s ease !important; cursor:pointer !important; display:flex !important; align-items:center !important; justify-content:center !important; box-shadow:inset 0 0 10px rgba(0,0,0,0.5) !important; }
        .tf-astro-outer { width:140px !important; height:140px !important; border-width:6px !important; border-style:double !important; border-color:#b8860b !important; }
        .tf-astro-middle { width:96px !important; height:96px !important; border-width:4px !important; border-style:solid !important; border-color:#846635 !important; }
        .tf-astro-inner { width:52px !important; height:52px !important; border-style:dotted !important; border-color:#daa520 !important; background:#22140a !important; }
        .tf-astro-pointer { position:absolute !important; top:0 !important; left:50% !important; transform:translateX(-50%) !important; width:4px !important; height:50% !important; background:rgba(255,255,255,0.1) !important; border-left:1px solid rgba(212,175,55,0.8) !important; pointer-events:none !important; z-index:10 !important; }
        .tf-astro-ring::before { content:"☾" !important; position:absolute !important; top:-10px !important; font-size:16px !important; color:#d4af37 !important; text-shadow:0 0 4px #000 !important; }
        .tf-astro-middle::before { content:"☼" !important; top:-6px !important; }
        .tf-astro-inner::before { content:"✧" !important; top:-2px !important; }

        /* PERGAMEN MODÁL */
        #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:410px !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; cursor:pointer !important; }
        .tf-modal-img-wrap { width:104px !important; height:104px !important; margin:0 auto 10px auto !important; perspective:600px !important; user-select:none !important; }
        .tf-modal-flip-inner { width:100% !important; height:100% !important; position:relative !important; transform-style:preserve-3d !important; transition:transform 0.65s cubic-bezier(0.4, 0.2, 0.2, 1) !important; }
        .tf-modal-flip-inner.is-flipped { transform:rotateY(180deg) !important; }
        .tf-modal-face { position:absolute !important; inset:0 !important; border:1px #7C6952 dashed !important; background:#382416 !important; padding:5px !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; backface-visibility:hidden !important; -webkit-backface-visibility:hidden !important; overflow:hidden !important; }
        .tf-modal-face-front img, .tf-modal-face-back img { width:100% !important; height:100% !important; object-fit:contain !important; display:block !important; }
        .tf-modal-face-front span { font-size:42px !important; filter:sepia(0.5) !important; }
        .tf-modal-face-back { transform:rotateY(180deg) !important; background:radial-gradient(circle, #2b1b10 0%, #170d07 100%) !important; color:#d8c3a5 !important; font-family:"Estonia", Georgia, cursive !important; font-size:18px !important; line-height:16px !important; text-align:center !important; padding:8px !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:10px !important; min-height:36px !important; }
        .tf-modal-pager { display:flex !important; align-items:center !important; justify-content:space-between !important; margin:6px 0 10px 0 !important; padding:4px 0 !important; border-top:1px dotted rgba(132, 102, 53, 0.45) !important; font-family:"Uncial Antiqua", Georgia, serif !important; font-size:10px !important; color:#4a3423 !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-monocle-lens { position:fixed !important; top:-200px; left:-200px; width:124px !important; height:124px !important; margin-left:-62px !important; margin-top:-62px !important; border-radius:50% !important; border:3px solid #846635 !important; box-shadow:0 0 0 2px #2b1a0e, inset 0 0 18px rgba(132, 102, 53, 0.55), 0 10px 24px rgba(0, 0, 0, 0.55) !important; background:radial-gradient(circle at 30% 30%, rgba(255, 248, 231, 0.22) 0%, rgba(218, 190, 140, 0.18) 65%, rgba(62, 38, 21, 0.38) 100%) !important; backdrop-filter:sepia(0.38) contrast(1.18) brightness(1.06) !important; -webkit-backdrop-filter:sepia(0.38) contrast(1.18) brightness(1.06) !important; pointer-events:none !important; z-index:9999998 !important; display:none; }
        #tf-monocle-lens.is-active { display:block !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":"13d431d73a","is_logged_in":false,"items":{"36":{"id":36,"title":"R\u00e9gi R\u00e9zkulcs","type":"tool","emoji":"\ud83d\udddd","image":"","hint":"Valahol egy poros sarokban lapul...","reward_text":"A polcon h\u00fazd r\u00e1 a Z\u00e1rt Bor\u00edt\u00e9kra!","back_text":"A kulcsba v\u00e9sett sz\u00f3: BAGOLY","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"Valahol egy poros sarokban lapul..."},"37":{"id":37,"title":"Viaszpecs\u00e9tes Bor\u00edt\u00e9k","type":"locked","emoji":"\u2709","image":"","hint":"Z\u00e1rt bor\u00edt\u00e9k. H\u00fazd r\u00e1 a megfelel\u0151 kulcsot a K\u00f3dexben!","reward_text":"A bor\u00edt\u00e9kban egy elfeledett, t\u00f6bboldalas k\u00e9zirat lapult.\n---\nII. oldal: \u201eAki az \u00c9jjell\u00e1t\u00f3 Elix\u00edrt k\u00edv\u00e1nja megf\u0151zni, h\u00fazzon egym\u00e1s mell\u00e9 Sz\u00e1r\u00edtott Holdf\u00fcvet \u00e9s Por\u00edtott Borosty\u00e1nt a M\u0171hely asztal\u00e1n...\u201d\n---\nIII. oldal: \u201eAz \u00c1loml\u00e1t\u00f3 F\u0151zethez k\u00e9t r\u00e9sz Sz\u00e1r\u00edtott Holdf\u0171 \u00e9s egy \u00c9jf\u00e9li Harmatgomba sz\u00fcks\u00e9ges.\u201d","back_text":"R\u00f3mai sz\u00e1mmal a bor\u00edt\u00e9k h\u00e1tulj\u00e1n: MDCCCXCVIII","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"AURORA15","req_item_id":36,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"Z\u00e1rt bor\u00edt\u00e9k. H\u00fazd r\u00e1 a megfelel\u0151 kulcsot a K\u00f3dexben!"},"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.","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":true,"is_monocle":false,"ink_clue":"F\u00e9nye l\u00e1that\u00f3v\u00e1 teszi a l\u00e1thatatlan tint\u00e1t."},"39":{"id":39,"title":"Hajnali Harmatcsepp","type":"daily","emoji":"\u2727","image":"","hint":"Minden nap \u00fajragy\u0171jthet\u0151 esszencia.","reward_text":"Tiszta esszencia, amellyel az alv\u00f3 n\u00f6v\u00e9nyeket t\u00e1pl\u00e1lhatod a M\u0171helyben.","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":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.","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":3,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":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.","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":3,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"\u00cdrd be a helyes jelsz\u00f3t (BAGOLY) a fi\u00f3kod \u00cdr\u00f3g\u00e9p\u00e9be!"},"51":{"id":51,"title":"Cseresznyefa Nagy\u00edt\u00f3 & M\u00e9cses","type":"tool","emoji":"\ud83d\udd0d","image":"","hint":"F\u00e9nye \u00e9s lencs\u00e9je l\u00e1that\u00f3v\u00e1 teszi a rejtett sorokat.","reward_text":"K\u00fcl\u00f6nleges optikai lencse \u00e9s m\u00e9cses. Felfedi a [titkos_tinta] \u00e9s [titkos_parazs] sorokat, ha pedig k\u00e9zbe veszed, a [titkos_vizjel] jegyzeteket is kibogar\u00e1szhatod vele!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":true,"is_monocle":true,"ink_clue":"F\u00e9nye \u00e9s lencs\u00e9je l\u00e1that\u00f3v\u00e1 teszi a rejtett sorokat."},"52":{"id":52,"title":"Alv\u00f3 Holdvir\u00e1g Mag","type":"evolving","emoji":"\ud83c\udf30","image":"","hint":"H\u00e1rom csepp Hajnali Harmatra van sz\u00fcks\u00e9ge.","reward_text":"A Holdvir\u00e1g teljes pomp\u00e1j\u00e1ban kiny\u00edlt! Ez\u00fcst\u00f6s szirmai k\u00f6z\u00f6tt egy \u0151si feljegyz\u00e9s v\u00e1lt olvashat\u00f3v\u00e1.","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":3,"evolved_title":"Kiny\u00edlt Ez\u00fcst Holdvir\u00e1g","evolved_emoji":"\ud83c\udf38","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"H\u00e1rom csepp Hajnali Harmatra van sz\u00fcks\u00e9ge."},"53":{"id":53,"title":"T\u00f6r\u00f6tt Ir\u00e1nyt\u0171 H\u00e1z","type":"fragment","emoji":"\u2699","image":"","hint":"Egy r\u00e9gi m\u0171szer egyik fele.","reward_text":"S\u00e1rgar\u00e9z ir\u00e1nyt\u0171h\u00e1z, amelyb\u0151l hi\u00e1nyzik a m\u00e1gnest\u0171.","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"Egy r\u00e9gi m\u0171szer egyik fele."},"54":{"id":54,"title":"M\u00e1gnesezett Csillagt\u0171","type":"fragment","emoji":"\ud83e\udded","image":"","hint":"Egy r\u00e9gi m\u0171szer m\u00e1sik fele.","reward_text":"Finoman megmunk\u00e1lt ac\u00e9lt\u0171. Csoportos\u00edtsd a h\u00e1z\u00e1val a M\u0171helyben!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"Egy r\u00e9gi m\u0171szer m\u00e1sik fele."},"55":{"id":55,"title":"Asztr\u00e1lis Ir\u00e1nyt\u0171","type":"craftable","emoji":"\u2638","image":"","hint":"A M\u0171helyben \u00e1ll\u00edthat\u00f3 \u00f6ssze k\u00e9t t\u00f6red\u00e9kb\u0151l.","reward_text":"Sikeresen \u00f6sszeillesztetted a polcon!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[67,68],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"A M\u0171helyben \u00e1ll\u00edthat\u00f3 \u00f6ssze k\u00e9t t\u00f6red\u00e9kb\u0151l."},"56":{"id":56,"title":"Sz\u00e1r\u00edtott Holdf\u0171","type":"ingredient","emoji":"\ud83c\udf3f","image":"","hint":"Ez\u00fcst\u00f6sen csillog\u00f3 gy\u00f3gyn\u00f6v\u00e9ny.","reward_text":"Dobd az \u00fcstbe!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"Ez\u00fcst\u00f6sen csillog\u00f3 gy\u00f3gyn\u00f6v\u00e9ny."},"57":{"id":57,"title":"Por\u00edtott Borosty\u00e1n","type":"ingredient","emoji":"\u26b1","image":"","hint":"Aranyl\u00f3 \u00e1sv\u00e1nyi \u0151rlem\u00e9ny.","reward_text":"Finomra \u0151r\u00f6lt feny\u0151gyanta-k\u0151zet. M\u00e1s alapanyagokkal csoportos\u00edtva elix\u00edrr\u00e9 f\u0151zhet\u0151.","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"Aranyl\u00f3 \u00e1sv\u00e1nyi \u0151rlem\u00e9ny."},"58":{"id":58,"title":"\u00c9jf\u00e9li Harmatgomba","type":"ingredient","emoji":"\ud83c\udf44","image":"","hint":"S\u00f6t\u00e9tben dereng\u0151 apr\u00f3 kalapos gomba.","reward_text":"Ritka, k\u00e9kesen dereng\u0151 gomba. K\u00e9t Sz\u00e1r\u00edtott Holdf\u0171vel kombin\u00e1lva \u00c1loml\u00e1t\u00f3 F\u0151zet k\u00e9sz\u00edthet\u0151 bel\u0151le.","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"S\u00f6t\u00e9tben dereng\u0151 apr\u00f3 kalapos gomba."},"59":{"id":59,"title":"\u00c9jjell\u00e1t\u00f3 Elix\u00edr","type":"potion","emoji":"\ud83e\uddea","image":"","hint":"A M\u0171helyben f\u0151zhet\u0151 b\u00e1jital (Sz\u00e1r\u00edtott Holdf\u0171 + Por\u00edtott Borosty\u00e1n).","reward_text":"Sikeresen megf\u0151zted az \u00c9jjell\u00e1t\u00f3 Elix\u00edrt! A fiol\u00e1ban s\u0171r\u0171, csillagf\u00e9ny\u0171 folyad\u00e9k \u00f6rv\u00e9nylik.","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[56,57],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"A M\u0171helyben f\u0151zhet\u0151 b\u00e1jital (Sz\u00e1r\u00edtott Holdf\u0171 + Por\u00edtott Borosty\u00e1n)."},"60":{"id":60,"title":"\u00c1loml\u00e1t\u00f3 F\u0151zet","type":"potion","emoji":"\u2697","image":"","hint":"A M\u0171helyben f\u0151zhet\u0151 elix\u00edr (2x Sz\u00e1r\u00edtott Holdf\u0171 + 1x \u00c9jf\u00e9li Harmatgomba).","reward_text":"Elk\u00e9sz\u00fclt a f\u0151zet az \u00fcstben!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[56,56,69],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"A M\u0171helyben f\u0151zhet\u0151 elix\u00edr (2x Sz\u00e1r\u00edtott Holdf\u0171 + 1x \u00c9jf\u00e9li Harmatgomba)."},"61":{"id":61,"title":"Titkos Rekesz","type":"code_locked","emoji":"\ud83d\udcdc","image":"","hint":"BAGOLY","reward_text":"A Kriptex t\u00e1rcs\u00e1i a hely\u00fckre \u00e1lltak! Megtal\u00e1ltad a rejtett napl\u00f3bejegyz\u00e9st.","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"BAGOLY"},"62":{"id":62,"title":"Rejtett Fi\u00f3k Kincse","type":"simple","emoji":"\ud83c\udffa","image":"","hint":"A titkos kopogtat\u00e1s jutalma.","reward_text":"A helyes ritmus\u00fa kopogtat\u00e1sra kipattant az \u00edr\u00f3asztal rejtett oldalfi\u00f3kja!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"A titkos kopogtat\u00e1s jutalma."},"63":{"id":63,"title":"Z\u00e1rt Bor\u00edt\u00e9k","type":"locked","emoji":"\u2709","image":"","hint":"","reward_text":"Titkos k\u00e9zirat.\n---\n\u201eAz \u00c1loml\u00e1t\u00f3 F\u0151zethez: T\u00f6rj \u00f6ssze egy Holdkrist\u00e1lyt a mozs\u00e1rban, majd dobd a por\u00e1t k\u00e9t Holdf\u0171vel egy\u00fctt az \u00fcstbe!\u201d","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":36,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":""},"64":{"id":64,"title":"Nagy\u00edt\u00f3 & M\u00e9cses","type":"tool","emoji":"\ud83d\udd0d","image":"","hint":"","reward_text":"Felfedi a [titkos_tinta] \u00e9s [titkos_parazs] sorokat, k\u00e9zbe v\u00e9ve a [titkos_vizjel]-et is!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":true,"is_monocle":true,"ink_clue":""},"65":{"id":65,"title":"Hajnali Harmat","type":"daily","emoji":"\u2727","image":"","hint":"","reward_text":"Az asztalr\u00f3l h\u00fazd r\u00e1 a polcon l\u00e9v\u0151 alv\u00f3 magra!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":""},"66":{"id":66,"title":"Alv\u00f3 Mag","type":"evolving","emoji":"\ud83c\udf30","image":"","hint":"","reward_text":"Kiny\u00edlt!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":3,"evolved_title":"Kiny\u00edlt Vir\u00e1g","evolved_emoji":"\ud83c\udf38","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":""},"67":{"id":67,"title":"T\u00f6r\u00f6tt Ir\u00e1nyt\u0171","type":"fragment","emoji":"\u2699","image":"","hint":"","reward_text":"H\u00fazd r\u00e1 a Csillagt\u0171re a polcon!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":""},"68":{"id":68,"title":"Csillagt\u0171","type":"fragment","emoji":"\ud83e\udded","image":"","hint":"","reward_text":"H\u00fazd \u00f6ssze a T\u00f6r\u00f6tt Ir\u00e1nyt\u0171vel a polcon!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":""},"69":{"id":69,"title":"Krist\u00e1lypor","type":"ingredient","emoji":"\u2728","image":"","hint":"","reward_text":"Mozs\u00e1rban finomra \u0151r\u00f6lt krist\u00e1ly. Dobd az \u00fcstbe!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":""},"70":{"id":70,"title":"Nyers Holdkrist\u00e1ly","type":"crushable","emoji":"\ud83d\udc8e","image":"","hint":"","reward_text":"H\u00fazd az asztalon l\u00e9v\u0151 mozs\u00e1rba, \u00e9s koppints r\u00e1 3-szor!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":69,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":""},"71":{"id":71,"title":"Titkos Rekesz (Kriptexhez)","type":"code_locked","emoji":"\ud83d\udcdc","image":"","hint":"","reward_text":"A Kriptex kinyitotta!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"BAGOLY"},"72":{"id":72,"title":"Csillagkapu (Asztrol\u00e1biumhoz)","type":"locked","emoji":"\ud83c\udf0c","image":"","hint":"","reward_text":"Az Asztrol\u00e1bium kinyitotta!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":""},"73":{"id":73,"title":"Arany Fi\u00f3k (M\u00e9rleghez)","type":"locked","emoji":"\ud83c\udffa","image":"","hint":"","reward_text":"A M\u00e9rleg kiegyens\u00falyoz\u00e1sa kinyitotta!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"crush_result_id":0,"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":""}},"initial_state":{"collected":[],"unlocked_locks":[],"evolved":[],"feed_counts":[],"ingredients":[],"essence":0,"last_daily":"","server_rev":0}};
            const CRYPTEX_CHARS = ['·','A','Á','B','C','D','E','É','F','G','H','I','Í','J','K','L','M','N','O','Ó','Ö','Ő','P','Q','R','S','T','U','Ú','Ü','Ű','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9'];
            const itemsDB = TF_Config.items || {};
            let userState = normalizeState(TF_Config.initial_state);
            let activeMonocleId = 0;
            
            // Lokális kísérleti állapotok
            let cauldronContents = [];
            let mortarContent = null;
            let mortarHits = 0;
            
            let lastMouseX = -1000;
            let lastMouseY = -1000;

            function getEmptyState() { return { collected: [], unlocked_locks: [], evolved: [], feed_counts: {}, ingredients: {}, essence: 0, last_daily: '', server_rev: 0 }; }
            function normalizeState(rawState) {
                const st = Object.assign(getEmptyState(), rawState || {});
                st.collected = (st.collected || []).map(Number);
                st.unlocked_locks = (st.unlocked_locks || []).map(Number);
                st.evolved = (st.evolved || []).map(Number);
                if (!st.ingredients || typeof st.ingredients !== 'object') st.ingredients = {};
                return st;
            }
            function applyServerState(state) {
                userState = normalizeState(state);
                refreshAllUI();
            }

            function getIngredientCount(itemId) { return (userState.ingredients && userState.ingredients[itemId]) ? Number(userState.ingredients[itemId]) : 0; }
            function isLockOpened(item) { return !item || item.type !== 'locked' || userState.unlocked_locks.includes(Number(item.id)); }
            function isItemEvolved(item) { return !item || item.type !== 'evolving' || userState.evolved.includes(Number(item.id)); }
            function getDisplayTitle(item) { return (item.type === 'evolving' && isItemEvolved(item) && item.evolved_title) ? item.evolved_title : item.title; }
            function getDisplayImage(item) { return (item.type === 'evolving' && isItemEvolved(item) && item.evolved_image) ? item.evolved_image : item.image; }
            function getDisplayEmoji(item) { return (item.type === 'evolving' && isItemEvolved(item) && item.evolved_emoji) ? item.evolved_emoji : item.emoji; }

            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 === '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 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 ensureMonocleLens() {
                let lens = document.getElementById('tf-monocle-lens');
                if (!lens) { lens = document.createElement('div'); lens.id = 'tf-monocle-lens'; document.body.appendChild(lens); }
                return lens;
            }

            function toggleMonocle(itemId) {
                const lens = ensureMonocleLens();
                if (activeMonocleId === Number(itemId)) {
                    activeMonocleId = 0; lens.classList.remove('is-active');
                    document.querySelectorAll('.tf-watermark.tf-watermark-revealed').forEach(el => el.classList.remove('tf-watermark-revealed'));
                } else {
                    activeMonocleId = Number(itemId); lens.classList.add('is-active');
                }
                triggerSfx('turn'); refreshAllUI();
            }

            // Drag & Drop Motor (Szertár)
            let dragContext = null;
            function ensureDragGhost() {
                let g = document.getElementById('tf-drag-ghost');
                if (!g) { g = document.createElement('div'); g.id = 'tf-drag-ghost'; document.body.appendChild(g); }
                return g;
            }

            function startCustomDrag(e, mode, itemId) {
                if (itemId !== 'essence') {
                    const item = itemsDB[itemId];
                    if (!item) return;
                }
                e.preventDefault(); e.stopPropagation();
                const ghost = ensureDragGhost();
                if (itemId === 'essence') {
                    ghost.innerHTML = '<span style="font-size:36px;">✧</span>';
                } else {
                    const item = itemsDB[itemId];
                    const dImg = getDisplayImage(item);
                    ghost.innerHTML = dImg ? '<img src="' + dImg + '" alt="">' : '<span>' + getDisplayEmoji(item) + '</span>';
                }
                ghost.style.left = e.clientX + 'px'; ghost.style.top = e.clientY + 'px';
                ghost.classList.add('is-dragging');
                dragContext = { mode: mode, itemId: itemId };
            }

            document.addEventListener('pointermove', function(e) {
                lastMouseX = e.clientX; lastMouseY = e.clientY;
                if (!dragContext) return;
                const ghost = ensureDragGhost();
                ghost.style.left = e.clientX + 'px'; ghost.style.top = e.clientY + 'px';

                document.querySelectorAll('.is-drop-target').forEach(el => el.classList.remove('is-drop-target'));
                const under = document.elementFromPoint(e.clientX, e.clientY);
                if (!under) return;

                if (dragContext.itemId === 'essence') {
                    const evRow = under.closest('.tf-placed-item[data-type="evolving"]');
                    if (evRow) evRow.classList.add('is-drop-target');
                } else {
                    const item = itemsDB[dragContext.itemId];
                    if (item.type === 'tool') {
                        const lockedRow = under.closest('.tf-placed-item[data-type="locked"].is-locked');
                        if (lockedRow) lockedRow.classList.add('is-drop-target');
                    } else if (item.type === 'fragment') {
                        const fragRow = under.closest('.tf-placed-item[data-type="fragment"]');
                        if (fragRow && Number(fragRow.dataset.itemId) !== item.id) fragRow.classList.add('is-drop-target');
                    } else if (item.type === 'crushable') {
                        const mortar = under.closest('.tf-mortar');
                        if (mortar && !mortarContent) mortar.classList.add('is-drop-target');
                    } else if (item.type === 'ingredient') {
                        const cauldron = under.closest('.tf-cauldron');
                        if (cauldron) cauldron.classList.add('is-drop-target');
                    }
                }
            });

            document.addEventListener('pointerup', function(e) {
                if (!dragContext) return;
                const ctx = dragContext; dragContext = null;
                const ghost = ensureDragGhost();
                ghost.classList.remove('is-dragging');
                document.querySelectorAll('.is-drop-target').forEach(el => el.classList.remove('is-drop-target'));
                const under = document.elementFromPoint(e.clientX, e.clientY);

                if (ctx.itemId === 'essence') {
                    const evRow = under ? under.closest('.tf-placed-item[data-type="evolving"]') : null;
                    if (evRow) {
                        const tId = Number(evRow.dataset.itemId);
                        sendAction('feed', tId, {}, (resData) => {
                            triggerSfx('collect');
                            if (resData && resData.state && resData.state.evolved.includes(tId) && itemsDB[tId]) openItemModal(itemsDB[tId]);
                        });
                    }
                } else {
                    const item = itemsDB[ctx.itemId];
                    if (item.type === 'tool') {
                        const lockedRow = under ? under.closest('.tf-placed-item[data-type="locked"].is-locked') : null;
                        if (lockedRow) {
                            const lockedId = Number(lockedRow.dataset.itemId);
                            sendAction('unlock_lock', lockedId, { key_id: ctx.itemId }, () => {
                                if (itemsDB[lockedId]) openItemModal(itemsDB[lockedId]);
                            }, null, true);
                        }
                    } else if (item.type === 'fragment') {
                        const fragRow = under ? under.closest('.tf-placed-item[data-type="fragment"]') : null;
                        if (fragRow) {
                            const otherId = Number(fragRow.dataset.itemId);
                            if (otherId !== ctx.itemId) {
                                const selectedSorted = [ctx.itemId, otherId].sort((a, b) => a - b).join(',');
                                const matchedCraftable = Object.values(itemsDB).find(it => it.type === 'craftable' && Array.isArray(it.req_fragments) && [...it.req_fragments].map(Number).sort((a,b)=>a-b).join(',') === selectedSorted);
                                if (matchedCraftable) {
                                    sendAction('craft', Number(matchedCraftable.id), {}, () => {
                                        triggerSfx('collect'); openItemModal(itemsDB[matchedCraftable.id]);
                                    });
                                }
                            }
                        }
                    } else if (item.type === 'crushable') {
                        const mortar = under ? under.closest('.tf-mortar') : null;
                        if (mortar && !mortarContent) {
                            mortarContent = item.id; mortarHits = 0;
                            triggerSfx('turn'); renderSzertar();
                        }
                    } else if (item.type === 'ingredient') {
                        const cauldron = under ? under.closest('.tf-cauldron') : null;
                        if (cauldron) {
                            cauldronContents.push(item.id);
                            triggerSfx('turn'); renderSzertar(); checkCauldronBrew();
                        }
                    }
                }
            });

            function checkCauldronBrew() {
                if (cauldronContents.length < 2) return;
                const sortedIds = [...cauldronContents].sort((a, b) => a - b).join(',');
                const matchedPotion = Object.values(itemsDB).find(it => it.type === 'potion' && Array.isArray(it.req_fragments) && [...it.req_fragments].map(Number).sort((a,b)=>a-b).join(',') === sortedIds);
                if (matchedPotion) {
                    const stirBtn = document.querySelector('.tf-cauldron-stir-btn');
                    if (stirBtn) stirBtn.classList.remove('tf-hidden');
                    const pourBtn = document.querySelector('.tf-cauldron-pour-btn');
                    if (pourBtn) pourBtn.classList.add('tf-hidden');
                } else if (cauldronContents.length > 3) {
                    const pourBtn = document.querySelector('.tf-cauldron-pour-btn');
                    if (pourBtn) pourBtn.classList.remove('tf-hidden');
                }
            }

            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-pager" id="tf-modal-pager" style="display:none;"></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 = isItemEvolved(item);
                const dTitle = getDisplayTitle(item); const dImg = getDisplayImage(item); const dEmoji = getDisplayEmoji(item);
                const imgWrap = modal.querySelector('#tf-modal-img');
                const frontHtml = dImg ? '<img src="' + dImg + '" alt="" draggable="false">' : '<span>' + dEmoji + '</span>';
                const hasBack = isEvolved && Boolean((item.back_text && item.back_text.trim()) || (item.back_image && item.back_image.trim()));
                const backHtml = item.back_image ? '<img src="' + item.back_image + '" alt="" draggable="false">' : '<div>' + (item.back_text || '') + '</div>';
                imgWrap.innerHTML = '<div class="tf-modal-flip-inner"><div class="tf-modal-face tf-modal-face-front">' + frontHtml + '</div><div class="tf-modal-face tf-modal-face-back">' + backHtml + '</div></div>';
                imgWrap.onclick = function(e) { if (!hasBack) return; e.preventDefault(); e.stopPropagation(); const flipInner = imgWrap.querySelector('.tf-modal-flip-inner'); if (flipInner) { triggerSfx('turn'); flipInner.classList.toggle('is-flipped'); } };
                modal.querySelector('#tf-modal-title').textContent = dTitle;
                const descEl = modal.querySelector('#tf-modal-desc'); const pagerEl = modal.querySelector('#tf-modal-pager');
                const fed = (userState.feed_counts && userState.feed_counts[item.id]) ? userState.feed_counts[item.id] : 0;
                const qty = getIngredientCount(item.id);
                let rawText = item.reward_text || 'Megtalált ereklye.';
                if (!isEvolved) rawText = 'Ez az ereklye még szunnyad. Tápláld Esszenciával (' + fed + ' / ' + item.req_essence + ').';
                if (item.type === 'ingredient') rawText += '\n\n(Készleten: ' + qty + ' db)';
                if (item.type === 'crushable') rawText += '\n\nEzt a kristályt a Mozsárba kell dobnod, hogy össze tudd törni!';
                
                const pages = rawText.split(/\n?\s*---\s*\n?/).map(p => p.trim()).filter(Boolean);
                let currentPage = 0;
                function renderModalPage() {
                    descEl.innerHTML = (pages[currentPage] || '').replace(/\n/g, '<br>');
                    if (pages.length > 1) {
                        pagerEl.style.display = 'flex';
                        pagerEl.innerHTML = '<button type="button" class="tf-vintage-btn tf-page-prev" ' + (currentPage === 0 ? 'disabled style="opacity:0.4;"' : '') + '>◀ Előző</button><span>' + (currentPage + 1) + ' / ' + pages.length + '. oldal</span><button type="button" class="tf-vintage-btn tf-page-next" ' + (currentPage === pages.length - 1 ? 'disabled style="opacity:0.4;"' : '') + '>Következő ▶</button>';
                        const prevBtn = pagerEl.querySelector('.tf-page-prev'); const nextBtn = pagerEl.querySelector('.tf-page-next');
                        if (prevBtn && currentPage > 0) prevBtn.addEventListener('click', () => { currentPage--; triggerSfx('turn'); renderModalPage(); });
                        if (nextBtn && currentPage < pages.length - 1) nextBtn.addEventListener('click', () => { currentPage++; triggerSfx('turn'); renderModalPage(); });
                    } else { pagerEl.style.display = 'none'; pagerEl.innerHTML = ''; }
                }
                renderModalPage();

                const rewardsBox = modal.querySelector('#tf-modal-rewards'); rewardsBox.innerHTML = '';
                if (isEvolved) {
                    if (item.is_monocle) {
                        const monoBtn = document.createElement('button'); monoBtn.type = 'button';
                        const isEquipped = activeMonocleId === Number(item.id);
                        monoBtn.className = 'tf-vintage-btn ' + (isEquipped ? 'is-equipped' : '');
                        monoBtn.textContent = isEquipped ? '✕ Nagyító Elrakása' : '🔍 Nagyító Kézbe Vétele';
                        monoBtn.addEventListener('click', () => { toggleMonocle(item.id); modal.classList.remove('is-open'); });
                        rewardsBox.appendChild(monoBtn);
                    }
                    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'; 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);
                fetch(TF_Config.ajax_url, { method: 'POST', body: formData, credentials: 'same-origin' })
                    .then(r => r.json()).then(res => { if (res.success && res.data && res.data.state) applyServerState(res.data.state); })
                    .catch(() => refreshAllUI());
            }

            function sendAction(actionType, itemId, extra = {}, onSuccess = null, onError = null, silentError = false) {
                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);
                Object.keys(extra).forEach(k => formData.append(k, extra[k]));
                fetch(TF_Config.ajax_url, { method: 'POST', body: formData, credentials: 'same-origin' })
                    .then(r => r.json()).then(res => {
                        if (res.success) { applyServerState(res.data.state); if (onSuccess) onSuccess(res.data); }
                        else { if (!silentError) triggerSfx('turn'); if (onError) onError(res.data); }
                    });
            }

            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 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) {
                            let cl = 0; let tot = 0; const d = ctx.getImageData(0,0,w,h).data;
                            for (let i=3; i<d.length; i+=16) { tot++; if (d[i]<90) cl++; }
                            if (tot>0 && (cl/tot)>=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 r = canvas.getBoundingClientRect(); wipe((e.clientX - r.left) * (canvas.width / r.width), (e.clientY - r.top) * (canvas.height / r.height)); });
                    canvas.addEventListener('mouseleave', () => { lastX = null; lastY = null; });
                    canvas.addEventListener('touchmove', e => { e.preventDefault(); const r = canvas.getBoundingClientRect(); const t = e.touches[0]; wipe((t.clientX - r.left) * (canvas.width / r.width), (t.clientY - r.top) * (canvas.height / r.height)); }, { passive: false });
                });
            }

            function updateCryptexWheelDisplay(wheelEl, newIndex) {
                const len = CRYPTEX_CHARS.length; const idx = ((newIndex % len) + len) % len;
                wheelEl.dataset.index = String(idx);
                const pEl = wheelEl.querySelector('.tf-wheel-prev'); const cEl = wheelEl.querySelector('.tf-wheel-curr'); const nEl = wheelEl.querySelector('.tf-wheel-next');
                if (pEl) pEl.textContent = CRYPTEX_CHARS[(idx - 1 + len) % len];
                if (cEl) cEl.textContent = CRYPTEX_CHARS[idx];
                if (nEl) nEl.textContent = CRYPTEX_CHARS[(idx + 1) % len];
            }

            function initStandalonePuzzles() {
                // Kriptex
                document.querySelectorAll('.tf-cryptex-wheel').forEach(wheel => {
                    if (wheel._tfBound) return; wheel._tfBound = true;
                    let dragging = false; let startY = 0; let totalMoved = 0; let lastWheelStepTime = 0; let wheelDeltaAccum = 0;
                    wheel.addEventListener('pointerdown', e => { e.preventDefault(); e.stopPropagation(); dragging = true; startY = e.clientY; totalMoved = 0; wheel.setPointerCapture(e.pointerId); });
                    wheel.addEventListener('pointermove', e => {
                        if (!dragging) return; e.preventDefault(); e.stopPropagation(); const dy = e.clientY - startY; totalMoved += Math.abs(dy);
                        if (Math.abs(dy) >= 30) { updateCryptexWheelDisplay(wheel, Number(wheel.dataset.index || 0) + (dy > 0 ? -1 : 1)); startY = e.clientY; }
                    });
                    wheel.addEventListener('pointerup', e => {
                        if (!dragging) return; dragging = false; try { wheel.releasePointerCapture(e.pointerId); } catch (err) {}
                        if (totalMoved < 6) {
                            const r = wheel.getBoundingClientRect(); const cy = e.clientY - r.top; const cur = Number(wheel.dataset.index || 0);
                            if (cy < r.height * 0.42) updateCryptexWheelDisplay(wheel, cur - 1); else if (cy > r.height * 0.58) updateCryptexWheelDisplay(wheel, cur + 1);
                        }
                    });
                    wheel.addEventListener('wheel', e => {
                        e.preventDefault(); e.stopPropagation(); const now = performance.now();
                        if (now - lastWheelStepTime < 180) return;
                        wheelDeltaAccum += e.deltaY;
                        if (Math.abs(wheelDeltaAccum) >= 20) { updateCryptexWheelDisplay(wheel, Number(wheel.dataset.index || 0) + (wheelDeltaAccum > 0 ? 1 : -1)); wheelDeltaAccum = 0; lastWheelStepTime = now; }
                    }, { passive: false });
                });

                // Mérleg
                document.querySelectorAll('.tf-merleg-puzzle').forEach(wrap => {
                    if (wrap._tfBound) return; wrap._tfBound = true;
                    const rId = Number(wrap.dataset.rewardId); const target = Number(wrap.dataset.target);
                    const arm = wrap.querySelector('.tf-merleg-arm'); const rightPan = wrap.querySelector('.tf-merleg-pan-right'); const tEl = wrap.querySelector('.tf-merleg-target-weight');
                    if (tEl) tEl.textContent = target;
                    let pDragging = null; let pGhost = null; let pWeight = 0; let placedWeights = [];
                    
                    function updateScale() {
                        const sum = placedWeights.reduce((a,b)=>a+b, 0);
                        const diff = target - sum;
                        const angle = Math.max(-25, Math.min(25, diff * 2));
                        if (arm) arm.style.transform = 'rotate(' + angle + 'deg)';
                        if (sum === target && rId > 0 && !userState.collected.includes(rId)) {
                            sendAction('collect', rId, {}, () => { triggerSfx('collect'); openItemModal(itemsDB[rId]); });
                        }
                    }
                    updateScale();

                    wrap.querySelectorAll('.tf-weight-item').forEach(wi => {
                        wi.addEventListener('pointerdown', e => {
                            e.preventDefault(); e.stopPropagation();
                            pWeight = Number(wi.dataset.weight);
                            if (wi.classList.contains('is-placed')) {
                                const idx = placedWeights.indexOf(pWeight);
                                if (idx>-1) placedWeights.splice(idx, 1);
                                wi.classList.remove('is-placed');
                                wrap.querySelector('.tf-merleg-inventory').appendChild(wi);
                                updateScale();
                                triggerSfx('turn');
                            } else {
                                pDragging = wi;
                                wi.style.position = 'fixed'; wi.style.zIndex = '9999'; wi.style.left = e.clientX-12+'px'; wi.style.top = e.clientY-12+'px';
                                wi.setPointerCapture(e.pointerId);
                            }
                        });
                        wi.addEventListener('pointermove', e => {
                            if (!pDragging) return;
                            e.preventDefault(); e.stopPropagation();
                            wi.style.left = e.clientX-12+'px'; wi.style.top = e.clientY-12+'px';
                            const u = document.elementFromPoint(e.clientX, e.clientY);
                            if (u && u.closest('.tf-merleg-pan-right')) rightPan.classList.add('is-drop-target'); else rightPan.classList.remove('is-drop-target');
                        });
                        wi.addEventListener('pointerup', e => {
                            if (!pDragging) return;
                            e.preventDefault(); e.stopPropagation();
                            pDragging = null; rightPan.classList.remove('is-drop-target');
                            try { wi.releasePointerCapture(e.pointerId); } catch(err){}
                            wi.style.position = ''; wi.style.zIndex = ''; wi.style.left = ''; wi.style.top = '';
                            const u = document.elementFromPoint(e.clientX, e.clientY);
                            if (u && u.closest('.tf-merleg-pan-right')) {
                                placedWeights.push(pWeight); wi.classList.add('is-placed'); rightPan.appendChild(wi); updateScale(); triggerSfx('turn');
                            }
                        });
                    });
                });

                // Asztrolábium
                document.querySelectorAll('.tf-asztrolabium-puzzle').forEach(wrap => {
                    if (wrap._tfBound) return; wrap._tfBound = true;
                    const rId = Number(wrap.dataset.rewardId); const ans = wrap.dataset.code.split(',').map(Number);
                    wrap.querySelectorAll('.tf-astro-ring').forEach(ring => {
                        ring.addEventListener('click', e => {
                            e.preventDefault(); e.stopPropagation();
                            let c = Number(ring.dataset.idx||0); c = (c+1)%12; ring.dataset.idx = c;
                            ring.style.transform = 'rotate(' + (c*30) + 'deg)'; triggerSfx('turn');
                        });
                    });
                    const btn = wrap.querySelector('.tf-astro-check-btn');
                    if (btn) btn.addEventListener('click', e => {
                        e.preventDefault(); e.stopPropagation();
                        const out = Number(wrap.querySelector('.tf-astro-outer').dataset.idx||0);
                        const mid = Number(wrap.querySelector('.tf-astro-middle').dataset.idx||0);
                        const inn = Number(wrap.querySelector('.tf-astro-inner').dataset.idx||0);
                        if (out === ans[0] && mid === ans[1] && inn === ans[2] && rId > 0 && !userState.collected.includes(rId)) {
                            sendAction('collect', rId, {}, () => { triggerSfx('collect'); openItemModal(itemsDB[rId]); });
                        } else {
                            triggerSfx('locked'); wrap.classList.remove('tf-shake'); void wrap.offsetWidth; wrap.classList.add('tf-shake');
                        }
                    });
                });
            }

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

            setInterval(() => {
                if (!hasLanternInCollection()) return;
                document.querySelectorAll('.tf-ember-ink:not(.is-burned)').forEach(el => {
                    const rect = el.getBoundingClientRect(); if (rect.width === 0 && rect.height === 0) return;
                    const cx = rect.left + rect.width / 2; const cy = rect.top + rect.height / 2; const dist = Math.hypot(lastMouseX - cx, lastMouseY - cy);
                    let heat = el._tfHeat || 0;
                    if (dist < 95) heat = Math.min(100, heat + 4.5); else heat = Math.max(0, heat - 3);
                    el._tfHeat = heat;
                    const glowEl = el.querySelector('.tf-ember-glow'); const textEl = el.querySelector('.tf-ember-text');
                    if (glowEl) glowEl.style.opacity = (heat / 100).toFixed(2);
                    if (textEl && heat > 25) { const alpha = ((heat - 25) / 75).toFixed(2); textEl.style.setProperty('color', 'rgba(61, 24, 6, ' + alpha + ')', 'important'); } else if (textEl) { textEl.style.setProperty('color', 'transparent', 'important'); }
                    if (heat >= 100) { el.classList.add('is-burned'); if (glowEl) glowEl.style.opacity = '0'; triggerSfx('dust'); }
                });
            }, 80);

            document.addEventListener('click', function(e) {
                const knocker = e.target.closest('.tf-knocker-box');
                if (knocker) {
                    e.preventDefault(); e.stopPropagation();
                    const now = performance.now(); const expected = (knocker.dataset.pattern || 'R,R,H').split(',').map(s => s.trim()).filter(Boolean);
                    const rewardId = Number(knocker.dataset.rewardId || 0); const dotsEl = knocker.querySelector('.tf-knock-dots');
                    knocker.classList.add('is-knocking'); setTimeout(() => knocker.classList.remove('is-knocking'), 120); triggerSfx('locked');
                    if (!knocker._tfLastKnock || (now - knocker._tfLastKnock) > 1700) {
                        knocker._tfIntervals = []; if (dotsEl) dotsEl.textContent = '•';
                    } else {
                        const dt = now - knocker._tfLastKnock; const symbol = dt < 480 ? 'R' : 'H';
                        knocker._tfIntervals.push(symbol);
                        if (dotsEl) dotsEl.textContent = '•' + knocker._tfIntervals.map(s => s === 'R' ? '•' : '—').join('');
                        if (knocker._tfIntervals.length === expected.length) {
                            const matched = knocker._tfIntervals.join(',') === expected.join(','); knocker._tfLastKnock = 0; knocker._tfIntervals = [];
                            if (matched && rewardId > 0 && !userState.collected.includes(rewardId)) {
                                sendAction('collect', rewardId, {}, () => { if (dotsEl) dotsEl.textContent = '✓'; if (itemsDB[rewardId]) openItemModal(itemsDB[rewardId]); });
                            } else {
                                knocker.classList.remove('tf-shake'); void knocker.offsetWidth; knocker.classList.add('tf-shake'); setTimeout(() => { if (dotsEl) dotsEl.textContent = ''; }, 450);
                            }
                            return;
                        }
                    }
                    knocker._tfLastKnock = now; return;
                }

                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; }
                    if (worldItem.dataset.seal === '1' && !worldItem._tfSealBroken) {
                        let sealEl = worldItem.querySelector('.tf-wax-seal'); worldItem._tfSealHits = (worldItem._tfSealHits || 0) + 1;
                        if (worldItem._tfSealHits < 3) { if (sealEl) sealEl.setAttribute('data-cracks', String(worldItem._tfSealHits)); worldItem.classList.remove('tf-shake'); void worldItem.offsetWidth; worldItem.classList.add('tf-shake'); return; }
                        else { worldItem._tfSealBroken = true; triggerSfx('turn'); if (sealEl) { sealEl.setAttribute('data-cracks', '2'); sealEl.classList.add('is-shattering'); setTimeout(() => sealEl.remove(), 360); } return; }
                    }
                    const id = Number(worldItem.dataset.itemId); const item = itemsDB[id]; if (!item) return;
                    if (item.type === 'code_locked') { bleedInkOnElement(worldItem, item.ink_clue || ' ? ? ? '); return; }
                    sendAction('collect', id, {}, () => {
                        if (item.type !== 'locked') triggerSfx('collect', item.sfx_url);
                        if (item.type === 'ingredient' || item.type === 'crushable') sessionCollected.push(id);
                        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'); }, true);
                    return;
                }

                const codeSubmit = e.target.closest('.tf-kriptex-open-btn');
                if (codeSubmit) {
                    e.preventDefault(); e.stopPropagation();
                    const box = codeSubmit.closest('.tf-kriptex-puzzle');
                    const rId = Number(box.dataset.rewardId);
                    const wheels = box.querySelectorAll('.tf-cryptex-wheel');
                    let val = ''; wheels.forEach(w => { const ch = CRYPTEX_CHARS[Number(w.dataset.index || 0)] || ''; if (ch !== '·') val += ch; });
                    val = val.trim();
                    if (!val) { box.classList.remove('tf-shake'); void box.offsetWidth; box.classList.add('tf-shake'); return; }

                    const expectedCode = itemsDB[rId] ? (itemsDB[rId].ink_clue || '').toUpperCase() : '';
                    if (val === expectedCode && rId > 0 && !userState.collected.includes(rId)) {
                        sendAction('collect', rId, {}, () => {
                            wheels.forEach(w => updateCryptexWheelDisplay(w, 0)); triggerSfx('collect'); openItemModal(itemsDB[rId]);
                        });
                    } else { box.classList.remove('tf-shake'); void box.offsetWidth; box.classList.add('tf-shake'); }
                    return;
                }

                const mortarClick = e.target.closest('.tf-mortar.has-item');
                if (mortarClick && mortarContent) {
                    e.preventDefault(); e.stopPropagation();
                    const mItem = itemsDB[mortarContent];
                    if (!mItem || mItem.type !== 'crushable' || !mItem.crush_result_id) return;
                    mortarHits++; triggerSfx('dust');
                    mortarClick.classList.remove('is-smashing'); void mortarClick.offsetWidth; mortarClick.classList.add('is-smashing');
                    if (mortarHits >= 3) {
                        sendAction('craft', mItem.crush_result_id, { consumed_crushable: mortarContent }, () => {
                            mortarContent = null; mortarHits = 0; triggerSfx('turn'); renderSzertar(); openItemModal(itemsDB[mItem.crush_result_id]);
                        });
                    }
                    return;
                }

                const stirBtn = e.target.closest('.tf-cauldron-stir-btn');
                if (stirBtn) {
                    e.preventDefault(); e.stopPropagation();
                    const sortedIds = [...cauldronContents].sort((a, b) => a - b).join(',');
                    const matchedPotion = Object.values(itemsDB).find(it => it.type === 'potion' && Array.isArray(it.req_fragments) && [...it.req_fragments].map(Number).sort((a,b)=>a-b).join(',') === sortedIds);
                    if (matchedPotion) {
                        sendAction('craft', Number(matchedPotion.id), { consumed_cauldron: cauldronContents.join(',') }, () => {
                            cauldronContents = []; triggerSfx('collect'); renderSzertar(); openItemModal(itemsDB[matchedPotion.id]);
                        });
                    }
                    return;
                }

                const pourBtn = e.target.closest('.tf-cauldron-pour-btn');
                if (pourBtn) {
                    e.preventDefault(); e.stopPropagation();
                    cauldronContents = []; triggerSfx('turn'); renderSzertar();
                    return;
                }
                
                const placedItem = e.target.closest('.tf-placed-item');
                if (placedItem) {
                    e.preventDefault(); e.stopPropagation();
                    const pType = placedItem.dataset.type; const pId = Number(placedItem.dataset.itemId);
                    if (pType !== 'tool' && pType !== 'crushable' && pType !== 'ingredient') {
                        openItemModal(itemsDB[pId]);
                    }
                    return;
                }
            });

            function renderSzertar() {
                const roots = document.querySelectorAll('.tf-szertar-wrapper');
                roots.forEach(root => {
                    const shelfCont = root.querySelector('.tf-shelf-container');
                    if (!shelfCont) return;
                    shelfCont.innerHTML = '';

                    // 1. Polcok: Minden collected tárgy, kivéve daily és crushable (az alapanyagok is itt jelennek meg).
                    const toPlace = Object.values(itemsDB).filter(it => userState.collected.includes(Number(it.id)) && it.type !== 'daily' && it.type !== 'crushable');
                    
                    let rowsHtml = '';
                    for (let i = 0; i < Math.max(3, Math.ceil(toPlace.length / 6)); i++) {
                        let rowItems = toPlace.slice(i*6, (i+1)*6);
                        let rowHtml = '<div class="tf-shelf-row">';
                        rowItems.forEach(it => {
                            const isLocked = (it.type === 'locked' && !isLockOpened(it));
                            const qty = getIngredientCount(it.id);
                            // Ha ingredient/potion, de elfogyott (qty===0), akkor ne mutassuk a polcon
                            if ((it.type === 'ingredient' || it.type === 'potion') && qty <= 0) return;
                            
                            const dImg = getDisplayImage(it);
                            const visual = dImg ? '<img src="' + dImg + '">' : '<span class="tf-emoji-icon">' + getDisplayEmoji(it) + '</span>';
                            const qtyBadge = ((it.type === 'ingredient' || it.type === 'potion') && qty > 1) ? '<span class="tf-qty-badge">×' + qty + '</span>' : '';
                            const dragClass = (it.type === 'tool' || it.type === 'ingredient') ? 'is-draggable-tool' : '';
                            const lockClass = isLocked ? 'is-locked' : '';
                            
                            rowHtml += '<div class="tf-placed-item ' + dragClass + ' ' + lockClass + '" data-item-id="' + it.id + '" data-type="' + it.type + '" title="' + getDisplayTitle(it) + '">'
                                + visual + qtyBadge
                                + '</div>';
                        });
                        rowHtml += '</div>';
                        rowsHtml += rowHtml;
                    }
                    shelfCont.innerHTML = rowsHtml;

                    shelfCont.querySelectorAll('.tf-placed-item.is-draggable-tool').forEach(el => {
                        el.addEventListener('pointerdown', e => { startCustomDrag(e, 'tool-drag', Number(el.dataset.itemId)); });
                    });

                    // Tegyük ki a crushable itemeket is, de ezek mondjuk a polc szélén állnak.
                    const crushables = Object.values(itemsDB).filter(it => userState.collected.includes(Number(it.id)) && it.type === 'crushable');
                    if (crushables.length > 0) {
                        let cHtml = '';
                        crushables.forEach(it => {
                            const qty = getIngredientCount(it.id);
                            if (qty <= 0) return;
                            const dImg = getDisplayImage(it);
                            const visual = dImg ? '<img src="' + dImg + '">' : '<span class="tf-emoji-icon">' + getDisplayEmoji(it) + '</span>';
                            const qtyBadge = (qty > 1) ? '<span class="tf-qty-badge">×' + qty + '</span>' : '';
                            cHtml += '<div class="tf-placed-item is-draggable-tool" data-item-id="' + it.id + '" data-type="' + it.type + '" title="' + getDisplayTitle(it) + '">' + visual + qtyBadge + '</div>';
                        });
                        if (cHtml) {
                            const lastRow = shelfCont.querySelector('.tf-shelf-row:last-child');
                            if (lastRow) lastRow.innerHTML += cHtml;
                        }
                    }
                    
                    // Újra bindoljuk a frissen hozzáadott crushables drageket
                    shelfCont.querySelectorAll('.tf-placed-item[data-type="crushable"]').forEach(el => {
                        el.addEventListener('pointerdown', e => { startCustomDrag(e, 'tool-drag', Number(el.dataset.itemId)); });
                    });

                    // 2. Munkaasztal
                    const mortar = root.querySelector('#tf-mortar');
                    if (mortar) {
                        if (mortarContent) {
                            mortar.classList.add('has-item');
                            const mIt = itemsDB[mortarContent];
                            mortar.querySelector('.tf-mortar-content').innerHTML = getDisplayImage(mIt) ? '<img src="' + getDisplayImage(mIt) + '" style="height:30px;">' : getDisplayEmoji(mIt);
                        } else {
                            mortar.classList.remove('has-item');
                            mortar.querySelector('.tf-mortar-content').innerHTML = '';
                        }
                    }

                    const cauldron = root.querySelector('#tf-cauldron');
                    if (cauldron) {
                        const bContainer = cauldron.querySelector('.tf-cauldron-bubbles');
                        const lContainer = cauldron.querySelector('.tf-cauldron-liquid');
                        if (cauldronContents.length > 0) {
                            cauldron.classList.add('has-items');
                            let bubs = ''; cauldronContents.forEach(cid => { const cIt = itemsDB[cid]; if(cIt) bubs += getDisplayEmoji(cIt) + ' '; });
                            if (bContainer) bContainer.innerHTML = bubs;
                            if (lContainer) {
                                // Gányolt dinamikus szín a betett ID-k alapján
                                const colSeed = cauldronContents.reduce((a,b)=>a+b,0) % 360;
                                lContainer.style.background = 'hsla(' + colSeed + ', 80%, 30%, 0.9)';
                            }
                        } else {
                            cauldron.classList.remove('has-items');
                            if (bContainer) bContainer.innerHTML = '';
                            if (lContainer) lContainer.style.background = 'rgba(30, 30, 30, 0.9)';
                            const sBtn = root.querySelector('.tf-cauldron-stir-btn'); if (sBtn) sBtn.classList.add('tf-hidden');
                            const pBtn = root.querySelector('.tf-cauldron-pour-btn'); if (pBtn) pBtn.classList.add('tf-hidden');
                        }
                    }

                    const vial = root.querySelector('#tf-essence-vial');
                    if (vial) {
                        vial.querySelector('.tf-essence-count').textContent = userState.essence || 0;
                        if (userState.essence > 0) {
                            vial.classList.remove('is-empty');
                            vial.onpointerdown = e => { startCustomDrag(e, 'essence-drag', 'essence'); };
                        } else {
                            vial.classList.add('is-empty');
                            vial.onpointerdown = null;
                        }
                    }
                });
            }

            function refreshAllUI() {
                withPreservedScroll(() => {
                    cleanRawExcerpts();
                    initStandalonePuzzles();
                    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 (item.type === 'ingredient' || item.type === 'crushable') {
                            if (sessionCollected.includes(id)) 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'); }
                    });

                    renderSzertar();
                });
            }

            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-szertar-wrapper') || m.target.closest('#tf-item-modal-overlay') || m.target.closest('.tf-world-item') || m.target.closest('#tf-monocle-lens') || m.target.closest('#tf-drag-ghost') || m.target.closest('.tf-ember-ink') || m.target.closest('.tf-knocker-box') || m.target.closest('.tf-standalone-puzzle'))) 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>
        