{"id":14468,"date":"2026-09-09T13:17:56","date_gmt":"2026-09-09T11:17:56","guid":{"rendered":"https:\/\/www.trolskaskogen.se\/?page_id=14468"},"modified":"2026-09-09T16:54:58","modified_gmt":"2026-09-09T14:54:58","slug":"wreath-making-class-nov-15","status":"publish","type":"page","link":"https:\/\/www.trolskaskogen.se\/en\/wreath-making-class-nov-15\/","title":{"rendered":"Wreath-Making Class, Nov. 15"},"content":{"rendered":"<div id=\"buy-ticket-module\" class=\"max-w-[800px]  xl:container mx-auto py-20 px-4 -mb-12\">\n    <div class=\"bg-chanterelleTwo relative h-full xl:h-[960px] rounded-lg overflow-hidden\">\n        <img decoding=\"async\" class=\"absolute right-0 object-cover h-full hidden xl:block z-10 rounded-lg\"\n             src=\"https:\/\/images.ohmyhosting.se\/l6uzSTXOeqDnd_LjtKTXxpgooa8=\/fit-in\/1233x960\/smart\/filters:quality(92)\/https%3A%2F%2Fwww.trolskaskogen.se%2Fwp-content%2Fuploads%2F2025%2F10%2Fkransbindarkurs_2000px.jpg\"\n              srcset=\"https:\/\/images.ohmyhosting.se\/l6uzSTXOeqDnd_LjtKTXxpgooa8=\/fit-in\/1233x960\/smart\/filters:quality(92)\/https%3A%2F%2Fwww.trolskaskogen.se%2Fwp-content%2Fuploads%2F2025%2F10%2Fkransbindarkurs_2000px.jpg\"              alt=\"wreath-making-class_2000px\" loading=\"lazy\">\n        <img decoding=\"async\" class=\"object-cover w-full xl:hidden\" src=\"https:\/\/images.ohmyhosting.se\/-uthGcWcFV_Glu9qkqvBbRYOoaU=\/fit-in\/358x220\/smart\/filters:quality(92)\/https%3A%2F%2Fwww.trolskaskogen.se%2Fwp-content%2Fuploads%2F2025%2F10%2Fkransbindarkurs_2000px.jpg\"\n              srcset=\"https:\/\/images.ohmyhosting.se\/-uthGcWcFV_Glu9qkqvBbRYOoaU=\/fit-in\/358x220\/smart\/filters:quality(92)\/https%3A%2F%2Fwww.trolskaskogen.se%2Fwp-content%2Fuploads%2F2025%2F10%2Fkransbindarkurs_2000px.jpg\"              alt=\"wreath-making-class_2000px\" loading=\"lazy\">\n        <div class=\"absolute top-0 -left-70 h-full z-20 pointer-events-none hidden xl:block w-[75%]\">\n            <div class=\"flex items-start justify-start h-full\">\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 643 660\"\n                     class=\"text-chanterelleTwo w-full h-full\">\n                    <path d=\"M560 660H0V0L560 0C670.617 210.032 670.617 449.968 560 660Z\" fill=\"currentColor\" \/>\n                <\/svg>\n            <\/div>\n        <\/div>\n        <div class=\"relative pb-20\">\n            <div class=\"absolute top-0 sm:-top-10 md:-top-16 -mt-[55px] mb-16 w-full z-20 pointer-events-none block xl:hidden\">\n                <svg class=\"text-chanterelleTwo w-full h-full\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n                     viewbox=\"0 0 358 60\" fill=\"none\">\n                    <path d=\"M358 41.6023V60H0V41.6023C113.926 -13.8674 244.074 -13.8674 358 41.6023Z\"\n                          fill=\"currentColor\" \/>\n                <\/svg>\n            <\/div>\n            <div class=\"relative flex flex-col items-start md:w-[415px] pt-8 md:pt-20 md:ml-28 px-6 md:px-0 z-30 justify-center\">\n                <div class=\"max-w-3xl flex flex-col gap-3 mb-8\">\n                    <h2 class=\"text-peppery heading-lg\">\n                        Wreath making course \n                    <\/h2>\n                    <h2 class=\"text-peppery body-md\">Sunday, November 15, 2026<\/h2>\n                <\/div>\n                \n                                <div id=\"person-names-translations\" style=\"position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;\" aria-hidden=\"true\">\n                                            <span data-original=\"Kransbindarkurs\">Wreath making course<\/span>\n                                            <span data-original=\"Vuxen (fr\u00e5n 13 \u00e5r)\">Adult (ages 13 and up)<\/span>\n                                    <\/div>\n                                    <div class=\"w-full mb-4\">\n                        <div class=\"relative\">\n                            <label for=\"product-selector\" class=\"block text-peppery font-excon font-medium mb-2\">\n                                Performance\n                            <\/label>\n                            <select\n                                id=\"product-selector\"\n                                name=\"product-selector\"\n                                class=\"js-show-select decorated appearance-none bg-white rounded-3xl px-4 py-2 focus:outline-none w-full md:w-[416px] text-black font-excon text-sm\"\n                            >\n                                                                    <option  value=\"14465\"  selected='selected'>\n                                        Wreath-Making Class \u2013 Nov. 15, 2026\n                                    <\/option>\n                                                                    <option  value=\"627\" >\n                                        Nightmares, Oct. 23\u201324\n                                    <\/option>\n                                                            <\/select>\n                            <div class=\"pointer-events-none absolute right-0 top-13 -translate-y-1\/2 flex items-center justify-center pr-3\">\n                                <svg class=\"h-4 w-4 text-black\"  viewbox=\"0 0 24 24\"  fill=\"none\"  stroke=\"currentColor\"  stroke-width=\"2\"  stroke-linecap=\"round\"  stroke-linejoin=\"round\">  <polyline points=\"6 9 12 15 18 9\" \/><\/svg>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                    <div id=\"booking-calendar-container\" class=\"w-full\">\n                        <div id=\"person-types-info\" class=\"mt-2 space-y-2\"><\/div>\n                        <div class=\"mb-4\">\n                            <label for=\"date-input\" class=\"block text-base font-excon mb-2 font-medium text-peppery\">\n                                date\n                            <\/label>\n                            <input id=\"date-input\" name=\"date-input\" type=\"text\"\n                                   class=\"kreng-datepicker decorated appearance-none bg-white rounded-3xl px-4 py-2 focus:outline-none w-full md:w-[416px] text-black text-sm font-excon\"\n                                   placeholder=\"Select date\" autocomplete=\"off\" inputmode=\"none\">\n                        <\/div>\n                        <div class=\"mb-4\">\n                            <div class=\"relative\">\n                                <label for=\"time-selector\" class=\"block text-peppery font-excon font-medium mb-2\">\n                                    Time\n                                <\/label>\n                                <select\n                                    id=\"time-selector\"\n                                    name=\"time-selector\"\n                                    class=\"decorated appearance-none bg-white rounded-3xl px-4 py-2 focus:outline-none w-full md:w-[416px] text-back text-sm font-excon\"\n                                >\n                                    <option value=\"\">Select date first<\/option>\n                                <\/select>\n                                <div class=\"pointer-events-none absolute right-0 top-13 -translate-y-1\/2 flex items-center justify-center pr-3\">\n                                    <svg class=\"h-4 w-4 text-black\"  viewbox=\"0 0 24 24\"  fill=\"none\"  stroke=\"currentColor\"  stroke-width=\"2\"  stroke-linecap=\"round\"  stroke-linejoin=\"round\">  <polyline points=\"6 9 12 15 18 9\" \/><\/svg>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                        <div id=\"total-price-box\" class=\"mt-6 text-lg font-semibold font-excon text-peppery\"><\/div>\n                        <button\n                            id=\"add-to-cart-btn\"\n                            type=\"button\"\n                            class=\"btn-green-rounded inline-flex mt-4 disabled:opacity-50 disabled:cursor-not-allowed\"\n                            disabled\n aria-disabled=\"true\"\n                        >\n                            <span class=\"btn-label\">Add to cart<\/span>\n                            <span class=\"spinner hidden ml-2 w-5 h-5 border-2 border-white border-t-transparent rounded-full animate-spin\"><\/span>\n                        <\/button>\n                    <\/div>\n                                        <script nonce=\"xaItQ5nueGUSYJ9IBtxMHBHVuW8=\">\n                        window.krengCurrency = { current: \"SEK\",rates: []};\n                        window.trp_language = 'en_US';\n                        window.krengTranslations = {\n                            selectDateFirst: \"V\\u00e4lj datum f\\u00f6rst\",\n                            noTimesAvailable: \"Inga tider tillg\\u00e4ngliga\",\n                            selectTime: \"V\\u00e4lj tid\",\n                            available: \"Lediga\",\n                            fullyBooked: \"Fullbokad\",\n                            totalPrice: \"Totalpris\",\n                            adding: \"L\\u00e4gger till...\",\n                            addToCart: \"L\\u00e4gg i varukorg\",\n                            failedToAddToCart: \"Misslyckades att l\\u00e4gga i varukorg\",\n                            productAddedToCart: \"Produkt lagd i varukorgen\",\n                            technicalError: \"Tekniskt fel vid varukorg\",\n                            cartVerificationFailed: \"Produkten kunde inte sparas i varukorgen. F\\u00f6rs\\u00f6k igen.\"                        };\n                        \/\/ Build person names translation map from DOM (TranslatePress will translate the hidden div)\n                        window.krengPersonNamesTranslations = {};\n                        (function(){\n                            const container = document.getElementById('person-names-translations');\n                            if (container) {\n                                container.querySelectorAll('span[data-original]').forEach(span => {\n                                    const original = span.getAttribute('data-original');\n                                    const translated = span.textContent;\n                                    if (original && translated) {\n                                        window.krengPersonNamesTranslations[original] = translated;\n                                    }\n                                });\n                            }\n                        })();\n                        (function(){\n                            if (window.location.hash !== '#buy-ticket-module') {\n                                return;\n                            }\n\n                            window.addEventListener('load', () => {\n                                window.setTimeout(() => {\n                                    const target = document.getElementById('buy-ticket-module');\n\n                                    if (target) {\n                                        target.scrollIntoView({ behavior: 'smooth', block: 'start' });\n                                    }\n                                }, 150);\n                            }, { once: true });\n                        })();\n                        (function(){\n                            const qs = id => document.getElementById(id)\n                            const productSelector = qs('product-selector')\n                            const dateInput = qs('date-input')\n                            const timeSelector = qs('time-selector')\n                            const personTypesBox = qs('person-types-info')\n                            const totalPriceBox = qs('total-price-box')\n                            const addToCartBtn = qs('add-to-cart-btn')\n                            let picker = null\n                            let availabilityData = {}\n                            let enabledDates = []\n                            let personTypesData = []\n                            let currentProduct = null\n                            let availabilityReqId = 0\n                            let cartReadyPromise = null\n                            const currencyFormat = v => {\n                                const cur = 'SEK';\n                                const rates = window.krengCurrency?.rates || { SEK: 1 };\n                                const rate = rates[cur] || 1;\n                                let value = v * rate;\n                                const locale = 'sv-SE';\n                                let opts = { style: 'currency', currency: cur };\n                                try { return value.toLocaleString(locale, opts); }\n                                catch (e) { return value + ' kr'; }\n                            }\n                            const clamp = (val,min,max) => Math.min(Math.max(val,min),max)\n                            function initFlatpickr(){\n                                if (!window.flatpickr || !dateInput) return\n                                if (dateInput._flatpickr) dateInput._flatpickr.destroy()\n                                picker = flatpickr(dateInput,{\n                                    dateFormat:'Y-m-d',\n                                    locale:'sv',\n                                    enable: enabledDates,\n                                    disableMobile:true,\n                                    onChange: ([d],str)=>{ if(str){ renderTimes(str); autoSelectSingleTime(); validateForm() } }\n                                })\n                            }\n                            function ensureFlatpickrReady(cb){\n                                if (window.flatpickr) return cb()\n                                const start = Date.now()\n                                const int = setInterval(()=>{\n                                    if (window.flatpickr){ clearInterval(int); cb() }\n                                    else if (Date.now()-start>5000){ clearInterval(int) }\n                                },40)\n                            }\n                            function applyEnabledDates(){\n                                if (!picker) return\n                                picker.set('enable', enabledDates)\n                                if (enabledDates.length){\n                                    const cur = picker.input.value\n                                    if (!cur || !enabledDates.includes(cur)){\n                                        picker.setDate(enabledDates[0],true)\n                                    } else {\n                                        renderTimes(cur)\n                                    }\n                                } else {\n                                    picker.clear()\n                                    resetTimesForNoDate()\n                                }\n                                validateForm()\n                            }\n                            function resetTimesForNoDate(){\n                                timeSelector.innerHTML = '<option value=\"\">' + (window.krengTranslations?.selectDateFirst || 'V\u00e4lj datum f\u00f6rst') + '<\/option>'\n                            }\n                            function renderTimes(date){\n                                timeSelector.innerHTML = ''\n                                const list = availabilityData[date] || []\n                                if (!list.length){\n                                    timeSelector.innerHTML = '<option value=\"\">' + (window.krengTranslations?.noTimesAvailable || 'Inga tider tillg\u00e4ngliga') + '<\/option>'\n                                    return\n                                }\n                                const def = document.createElement('option')\n                                def.value=''\n                                def.textContent = window.krengTranslations?.selectTime || 'V\u00e4lj tid'\n                                timeSelector.appendChild(def)\n                                list.forEach(slot=>{\n                                    const o = document.createElement('option')\n                                    const remaining = (slot.remaining ?? null)\n                                    const availableText = window.krengTranslations?.available || 'Lediga'\n                                    const fullyBookedText = window.krengTranslations?.fullyBooked || 'Fullbokad'\n                                    const labelRemaining = remaining === null ? '' : (remaining > 0 ? ' (' + availableText + ': '+remaining+')' : ' (' + fullyBookedText + ')')\n                                    o.value = slot.slot\n                                    \/\/ Use display_time if available, otherwise extract start time from slot\n                                    const displayTime = slot.display_time || (slot.slot.includes(' - ') ? slot.slot.split(' - ')[0].trim() : slot.slot)\n                                    o.textContent = displayTime + labelRemaining\n                                    if (slot.available === false || remaining === 0) o.disabled = true\n                                    timeSelector.appendChild(o)\n                                })\n                            }\n                            function autoSelectSingleTime(){\n                                const opts = [...timeSelector.options].filter(o=>o.value)\n                                if (opts.length === 1 && !timeSelector.value && !opts[0].disabled){\n                                    timeSelector.value = opts[0].value\n                                }\n                            }\n                            async function fetchJSON(url, signal){\n                                const timeout = new Promise((_,rej)=>setTimeout(()=>rej(new Error('timeout')),7000))\n                                const res = await Promise.race([fetch(url,{credentials:'include',signal}), timeout])\n                                if (!res.ok) throw new Error('HTTP '+res.status)\n                                return res.json()\n                            }\n                            async function fetchAvailability(productId){\n                                if (!productId) return\n                                const reqId = ++availabilityReqId\n                                currentProduct = productId\n                                availabilityData = {}\n                                enabledDates = []\n                                resetTimesForNoDate()\n                                if (picker) picker.clear()\n                                validateForm()\n                                try {\n                                    const data = await fetchJSON(`\/wp-json\/kreng\/v1\/availability?product_id=${encodeURIComponent(productId)}`)\n                                    if (reqId !== availabilityReqId) return\n                                    availabilityData = data || {}\n                                    enabledDates = Object.keys(availabilityData)\n                                    applyEnabledDates()\n                                } catch(e){\n                                    availabilityData = {}\n                                    enabledDates = []\n                                    applyEnabledDates()\n                                }\n                            }\n                            function renderPersonTypes(data){\n                                if (!data || !data.enabled || !Array.isArray(data.types) || !data.types.length){\n                                    personTypesData = []\n                                    personTypesBox.innerHTML = ''\n                                    updateTotalPrice()\n                                    validateForm()\n                                    return\n                                }\n                                personTypesData = data.types\n                                personTypesBox.innerHTML = `<form id=\"person-types-form\" class=\"space-y-3 mb-4\">${\n                                    data.types.map(t=>{\n                                        const priceVal = (t.cost || t.base_cost || 0)\n                                        const priceLabel = currencyFormat(priceVal)\n                                        \/\/ Get translated name from mapping, fallback to original\n                                        const translatedName = window.krengPersonNamesTranslations[t.name] || t.name\n                                        return `\n                                            <div class=\"person-type-row flex items-center justify-between font-excon\">\n                                                <label class=\"text-base font-medium text-peppery\" for=\"person-type-${t.id}\">\n                                                    ${translatedName} <span class=\"text-peppery font-normal\">(${priceLabel})<\/span>\n                                                <\/label>\n                                                <div class=\"quantity-selector flex flex-col items-start gap-2 mt-0\">\n                                                    <div class=\"flex items-center justify-center md:w-[94px] p-0 md:bg-white rounded-full\">\n                                                        <button type=\"button\"\n                                                            class=\"qty-btn quantity-decrease max-md:bg-greenTwo text-white block md:w-6 w-11 rounded-full h-11 m-0 no-underline text-center leading-10 md:text-[#8F9496] text-lg font-bold cursor-pointer\"\n                                                            data-target=\"person-type-${t.id}\" data-delta=\"-1\" aria-label=\"Minska ${translatedName}\">\u2013<\/button>\n                                                        <input\n                                                            type=\"number\"\n                                                            inputmode=\"numeric\"\n                                                            pattern=\"[0-9]*\"\n                                                            id=\"person-type-${t.id}\"\n                                                            name=\"person-type-${t.id}\"\n                                                            min=\"0\"\n                                                            max=\"${t.max ?? 99}\"\n                                                            value=\"0\"\n                                                            aria-label=\"${translatedName}\"\n                                                            class=\"quantity-input md:bg-white bg-chanterelleTwo h-11 w-8 md:mx-0 mx-2 text-center text-md\"\n                                                            ${t.max === 0 ? 'disabled' : ''}\n                                                        \/>\n                                                        <button type=\"button\"\n                                                            class=\"qty-btn quantity-increase block md:w-6 w-11 h-11 m-0 no-underline text-center leading-10 md:text-[#8F9496] text-lg rounded-full max-md:bg-greenTwo text-white font-bold cursor-pointer\"\n                                                            data-target=\"person-type-${t.id}\" data-delta=\"1\" aria-label=\"\u00d6ka ${translatedName}\">+<\/button>\n                                                    <\/div>\n                                                <\/div>\n                                            <\/div>\n                                        `\n                                    }).join('')\n                                }<\/form>`\n                                const form = document.getElementById('person-types-form')\n                                if (form){\n                                    form.querySelectorAll('input.quantity-input').forEach(inp=>{\n                                        inp.addEventListener('input', e=>{\n                                            const max = parseInt(e.target.getAttribute('max'),10) || 999\n                                            const min = parseInt(e.target.getAttribute('min'),10) || 0\n                                            const v = parseInt(e.target.value,10)\n                                            e.target.value = isNaN(v)?0:clamp(v,min,max)\n                                            updateTotalPrice()\n                                            validateForm()\n                                        })\n                                    })\n                                }\n                                updateTotalPrice()\n                                validateForm()\n                            }\n                            async function fetchPersonTypes(productId){\n                                if (!productId){ renderPersonTypes(null); return }\n                                try {\n                                    const data = await fetchJSON(`\/wp-json\/kreng\/v1\/person-types?product_id=${encodeURIComponent(productId)}`)\n                                    renderPersonTypes(data)\n                                } catch(e){\n                                    renderPersonTypes(null)\n                                }\n                            }\n                            function getSelectedPersons(){\n                                const form = document.getElementById('person-types-form')\n                                if (!form || !personTypesData.length) return []\n                                const out = []\n                                personTypesData.forEach(t=>{\n                                    const el = form.querySelector(`#person-type-${t.id}`)\n                                    if (!el || el.disabled) return\n                                    const qty = parseInt(el.value,10)||0\n                                    if (qty>0) out.push({id:t.id, qty})\n                                })\n                                return out\n                            }\n                            function updateTotalPrice(){\n                                if (!totalPriceBox) return\n                                const persons = getSelectedPersons()\n                                let total = 0\n                                persons.forEach(p=>{\n                                    const meta = personTypesData.find(t=>t.id === p.id)\n                                    if (meta) total += p.qty * (meta.cost || meta.base_cost || 0)\n                                })\n                                const totalPriceText = window.krengTranslations?.totalPrice || 'Totalpris'\n                                totalPriceBox.textContent = `${totalPriceText}: ${currencyFormat(total)}`\n                            }\n                            function timeIsValid(){\n                                const d = dateInput.value\n                                const t = timeSelector.value\n                                if (!d || !t) return false\n                                const list = availabilityData[d] || []\n                                return list.some(s=>s.slot===t && s.available !== false && (s.remaining === null || s.remaining > 0))\n                            }\n                            function validateForm(){\n                                const valid = !!(productSelector.value && dateInput.value && timeSelector.value && timeIsValid() && getSelectedPersons().length)\n                                addToCartBtn.disabled = !valid\n                                addToCartBtn.setAttribute('aria-disabled', addToCartBtn.disabled ? 'true':'false')\n                                return valid\n                            }\n                            function setLoading(loading){\n                                const spinner = addToCartBtn.querySelector('.spinner')\n                                const label = addToCartBtn.querySelector('.btn-label')\n                                const addingText = window.krengTranslations?.adding || 'L\u00e4gger till...'\n                                const addToCartText = window.krengTranslations?.addToCart || 'L\u00e4gg i varukorg'\n                                if (label) label.textContent = loading ? addingText : addToCartText\n                                if (spinner){\n                                    if (loading){ spinner.classList.remove('hidden'); spinner.classList.add('inline-block') }\n                                    else { spinner.classList.add('hidden'); spinner.classList.remove('inline-block') }\n                                }\n                                addToCartBtn.disabled = loading || !validateForm()\n                                addToCartBtn.setAttribute('aria-disabled', addToCartBtn.disabled ? 'true':'false')\n                                const disable = el => { if (el) el.toggleAttribute('data-disabled-original', loading); el && (el.disabled = loading) }\n                                ;[productSelector,dateInput,timeSelector].forEach(disable)\n                                const form = document.getElementById('person-types-form')\n                                if (form){\n                                    form.querySelectorAll('input,select,button').forEach(i=> i.disabled = loading)\n                                }\n                            }\n                            function clearForm(){\n                                const form = document.getElementById('person-types-form')\n                                if (form){\n                                    form.querySelectorAll('input[type=\"number\"]').forEach(i=> i.value = 0)\n                                }\n                                if (picker) picker.clear()\n                                resetTimesForNoDate()\n                                updateTotalPrice()\n                                validateForm()\n                            }\n                            function notify(msg,type='success'){\n                                const ev = new CustomEvent('kreng:notify',{detail:{message:msg,type}})\n                                document.dispatchEvent(ev)\n                                if (!window?.krengNotifyHandled) console.log(msg)\n                            }\n                            async function addToCartRequest(payload){\n                                const res = await fetch('\/wp-json\/kreng\/v1\/add-show-to-cart',{\n                                    method:'POST',\n                                    headers:{'Content-Type':'application\/json'},\n                                    body: JSON.stringify(payload),\n                                    credentials:'include'\n                                })\n                                const data = await res.json().catch(()=>null)\n                                return {res, data}\n                            }\n                            addToCartBtn.addEventListener('click', async function(){\n                                if (addToCartBtn.disabled) return\n                                if (!validateForm()) return\n                                const productId = parseInt(productSelector.value,10)\n                                const selectedDate = dateInput.value\n                                const selectedTime = timeSelector.value\n                                if (!timeIsValid()) return\n                                const persons = getSelectedPersons()\n                                if (!persons.length) return\n                                const payload = { product_id: productId, date: selectedDate, time: selectedTime, persons }\n                                setLoading(true)\n                                try {\n                                    const {res, data} = await addToCartRequest(payload)\n                                    if (!res.ok || !data || data.error){\n                                        notify(window.krengTranslations?.failedToAddToCart || 'Misslyckades att l\u00e4gga i varukorg','error')\n                                    } else {\n                                        document.dispatchEvent(new CustomEvent('kreng:added-to-cart',{detail:data}))\n                                        document.dispatchEvent(new CustomEvent('kreng:cart-updated',{detail:data}))\n                                        clearForm()\n                                        notify(window.krengTranslations?.productAddedToCart || 'Produkt lagd i varukorgen','success')\n                                    }\n                                } catch(e){\n                                    notify(window.krengTranslations?.technicalError || 'Tekniskt fel vid varukorg','error')\n                                } finally {\n                                    setLoading(false)\n                                }\n                            })\n                            productSelector.addEventListener('change', e=>{\n                                fetchAvailability(e.target.value)\n                                fetchPersonTypes(e.target.value)\n                            })\n                            timeSelector.addEventListener('change', ()=>{ validateForm() })\n                            document.addEventListener('input', e=>{\n                                if (e.target && e.target.closest('#person-types-form')) validateForm()\n                            })\n                            ensureFlatpickrReady(()=>{\n                                initFlatpickr()\n                                if (productSelector.value){\n                                    fetchAvailability(productSelector.value)\n                                    fetchPersonTypes(productSelector.value)\n                                }\n                            })\n                            \/\/ Delegated handler for + \/ - buttons (added)\n                            document.addEventListener('click', e=>{\n                                const btn = e.target.closest('.qty-btn')\n                                if (!btn) return\n                                const targetId = btn.getAttribute('data-target')\n                                const delta = parseInt(btn.getAttribute('data-delta'),10) || 0\n                                const input = targetId && document.getElementById(targetId)\n                                if (!input || input.disabled) return\n                                const max = parseInt(input.getAttribute('max'),10) || 999\n                                const min = parseInt(input.getAttribute('min'),10) || 0\n                                const cur = parseInt(input.value,10) || 0\n                                const next = clamp(cur + delta, min, max)\n                                if (next !== cur){\n                                    input.value = next\n                                    input.dispatchEvent(new Event('input', {bubbles:true}))\n                                }\n                            })\n                        })()\n                    <\/script>\n                            <\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n\n<div data-block=\"text-and-image\"\n    class=\"acf-text-and-image bg-greenFive  mb-0\">\n    <div\n        class=\"lg:grid lg:grid-cols-2 flex flex-col-reverse lg:flex-row max-w-[1440px] mx-auto py-24 px-4 md:px-8 text-lg gap-y-8 items-center gap-x-28 justify-items-center\">\n        \n                                    <div class=\"relative overflow-hidden rounded-2xl max-h-[880px] h-full md:order-1\">\n                    \n                    <img decoding=\"async\" src=\"https:\/\/images.ohmyhosting.se\/3WJGJ_Aqztob0u2vxkV1ZkAfAb0=\/fit-in\/1220x740\/smart\/filters:quality(90)\/https%3A%2F%2Fwww.trolskaskogen.se%2Fwp-content%2Fuploads%2F2026%2F09%2Fkransbinderi.jpg\" alt=\"\"\n                        class=\"w-full lg:max-w-[582px] h-full max-w-[600px] object-contain object-center\" loading=\"lazy\" \/>\n                <\/div>\n                            \n        <div class=\"flex flex-col gap-3 justify-center max-w-[512px] md:order-2\">\n            \n                                                            <h2\n                        class=\"heading-md md:!text-[28px] font-bold leading-[110%] text-greenOne\">\n                        Welcome to a cozy and creative day in the Enchanted Forest!\n                    <\/h2>\n                            \n                            <div class=\"wysiwyg wysiwyg-text text-black mb-2 max-w-[426px] break-normal\">\n                    <p>Together, we'll make beautiful wreaths with our set designer, Janina Stoor von Wachenfeldt.<br \/>\nDuring the course, you\u2019ll learn the basics of wreath-making and create two personalized wreaths using natural materials.<\/p>\n<p>You don't need any prior knowledge\u2014we'll walk you through it step by step and help you throughout the day.<\/p>\n<p>date<\/p>\n<p>Sunday, November 15, 2026<\/p>\n<p>Date and time:<\/p>\n<p>10:00 a.m.\u20132:00 p.m. at the Trolska Skogen Caf\u00e9<\/p>\n<p>Number of seats:<\/p>\n<p>We only have 15 spots available, so be sure to reserve your spot well in advance!<\/p>\n<p>Price: 390 SEK per person, including soup for lunch and coffee and pastries<\/p>\n<p>We're looking forward to a creative, cozy, and inspiring day together in Trolska Skogen!<\/p>\n\n                <\/div>\n            \n                    <\/div>\n    <\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-14468","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.trolskaskogen.se\/en\/wp-json\/wp\/v2\/pages\/14468","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.trolskaskogen.se\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.trolskaskogen.se\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.trolskaskogen.se\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.trolskaskogen.se\/en\/wp-json\/wp\/v2\/comments?post=14468"}],"version-history":[{"count":5,"href":"https:\/\/www.trolskaskogen.se\/en\/wp-json\/wp\/v2\/pages\/14468\/revisions"}],"predecessor-version":[{"id":14485,"href":"https:\/\/www.trolskaskogen.se\/en\/wp-json\/wp\/v2\/pages\/14468\/revisions\/14485"}],"wp:attachment":[{"href":"https:\/\/www.trolskaskogen.se\/en\/wp-json\/wp\/v2\/media?parent=14468"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}