{"header":"<!-- Site header -->\n<div class=\"header__container\">\n\n  <div class=\"label\">\n    <a aria-label=\"Spinberry home\" href=\"index.html\">\n      <img alt=\"Spinberry\" class=\"label__logo\" height=\"97\" src=\"images/spinberry_logo.svg\" width=\"367\">\n    </a>\n  </div>\n\n  <div id=\"mobile-menu\"></div>\n\n  <nav aria-label=\"Main navigation\" class=\"header__menu\">\n    <div class=\"header__menu-inner\">\n      <div class=\"header__menu-pages\">\n        <h3>Pages</h3>\n        <div class=\"header__menu-links\">\n          <a href=\"index.html\">Home</a>\n          <a href=\"pages/games.html\">Games</a>\n          <a href=\"pages/rgs.html\">RGS</a>\n          <a href=\"pages/aboutUs.html\">About</a>\n          <a href=\"pages/ourPartners.html\">Partners</a>\n          <a href=\"pages/contacts.html\">Contact Us</a>\n        </div>\n      </div>\n\n      <div class=\"header__menu-socials\">\n        <h3>Socials</h3>\n        <div class=\"menu__socials\">\n          <a class=\"social-link\" href=\"https://www.linkedin.com/company/spinberrygames/\" rel=\"noopener noreferrer\" target=\"_blank\">\n            <img alt=\"LinkedIn\" src=\"images/icons/linkedIn.svg\">\n            <span class=\"social-link__label\">LinkedIn</span>\n          </a>\n          <a class=\"social-link\" href=\"https://www.instagram.com/spinberry.games/\" rel=\"noopener noreferrer\" target=\"_blank\">\n            <img alt=\"Instagram\" src=\"images/icons/instagram.svg\">\n            <span class=\"social-link__label\">Instagram</span>\n          </a>\n          <a class=\"social-link\" href=\"https://www.facebook.com/spinberrygames/\" rel=\"noopener noreferrer\" target=\"_blank\">\n            <img alt=\"Facebook\" src=\"images/icons/facebook.svg\">\n            <span class=\"social-link__label\">Facebook</span>\n          </a>\n        </div>\n      </div>\n    </div>\n  </nav>\n\n</div>\n","breadcrumbs":"<nav class=\"breadcrumbs\" aria-label=\"Breadcrumb\">\n    <ol class=\"breadcrumbs__list\" id=\"breadcrumbs-list\"></ol>\n</nav>\n<script>\n(function () {\n    const list = document.getElementById('breadcrumbs-list');\n    if (!list) return;\n\n    const pathMap = {\n        'index.html': 'Home',\n        'pages/contacts.html': 'Contact',\n        'pages/404.html': '404',\n        'pages/games.html': 'Games',\n        'pages/rgs.html': 'RGS',\n        'pages/game.html': 'Game',\n        'pages/aboutUs.html': 'About',\n        'pages/ourPartners.html': 'Partners'\n    };\n\n    const path = window.location.pathname.split('?')[0];\n    const items = [{ label: 'Home', href: 'index.html' }];\n\n    const match = Object.entries(pathMap).find(([key]) => path.endsWith(key));\n    if (match && match[0] !== 'index.html') {\n        items.push({ label: match[1], href: null });\n    }\n\n    list.innerHTML = items.map((item, i) => {\n        const isLast = i === items.length - 1;\n        if (isLast) {\n            return `<li class=\"breadcrumbs__item breadcrumbs__item--active\" aria-current=\"page\">${item.label}</li>`;\n        }\n        return `<li class=\"breadcrumbs__item\"><a class=\"breadcrumbs__link\" href=\"${item.href}\">${item.label}</a></li>`;\n    }).join('');\n})();\n</script>\n","our-games-section":"<div class=\"our-games\">\n  <div class=\"our-games__header\">\n    <h1>Our <b>games</b></h1>\n    <p>Creating hit slot games for the global stage. Where creativity meets technology to drive engagement and\n      revenue.</p>\n  </div>\n\n  <div aria-hidden=\"true\" class=\"our-games__filters-backdrop\"></div>\n  <div class=\"our-games__toolbar\">\n    <button aria-controls=\"our-games-filters\" aria-expanded=\"false\" class=\"our-games__filters-toggle\" type=\"button\">\n      Filters\n    </button>\n    <div class=\"our-games__filters\" id=\"our-games-filters\">\n      <div class=\"our-games__filters-inner\">\n        <div class=\"multi-select\" data-label=\"Theme\" id=\"theme-select\">\n          <div class=\"multi-select__label\">Theme</div>\n          <div class=\"multi-select__dropdown\" id=\"theme-options\"></div>\n        </div>\n        <div class=\"multi-select\" data-label=\"Features\" id=\"features-select\">\n          <div class=\"multi-select__label\">Features</div>\n          <div class=\"multi-select__dropdown\" id=\"features-options\"></div>\n        </div>\n        <div class=\"multi-select\" data-label=\"Newest\" id=\"sort-select\">\n          <div class=\"multi-select__label\">Newest</div>\n          <div class=\"multi-select__dropdown\">\n            <div class=\"multi-select__option\" data-value=\"newest\"><span class=\"option-text\">Newest</span></div>\n            <div class=\"multi-select__option\" data-value=\"az\"><span class=\"option-text\">A-Z</span></div>\n            <div class=\"multi-select__option\" data-value=\"za\"><span class=\"option-text\">Z-A</span></div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"search-bar\" id=\"games-search\">\n      <div class=\"search-bar__wrapper\">\n        <div class=\"search-bar__icon\"></div>\n        <input class=\"search-bar__input\" placeholder=\"Search games\" type=\"text\">\n        <div class=\"search-bar__clear\"></div>\n      </div>\n      <div class=\"search-bar__dropdown\"></div>\n    </div>\n  </div>\n\n  <div class=\"our-games__tags\" id=\"active-tags\"></div>\n\n  <div class=\"our-games__grid-wrap\">\n    <div class=\"our-games__grid\" id=\"games-grid\"></div>\n  </div>\n\n  <div class=\"our-games__load-more\">\n    <button class=\"btn btn-secondary\" id=\"load-more-btn\">MORE GAMES</button>\n  </div>\n</div>\n\n<script>\n    (function () {\n        const ITEMS_PER_PAGE = 12;\n        let allGames = [];\n        let filteredGames = [];\n        let visibleCount = ITEMS_PER_PAGE;\n        let searchQuery = '';\n        let activeTags = [];\n        let sortMode = 'newest';\n\n        const grid = document.getElementById('games-grid');\n        const tagsContainer = document.getElementById('active-tags');\n        const loadMoreBtn = document.getElementById('load-more-btn');\n        const loadMoreWrap = document.querySelector('.our-games__load-more');\n        const ourGamesRoot = document.querySelector('.our-games');\n        const filtersToggle = document.querySelector('.our-games__filters-toggle');\n        const filtersBackdrop = document.querySelector('.our-games__filters-backdrop');\n\n        function paintGridSkeletons(count) {\n            if (!grid || grid.children.length) return;\n            const n = count || ITEMS_PER_PAGE;\n            grid.innerHTML = Array.from({ length: n }, () =>\n                '<div class=\"game-card game-card--medium game-card--loading game-card--skeleton\" aria-hidden=\"true\"></div>'\n            ).join('');\n        }\n\n        paintGridSkeletons();\n\n        function hasDemoLink(g) {\n            const link = g && g.link;\n            return typeof link === 'string' && link.trim() !== '';\n        }\n\n        function setFiltersSheetOpen(open) {\n            if (!ourGamesRoot || !filtersToggle) return;\n            ourGamesRoot.classList.toggle('our-games--filters-open', open);\n            filtersToggle.setAttribute('aria-expanded', open ? 'true' : 'false');\n            if (filtersBackdrop) {\n                filtersBackdrop.setAttribute('aria-hidden', open ? 'false' : 'true');\n            }\n\n            if (open) {\n                document.documentElement.style.overflow = 'hidden';\n                document.body.style.overflow = 'hidden';\n            } else {\n                document.documentElement.style.overflow = '';\n                document.body.style.overflow = '';\n            }\n        }\n\n        if (filtersToggle) {\n            filtersToggle.addEventListener('click', (e) => {\n                e.stopPropagation();\n                setFiltersSheetOpen(!ourGamesRoot.classList.contains('our-games--filters-open'));\n            });\n        }\n        if (filtersBackdrop) {\n            filtersBackdrop.addEventListener('click', () => setFiltersSheetOpen(false));\n        }\n        document.addEventListener('keydown', (e) => {\n            if (e.key === 'Escape' && ourGamesRoot && ourGamesRoot.classList.contains('our-games--filters-open')) {\n                setFiltersSheetOpen(false);\n            }\n        });\n\n        /** Matches `.our-games__grid` column breakpoints in ourGames.css */\n        function getGridColumnCount() {\n            const w = window.innerWidth;\n            if (w <= 440) return 2;\n            if (w <= 680) return 3;\n            return 4;\n        }\n\n        function getRenderSliceEnd() {\n            const len = filteredGames.length;\n            if (len === 0) return 0;\n            if (visibleCount >= len) return len;\n            const cols = getGridColumnCount();\n            return Math.min(visibleCount + cols, len);\n        }\n\n        const searchInput = document.querySelector('#games-search .search-bar__input');\n        const searchDropdown = document.querySelector('#games-search .search-bar__dropdown');\n        const searchBar = document.getElementById('games-search');\n        const searchClear = document.querySelector('#games-search .search-bar__clear');\n\n        function classifyGames(games, isNewGame) {\n            games.forEach(g => {\n                if (isNewGame(g.goLiveDate)) {\n                    g.newGame = true;\n                }\n            });\n        }\n\n        async function init() {\n            try {\n                const {loadAllGames, isNewGame} = await import(\n                    new URL('modules/gamesLoader.js', document.baseURI).href\n                    );\n                allGames = await loadAllGames();\n                classifyGames(allGames, isNewGame);\n                let featureKeysFromConfig = null;\n                try {\n                    const fr = await fetch('filters.json');\n                    if (fr.ok) {\n                        const cfg = await fr.json();\n                        const feat = cfg?.filters?.features;\n                        if (feat && typeof feat === 'object' && !Array.isArray(feat)) {\n                            featureKeysFromConfig = Object.keys(feat).filter(k => feat[k] === true);\n                        }\n                    }\n                } catch (e) {\n                    console.warn('filters.json not loaded:', e);\n                }\n                setupTagDropdown(\n                    document.getElementById('theme-select'),\n                    document.getElementById('theme-options'),\n                    'themes',\n                    allThemeValues\n                );\n                setupTagDropdown(\n                    document.getElementById('features-select'),\n                    document.getElementById('features-options'),\n                    'features',\n                    allFeatureValues,\n                    featureKeysFromConfig\n                );\n                applyFilters();\n            } catch (err) {\n                console.error('Failed to load games:', err);\n            }\n        }\n\n        function featureKeyToLabel(key) {\n            return String(key)\n                .replace(/([a-z])([A-Z])/g, '$1 $2')\n                .replace(/^./, c => c.toUpperCase());\n        }\n\n        function featureFilterButtonLabel(key) {\n            const display = featureKeyToLabel(key).trim().replace(/\\s+/g, ' ');\n            if (/\\bfeatures?$/i.test(display)) return display;\n            return `${display} Feature`;\n        }\n\n        function themeFilterButtonLabel(raw) {\n            const display = featureKeyToLabel(String(raw)).trim().replace(/\\s+/g, ' ');\n            if (/\\bthemes?$/i.test(display)) return display;\n            return `${display} Theme`;\n        }\n\n        function getGameFilterFeatureStrings(g) {\n            const f = g?.filters?.features;\n            if (f && typeof f === 'object' && !Array.isArray(f)) {\n                return Object.entries(f)\n                    .filter(([, v]) => v === true)\n                    .map(([k]) => k.toLowerCase());\n            }\n            if (Array.isArray(f)) {\n                return f.map(x =>\n                    (typeof x === 'object' && x?.name ? x.name : String(x)).toLowerCase()\n                );\n            }\n            return [];\n        }\n\n        function applyFilters() {\n            const now = new Date();\n            now.setHours(0, 0, 0, 0);\n            filteredGames = allGames.filter(g => {\n                if (!g.goLiveDate) return true;\n                return new Date(g.goLiveDate) <= now;\n            });\n\n            if (searchQuery) {\n                const q = searchQuery.toLowerCase();\n                filteredGames = filteredGames.filter(g => g.name.toLowerCase().includes(q));\n            }\n\n            if (activeTags.length > 0) {\n                filteredGames = filteredGames.filter(g => {\n                    const themes = (g?.filters?.themes || g?.themes || []).map(t => String(t).toLowerCase());\n                    const featureStrings = getGameFilterFeatureStrings(g);\n                    const all = [...themes, ...featureStrings, g.name.toLowerCase()];\n                    return activeTags.every(tag => {\n                        const t = tag.toLowerCase();\n                        return all.some(a => a.includes(t));\n                    });\n                });\n            }\n\n            if (sortMode === 'az') {\n                filteredGames.sort((a, b) => a.name.localeCompare(b.name));\n            } else if (sortMode === 'za') {\n                filteredGames.sort((a, b) => b.name.localeCompare(a.name));\n            } else if (sortMode === 'newest') {\n                const withDate = filteredGames.filter(g => g.goLiveDate);\n                const noDate = filteredGames.filter(g => !g.goLiveDate);\n                withDate.sort((a, b) => new Date(b.goLiveDate) - new Date(a.goLiveDate));\n                filteredGames = [...withDate, ...noDate];\n            }\n\n            visibleCount = ITEMS_PER_PAGE;\n            renderGrid(false);\n            renderTags();\n            updateLoadMoreBtn();\n        }\n\n        function buildCardHTML(game) {\n            const badge = game.newGame\n                ? '<div class=\"game-card__badge\">NEW GAME</div>'\n                : '';\n\n            const moreInfoHref = `pages/game.html?game=${encodeURIComponent(game.name)}`;\n            const demoBtn = hasDemoLink(game)\n                ? `<a class=\"btn btn-primary icon-play\" href=\"${game.link}\" target=\"_blank\" rel=\"noopener noreferrer\">DEMO</a>`\n                : '';\n            return `\n            <div class=\"game-card game-card--medium game-card--loading\" data-more-info=\"${moreInfoHref}\">\n                ${badge}\n                <img class=\"game-card__img\" src=\"${game.thumbnailR || game.thumbnail || ''}\" alt=\"${game.name}\" loading=\"lazy\">\n                <div class=\"game-card__overlay\">\n                    <span class=\"game-card__header\">${game.name}</span>\n                    <div class=\"game-card__actions\">\n                        ${demoBtn}\n                        <a class=\"btn btn-secondary\" href=\"${moreInfoHref}\">MORE INFO</a>\n                    </div>\n                </div>\n            </div>`;\n        }\n\n        /**\n         * DOM prefix matches filtered order — lets “Load more” append nodes only (no full innerHTML refresh).\n         */\n        function gridPrefixMatchesFilteredOrder(visible, count) {\n            if (count === 0 || count > visible.length) return false;\n            const children = grid.children;\n            if (children.length < count) return false;\n            for (let i = 0; i < count; i++) {\n                const title = children[i].querySelector('.game-card__header')?.textContent?.trim();\n                if (title !== visible[i].name) return false;\n            }\n            return true;\n        }\n\n        function appendGameCardsFromSlice(games, withMotion) {\n            games.forEach((g, idx) => {\n                const tpl = document.createElement('template');\n                tpl.innerHTML = buildCardHTML(g).trim();\n                const card = tpl.content.firstElementChild;\n                if (!card) return;\n                grid.appendChild(card);\n                if (!withMotion) return;\n                card.style.opacity = '0';\n                card.style.transform = 'translateY(14px)';\n                const delay = Math.min(idx, 10) * 0.032;\n                requestAnimationFrame(() => {\n                    requestAnimationFrame(() => {\n                        card.style.transition =\n                            `opacity 0.38s cubic-bezier(0.25, 0.1, 0.25, 1) ${delay}s, ` +\n                            `transform 0.38s cubic-bezier(0.25, 0.1, 0.25, 1) ${delay}s`;\n                        card.style.opacity = '1';\n                        card.style.transform = 'translateY(0)';\n                    });\n                });\n            });\n        }\n\n        function renderGrid(animate) {\n            const sliceEnd = getRenderSliceEnd();\n            const visible = filteredGames.slice(0, sliceEnd);\n            const prevCount = grid.children.length;\n\n            const canAppendMore =\n                animate &&\n                visible.length > prevCount &&\n                prevCount > 0 &&\n                gridPrefixMatchesFilteredOrder(visible, prevCount);\n\n            if (canAppendMore) {\n                appendGameCardsFromSlice(visible.slice(prevCount), true);\n                return;\n            }\n\n            grid.innerHTML = visible.map(g => buildCardHTML(g)).join('');\n            if (animate && prevCount < visible.length) {\n                [...grid.children].forEach((card, i) => {\n                    if (i >= prevCount) {\n                        card.style.opacity = '0';\n                        card.style.transform = 'translateY(14px)';\n                        requestAnimationFrame(() => {\n                            requestAnimationFrame(() => {\n                                const delay = (i - prevCount) * 0.04;\n                                card.style.transition =\n                                    `opacity 0.38s cubic-bezier(0.25, 0.1, 0.25, 1) ${delay}s, ` +\n                                    `transform 0.38s cubic-bezier(0.25, 0.1, 0.25, 1) ${delay}s`;\n                                card.style.opacity = '1';\n                                card.style.transform = 'translateY(0)';\n                            });\n                        });\n                    }\n                });\n            }\n        }\n\n        const allThemeValues = new Set();\n        const allFeatureValues = new Set();\n\n        function getTagType(tag) {\n            return allFeatureValues.has(tag) ? 'btn tag-secondary' : 'btn tag-primary';\n        }\n\n        function renderTags() {\n            tagsContainer.innerHTML = activeTags.map(tag => `\n            <button class=\"${getTagType(tag)}\" data-tag=\"${tag}\">${tag}</button>\n        `).join('');\n\n            tagsContainer.querySelectorAll('[data-tag]').forEach(btn => {\n                btn.addEventListener('click', () => {\n                    activeTags = activeTags.filter(t => t !== btn.dataset.tag);\n                    applyFilters();\n                    updateDropdownLabels();\n                });\n            });\n        }\n\n        function updateLoadMoreBtn() {\n            const hide = visibleCount >= filteredGames.length;\n            if (loadMoreWrap) {\n                loadMoreWrap.style.display = hide ? 'none' : 'flex';\n            } else {\n                loadMoreBtn.style.display = hide ? 'none' : '';\n            }\n        }\n\n        loadMoreBtn.addEventListener('click', () => {\n            visibleCount += ITEMS_PER_PAGE;\n            renderGrid(true);\n            updateLoadMoreBtn();\n        });\n\n        window.addEventListener('resize', () => {\n            if (window.innerWidth > 600) {\n                setFiltersSheetOpen(false);\n            }\n        });\n\n        // Search\n        searchInput.addEventListener('input', () => {\n            const val = searchInput.value.trim();\n            searchQuery = val;\n\n            if (val.length > 0) {\n                searchBar.classList.add('is-open', 'has-text');\n                const matches = allGames.filter(g => g.name.toLowerCase().includes(val.toLowerCase())).slice(0, 8);\n                searchDropdown.innerHTML = matches.map(g =>\n                    `<div class=\"search-bar__result\" data-name=\"${g.name}\">${g.name.replace(new RegExp('(' + val.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') + ')', 'gi'), '<b>$1</b>')}</div>`\n                ).join('');\n            } else {\n                searchBar.classList.remove('is-open', 'has-text');\n                searchDropdown.innerHTML = '';\n            }\n\n            applyFilters();\n        });\n\n        searchDropdown.addEventListener('click', (e) => {\n            const result = e.target.closest('.search-bar__result');\n            if (!result) return;\n            searchInput.value = result.dataset.name;\n            searchQuery = result.dataset.name;\n            searchBar.classList.remove('is-open');\n            applyFilters();\n        });\n\n        searchClear.addEventListener('click', () => {\n            searchInput.value = '';\n            searchQuery = '';\n            searchBar.classList.remove('is-open', 'has-text');\n            searchDropdown.innerHTML = '';\n            applyFilters();\n        });\n\n        // Sort dropdown\n        const sortSelect = document.getElementById('sort-select');\n        const sortLabel = sortSelect.querySelector('.multi-select__label');\n\n        sortSelect.addEventListener('click', (e) => {\n            e.stopPropagation();\n            sortSelect.classList.toggle('is-open');\n        });\n\n        sortSelect.querySelectorAll('.multi-select__option').forEach(opt => {\n            opt.addEventListener('click', (e) => {\n                e.stopPropagation();\n                sortMode = opt.dataset.value;\n                const text = opt.querySelector('.option-text')?.textContent?.trim() ?? opt.textContent.trim();\n                sortLabel.textContent = text;\n                sortSelect.classList.remove('is-open');\n                applyFilters();\n            });\n        });\n\n        // Theme & Features dropdowns (tags)\n        const dropdowns = [];\n\n        function updateDropdownLabels() {\n            dropdowns.forEach(({selectEl, valuesSet, property}) => {\n                const label = selectEl.querySelector('.multi-select__label');\n                const baseLabel = selectEl.dataset.label;\n                const picked = activeTags.filter(t => valuesSet.has(t));\n\n                if (picked.length === 0) {\n                    label.textContent = baseLabel;\n                } else if (picked.length === 1) {\n                    const v = picked[0];\n                    if (property === 'features') {\n                        label.textContent = featureFilterButtonLabel(v);\n                    } else if (property === 'themes') {\n                        label.textContent = themeFilterButtonLabel(v);\n                    } else {\n                        label.textContent = String(v);\n                    }\n                } else if (property === 'features') {\n                    label.textContent = 'Multiple features';\n                } else if (property === 'themes') {\n                    label.textContent = 'Multiple themes';\n                } else {\n                    label.textContent = 'Multiple';\n                }\n\n                // Sync checkbox icons\n                selectEl.querySelectorAll('.multi-select__option').forEach(opt => {\n                    const icon = opt.querySelector('.multi-select__icon');\n                    if (!icon) return;\n                    if (activeTags.includes(opt.dataset.value)) {\n                        icon.classList.remove('inactive');\n                        icon.classList.add('active');\n                    } else {\n                        icon.classList.remove('active');\n                        icon.classList.add('inactive');\n                    }\n                });\n            });\n        }\n\n        function setupTagDropdown(selectEl, optionsEl, property, valuesSet, precomputedOptionValues) {\n            dropdowns.push({selectEl, valuesSet, property});\n\n            selectEl.addEventListener('click', (e) => {\n                e.stopPropagation();\n\n                if (!optionsEl.children.length) {\n                    if (Array.isArray(precomputedOptionValues) && precomputedOptionValues.length) {\n                        precomputedOptionValues.forEach(v => {\n                            if (v) valuesSet.add(v);\n                        });\n                    } else if (Array.isArray(precomputedOptionValues) && precomputedOptionValues.length === 0) {\n                        selectEl.classList.add('inactive');\n                        return;\n                    } else {\n                        allGames.forEach(g => (g[property] || []).forEach(v => {\n                            const name = typeof v === 'object' && v !== null && v.name ? v.name : String(v);\n                            if (name) valuesSet.add(name);\n                        }));\n                    }\n\n                    if (valuesSet.size === 0) {\n                        selectEl.classList.add('inactive');\n                        return;\n                    }\n\n                    const list = precomputedOptionValues && precomputedOptionValues.length\n                        ? precomputedOptionValues.slice().sort()\n                        : [...valuesSet].sort();\n                    const optionLabel = (v) => property === 'features' ? featureKeyToLabel(v) : v;\n                    optionsEl.innerHTML = list.map(v => `\n                    <div class=\"multi-select__option\" data-value=\"${v}\">\n                        <span class=\"option-text\">${optionLabel(v)}</span>\n                        <span class=\"multi-select__icon ${activeTags.includes(v) ? 'active' : 'inactive'}\"></span>\n                    </div>\n                `).join('');\n                }\n\n                selectEl.classList.toggle('is-open');\n            });\n\n            optionsEl.addEventListener('click', (e) => {\n                e.stopPropagation();\n                const opt = e.target.closest('.multi-select__option');\n                if (!opt) return;\n\n                const val = opt.dataset.value;\n                const icon = opt.querySelector('.multi-select__icon');\n\n                if (activeTags.includes(val)) {\n                    activeTags = activeTags.filter(t => t !== val);\n                    icon.classList.remove('active');\n                    icon.classList.add('inactive');\n                } else {\n                    activeTags.push(val);\n                    icon.classList.remove('inactive');\n                    icon.classList.add('active');\n                }\n                applyFilters();\n                updateDropdownLabels();\n            });\n        }\n\n        // Close dropdowns on outside click\n        document.addEventListener('click', () => {\n            document.querySelectorAll('.our-games .multi-select').forEach(el => el.classList.remove('is-open'));\n        });\n\n        init();\n    })();\n</script>\n","partners-section":"<div class=\"partners-section__container margin-bottom\">\n  <div class=\"partners-section__intro\">\n    <h1>Our <b>partners</b></h1>\n    <p>At Spinberry, we design next-generation slot experiences that combine innovative mechanics, beautiful design, and responsible entertainment.</p>\n    <a class=\"btn btn-secondary\" href=\"pages/ourPartners.html\">ALL PARTNERS</a>\n  </div>\n  <div aria-hidden=\"true\" class=\"partners-section__sliders\" data-partners-sliders></div>\n</div>\n","advantages-section":"<div class=\"advantages-section__container margin-bottom\">\n  <h1>Why spinberry?</h1>\n  <div class=\"advantages-section__grid\">\n    <div class=\"advantages-section__item\">\n      <div class=\"advantages-section__icon\">\n        <img alt=\"clover\" src=\"images/advantages/clover.webp\">\n      </div>\n      <div class=\"advantages-section__content\">\n        <h4>Game profitability</h4>\n        <p>Games designed for optimum balance between player experience and operator profitability.</p>\n      </div>\n    </div>\n    <div class=\"advantages-section__item\">\n      <div class=\"advantages-section__icon\">\n        <img alt=\"clover\" src=\"images/advantages/clover.webp\">\n      </div>\n      <div class=\"advantages-section__content\">\n        <h4>Rapid growth</h4>\n        <p>Fastest growing studio with multiple operators.</p>\n      </div>\n    </div>\n    <div class=\"advantages-section__item\">\n      <div class=\"advantages-section__icon\">\n        <img alt=\"clover\" src=\"images/advantages/clover.webp\">\n      </div>\n      <div class=\"advantages-section__content\">\n        <h4>More choice. More control. More excitement.</h4>\n        <p>Spinberry games let players decide when to spin, when to stop, and how to play.</p>\n      </div>\n    </div>\n    <div class=\"advantages-section__item\">\n      <div class=\"advantages-section__icon\">\n        <img alt=\"clover\" src=\"images/advantages/clover.webp\">\n      </div>\n      <div class=\"advantages-section__content\">\n        <h4>Unique features and mechanics</h4>\n        <img alt=\"Unique game features and mechanics\" class=\"advantages-section__features\" decoding=\"async\" height=\"63\" loading=\"lazy\" src=\"images/advantages/features.webp\" width=\"361\">\n      </div>\n    </div>\n  </div>\n</div>","difference-section":"<div class=\"difference-section__container margin-bottom\">\n  <h1>What makes <b>spinberry different</b></h1>\n  <div class=\"difference-section__grid\">\n    <div class=\"difference-section__item\">\n      <div class=\"difference-section__icon\">\n        <img alt=\"scarab\" src=\"images/advantages/scarab.webp\">\n      </div>\n      <div class=\"difference-section__content\">\n        <h4>We think BIG</h4>\n        <p>We challenge conventions and explore bold ideas </p>\n      </div>\n    </div>\n    <div class=\"difference-section__item\">\n      <div class=\"difference-section__icon\">\n        <img alt=\"scarab\" src=\"images/advantages/scarab.webp\">\n      </div>\n      <div class=\"difference-section__content\">\n        <h4>We set new standards</h4>\n        <p>Our quality, high performance, and originality at your service </p>\n      </div>\n    </div>\n    <div class=\"difference-section__item\">\n      <div class=\"difference-section__icon\">\n        <img alt=\"scarab\" src=\"images/advantages/scarab.webp\">\n      </div>\n      <div class=\"difference-section__content\">\n        <h4>We innovate</h4>\n        <p>New mechanics, smarter math models, and fresh gameplay </p>\n      </div>\n    </div>\n    <div class=\"difference-section__item\">\n      <div class=\"difference-section__icon\">\n        <img alt=\"scarab\" src=\"images/advantages/scarab.webp\">\n      </div>\n      <div class=\"difference-section__content\">\n        <h4>We deliver profitability</h4>\n        <p>Games built to perform for operators </p>\n      </div>\n    </div>\n    <div class=\"difference-section__item\">\n      <div class=\"difference-section__icon\">\n        <img alt=\"scarab\" src=\"images/advantages/scarab.webp\">\n      </div>\n      <div class=\"difference-section__content\">\n        <h4>We are player-first</h4>\n        <p>Every feature is designed with player enjoyment at its heart </p>\n      </div>\n    </div>\n  </div>\n</div>\n<img alt=\"\" aria-hidden=\"true\" class=\"difference-section__character\" decoding=\"async\" height=\"389\" loading=\"lazy\" src=\"images/aboutUs/character.png\" width=\"458\">\n","contact-form-section":"<div class=\"contact-form-section__layout\">\n    <div class=\"contact-form-section__container\">\n        <div class=\"contact-form-section__copy\">\n            <h1 class=\"contact-form-section__title\">Get in <b>touch</b></h1>\n            <p class=\"contact-form-section__intro\">Whether you’re an operator, aggregator, platform partner, or just curious about our games, we’d love to hear from you. At Spinberry, we believe great partnerships start with a simple conversation. If you’re interested in our slot games, integrations, or business opportunities, our team is ready to connect.</p>\n        </div>\n        <div class=\"contact-form-section__form\">\n            <form action=\"https://formgrid.dev/api/f/7en730kw\" id=\"send_email\" method=\"POST\" novalidate>\n            <label class=\"contact-form-section__label\">\n                <input autocomplete=\"given-name\" class=\"contact-form-section__input\" id=\"contact-firstName\" name=\"firstName\" placeholder=\"Name\" type=\"text\">\n                <span class=\"contact-form-section__error\" data-error-for=\"firstName\" role=\"alert\"></span>\n            </label>\n            <label class=\"contact-form-section__label\">\n                <input autocomplete=\"email\" class=\"contact-form-section__input\" id=\"contact-email\" name=\"email\" placeholder=\"Mail Address\" type=\"email\">\n                <span class=\"contact-form-section__error\" data-error-for=\"email\" role=\"alert\"></span>\n            </label>\n            <label class=\"contact-form-section__label\">\n                <textarea class=\"contact-form-section__input contact-form-section__textarea\" id=\"contact-message\" name=\"message\" placeholder=\"Message\" rows=\"2\"></textarea>\n                <span class=\"contact-form-section__error\" data-error-for=\"message\" role=\"alert\"></span>\n            </label>\n            <div class=\"contact-form-section__consent-wrap\">\n                <label class=\"contact-form-section__consent\">\n                    <input class=\"contact-form-section__checkbox\" id=\"contact-consent\" name=\"consent\" type=\"checkbox\">\n                    <span>I agree to the processing of my personal data*</span>\n                </label>\n                <span class=\"contact-form-section__error\" data-error-for=\"consent\" role=\"alert\"></span>\n            </div>\n            <div class=\"contact-form-section__button-container\">\n                <button class=\"contact-form-section__submit\" type=\"submit\">SEND NOW</button>\n                <div aria-live=\"polite\" class=\"contact-form-section__success\" id=\"contact-form-section__success-email\"></div>\n            </div>\n        </form>\n        </div>\n    </div>\n    <div aria-hidden=\"true\" class=\"contact-form-section__aside\">\n        <img alt=\"\" decoding=\"async\" height=\"2598\" loading=\"lazy\" src=\"images/contactUs/background_right.webp\" width=\"3952\">\n    </div>\n</div>\n<script>\n(function () {\n    const form = document.getElementById('send_email');\n    const successEl = document.getElementById('contact-form-section__success-email');\n    if (!form || !successEl) return;\n\n    const emailRe = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\n    function clearFieldErrors() {\n        form.querySelectorAll('.contact-form-section__error').forEach(function (el) {\n            el.textContent = '';\n        });\n    }\n\n    function setError(name, message) {\n        const el = form.querySelector('[data-error-for=\"' + name + '\"]');\n        if (el) el.textContent = message;\n    }\n\n    function validateForm() {\n        clearFieldErrors();\n        let ok = true;\n\n        const firstName = (form.querySelector('[name=\"firstName\"]') || {}).value;\n        if (!firstName || !String(firstName).trim()) {\n            setError('firstName', 'Please fill in your name.');\n            ok = false;\n        }\n\n        const email = (form.querySelector('[name=\"email\"]') || {}).value;\n        const emailTrim = email ? String(email).trim() : '';\n        if (!emailTrim) {\n            setError('email', 'Please fill in your email address.');\n            ok = false;\n        } else if (!emailRe.test(emailTrim)) {\n            setError('email', 'Please enter a valid email address.');\n            ok = false;\n        }\n\n        const message = (form.querySelector('[name=\"message\"]') || {}).value;\n        if (!message || !String(message).trim()) {\n            setError('message', 'Please enter a message.');\n            ok = false;\n        }\n\n        const consent = form.querySelector('[name=\"consent\"]');\n        if (!consent || !consent.checked) {\n            setError('consent', 'Please accept the processing of personal data to continue.');\n            ok = false;\n        }\n\n        return ok;\n    }\n\n    function clearErrorForField(el) {\n        var name = el.name;\n        if (!name) return;\n        var err = form.querySelector('[data-error-for=\"' + name + '\"]');\n        if (err) err.textContent = '';\n    }\n\n    form.querySelectorAll('.contact-form-section__input, .contact-form-section__checkbox').forEach(function (el) {\n        el.addEventListener('input', function () { clearErrorForField(el); });\n        el.addEventListener('change', function () { clearErrorForField(el); });\n    });\n\n    form.addEventListener('submit', async function (e) {\n        e.preventDefault();\n        successEl.textContent = '';\n\n        if (!validateForm()) {\n            ['firstName', 'email', 'message', 'consent'].some(function (name) {\n                var err = form.querySelector('[data-error-for=\"' + name + '\"]');\n                if (!err || !err.textContent.trim()) return false;\n                var field = form.querySelector('[name=\"' + name + '\"]');\n                if (field && field.focus) field.focus();\n                return true;\n            });\n            return;\n        }\n\n        const submitBtn = form.querySelector('.contact-form-section__submit');\n        if (submitBtn) {\n            submitBtn.disabled = true;\n        }\n        try {\n            const res = await fetch(form.action, {\n                method: form.method,\n                body: new FormData(form),\n                headers: { Accept: 'application/json' }\n            });\n            if (res.ok) {\n                successEl.textContent = 'Email sent.';\n                form.reset();\n                clearFieldErrors();\n            } else {\n                successEl.textContent = 'Something went wrong.';\n            }\n        } catch (err) {\n            successEl.textContent = 'Something went wrong.';\n        }\n        if (submitBtn) submitBtn.disabled = false;\n        setTimeout(function () { successEl.textContent = ''; }, 3000);\n    });\n})();\n</script>","footer":"<!-- Site footer -->\n<div class=\"footer__container\">\n  <div class=\"footer__top\">\n    <div class=\"footer__contact\">\n      <h3>Get in <b>touch</b></h3>\n      <p class=\"footer__description\">\n        Whether you’re an operator, aggregator, platform partner, or just curious about our games, we’d love to hear\n        from you. At Spinberry, we believe great partnerships start with a simple conversation. If you’re interested in\n        our slot games, integrations, or business opportunites, our team is ready to connect.\n      </p>\n      <a class=\"btn btn-secondary\" href=\"pages/contacts.html\">CONTACT</a>\n    </div>\n    <div class=\"footer__navigation\">\n      <div class=\"footer__pages\">\n        <h3>Pages</h3>\n        <nav class=\"footer__menu\">\n          <a href=\"pages/games.html\">Games</a>\n          <a href=\"pages/rgs.html\">RGS</a>\n          <a href=\"pages/aboutUs.html\">About Us</a>\n          <a href=\"pages/ourPartners.html\">Partners</a>\n          <a href=\"pages/contacts.html\">Contact Us</a>\n        </nav>\n      </div>\n\n      <div class=\"footer__socials\">\n        <h3>Socials</h3>\n        <nav class=\"footer__menu\">\n          <a class=\"social-link\" href=\"https://www.linkedin.com/company/spinberrygames/\" rel=\"noopener noreferrer\" target=\"_blank\">\n            <img alt=\"LinkedIn\" src=\"images/icons/linkedIn.svg\">\n            LinkedIn\n          </a>\n          <a class=\"social-link\" href=\"https://www.instagram.com/spinberry.games/\" rel=\"noopener noreferrer\" target=\"_blank\">\n            <img alt=\"Instagram\" src=\"images/icons/instagram.svg\">\n            Instagram\n          </a>\n          <a class=\"social-link\" href=\"https://www.facebook.com/spinberrygames/\" rel=\"noopener noreferrer\" target=\"_blank\">\n            <img alt=\"Facebook\" src=\"images/icons/facebook.svg\">\n            Facebook\n          </a>\n        </nav>\n      </div>\n    </div>\n  </div>\n  <div class=\"footer__bottom\">\n    <img alt=\"Spinberry\" src=\"images/spinberry_logo.svg\">\n    <p>Spinberry © Copyright 2021-2026. All rights reserved</p>\n  </div>\n</div>\n"}
