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

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

        /* Repedező Viaszpecsét (3 kattintás) */
        .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;
            max-width: 90% !important;
            max-height: 90% !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;
        }

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

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

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

        /* Láthatatlan tinta, Hőre sötétedő parázs-tinta és Monokli Vízjel */
        .tf-secret-ink {
            color: transparent !important;
            border-bottom: 1px dashed rgba(124, 105, 82, 0.4) !important;
            padding: 0 3px !important;
            transition: color 0.35s ease, text-shadow 0.35s ease !important;
        }
        .tf-secret-ink.tf-ink-revealed {
            color: #4a2511 !important;
            text-shadow: 0 0 4px rgba(132, 102, 53, 0.6) !important;
        }

        .tf-ember-ink {
            position: relative !important;
            display: inline-block !important;
            padding: 0 4px !important;
            border-bottom: 1px dotted rgba(160, 95, 45, 0.35) !important;
            user-select: none !important;
        }
        .tf-ember-glow {
            position: absolute !important;
            inset: -6px -10px !important;
            background: radial-gradient(circle, rgba(224, 110, 24, 0.55) 0%, rgba(168, 62, 12, 0.2) 55%, rgba(0,0,0,0) 80%) !important;
            opacity: 0;
            pointer-events: none !important;
            border-radius: 50% !important;
            transition: opacity 0.15s ease !important;
        }
        .tf-ember-text {
            position: relative !important;
            color: transparent !important;
            transition: color 0.2s ease, text-shadow 0.2s ease !important;
        }
        .tf-ember-ink.is-burned {
            border-bottom-color: transparent !important;
        }
        .tf-ember-ink.is-burned .tf-ember-text {
            color: #3d1806 !important;
            text-shadow: 0 0 3px rgba(120, 52, 14, 0.65) !important;
            filter: url(#tf-ink-bleed-filter) !important;
        }

        .tf-watermark {
            display: inline-block !important;
            font-family: "Estonia", Georgia, cursive !important;
            font-size: 16px !important;
            color: rgba(90, 66, 42, 0.14) !important;
            filter: blur(2.2px) !important;
            user-select: none !important;
            padding: 0 4px !important;
            transition: filter 0.25s ease, color 0.25s ease, transform 0.25s ease, text-shadow 0.25s ease !important;
        }
        .tf-watermark.tf-watermark-revealed {
            color: #7a1c1c !important;
            filter: blur(0px) !important;
            transform: scale(1.12) !important;
            text-shadow: 0 0 6px rgba(227, 210, 179, 0.95) !important;
        }

        /* Titkos Kopogtató ([titkos_kopogas]) */
        .tf-knocker-box {
            display: inline-flex !important;
            align-items: center !important;
            gap: 8px !important;
            background: linear-gradient(180deg, #3d2d1e 0%, #26190f 100%) !important;
            border: 1px solid #846635 !important;
            box-shadow: inset 0 0 8px rgba(0,0,0,0.7), 0 2px 6px rgba(0,0,0,0.4) !important;
            color: #dfd0b8 !important;
            padding: 5px 12px !important;
            margin: 4px 6px !important;
            border-radius: 3px !important;
            cursor: pointer !important;
            user-select: none !important;
            position: relative !important;
            vertical-align: middle !important;
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 11px !important;
        }
        .tf-knocker-ring {
            width: 16px !important;
            height: 16px !important;
            border: 2px solid #d4af37 !important;
            border-radius: 50% !important;
            display: inline-block !important;
            box-shadow: 0 2px 3px rgba(0,0,0,0.6) !important;
            transition: transform 0.1s ease !important;
        }
        .tf-knocker-box.is-knocking .tf-knocker-ring {
            transform: translateY(-3px) scale(0.92) !important;
        }
        .tf-knock-dots {
            font-family: monospace !important;
            font-size: 12px !important;
            color: #d4af37 !important;
            letter-spacing: 2px !important;
            min-width: 14px !important;
        }

        /* Kézbe vehető Nagyító / Monokli Lencse */
        #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;
        }

        /* Lebegő Drag & Drop Ikon (Teljesen keret nélkül!) */
        #tf-drag-ghost {
            position: fixed !important;
            top: -200px;
            left: -200px;
            width: 52px !important;
            height: 52px !important;
            margin-left: -26px !important;
            margin-top: -26px !important;
            background: transparent !important;
            border: none !important;
            box-shadow: none !important;
            filter: drop-shadow(0 6px 10px rgba(0,0,0,0.65)) !important;
            display: none;
            align-items: center !important;
            justify-content: center !important;
            pointer-events: none !important;
            z-index: 9999999 !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: 30px !important;
        }

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

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

        /* ALKIMISTA MŰHELY: KERET NÉLKÜLI KÉPEK ÉS CSOPORTOSÍTÁS */
        .tf-alchemy-combiner {
            background: transparent !important;
            border: none !important;
            padding: 4px 2px 10px 2px !important;
            margin-bottom: 10px !important;
            text-align: center !important;
            position: relative !important;
            border-bottom: 1px solid rgba(74, 55, 35, 0.45) !important;
        }
        .tf-alchemy-combiner h4 {
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 10.5px !important;
            color: #3e2615 !important;
            margin: 0 0 2px 0 !important;
            text-transform: uppercase !important;
            letter-spacing: 0.5px !important;
        }
        .tf-alchemy-worktable {
            position: relative !important;
            width: 100% !important;
            height: 105px !important;
            margin: 6px 0 8px 0 !important;
            background: radial-gradient(ellipse at center, rgba(132, 102, 53, 0.18) 0%, rgba(132, 102, 53, 0.04) 65%, transparent 100%) !important;
            border: none !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            overflow: visible !important;
            touch-action: none !important;
        }
        .tf-alchemy-worktable.is-drop-target {
            background: radial-gradient(ellipse at center, rgba(212, 175, 55, 0.35) 0%, rgba(132, 102, 53, 0.08) 70%, transparent 100%) !important;
        }
        .tf-worktable-hint {
            font-family: "Estonia", cursive !important;
            font-size: 19px !important;
            color: rgba(61, 45, 30, 0.55) !important;
            pointer-events: none !important;
            user-select: none !important;
        }
        /* Keret nélküli, szabadon csoportosítható elemek a munkafelületen */
        .tf-table-placed-item {
            position: absolute !important;
            width: 50px !important;
            height: 50px !important;
            margin-left: -25px !important;
            margin-top: -25px !important;
            background: transparent !important;
            border: none !important;
            box-shadow: none !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            cursor: grab !important;
            user-select: none !important;
            touch-action: none !important;
            z-index: 5 !important;
            transition: transform 0.12s ease !important;
            filter: drop-shadow(0 3px 5px rgba(27, 17, 11, 0.45)) !important;
        }
        .tf-table-placed-item:hover {
            transform: scale(1.12) !important;
        }
        .tf-table-placed-item img {
            width: 100% !important;
            height: 100% !important;
            object-fit: contain !important;
            border: none !important;
            background: transparent !important;
            pointer-events: none !important;
        }
        .tf-table-placed-item span {
            font-size: 32px !important;
            line-height: 1 !important;
            pointer-events: none !important;
            filter: sepia(0.5) !important;
        }

        /* Csoportosított, keret nélküli készlet a Műhelyben */
        .tf-alchemy-group {
            margin: 6px 0 8px 0 !important;
            text-align: center !important;
        }
        .tf-alchemy-group-title {
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 9px !important;
            color: #5c442c !important;
            text-transform: uppercase !important;
            letter-spacing: 0.5px !important;
            margin-bottom: 4px !important;
        }
        .tf-alchemy-inventory {
            display: flex !important;
            flex-wrap: wrap !important;
            gap: 10px !important;
            justify-content: center !important;
            align-items: center !important;
            padding: 2px 4px !important;
            min-height: 44px !important;
        }
        .tf-alchemy-pick {
            position: relative !important;
            width: 44px !important;
            height: 44px !important;
            background: transparent !important;
            border: none !important;
            box-shadow: none !important;
            padding: 0 !important;
            cursor: grab !important;
            user-select: none !important;
            touch-action: none !important;
            display: inline-flex !important;
            align-items: center !important;
            justify-content: center !important;
            transition: transform 0.15s ease, opacity 0.15s ease !important;
            filter: drop-shadow(0 2px 4px rgba(27, 17, 11, 0.35)) !important;
        }
        .tf-alchemy-pick:hover {
            transform: scale(1.15) !important;
        }
        .tf-alchemy-pick img {
            width: 100% !important;
            height: 100% !important;
            object-fit: contain !important;
            border: none !important;
            background: transparent !important;
            pointer-events: none !important;
        }
        .tf-alchemy-pick .tf-pick-emoji {
            font-size: 28px !important;
            line-height: 1 !important;
            filter: sepia(0.55) !important;
            pointer-events: none !important;
        }
        .tf-alchemy-pick .tf-pick-qty {
            position: absolute !important;
            bottom: -2px !important;
            right: -4px !important;
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 9.5px !important;
            color: #1f140b !important;
            text-shadow: 0 0 3px #f1e6d2, 0 0 3px #f1e6d2 !important;
            pointer-events: none !important;
            font-weight: bold !important;
        }
        .tf-alchemy-pick.is-depleted {
            opacity: 0.22 !important;
            pointer-events: none !important;
        }

        /* SÁRGARÉZ KRIPTEX (III. FÜL) */
        .tf-typewriter-box {
            background: #e3d2b3 !important;
            border: 1px solid #846635 !important;
            box-shadow: inset 0 0 12px rgba(62, 38, 21, 0.25) !important;
            padding: 12px !important;
            text-align: center !important;
            position: relative !important;
            overflow: hidden !important;
        }
        .tf-typewriter-box h4 {
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 11px !important;
            color: #3e2615 !important;
            letter-spacing: 1px !important;
            text-transform: uppercase !important;
            margin: 0 0 4px 0 !important;
        }
        .tf-cryptex-assembly {
            display: inline-flex !important;
            align-items: center !important;
            justify-content: center !important;
            gap: 4px !important;
            background: linear-gradient(180deg, #1e130b 0%, #382416 50%, #1e130b 100%) !important;
            border: 2px solid #846635 !important;
            box-shadow: inset 0 0 10px rgba(0,0,0,0.85), 0 3px 8px rgba(0,0,0,0.35) !important;
            padding: 6px 10px !important;
            margin: 4px auto 10px auto !important;
            border-radius: 4px !important;
            user-select: none !important;
        }
        .tf-cryptex-wheel {
            width: 28px !important;
            height: 58px !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: 3px 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: 20px !important;
            border-top: 1px solid rgba(122, 28, 28, 0.55) !important;
            border-bottom: 1px solid rgba(122, 28, 28, 0.55) !important;
            pointer-events: none !important;
        }
        .tf-wheel-prev,
        .tf-wheel-next {
            font-family: Georgia, serif !important;
            font-size: 9px !important;
            line-height: 12px !important;
            color: rgba(35, 23, 13, 0.45) !important;
            pointer-events: none !important;
        }
        .tf-wheel-curr {
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 14px !important;
            line-height: 18px !important;
            font-weight: bold !important;
            color: #1b0f08 !important;
            pointer-events: none !important;
        }

        /* FELUGRÓ PERGAMEN ABLAK + REJTETT 3D HÁTOLDAL + LAPOZÁS */
        #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-close:hover {
            color: #7a1c1c !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-modal-coupon {
            font-family: "Uncial Antiqua", Georgia, serif !important;
            font-size: 11px !important;
            color: #7a1c1c !important;
            background: rgba(27, 17, 11, 0.08) !important;
            border: 1px dashed #7a1c1c !important;
            padding: 4px 10px !important;
        }
        .tf-rhythm-puzzle {
            background: #e3d2b3 !important;
            border: 1px solid #846635 !important;
            box-shadow: inset 0 0 10px rgba(62, 38, 21, 0.25) !important;
            padding: 8px 12px !important;
            display: inline-block !important;
            text-align: center !important;
            margin: 6px 0 !important;
        }
        .tf-rhythm-buttons {
            display: flex !important;
            gap: 6px !important;
            justify-content: center !important;
        }
        .tf-rhythm-btn {
            background: #382416 !important;
            border: 1px dashed #7C6952 !important;
            color: #dfd0b8 !important;
            font-size: 16px !important;
            padding: 4px 10px !important;
        }
        .tf-hidden { display: none !important; }
        </style>

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

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

            const TF_Config = {"ajax_url":"https:\/\/matolanorbert.hu\/wp-admin\/admin-ajax.php","nonce":"ba70083317","is_logged_in":false,"items":{"36":{"id":36,"title":"R\u00e9gi R\u00e9zkulcs","type":"tool","emoji":"\ud83d\udddd\ufe0f","image":"","hint":"Valahol egy poros sarokban lapul...","reward_text":"Egy apr\u00f3, m\u00edves r\u00e9zkulcs. Ha k\u00e9zbe veszed a fi\u00f3kodban, kinyithatsz vele lepecs\u00e9telt l\u00e1dik\u00e1kat.","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"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\ufe0f","image":"","hint":"Csak a R\u00e9gi R\u00e9zkulccsal nyithat\u00f3 fel.","reward_text":"A bor\u00edt\u00e9kban egy elfeledett k\u00e9zirat r\u00e9szlete \u00e9s egy titkos kupon lapult!","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"VARAZSLAT15","req_item_id":36,"req_fragments":[],"req_essence":1,"evolved_title":"","evolved_emoji":"","evolved_image":"","time_restriction":"any","is_lantern":false,"is_monocle":false,"ink_clue":"Csak a R\u00e9gi R\u00e9zkulccsal nyithat\u00f3 fel."},"38":{"id":38,"title":"Holdf\u00e9ny L\u00e1mp\u00e1s","type":"tool","emoji":"\ud83c\udfee","image":"","hint":"F\u00e9nye l\u00e1that\u00f3v\u00e1 teszi a l\u00e1thatatlan tint\u00e1t.","reward_text":"Vedd k\u00e9zbe ezt a l\u00e1mp\u00e1st! Am\u00edg akt\u00edv, az eg\u00e9rmutat\u00f3d f\u00e9nyk\u00f6re felfedi a [titkos_tinta] elemeket az oldalon.","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"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":"\ud83d\udca7","image":"","hint":"Minden nap \u00fajragy\u0171jthet\u0151 esszencia.","reward_text":"Tiszta esszencia, amellyel az alv\u00f3 magokat \u00e9s gub\u00f3kat t\u00e1pl\u00e1lhatod a M\u0171helyben.","back_text":"","back_image":"","audio_url":"","sfx_url":"","reward_link":"","coupon_code":"","req_item_id":0,"req_fragments":[],"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":[],"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":[],"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!"}}};
            const STORAGE_KEY = 'tf_guest_state_v2';
            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 = loadLocalState();
            let activeMonocleId = 0;
            // Szabadon csoportosítható munkafelület-elemek: [{ id, x, y }]
            let alchemyCluster = [];
            let sessionCollected = [];
            let lastMouseX = -1000;
            let lastMouseY = -1000;

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

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

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

            function getIngredientCount(itemId) {
                return (userState.ingredients && userState.ingredients[itemId]) ? Number(userState.ingredients[itemId]) : 0;
            }

            function isLockOpened(item) {
                if (!item) return false;
                return item.type !== 'locked' || userState.unlocked_locks.includes(Number(item.id));
            }
            function isItemEvolved(item) {
                if (!item) return false;
                return item.type !== 'evolving' || userState.evolved.includes(Number(item.id));
            }
            function getDisplayTitle(item) {
                if (item.type === 'evolving' && userState.evolved.includes(Number(item.id)) && item.evolved_title) {
                    return item.evolved_title;
                }
                return item.title;
            }
            function getDisplayImage(item) {
                if (item.type === 'evolving' && userState.evolved.includes(Number(item.id)) && item.evolved_image) {
                    return item.evolved_image;
                }
                return item.image;
            }
            function getDisplayEmoji(item) {
                if (item.type === 'evolving' && userState.evolved.includes(Number(item.id)) && item.evolved_emoji) {
                    return item.evolved_emoji;
                }
                return item.emoji;
            }

            function getCollectorRank(collectedCount, totalCount) {
                if (totalCount === 0 || collectedCount === 0) return 'Kíváncsi Látogató';
                const ratio = collectedCount / totalCount;
                if (ratio >= 1) return '⚜ A Kódex Őrzője ⚜';
                if (ratio >= 0.75) return 'Alkimista Beavatott';
                if (ratio >= 0.50) return 'Titkok Tudója';
                if (ratio >= 0.25) return 'Poros Fiókok Kutatója';
                return 'Műhely-inas';
            }

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

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

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

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

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

                fn();

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

            function 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();
            }

            // Egyedi Pointer Drag & Drop Motor (Keret nélküli Műhely-csoportosításhoz és Kódex Kulcsokhoz)
            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, clusterIdx = -1) {
                const item = itemsDB[itemId];
                if (!item) return;
                e.preventDefault();
                e.stopPropagation();

                const ghost = ensureDragGhost();
                const dImg = getDisplayImage(item);
                const dEmoji = getDisplayEmoji(item);
                ghost.innerHTML = dImg ? '<img src="' + dImg + '" alt="">' : '<span>' + dEmoji + '</span>';
                ghost.style.left = e.clientX + 'px';
                ghost.style.top = e.clientY + 'px';
                ghost.classList.add('is-dragging');

                dragContext = {
                    mode: mode, // 'alchemy-pick', 'alchemy-table', 'codex-key'
                    itemId: Number(itemId),
                    clusterIdx: clusterIdx
                };
            }

            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.mode === 'alchemy-pick' || dragContext.mode === 'alchemy-table') {
                    const tableEl = under.closest('.tf-alchemy-worktable');
                    if (tableEl) tableEl.classList.add('is-drop-target');
                } else if (dragContext.mode === 'codex-key') {
                    const rowEl = under.closest('.tf-codex-row.is-key-locked');
                    if (rowEl) rowEl.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.mode === 'alchemy-pick' || ctx.mode === 'alchemy-table') {
                    const targetTable = under ? under.closest('.tf-alchemy-worktable') : null;
                    if (targetTable) {
                        const rect = targetTable.getBoundingClientRect();
                        const relX = Math.max(18, Math.min(82, ((e.clientX - rect.left) / rect.width) * 100));
                        const relY = Math.max(24, Math.min(76, ((e.clientY - rect.top) / rect.height) * 100));

                        if (ctx.mode === 'alchemy-table' && ctx.clusterIdx !== -1 && alchemyCluster[ctx.clusterIdx]) {
                            alchemyCluster[ctx.clusterIdx].x = relX;
                            alchemyCluster[ctx.clusterIdx].y = relY;
                        } else {
                            alchemyCluster.push({ id: ctx.itemId, x: relX, y: relY });
                        }
                        renderAlchemyPanels();
                    } else if (ctx.mode === 'alchemy-table' && ctx.clusterIdx !== -1) {
                        // Ha kihúzta a munkafelületről, levesszük az asztalról
                        alchemyCluster.splice(ctx.clusterIdx, 1);
                        renderAlchemyPanels();
                    }
                } else if (ctx.mode === 'codex-key') {
                    const targetRow = under ? under.closest('.tf-codex-row.is-key-locked') : null;
                    if (targetRow) {
                        const lockedItemId = Number(targetRow.dataset.itemId);
                        // Néma zárszerkezet: nincs hangeffekt
                        sendAction('unlock_lock', lockedItemId, { key_id: ctx.itemId }, () => {
                            if (itemsDB[lockedItemId]) openItemModal(itemsDB[lockedItemId]);
                        }, () => {
                            targetRow.classList.remove('tf-shake');
                            void targetRow.offsetWidth;
                            targetRow.classList.add('tf-shake');
                        }, true);
                    }
                }
            });

            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 fed = (userState.feed_counts && userState.feed_counts[item.id]) ? userState.feed_counts[item.id] : 0;

                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 rawText = isEvolved
                    ? (item.reward_text || 'Megtalált ereklye a gyűjteményedben.')
                    : 'Ez az ereklye még szunnyad. Tápláld Napi Esszenciával (' + fed + ' / ' + item.req_essence + '), hogy átváltozzon és felfedje titkát.';

                const pages = rawText.split(/\n?\s*---\s*\n?/).map(p => p.trim()).filter(Boolean);
                let currentPage = 0;

                function renderModalPage() {
                    descEl.textContent = pages[currentPage] || '';
                    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) {
                    const feedBtn = document.createElement('button');
                    feedBtn.type = 'button';
                    feedBtn.className = 'tf-vintage-btn';
                    feedBtn.textContent = 'Táplálás Esszenciával (' + fed + '/' + item.req_essence + ')';
                    feedBtn.addEventListener('click', () => {
                        sendAction('feed', Number(item.id), {}, () => {
                            triggerSfx('collect');
                            openItemModal(itemsDB[item.id]);
                        });
                    });
                    rewardsBox.appendChild(feedBtn);
                } else {
                    if (item.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 / Megnyitása';
                        rewardsBox.appendChild(linkBtn);
                    }
                    if (item.coupon_code) {
                        const codeEl = document.createElement('div');
                        codeEl.className = 'tf-modal-coupon';
                        codeEl.innerHTML = 'Jutalom Kód: <strong>' + item.coupon_code + '</strong>';
                        rewardsBox.appendChild(codeEl);
                    }
                }

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

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

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

            function sendAction(actionType, itemId, extra = {}, onSuccess = null, onError = null, 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);
                formData.append('client_state', JSON.stringify(userState));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            // Sárgaréz Kriptex Tárcsák Inicializálása (NÉMA ZÁRSZERKEZET: nincs hang tekeréskor!)
            function updateCryptexWheelDisplay(wheelEl, newIndex) {
                const len = CRYPTEX_CHARS.length;
                const idx = ((newIndex % len) + len) % len;
                wheelEl.dataset.index = String(idx);
                const prevIdx = (idx - 1 + len) % len;
                const nextIdx = (idx + 1) % len;
                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[prevIdx];
                if (cEl) cEl.textContent = CRYPTEX_CHARS[idx];
                if (nEl) nEl.textContent = CRYPTEX_CHARS[nextIdx];
            }

            function initCryptexWheels() {
                document.querySelectorAll('.tf-cryptex-wheel').forEach(wheel => {
                    if (wheel._tfBound) return;
                    wheel._tfBound = true;

                    let dragging = false;
                    let startY = 0;

                    wheel.addEventListener('pointerdown', e => {
                        e.preventDefault();
                        e.stopPropagation();
                        dragging = true;
                        startY = e.clientY;
                        wheel.setPointerCapture(e.pointerId);
                    });

                    wheel.addEventListener('pointermove', e => {
                        if (!dragging) return;
                        e.preventDefault();
                        e.stopPropagation();
                        const dy = e.clientY - startY;
                        if (Math.abs(dy) >= 16) {
                            const dir = dy > 0 ? -1 : 1;
                            const cur = Number(wheel.dataset.index || 0);
                            updateCryptexWheelDisplay(wheel, cur + dir);
                            startY = e.clientY;
                        }
                    });

                    wheel.addEventListener('pointerup', e => {
                        if (!dragging) return;
                        dragging = false;
                        try { wheel.releasePointerCapture(e.pointerId); } catch (err) {}
                    });

                    wheel.addEventListener('wheel', e => {
                        e.preventDefault();
                        e.stopPropagation();
                        const dir = e.deltaY > 0 ? 1 : -1;
                        const cur = Number(wheel.dataset.index || 0);
                        updateCryptexWheelDisplay(wheel, cur + dir);
                    }, { passive: false });
                });
            }

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

            // Hőre sötétedő parázs-tinta ([titkos_parazs]) időzítő ciklus
            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) {
                // Titkos Kopogtató ([titkos_kopogas])
                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);

                    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) {
                                sendAction('collect', rewardId, {}, () => {
                                    if (dotsEl) dotsEl.textContent = '✓';
                                    if (itemsDB[rewardId]) openItemModal(itemsDB[rewardId]);
                                }, null, true);
                            } 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();

                    // 1. Porréteg ellenőrzés
                    if (worldItem.dataset.dust === '1' && !worldItem._tfDustCleared) {
                        worldItem.classList.remove('tf-shake');
                        void worldItem.offsetWidth;
                        worldItem.classList.add('tf-shake');
                        return;
                    }

                    // 2. Repedező Viaszpecsét ellenőrzés (3 kattintás)
                    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;

                    // Néma zárszerkezet: a jelszavas zár nem ad hangot
                    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') {
                            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 tabBtn = e.target.closest('.tf-tab');
                if (tabBtn) {
                    e.preventDefault();
                    e.stopPropagation();
                    const embed = tabBtn.closest('.tf-codex-embed');
                    if (!embed || tabBtn.classList.contains('active')) return;

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

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

                // Néma zárszerkezet nyitása (Kriptex)
                const codeSubmit = e.target.closest('.tf-secret-code-submit');
                if (codeSubmit) {
                    e.preventDefault();
                    e.stopPropagation();
                    const box = codeSubmit.closest('.tf-typewriter-box');
                    const wheels = box.querySelectorAll('.tf-cryptex-wheel');
                    let val = '';
                    wheels.forEach(w => {
                        const idx = Number(w.dataset.index || 0);
                        const ch = CRYPTEX_CHARS[idx] || '';
                        if (ch !== '·') val += ch;
                    });
                    val = val.trim();
                    if (!val) {
                        box.classList.remove('tf-shake');
                        void box.offsetWidth;
                        box.classList.add('tf-shake');
                        return;
                    }

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

            document.addEventListener('mousemove', e => {
                lastMouseX = e.clientX;
                lastMouseY = e.clientY;

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

                if (activeMonocleId > 0) {
                    const lens = ensureMonocleLens();
                    lens.style.left = e.clientX + 'px';
                    lens.style.top = e.clientY + 'px';

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

            function refreshAllUI() {
                withPreservedScroll(() => {
                    cleanRawExcerpts();
                    initCryptexWheels();
                    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') {
                            // Az alapanyagok újrateremnek, de az adott munkamenetben felszedés után eltűnnek
                            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');
                        }
                    });

                    document.querySelectorAll('.tf-secret-content-block').forEach(block => {
                        const reqId = Number(block.dataset.reqItem);
                        const reqItem = itemsDB[reqId];
                        const isOwned = userState.collected.includes(reqId) && (!reqItem || isLockOpened(reqItem));
                        block.style.display = isOwned ? 'block' : 'none';
                    });

                    const totalItems = Object.keys(itemsDB).length;
                    const collectedLen = userState.collected.length;
                    const rankTitle = getCollectorRank(collectedLen, totalItems);

                    document.querySelectorAll('.tf-collected-counter').forEach(el => {
                        el.textContent = collectedLen + '/' + totalItems;
                    });
                    document.querySelectorAll('.tf-collector-rank').forEach(el => {
                        el.textContent = 'Rang: ' + rankTitle;
                    });
                    document.querySelectorAll('.tf-essence-count').forEach(el => {
                        el.textContent = userState.essence || 0;
                    });

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

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

                    Object.values(itemsDB).forEach(item => {
                        const isCollected = userState.collected.includes(Number(item.id));
                        const lockOpened = isLockOpened(item);
                        const isEvolved = isItemEvolved(item);
                        const qty = getIngredientCount(item.id);

                        const dTitle = getDisplayTitle(item);
                        const dImg = getDisplayImage(item);
                        const dEmoji = getDisplayEmoji(item);

                        const row = document.createElement('div');
                        row.dataset.itemId = String(item.id);

                        let rowClasses = 'tf-codex-row ' + (isCollected ? 'unlocked' : 'locked');
                        if (isCollected && item.type === 'tool') rowClasses += ' is-draggable-key';
                        if (isCollected && item.type === 'locked' && !lockOpened) rowClasses += ' is-key-locked';
                        row.className = rowClasses;

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

                        let actionBtnHtml = '';
                        if (isCollected && lockOpened && item.is_monocle) {
                            const equipped = activeMonocleId === Number(item.id);
                            actionBtnHtml = '<button type="button" class="tf-vintage-btn tf-equip-monocle ' + (equipped ? 'is-equipped' : '') + '" data-id="' + item.id + '">'
                                + (equipped ? '✕ Elrak' : '🔍 Kézbe vesz')
                                + '</button>';
                        }

                        let descStatus = item.hint;
                        if (isCollected) {
                            if (!lockOpened) {
                                descStatus = '🔒 Lezárt ereklye (Húzd rá a kulcsát!)';
                            } else if (!isEvolved) {
                                descStatus = 'Alvó ereklye (Táplálásra vár)';
                            } else if (item.type === 'ingredient') {
                                descStatus = 'Alapanyag készleten: ' + qty + ' db';
                            } else if (item.type === 'potion') {
                                descStatus = 'Megfőzött elixír' + (qty > 0 ? ' (' + qty + ' db)' : '');
                            } else if (item.type === 'tool') {
                                descStatus = 'Megtekintés / Húzható eszköz';
                            } else {
                                descStatus = 'Megtekintés';
                            }
                        }

                        row.innerHTML = '<div class="tf-codex-thumb-box">' + thumbHtml + '</div>'
                            + '<div class="tf-codex-row-text">'
                            + '<div class="tf-codex-row-title">' + (isCollected ? dTitle : '? ? ?') + '</div>'
                            + '<div class="tf-codex-row-desc">' + descStatus + '</div>'
                            + '</div>'
                            + actionBtnHtml;

                        if (isCollected) {
                            if (item.type === 'tool') {
                                const thumbBox = row.querySelector('.tf-codex-thumb-box');
                                if (thumbBox) {
                                    thumbBox.addEventListener('pointerdown', (e) => {
                                        startCustomDrag(e, 'codex-key', Number(item.id));
                                    });
                                }
                            }

                            row.addEventListener('click', (e) => {
                                const monoBtn = e.target.closest('.tf-equip-monocle');
                                if (monoBtn) {
                                    e.preventDefault();
                                    e.stopPropagation();
                                    toggleMonocle(Number(monoBtn.dataset.id));
                                    return;
                                }
                                e.preventDefault();
                                e.stopPropagation();
                                if (!lockOpened) {
                                    row.classList.remove('tf-shake');
                                    void row.offsetWidth;
                                    row.classList.add('tf-shake');
                                    return;
                                }
                                openItemModal(item);
                            });
                        }
                        list.appendChild(row);
                    });
                });
            }

            function renderAlchemyPanels() {
                document.querySelectorAll('.tf-alchemy-list').forEach(container => {
                    container.innerHTML = '';

                    // Számoljuk meg, melyik tárgyból hány darab van már kint a munkafelületen
                    const usedCounts = {};
                    alchemyCluster.forEach(entry => {
                        usedCounts[entry.id] = (usedCounts[entry.id] || 0) + 1;
                    });

                    const combiner = document.createElement('div');
                    combiner.className = 'tf-alchemy-combiner';

                    let placedHtml = '';
                    if (alchemyCluster.length === 0) {
                        placedHtml = '<span class="tf-worktable-hint">Húzd ide és csoportosítsd az alapanyagokat vagy töredékeket...</span>';
                    } else {
                        alchemyCluster.forEach((entry, idx) => {
                            const sItem = itemsDB[entry.id];
                            if (!sItem) return;
                            const inner = getDisplayImage(sItem)
                                ? '<img src="' + getDisplayImage(sItem) + '" alt="">'
                                : '<span>' + getDisplayEmoji(sItem) + '</span>';
                            placedHtml += '<div class="tf-table-placed-item" data-cluster-idx="' + idx + '" style="left:' + entry.x + '%; top:' + entry.y + '%;" title="' + getDisplayTitle(sItem) + ' (Húzd arrébb vagy húzd ki a levételhez)">' + inner + '</div>';
                        });
                    }

                    // Csoportosítás: 1. Alapanyagok (ingredient) | 2. Töredékek és Ereklyék
                    const ingGroup = Object.values(itemsDB).filter(it => it.type === 'ingredient' && getIngredientCount(it.id) > 0);
                    const relicGroup = Object.values(itemsDB).filter(it => it.type !== 'ingredient' && it.type !== 'daily' && userState.collected.includes(Number(it.id)) && isLockOpened(it));

                    function buildFramelessPicksHtml(list, isStackable) {
                        let html = '';
                        list.forEach(it => {
                            const used = usedCounts[it.id] || 0;
                            const maxAvail = isStackable ? getIngredientCount(it.id) : 1;
                            const remaining = Math.max(0, maxAvail - used);
                            const depletedClass = remaining <= 0 ? 'is-depleted' : '';
                            const visual = getDisplayImage(it)
                                ? '<img src="' + getDisplayImage(it) + '" alt="">'
                                : '<span class="tf-pick-emoji">' + getDisplayEmoji(it) + '</span>';
                            const qtyBadge = isStackable ? '<span class="tf-pick-qty">×' + remaining + '</span>' : '';

                            html += '<div class="tf-alchemy-pick ' + depletedClass + '" data-pick-id="' + it.id + '" title="' + getDisplayTitle(it) + '">'
                                + visual + qtyBadge
                                + '</div>';
                        });
                        return html;
                    }

                    let groupsHtml = '';
                    if (ingGroup.length === 0 && relicGroup.length === 0) {
                        groupsHtml = '<div class="tf-codex-row-desc" style="margin-bottom:6px;">Még nincs begyűjtött alapanyagod vagy töredéked.</div>';
                    } else {
                        if (ingGroup.length > 0) {
                            groupsHtml += '<div class="tf-alchemy-group">'
                                + '<div class="tf-alchemy-group-title">Alapanyagok &amp; Növények</div>'
                                + '<div class="tf-alchemy-inventory">' + buildFramelessPicksHtml(ingGroup, true) + '</div>'
                                + '</div>';
                        }
                        if (relicGroup.length > 0) {
                            groupsHtml += '<div class="tf-alchemy-group">'
                                + '<div class="tf-alchemy-group-title">Töredékek &amp; Ereklyék</div>'
                                + '<div class="tf-alchemy-inventory">' + buildFramelessPicksHtml(relicGroup, false) + '</div>'
                                + '</div>';
                        }
                    }

                    combiner.innerHTML = '<h4>Alkimista Műhely &amp; Bájitalfőző</h4>'
                        + '<div class="tf-alchemy-worktable">' + placedHtml + '</div>'
                        + groupsHtml
                        + '<button type="button" class="tf-vintage-btn tf-alchemy-combine-btn">Összeállítás / Főzés</button>'
                        + '<div class="tf-ink-overlay"><span class="tf-ink-text"></span></div>';

                    container.appendChild(combiner);

                    // Munkafelületen lévő képek szabad mozgatása / csoportosítása / kihúzása
                    combiner.querySelectorAll('.tf-table-placed-item').forEach(placedEl => {
                        placedEl.addEventListener('pointerdown', (e) => {
                            const idx = Number(placedEl.dataset.clusterIdx);
                            const entry = alchemyCluster[idx];
                            if (entry) {
                                startCustomDrag(e, 'alchemy-table', entry.id, idx);
                            }
                        });
                    });

                    // Keret nélküli készletből való behúzás
                    combiner.querySelectorAll('.tf-alchemy-pick:not(.is-depleted)').forEach(pickEl => {
                        pickEl.addEventListener('pointerdown', (e) => {
                            const pid = Number(pickEl.dataset.pickId);
                            if (pid) {
                                startCustomDrag(e, 'alchemy-pick', pid, -1);
                            }
                        });
                    });

                    const combineBtn = combiner.querySelector('.tf-alchemy-combine-btn');
                    if (combineBtn) {
                        combineBtn.addEventListener('click', (e) => {
                            e.preventDefault();
                            e.stopPropagation();
                            const activeIds = alchemyCluster.map(entry => Number(entry.id)).filter(Boolean);
                            if (activeIds.length < 2) {
                                combiner.classList.remove('tf-shake');
                                void combiner.offsetWidth;
                                combiner.classList.add('tf-shake');
                                bleedInkOnElement(combiner, 'Legalább 2 elemet húzz középre!');
                                return;
                            }

                            const selectedSorted = [...activeIds].sort((a, b) => a - b).join(',');
                            const matchedOutput = Object.values(itemsDB).find(it => {
                                if ((it.type !== 'craftable' && it.type !== 'potion') || !Array.isArray(it.req_fragments) || it.req_fragments.length === 0) return false;
                                const reqSorted = [...it.req_fragments].map(Number).sort((a, b) => a - b).join(',');
                                return reqSorted === selectedSorted;
                            });

                            if (matchedOutput) {
                                sendAction('craft', Number(matchedOutput.id), {}, () => {
                                    alchemyCluster = [];
                                    triggerSfx('collect');
                                    openItemModal(itemsDB[matchedOutput.id]);
                                });
                            } else {
                                combiner.classList.remove('tf-shake');
                                void combiner.offsetWidth;
                                combiner.classList.add('tf-shake');
                                bleedInkOnElement(combiner, 'Sikertelen elegy...');
                            }
                        });
                    }

                    // 2. FEJLŐDŐ TÁRGYAK (ESSZENCIA TÁPLÁLÁS)
                    const evolvings = Object.values(itemsDB).filter(it => it.type === 'evolving');
                    evolvings.forEach(item => {
                        const row = document.createElement('div');
                        row.className = 'tf-codex-row unlocked';
                        const isCollected = userState.collected.includes(Number(item.id));
                        const isEvolved = isItemEvolved(item);
                        const fed = (userState.feed_counts && userState.feed_counts[item.id]) ? userState.feed_counts[item.id] : 0;

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

                        container.appendChild(row);
                    });

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

            let observerTimeout = null;
            const observer = new MutationObserver((mutations) => {
                let shouldUpdate = false;
                for (let i = 0; i < mutations.length; i++) {
                    const m = mutations[i];
                    if (m.target && (m.target.closest('.tf-codex-embed') || m.target.closest('#tf-item-modal-overlay') || m.target.closest('.tf-world-item') || m.target.closest('#tf-monocle-lens') || m.target.closest('#tf-drag-ghost') || m.target.closest('.tf-ember-ink') || m.target.closest('.tf-knocker-box'))) {
                        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>
        