{"id":16561,"date":"2025-11-20T11:42:57","date_gmt":"2025-11-20T10:42:57","guid":{"rendered":"https:\/\/verohomes.pl\/?page_id=16561"},"modified":"2026-03-31T11:31:15","modified_gmt":"2026-03-31T09:31:15","slug":"mobile-homes-configurator","status":"publish","type":"page","link":"https:\/\/verohomes.pl\/en\/mobile-homes-configurator\/","title":{"rendered":"Configurator"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"16561\" class=\"elementor elementor-16561\" data-elementor-post-type=\"page\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-31bc554 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"31bc554\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-dc66e62\" data-id=\"dc66e62\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-b618c94 elementor-widget elementor-widget-html\" data-id=\"b618c94\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <title>VERO HOMES Configurator<\/title>\r\n    \r\n    <meta property=\"og:title\" content=\"VERO HOMES Configurator\">\r\n    <meta property=\"og:description\" content=\"Choose the size, customize the equipment, and get a quote for your house.\">\r\n    <meta property=\"og:image\" content=\"https:\/\/tinyurl.com\/56awzvz5\">\r\n    \r\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@300;400;500;600;700;800&display=swap\" rel=\"stylesheet\">\r\n    <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/6.5.1\/css\/all.min.css\">\r\n\r\n    <style>\r\n        :root {\r\n            --blue-main: #2563eb; --blue-light: #eff6ff; --blue-dark: #1e40af;\r\n            --green-main: #059669; --green-light: #ecfdf5; --green-dark: #047857;\r\n            --honey-main: #d97706; --honey-light: #fffbeb; --honey-dark: #b45309;\r\n            --bg-page: #f8fafc; \r\n            --bg-card: #ffffff;\r\n            --text-main: #0f172a; --text-muted: #64748b;\r\n            --border: #e2e8f0; --radius: 16px;\r\n            --font-main: 'Inter', sans-serif;\r\n            --shadow-card: 0 4px 6px -1px rgba(0, 0, 0, 0.05);\r\n        }\r\n\r\n        body { font-family: var(--font-main); background-color: var(--bg-page); color: var(--text-main); margin: 0; padding: 0; line-height: 1.5; }\r\n        \r\n        .container { max-width: 1100px; margin: 0 auto; padding: 40px 20px 60px 20px; position: relative; }\r\n\r\n        .language-switcher {\r\n            position: absolute;\r\n            top: 20px;\r\n            right: 20px;\r\n            display: flex;\r\n            gap: 12px;\r\n            z-index: 10;\r\n        }\r\n        .language-switcher a {\r\n            text-decoration: none;\r\n            transition: transform 0.2s ease;\r\n            display: block;\r\n        }\r\n        .language-switcher a:hover { transform: scale(1.1); }\r\n        .language-switcher img {\r\n            width: 34px; height: auto; border-radius: 4px;\r\n            box-shadow: 0 2px 5px rgba(0,0,0,0.15); display: block;\r\n        }\r\n\r\n        header { text-align: center; margin-bottom: 50px; margin-top: 20px; }\r\n        h1 { font-size: 2.5rem; font-weight: 800; color: var(--text-main); margin-bottom: 10px; }\r\n        .subtitle { font-size: 1.1rem; color: var(--text-muted); max-width: 800px; margin: 0 auto; }\r\n\r\n        .card { background: var(--bg-card); border-radius: var(--radius); box-shadow: var(--shadow-card); padding: 30px; margin-bottom: 30px; border: 1px solid var(--border); position: relative; }\r\n        .card.theme-blue { border-top: 5px solid var(--blue-main); }\r\n        .card.theme-blue h2 i { color: var(--blue-main); }\r\n        .card.theme-green { border-top: 5px solid var(--green-main); }\r\n        .card.theme-green h2 i { color: var(--green-main); }\r\n        .card.theme-green h3.category-header { background: var(--green-light); color: var(--green-dark); border-left-color: var(--green-main); }\r\n        .card.theme-honey { border-top: 5px solid var(--honey-main); }\r\n        .card.theme-honey h2 i { color: var(--honey-main); }\r\n        .card.theme-honey h3.category-header { background: var(--honey-light); color: var(--honey-dark); border-left-color: var(--honey-main); }\r\n\r\n        h2 { font-size: 1.5rem; margin-top: 0; margin-bottom: 25px; display: flex; align-items: center; gap: 12px; font-weight: 700; }\r\n        h3.category-header {\r\n            font-size: 1.05rem; padding: 12px 15px; border-radius: 8px; margin: 25px 0 15px 0;\r\n            font-weight: 700; display: flex; align-items: center; gap: 10px; border-left: 4px solid transparent;\r\n        }\r\n\r\n        .model-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 15px; }\r\n        .model-option { position: relative; }\r\n        .model-radio { display: none; }\r\n        .model-label {\r\n            display: flex; flex-direction: column; align-items: center; justify-content: center;\r\n            padding: 20px; border: 2px solid var(--border); border-radius: 12px;\r\n            cursor: pointer; transition: all 0.2s; background: #fff; text-align: center;\r\n        }\r\n        .model-label span.m-name { font-weight: 700; font-size: 1.1rem; margin-bottom: 5px; }\r\n        .model-radio:checked + .model-label {\r\n            border-color: var(--honey-main); background-color: var(--honey-light); color: var(--honey-dark);\r\n        }\r\n        #custom-metraz-wrapper { margin-top: 20px; }\r\n        .styled-input { width: 100%; padding: 12px 15px; border: 1px solid var(--border); border-radius: 8px; font-family: var(--font-main); box-sizing: border-box; }\r\n        textarea.styled-input { resize: vertical; min-height: 80px; }\r\n\r\n        .config-table { width: 100%; border-collapse: collapse; }\r\n        .config-table th {\r\n            text-align: left; padding: 12px 15px; color: var(--text-muted); font-size: 0.8rem;\r\n            text-transform: uppercase; font-weight: 600; border-bottom: 2px solid var(--border);\r\n        }\r\n        .config-table th.th-center { text-align: center; }\r\n        .config-table td { padding: 16px 15px; border-bottom: 1px solid var(--border); vertical-align: top; }\r\n        .config-table tr:last-child td { border-bottom: none; }\r\n        .config-table tbody tr { cursor: pointer; transition: background-color 0.15s; }\r\n        .config-table tbody tr:hover { background-color: #f1f5f9; }\r\n\r\n        .product-name { font-weight: 600; color: var(--text-main); font-size: 1rem; display: block; }\r\n        .details-link { font-size: 0.85rem; color: var(--blue-main); cursor: pointer; text-decoration: none; font-weight: 500; display: inline-flex; align-items: center; gap: 4px; margin-top: 4px; }\r\n        .details-link:hover { text-decoration: underline; }\r\n        .details-box { display: none; margin-top: 8px; font-size: 0.9rem; color: #475569; background: #f1f5f9; padding: 10px 12px; border-radius: 6px; border-left: 3px solid var(--blue-main); line-height: 1.5; cursor: auto; }\r\n\r\n        .toggle-switch { position: relative; display: inline-block; width: 46px; height: 26px; }\r\n        .toggle-switch input { opacity: 0; width: 0; height: 0; }\r\n        .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #cbd5e1; transition: .3s; border-radius: 34px; }\r\n        .slider:before { position: absolute; content: \"\"; height: 20px; width: 20px; left: 3px; bottom: 3px; background-color: white; transition: .3s; border-radius: 50%; }\r\n        \r\n        .theme-green input:checked + .slider { background-color: var(--green-main); }\r\n        .theme-green input:checked + .slider:before { transform: translateX(20px); }\r\n        .theme-honey input:checked + .slider { background-color: var(--honey-main); }\r\n        .theme-honey input:checked + .slider:before { transform: translateX(20px); }\r\n        input:disabled + .slider { background-color: #e2e8f0; cursor: not-allowed; opacity: 0.6; }\r\n\r\n        .note-input { width: 100%; padding: 8px 10px; border: 1px solid var(--border); border-radius: 6px; font-family: var(--font-main); font-size: 0.85rem; cursor: text; }\r\n\r\n        .features-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 15px; margin-bottom: 30px; }\r\n        .feature-box { display: flex; gap: 12px; padding: 15px; background: #ffffff; border-radius: 10px; border: 1px solid var(--border); box-shadow: 0 2px 4px rgba(0,0,0,0.02); }\r\n        .feature-box i { color: var(--green-main); font-size: 1.2rem; margin-top: 3px; }\r\n        .feature-text { font-weight: 600; font-size: 0.95rem; line-height: 1.4; }\r\n        .feature-text small { display: block; margin-top: 4px; font-weight: 400; color: var(--text-muted); font-size: 0.85rem; }\r\n\r\n        .checkout-section { background: #fff; margin-top: 50px; border-radius: var(--radius); box-shadow: 0 10px 25px rgba(0,0,0,0.05); border-top: 6px solid var(--green-main); display: grid; grid-template-columns: 1.2fr 0.8fr; overflow: hidden; }\r\n        .contact-col { padding: 40px; }\r\n        .summary-col { background: #fdfdfd; padding: 40px; border-left: 1px solid var(--border); display: flex; flex-direction: column; }\r\n        \r\n        .summary-row { display: flex; justify-content: space-between; padding: 12px 0; border-bottom: 1px dashed var(--border); font-size: 1rem; color: var(--text-muted); }\r\n        .summary-row span:nth-child(2) { font-weight: 600; color: var(--text-main); }\r\n        \r\n        .summary-total { margin-top: auto; background: var(--green-light); padding: 30px 25px; border-radius: 12px; border: 2px solid #bbf7d0; text-align: center; }\r\n        .summary-total i { font-size: 2rem; color: var(--green-dark); margin-bottom: 15px; display: block; }\r\n\r\n        .red-text { color: #ef4444 !important; }\r\n        .green-text { color: #059669 !important; }\r\n\r\n        .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }\r\n        .form-group label { display: block; font-size: 0.85rem; font-weight: 600; margin-bottom: 6px; }\r\n        .contact-input { border: 2px solid var(--border); }\r\n        \r\n        .btn-submit {\r\n            grid-column: span 2; width: 100%; padding: 18px; margin-top: 25px;\r\n            background: linear-gradient(135deg, var(--green-main) 0%, var(--green-dark) 100%);\r\n            color: white; border: none; border-radius: 10px; font-weight: 700; font-size: 1.1rem;\r\n            cursor: pointer; box-shadow: 0 4px 10px rgba(5, 150, 105, 0.2); transition: all 0.3s;\r\n        }\r\n        .btn-submit:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(5, 150, 105, 0.3); }\r\n        .btn-submit:disabled { background: #94a3b8; cursor: not-allowed; transform: none; box-shadow: none; }\r\n\r\n        .gdpr-box { grid-column: span 2; display: flex; align-items: flex-start; gap: 10px; margin-top: 15px; font-size: 0.85rem; color: var(--text-muted); line-height: 1.4; }\r\n        .gdpr-box input[type=\"checkbox\"] { margin-top: 3px; min-width: 16px; min-height: 16px; cursor: pointer; }\r\n\r\n        #result { grid-column: span 2; margin-top: 15px; text-align: center; font-weight: 600; padding: 10px; border-radius: 8px; line-height: 1.4; }\r\n\r\n        .reset-btn { display: block; margin-top: 20px; text-align: center; color: var(--text-muted); font-size: 0.9rem; cursor: pointer; text-decoration: underline; }\r\n\r\n        .exchange-note { text-align: center; font-size: 0.85rem; color: var(--text-muted); margin-top: 15px; padding: 0 20px; }\r\n\r\n        @media (max-width: 900px) {\r\n            .language-switcher { position: relative; top: 0; right: 0; justify-content: center; margin-bottom: 20px; }\r\n            .checkout-section { grid-template-columns: 1fr; }\r\n            .summary-col { border-left: none; border-top: 1px solid var(--border); }\r\n            .form-grid { grid-template-columns: 1fr; }\r\n            .btn-submit, #result, .gdpr-box { grid-column: span 1; }\r\n            .config-table thead { display: none; }\r\n            .config-table tr { display: grid; grid-template-columns: 1fr auto; gap: 10px; padding: 15px; border: 1px solid var(--border); margin-bottom: 10px; border-radius: 10px; }\r\n            .config-table td { border: none; padding: 0; }\r\n            .config-table td:nth-child(1) { grid-column: 1 \/ 2; } \r\n            .config-table td:nth-child(2) { grid-column: 1 \/ 3; order: 3; margin-top: 5px; } \r\n            .config-table td:nth-child(3) { grid-column: 2 \/ 3; text-align: right; } \r\n            .config-table td:nth-child(4) { grid-column: 1 \/ 3; order: 4; margin-top: 10px; } \r\n        }\r\n    <\/style>\r\n<\/head>\r\n<body>\r\n\r\n    <form id=\"config-form-main\" class=\"container\" data-author=\"Szymon Sterna\" data-env=\"PersonalHardware\">\r\n        \r\n        <div class=\"language-switcher\">\r\n            <a href=\"https:\/\/verohomes.pl\/domy-mobilne-konfigurator\/\" title=\"Polski\">\r\n                <img decoding=\"async\" src=\"https:\/\/flagcdn.com\/w40\/pl.png\" alt=\"Polski\">\r\n            <\/a>\r\n            <a href=\"https:\/\/verohomes.pl\/de\/die-mobilheime-konfigurator\/\" title=\"Deutsch\">\r\n                <img decoding=\"async\" src=\"https:\/\/flagcdn.com\/w40\/de.png\" alt=\"Deutsch\">\r\n            <\/a>\r\n            <a href=\"https:\/\/verohomes.pl\/cs\/mobilni-domy-konfigurator\/\" title=\"\u010ce\u0161tina\">\r\n                <img decoding=\"async\" src=\"https:\/\/flagcdn.com\/w40\/cz.png\" alt=\"\u010ce\u0161tina\">\r\n            <\/a>\r\n            <a href=\"https:\/\/verohomes.pl\/konfigurator-domu-mobilnego-ua\/\" title=\"\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430\">\r\n                <img decoding=\"async\" src=\"https:\/\/flagcdn.com\/w40\/ua.png\" alt=\"\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430\">\r\n            <\/a>\r\n        <\/div>\r\n\r\n        <input type=\"hidden\" name=\"Kraj\" value=\"Global\/English\">\r\n        <input type=\"hidden\" name=\"Podsumowanie_OFERTY\" id=\"hidden_summary_field\">\r\n\r\n        <header>\r\n            <h1>Mobile Home Configurator<\/h1>\r\n            <p class=\"subtitle\">Choose the size, customize the equipment, and get a quote for your house.<\/p>\r\n        <\/header>\r\n\r\n        <section class=\"card theme-honey\">\r\n            <h2><i class=\"fa-solid fa-ruler-combined\"><\/i> 1. Choose house size<\/h2>\r\n            <div id=\"model-options-wrapper\" class=\"model-grid\"><\/div>\r\n            <div id=\"custom-metraz-wrapper\" style=\"display:none;\">\r\n                <label style=\"font-weight:600; display:block; margin-bottom:8px;\">Enter custom dimensions:<\/label>\r\n                <input type=\"text\" id=\"customMetrazInput\" class=\"styled-input\" placeholder=\"e.g., 48m2 or 4x12\">\r\n            <\/div>\r\n        <\/section>\r\n\r\n        <section class=\"card theme-green\">\r\n            <h2><i class=\"fa-solid fa-check-circle\"><\/i> 2. Equipment included in the price<\/h2>\r\n            <h3 style=\"font-size:1.1rem; color:var(--green-dark); margin-bottom:20px;\">Fixed elements<\/h3>\r\n            <div class=\"features-list\"><\/div>\r\n            <p style=\"color:var(--text-muted); margin-top:30px; margin-bottom: 20px;\">\r\n                The items below are also included in the price. You can <strong style=\"color:#ef4444;\">uncheck them<\/strong> (opt out) to reduce the cost.\r\n            <\/p>\r\n            <div id=\"items-included-container\"><\/div>\r\n        <\/section>\r\n\r\n        <section class=\"card theme-honey\">\r\n            <h2><i class=\"fa-solid fa-plus-circle\"><\/i> 3. Additional elements<\/h2>\r\n            <p style=\"color:var(--text-muted); margin-bottom: 25px;\">You can expand your home with premium options for an additional fee.<\/p>\r\n            <table class=\"config-table\">\r\n                <thead>\r\n                    <tr>\r\n                        <th style=\"width: 50%;\">Addition name<\/th>\r\n                        <th style=\"width: 20%;\">Net price<\/th>\r\n                        <th style=\"width: 10%;\" class=\"th-center\">WANT IT<\/th>\r\n                        <th style=\"width: 20%;\">Notes<\/th>\r\n                    <\/tr>\r\n                <\/thead>\r\n                <tbody id=\"items-extra-body\"><\/tbody>\r\n            <\/table>\r\n        <\/section>\r\n\r\n        <div class=\"checkout-section\" id=\"contact-section\">\r\n            <div class=\"contact-col\">\r\n                <h3 style=\"margin-top:0; margin-bottom:25px; font-size:1.3rem; font-weight:700;\">Investor details<\/h3>\r\n                <div class=\"form-grid\">\r\n                    <div class=\"form-group\">\r\n                        <label>First and Last Name<\/label>\r\n                        <input type=\"text\" name=\"Imie_Nazwisko\" id=\"client_name\" class=\"styled-input contact-input\" placeholder=\"John Doe\">\r\n                    <\/div>\r\n                    <div class=\"form-group\">\r\n                        <label>E-mail Address *<\/label>\r\n                        <input type=\"email\" name=\"email\" id=\"client_email\" class=\"styled-input contact-input\" required placeholder=\"john@example.com\">\r\n                    <\/div>\r\n                    <div class=\"form-group\">\r\n                        <label>Phone number *<\/label>\r\n                        <input type=\"text\" name=\"Telefon\" id=\"client_phone\" class=\"styled-input contact-input\" required placeholder=\"+44 ...\">\r\n                    <\/div>\r\n                    <div class=\"form-group\">\r\n                        <label>Preferred contact hours (optional)<\/label>\r\n                        <input type=\"text\" name=\"Preferowane_godziny\" id=\"contact_hours\" class=\"styled-input contact-input\" placeholder=\"e.g., 14:00 - 17:00\">\r\n                    <\/div>\r\n                    <div class=\"form-group\">\r\n                        <label>Postal code (delivery)<\/label>\r\n                        <input type=\"text\" name=\"Kod_Pocztowy\" id=\"postal_code_input\" class=\"styled-input contact-input\" placeholder=\"00-000\">\r\n                    <\/div>\r\n                    <div class=\"form-group\">\r\n                        <label>Planned realization date (optional)<\/label>\r\n                        <input type=\"text\" name=\"Termin_realizacji\" id=\"planned_date\" class=\"styled-input contact-input\" placeholder=\"e.g., Spring 2027\">\r\n                    <\/div>\r\n                    <div class=\"form-group\" style=\"grid-column: 1 \/ -1;\">\r\n                        <label>Inquiry content (optional)<\/label>\r\n                        <textarea name=\"Tresc_zapytania\" id=\"client_message\" class=\"styled-input contact-input\" placeholder=\"Additional information, questions...\"><\/textarea>\r\n                    <\/div>\r\n                    \r\n                    <div class=\"gdpr-box\">\r\n                        <input type=\"checkbox\" name=\"RODO\" id=\"rodo-check\" required checked>\r\n                        <label for=\"rodo-check\">I consent to the processing of my personal data by Rafik Mazurkiewicz Nazim Sp. K. under the terms outlined in the Privacy Policy.<\/label>\r\n                    <\/div>\r\n\r\n                    <button type=\"submit\" class=\"btn-submit\" id=\"submit-btn\">Request a free quote<\/button>\r\n                    <div id=\"result\"><\/div>\r\n                <\/div>\r\n                <a id=\"reset-btn\" class=\"reset-btn\">Clear form<\/a>\r\n            <\/div>\r\n\r\n            <div class=\"summary-col\">\r\n                <h3 style=\"margin-top:0; margin-bottom:25px; font-size:1.3rem; font-weight:700;\">Your configuration<\/h3>\r\n                <div style=\"flex-grow:1;\">\r\n                    <div class=\"summary-row\">\r\n                        <span>Selected model<\/span>\r\n                        <span id=\"summary-model-name\" style=\"font-weight:600; color:var(--text-main);\">...<\/span>\r\n                    <\/div>\r\n                    <div class=\"summary-row\">\r\n                        <span>Cancellations value<\/span>\r\n                        <span id=\"summary-subtractions\" class=\"red-text\">-<\/span>\r\n                    <\/div>\r\n                    <div class=\"summary-row\">\r\n                        <span>Additions value<\/span>\r\n                        <span id=\"summary-additions\" class=\"green-text\">-<\/span>\r\n                    <\/div>\r\n                <\/div>\r\n                \r\n                <div class=\"summary-total\">\r\n                    <i class=\"fa-solid fa-file-invoice-dollar\"><\/i>\r\n                    <span style=\"display:block; font-size:1.1rem; font-weight:700; color:var(--green-dark); margin-bottom:5px;\">Complete quote<\/span>\r\n                    <span style=\"font-size:0.9rem; color:#065f46; line-height:1.4; display:block;\">\r\n                        Submit the form to receive an email quote tailored to your selected size and modifications.\r\n                    <\/span>\r\n                <\/div>\r\n                <div id=\"exchange-rate-info\" class=\"exchange-note\">Prices are being loaded...<\/div>\r\n            <\/div>\r\n        <\/div>\r\n    <\/form>\r\n\r\n    <script>\r\n        \/**\r\n         * @project Konfigurator Dom\u00f3w Mobilnych Vero Homes (EN Version)\r\n         * @author Szymon Sterna\r\n         * @license Copyright (c) 2026 Szymon Sterna.\r\n         *\/\r\n\r\n        document.addEventListener('DOMContentLoaded', async () => {\r\n            console.log(\"%c--- VERO HOMES CONFIGURATOR (EN) ---\", \"color: #059669; font-weight: bold; font-size: 16px;\");\r\n\r\n            \/\/ --- ZDALNY KILL-SWITCH (Z NATYCHMIASTOWYM OD\u015aWIE\u017bANIEM) ---\r\n            const KILL_SWITCH_URL = 'https:\/\/gist.githubusercontent.com\/sternaszymon7-eng\/e75022d615428c3bec31ef969a87c44e\/raw\/status.txt?nocache=' + new Date().getTime(); \r\n            \r\n            try {\r\n                const response = await fetch(KILL_SWITCH_URL, { cache: \"no-store\" });\r\n                const status = await response.text();\r\n                \r\n                if (status.trim().toUpperCase() === 'OFF') {\r\n                    document.body.innerHTML = `\r\n                        <div style=\"display: flex; flex-direction: column; justify-content: center; align-items: center; height: 100vh; font-family: sans-serif; text-align: center; background-color: #f8fafc; color: #475569;\">\r\n                            <h2 style=\"color: #0f172a;\">Przerwa techniczna \/ Maintenance<\/h2>\r\n                            <p>Konfigurator jest tymczasowo niedost\u0119pny. Przepraszamy za utrudnienia.<\/p>\r\n                        <\/div>`;\r\n                    return; \r\n                }\r\n            } catch (error) {\r\n                console.warn(\"Status konfiguratora: brak po\u0142\u0105czenia kontrolnego.\");\r\n            }\r\n            \/\/ --- KONIEC KILL-SWITCHA ---\r\n            \r\n            const GOOGLE_SCRIPT_URL = 'https:\/\/script.google.com\/macros\/s\/AKfycby63pHl7RU0YKolWMzESBBRk4BBIzeU6EX142FKafBc1xsE6CCkHmTICmPuub47MY-U\/exec';\r\n\r\n            let exchangeRate = 4.30; \/\/ Fallback default PLN\/EUR rate\r\n\r\n            \/\/ Fetch current NBP exchange rate\r\n            try {\r\n                const response = await fetch('https:\/\/api.nbp.pl\/api\/exchangerates\/rates\/a\/eur\/?format=json');\r\n                if(response.ok) {\r\n                    const data = await response.json();\r\n                    exchangeRate = data.rates[0].mid;\r\n                }\r\n            } catch (error) {\r\n                console.warn('Failed to fetch NBP exchange rate, using fallback rate.', error);\r\n            }\r\n\r\n            \/\/ Converter function: converts PLN to EUR and rounds up to nearest multiple of 5\r\n            function getConvertedPrice(plnPrice) {\r\n                if (!plnPrice || plnPrice === 0) return 0;\r\n                const inEur = plnPrice \/ exchangeRate;\r\n                return Math.ceil(inEur \/ 5) * 5;\r\n            }\r\n\r\n            \/\/ ZAKTUALIZOWANE CENY ORAZ DODANE WARTO\u015aCI SIZE DO WYLICZE\u0143\r\n            const models = [\r\n                { id: 'm36', name: \"36 m\u00b2\", sub: \"4m x 9m\", pricePln: 248000, size: 36 },\r\n                { id: 'm40', name: \"40 m\u00b2\", sub: \"4m x 10m\", pricePln: 269000, size: 40 },\r\n                { id: 'm44', name: \"44 m\u00b2\", sub: \"4m x 11m\", pricePln: 278000, size: 44 },\r\n                { id: 'm45', name: \"45 m\u00b2\", sub: \"4.5m x 10m\", pricePln: 284318, size: 45 },\r\n                { id: 'm48', name: \"48 m\u00b2\", sub: \"4m x 12m\", pricePln: 297000, size: 48 },\r\n                { id: 'm54', name: \"54 m\u00b2\", sub: \"4.5m x 12m\", pricePln: 343286, size: 54 },\r\n                { id: 'm56', name: \"56 m\u00b2\", sub: \"4m x 14m\", pricePln: 356000, size: 56 },\r\n                { id: 'm63', name: \"63 m\u00b2\", sub: \"4.5m x 14m\", pricePln: 395000, size: 63 },\r\n                { id: 'custom', name: \"Custom\", sub: \"Other size\", pricePln: 0, isCustom: true }\r\n            ];\r\n\r\n            \/\/ Convert model prices\r\n            models.forEach(m => m.price = getConvertedPrice(m.pricePln));\r\n\r\n            const allItems = [\r\n                { id: 'base_1', category: 'Fixed elements', name: 'Steel house structure', pricePln: 0, included: true, static: true, icon: 'fa-solid fa-layer-group', details: 'Frame made of steel profiles protected against corrosion; bottom protected with galvanized sheet; 2 axles with wheels and drawbar for transport.' },\r\n                { id: 'base_3', category: 'Fixed elements', name: 'Pent roof (sheet metal)', pricePln: 0, included: true, static: true, icon: 'fa-solid fa-house-chimney' },\r\n                { id: 'base_4', category: 'Fixed elements', name: 'Kerrafront Classic facade', pricePln: 0, included: true, static: true, description: 'FS-201 \/ FS-202', icon: 'fa-solid fa-paint-roller' },\r\n                { id: 'base_5', category: 'Fixed elements', name: 'Triple-glazed windows', pricePln: 0, included: true, static: true, icon: 'fa-regular fa-window-maximize', details: 'Manufactured according to EN 14351-1 (anthracite outside, white inside). Set: 3x 80x120cm, 1x 50x50cm, 1x 195x75cm and large terrace glazing (4-leaf balcony or 2-leaf sliding door).' },\r\n                { id: 'base_6', category: 'Fixed elements', name: 'PUR foam insulation', pricePln: 0, included: true, static: true, description: 'Roof 20cm, Walls 15cm, Floor 30-45cm', icon: 'fa-solid fa-temperature-arrow-up' },\r\n                { id: 'base_7', category: 'Fixed elements', name: 'Interior wall and ceiling finish', pricePln: 0, included: true, static: true, description: 'Waterproof white MDF board Finsa', icon: 'fa-solid fa-fill-drip' },\r\n                { id: 'base_8', category: 'Fixed elements', name: 'Electrical installation', pricePln: 0, included: true, static: true, description: 'Antenna socket, distribution box, external socket, heating cable socket', icon: 'fa-solid fa-bolt' },\r\n                { id: 'base_9', category: 'Fixed elements', name: 'Plumbing installation', pricePln: 0, included: true, static: true, description: 'In bathroom and kitchen', icon: 'fa-solid fa-faucet' },\r\n                { id: 'base_10', category: 'Fixed elements', name: 'Mechanical ventilation', pricePln: 0, included: true, static: true, description: 'In bathroom and sanitary system vent', icon: 'fa-solid fa-wind' },\r\n                { id: 'base_11', category: 'Fixed elements', name: 'Heating', pricePln: 0, included: true, static: true, description: '(Termofol with online control) or electric radiators (max. 5)', icon: 'fa-solid fa-fire-burner' },\r\n                { id: 'base_12', category: 'Fixed elements', name: 'Lighting', pricePln: 0, included: true, static: true, description: 'External and internal', icon: 'fa-regular fa-lightbulb', details: 'External LED (2 points) and internal (20 points).' },\r\n                \r\n                { id: 'int_1', category: 'General elements', name: 'Interior doors (3 pcs)', pricePln: 1950.00, included: true, details: 'Choice of traditional leaves (70 cm, white DRE Estra 5 \/ Malibu White Artens) or sliding with frames.' },\r\n                { id: 'int_2', category: 'General elements', name: 'Vinyl floor panels + skirting boards', pricePln: 1800.00, included: true, details: 'Vinyl VOX Rigio, installed in all rooms. Skirting boards Yutra Alpha 60 white or black.' },\r\n                { id: 'int_3', category: 'General elements', name: 'Sockets and switches (20 pcs)', pricePln: 1000.00, included: true },\r\n                { id: 'int_4', category: 'Bathroom', name: 'Freestanding shower cabin 90 x 90 cm', pricePln: 1250.00, included: true, details: 'Four-walled.' },\r\n                { id: 'int_5', category: 'Bathroom', name: 'Wall-hung toilet (Geberit)', pricePln: 2500.00, included: true },\r\n                { id: 'int_6', category: 'Bathroom', name: 'Washbasin with faucet', pricePln: 350.00, included: true },\r\n                { id: 'int_7', category: 'Bathroom', name: 'Under-sink cabinet', pricePln: 500.00, included: true },\r\n                { id: 'int_8', category: 'Bathroom', name: 'Water heater (Boiler)', pricePln: 1100.00, included: true },\r\n                { id: 'int_9', category: 'Bathroom', name: 'Electric radiator', pricePln: 350.00, included: true },\r\n                { id: 'int_10', category: 'Bathroom', name: 'Washing machine 40 or 60 cm', pricePln: 800.00, included: true },\r\n                { id: 'int_11', category: 'Bathroom', name: 'Mirror', pricePln: 70.00, included: true },\r\n                { id: 'int_12', category: 'Bathroom', name: 'Bathroom rug', pricePln: 50.00, included: true },\r\n                { id: 'int_13', category: 'Bathroom', name: 'Bathroom accessories', pricePln: 120.00, included: true },\r\n                { id: 'int_14', category: 'Living room with kitchenette', name: 'Custom-made kitchen furniture', pricePln: 8000.00, included: true, details: '* Price includes a total of 10 linear meters of furniture (kitchen + rooms). Standard number of drawers: 10 pcs. Kronospan Standard \/ Color boards; Kronospan Avant-Garde fronts; Kronospan countertops; Blum hardware. Soft-close or tip-on. LED lighting under cabinets. Surcharges for: extra drawers, cargo, exceeding dimensions.' },\r\n                { id: 'int_15', category: 'Living room with kitchenette', name: 'Large sofa', pricePln: 2000.00, included: true, details: 'Corner sofa with sleeping function.' },\r\n                { id: 'int_16', category: 'Living room with kitchenette', name: 'Table', pricePln: 550.00, included: true },\r\n                { id: 'int_17', category: 'Living room with kitchenette', name: 'Chairs (4 pcs)', pricePln: 1000.00, included: true },\r\n                { id: 'int_18', category: 'Living room with kitchenette', name: 'TV set', pricePln: 1200.00, included: true, details: 'TV with Smart TV function, up to 42 inches.' },\r\n                { id: 'int_19', category: 'Living room with kitchenette', name: 'Coffee table', pricePln: 150.00, included: true },\r\n                { id: 'int_21', category: 'Living room with kitchenette', name: 'Frame + poster', pricePln: 25.00, included: true },\r\n                { id: 'int_22', category: 'Living room with kitchenette', name: 'Rug', pricePln: 400.00, included: true },\r\n                { id: 'int_23', category: 'Living room with kitchenette', name: 'Pillows (4 pcs)', pricePln: 160.00, included: true },\r\n                { id: 'int_24', category: 'Living room with kitchenette', name: 'Sink with faucet', pricePln: 450.00, included: true },\r\n                { id: 'int_25', category: 'Living room with kitchenette', name: 'Fridge-freezer', pricePln: 1200.00, included: true },\r\n                { id: 'int_26', category: 'Living room with kitchenette', name: 'Oven', pricePln: 800.00, included: true },\r\n                { id: 'int_27', category: 'Living room with kitchenette', name: 'Hob \/ Cooktop', pricePln: 800.00, included: true, details: 'Choice of: induction, electric, or gas.' },\r\n                { id: 'int_28', category: 'Living room with kitchenette', name: 'Dishwasher', pricePln: 850.00, included: true, details: 'Width 45 cm or 60 cm.' },\r\n                { id: 'int_29', category: 'Living room with kitchenette', name: 'Range hood', pricePln: 250.00, included: true },\r\n                { id: 'int_30', category: 'Other rooms', name: 'Custom-made furniture', pricePln: 5000.00, included: true, details: '* Price includes a total of 10 linear meters of furniture (kitchen + rooms). Sliding or traditional wardrobes. Surcharges for: extra drawers, cargo, exceeding dimensions.' },\r\n                { id: 'int_31', category: 'Other rooms', name: 'Bed 160 x 200 cm', pricePln: 1000.00, included: true, details: 'Bed with lifting frame for storage.' },\r\n                { id: 'int_32', category: 'Other rooms', name: 'Bed 90 x 200 cm (2 pcs)', pricePln: 500.00, included: true },\r\n                { id: 'int_33', category: 'Other rooms', name: 'Mattress 160 x 200 cm', pricePln: 400.00, included: true },\r\n                { id: 'int_34', category: 'Other rooms', name: 'Mattress 90 x 200 cm (2 pcs)', pricePln: 500.00, included: true },\r\n                { id: 'int_35', category: 'Other rooms', name: 'Bedspread 160cm', pricePln: 120.00, included: true },\r\n                { id: 'int_36', category: 'Other rooms', name: 'Bedspreads 90cm (2 pcs)', pricePln: 140.00, included: true },\r\n                { id: 'int_37', category: 'Other rooms', name: 'Frames + posters (2 pcs)', pricePln: 50.00, included: true },\r\n                { id: 'int_38', category: 'Other rooms', name: 'Wall lamps (2 pcs)', pricePln: 300.00, included: true },\r\n                { id: 'int_41', category: 'Other rooms', name: 'Pillows (6 pcs)', pricePln: 240.00, included: true },\r\n\r\n                { id: 'ext_2', category: 'Construction', name: 'Foundation and leveling', pricePln: 8500.00, included: false, details: 'Includes up to 8 man-hours over 2 business days.' },\r\n                { id: 'ext_3', category: 'Construction', name: 'Gable or hidden roof', pricePln: 0, included: false, unit: 'custom pricing', details: 'Approx. 29,000 - 38,000 PLN net depending on house size.' },\r\n                { id: 'ext_4', category: 'Terrace', name: 'Terrace', pricePln: 37000.00, included: false, details: 'Price is for a 20 m2 terrace. Steel structure, BergDeck terrace boards.' },\r\n                { id: 'ext_5', category: 'Terrace', name: 'Terrace extension without roof', pricePln: 2200.00, included: false, unit: 'm2' },\r\n                { id: 'ext_6', category: 'Terrace', name: 'Terrace extension with roof', pricePln: 2700.00, included: false, unit: 'm2' },\r\n                { id: 'ext_7', category: 'Terrace', name: 'Extension creating a gazebo', pricePln: 25000.00, included: false },\r\n                { id: 'ext_8', category: 'Terrace', name: 'Transport of terrace and gazebo', pricePln: 8500.00, included: false, details: 'Fixed price within Poland.' },\r\n                { id: 'ext_9', category: 'Terrace', name: 'Assembly of terrace and gazebo', pricePln: 8500.00, included: false, details: 'Assembly in Poland.' },\r\n                { id: 'ext_schody_standard', category: 'Construction', name: 'Stairs to the house', pricePln: 2900.00, included: false, details: 'two-step, 1 m wide' },\r\n                { id: 'ext_stairs_plus', category: 'Construction', name: 'Surcharge for larger stairs', pricePln: 2900.00, included: false, unit: 'lm' },\r\n                { id: 'ext_handrail', category: 'Construction', name: 'Handrail', pricePln: 350.00, included: false, unit: 'm2' },\r\n                { id: 'ext_12', category: 'Facade', name: 'VOX Solvo SO-01 panels', pricePln: 90.00, included: false, unit: 'm2' },\r\n                { id: 'ext_13', category: 'Facade', name: 'Kerrafront Wood Effect panels', pricePln: 186.00, included: false, unit: 'm2' },\r\n                { id: 'ext_14', category: 'Facade', name: 'Vinylit panels', pricePln: 186.00, included: false, unit: 'm2' },\r\n                { id: 'ext_45', category: 'Facade', name: 'Plaster on the facade', pricePln: 210.00, included: false, unit: 'm2' },\r\n                { id: 'ext_15', category: 'Interior', name: 'Herringbone floor', pricePln: 120.00, included: false, unit: 'm2' },\r\n                { id: 'ext_door_large', category: 'Interior', name: 'Larger internal doors (width >70 cm)', pricePln: 0, included: false, unit: 'custom pricing', details: 'Cost 200-500 PLN' },\r\n                { id: 'ext_16', category: 'Windows', name: 'Larger windows', pricePln: 0, included: false, unit: 'custom pricing', details: 'E.g., a) windows 60 x 210 cm 5 pcs, b) sliding 2-leaf window (200 x 210 cm).' },\r\n                { id: 'ext_17', category: 'Windows', name: 'External roller shutters (House)', pricePln: 8900.00, included: false },\r\n                { id: 'ext_18', category: 'Windows', name: 'External roller shutters (Gazebo)', pricePln: 14000.00, included: false },\r\n                { id: 'ext_19', category: 'Windows', name: 'Window mosquito nets', pricePln: 4800.00, included: false },\r\n                { id: 'ext_20', category: 'Windows', name: 'Sliding mosquito net (door)', pricePln: 2800.00, included: false },\r\n                { id: 'ext_21', category: 'Windows', name: 'Mosquito nets (Gazebo)', pricePln: 9700.00, included: false },\r\n                { id: 'ext_22', category: 'Installations', name: 'Air conditioning', pricePln: 8500.00, included: false },\r\n                { id: 'ext_23', category: 'Installations', name: 'Additional air conditioning', pricePln: 1800.00, included: false },\r\n                { id: 'ext_24', category: 'Installations', name: 'Preparation for A\/C', pricePln: 3500.00, included: false },\r\n                { id: 'ext_25', category: 'Smart Home', name: 'Monitoring (CCTV)', pricePln: 6500.00, included: false, details: 'Set of 4 cameras.' },\r\n                { id: 'ext_26', category: 'Smart Home', name: 'Alarm system', pricePln: 6500.00, included: false, details: 'Set of 4 sensors.' },\r\n                { id: 'ext_27', category: 'Bathroom', name: 'Fibo panels + bathtub', pricePln: 9500.00, included: false, details: 'Fibo panels only in wet areas.' },\r\n                { id: 'ext_28', category: 'Bathroom', name: 'Fibo panels + shower cabin', pricePln: 9500.00, included: false, details: 'Two-wall cabin, shallow tray. Fibo panels only in wet areas.' },\r\n                \r\n                { id: 'ext_29', category: 'Interior', name: 'Forestia wall panels', pricePln: 280.00, included: false, unit: 'm2', details: 'Tongue and groove connection, no plastic strips.' },\r\n                { id: 'ext_46', category: 'Interior', name: 'Plasterboard on internal walls', pricePln: 195.00, included: false, unit: 'm2' },\r\n                { id: 'ext_31', category: 'Kitchen', name: 'Lacquered fronts', pricePln: 190.00, included: false, unit: 'm2' },\r\n                { id: 'ext_34', category: 'Kitchen', name: 'Additional furniture', pricePln: 950.00, included: false, unit: 'lm' },\r\n                { id: 'ext_42', category: 'Design', name: '3D Visualization', pricePln: 0, included: false, unit: 'custom pricing', details: 'Cost between 6000 and 8000 PLN' },\r\n\r\n                { id: 'ext_32', category: 'Kitchen', name: 'Cargo baskets', pricePln: 0, included: false, unit: 'custom pricing' },\r\n                { id: 'ext_33', category: 'Kitchen', name: 'Extra Blum drawers', pricePln: 450.00, included: false, unit: 'pcs' },\r\n                { id: 'ext_35', category: 'Installations', name: 'Extra electrical sockets', pricePln: 120.00, included: false, unit: 'pcs' },\r\n                { id: 'ext_36', category: 'RES', name: 'Photovoltaics (Solar panels)', pricePln: 0, included: false, unit: 'custom pricing' },\r\n                { id: 'ext_37', category: 'RES', name: 'Preparation for photovoltaics', pricePln: 1200.00, included: false },\r\n                { id: 'ext_38', category: 'RES', name: 'Heat pump', pricePln: 0, included: false, unit: 'custom pricing' },\r\n                { id: 'ext_39', category: 'Ventilation', name: 'Central recuperation', pricePln: 15000.00, included: false, details: 'Possible only with a gable roof.' },\r\n                { id: 'ext_40', category: 'Ventilation', name: 'Single recuperator', pricePln: 2800.00, included: false },\r\n                { id: 'ext_41', category: 'Construction', name: 'Enclosing the bottom of the house', pricePln: 0, included: false, unit: 'custom pricing' },\r\n                { id: 'ext_43', category: 'Design', name: 'Building project (Architecture plan)', pricePln: 8000.00, included: false },\r\n                { id: 'ext_44', category: 'Other', name: 'Other wishes', pricePln: 0, included: false, unit: 'custom pricing' }\r\n            ];\r\n\r\n            \/\/ Convert items prices\r\n            allItems.forEach(i => i.price = getConvertedPrice(i.pricePln));\r\n\r\n            document.getElementById('exchange-rate-info').innerHTML = `Prices are based on the current NBP exchange rate:<br><strong>1 EUR = ${exchangeRate.toFixed(4)} PLN<\/strong>. Converted values are rounded up to the nearest \u20ac5.`;\r\n\r\n            let state = { \r\n                selectedModelId: 'm36', \r\n                customMetrazValue: '', \r\n                items: JSON.parse(JSON.stringify(allItems)).map(i => ({...i, selected: i.included, note: ''}))\r\n            };\r\n\r\n            function formatCurrency(v) { if (v === 0) return 'included'; return isNaN(v) ? v : '\u20ac ' + v.toLocaleString('en-US', {minimumFractionDigits: 0}); }\r\n            function formatCurrencyNetto(v) { return isNaN(v) ? v : '\u20ac ' + v.toLocaleString('en-US', {minimumFractionDigits: 2}); }\r\n\r\n            function parseCustomArea(input) {\r\n                if(!input) return 0;\r\n                let clean = input.replace(',', '.').toLowerCase();\r\n                let numbers = clean.match(\/(\\d+(\\.\\d+)?)\/g); \r\n                if (!numbers) return 0;\r\n                if (numbers.length === 1) return parseFloat(numbers[0]);\r\n                if (numbers.length >= 2) return parseFloat(numbers[0]) * parseFloat(numbers[1]);\r\n                return 0;\r\n            }\r\n\r\n            function renderModels() {\r\n                document.getElementById('model-options-wrapper').innerHTML = models.map(m => `\r\n                    <div class=\"model-option\">\r\n                        <input type=\"radio\" name=\"model\" id=\"${m.id}\" value=\"${m.id}\" class=\"model-radio\" ${m.id === state.selectedModelId ? 'checked' : ''}>\r\n                        <label for=\"${m.id}\" class=\"model-label\"><span class=\"m-name\">${m.name}<\/span><span class=\"m-area\">${m.sub ? m.sub : ''}<\/span><\/label>\r\n                    <\/div>`).join('');\r\n                document.getElementById('custom-metraz-wrapper').style.display = state.selectedModelId === 'custom' ? 'block' : 'none';\r\n            }\r\n\r\n            function renderRow(item, context) {\r\n                const isIncluded = context === 'included';\r\n                let priceDisplay = isIncluded ? `<div style=\"font-size:0.9rem; font-weight:600; color:#334155;\">Value: ${formatCurrency(item.price)}<\/div>` : `<span class=\"product-name\" style=\"font-size:0.95rem;\">${item.unit === 'custom pricing' ? 'Custom pricing' : formatCurrency(item.price)}<\/span>${item.unit && item.unit !== 'custom pricing' ? `<span class=\"price-unit\">\/ ${item.unit}<\/span>`:''}`;\r\n                let disabled = (item.id === 'ext_24' && state.items.find(x => x.id === 'ext_22').selected) ? 'disabled' : '';\r\n                let detailsHtml = item.details ? `<a class=\"details-link\" onclick=\"toggleDetails('${item.id}')\"><i class=\"fa-solid fa-circle-info\"><\/i> Show details<\/a><div id=\"details-${item.id}\" class=\"details-box\">${item.details}<\/div>` : '';\r\n\r\n                return `<tr>\r\n                    <td class=\"td-name\"><div class=\"product-info\"><span class=\"product-name\">${item.name}<\/span>${item.description ? `<span class=\"product-name\" style=\"font-size:0.85rem; color:var(--text-muted); font-weight:400;\">${item.description}<\/span>` : ''}${detailsHtml}<\/div><\/td>\r\n                    <td class=\"td-price\">${priceDisplay}<\/td>\r\n                    <td class=\"td-toggle\"><label class=\"toggle-switch\"><input type=\"checkbox\" class=\"item-trigger\" data-id=\"${item.id}\" ${item.selected ? 'checked' : ''} ${disabled}><span class=\"slider\"><\/span><\/label><\/td>\r\n                    <td class=\"td-note\"><input type=\"text\" class=\"note-input\" data-id=\"${item.id}\" value=\"${item.note}\" placeholder=\"Add notes...\"><\/td>\r\n                <\/tr>`;\r\n            }\r\n\r\n            window.toggleDetails = function(id) { const el = document.getElementById(`details-${id}`); el.style.display = el.style.display === 'block' ? 'none' : 'block'; };\r\n\r\n            function renderIncluded() {\r\n                const staticItems = state.items.filter(i => i.included && i.static);\r\n                document.querySelector('.features-list').innerHTML = staticItems.map(i => `<div class=\"feature-box\"><i class=\"${i.icon}\"><\/i><div class=\"feature-text\">${i.name} ${i.description ? `<small>${i.description}<\/small>` : ''}${i.details ? `<br><small style=\"font-weight:400;color:var(--text-muted)\">${i.details}<\/small>` : ''}<\/div><\/div>`).join('');\r\n                \r\n                const configurable = state.items.filter(i => i.included && !i.static);\r\n                const categories = {};\r\n                configurable.forEach(item => { if(!categories[item.category]) categories[item.category] = []; categories[item.category].push(item); });\r\n                \r\n                let html = '';\r\n                for (const [catName, items] of Object.entries(categories)) {\r\n                    html += `<h3 class=\"category-header\">${catName}<\/h3><table class=\"config-table\"><thead><tr><th style=\"width:50%\">Product<\/th><th style=\"width:20%\">Value<\/th><th style=\"width:10%;text-align:center\">Uncheck to opt-out<\/th><th style=\"width:20%\">Notes<\/th><\/tr><\/thead><tbody>${items.map(i => renderRow(i, 'included')).join('')}<\/tbody><\/table>`;\r\n                }\r\n                document.getElementById('items-included-container').innerHTML = html;\r\n            }\r\n\r\n            function renderExtras() {\r\n                document.getElementById('items-extra-body').innerHTML = state.items.filter(i => !i.included).map(i => renderRow(i, 'extra')).join('');\r\n            }\r\n\r\n            \/\/ ZAKTUALIZOWANE OBLICZANIE WYNIK\u00d3W BAZOWYCH Z NOWYM ALGORYTMEM DLA \"CUSTOM\"\r\n            function updateSummary() {\r\n                let base = 0;\r\n                let customArea = 0;\r\n                let modelName = '';\r\n\r\n                const model = models.find(m => m.id === state.selectedModelId);\r\n                \r\n                if (model) {\r\n                    if (!model.isCustom) {\r\n                        modelName = model.name;\r\n                        base = model.price;\r\n                    } else {\r\n                        const inputVal = document.getElementById('customMetrazInput').value;\r\n                        customArea = parseCustomArea(inputVal);\r\n                        \r\n                        if (customArea > 0) {\r\n                            \/\/ Znajd\u017a metra\u017c najbli\u017cej warto\u015bci u\u017cytkownika\r\n                            const definedModels = models.filter(m => !m.isCustom);\r\n                            let closestModel = definedModels[0];\r\n                            let minDiff = Math.abs(customArea - closestModel.size);\r\n                            \r\n                            for (let i = 1; i < definedModels.length; i++) {\r\n                                let diff = Math.abs(customArea - definedModels[i].size);\r\n                                if (diff < minDiff) {\r\n                                    minDiff = diff;\r\n                                    closestModel = definedModels[i];\r\n                                }\r\n                            }\r\n                            \r\n                            \/\/ Wylicz stawk\u0119 m2 w PLN wybranego najbli\u017cszego modelu\r\n                            const pricePerSqmPln = closestModel.pricePln \/ closestModel.size;\r\n                            \/\/ Policz now\u0105 stawk\u0119 za podany metra\u017c w PLN\r\n                            const customBasePln = pricePerSqmPln * customArea;\r\n                            \r\n                            base = getConvertedPrice(customBasePln);\r\n                            modelName = `Custom ${customArea} m\u00b2`;\r\n                        } else {\r\n                            modelName = `Custom (to be priced)`;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                let sub = 0, add = 0;\r\n                const roofPricesPln = { 'm40': 29000, 'm44': 31000, 'm45': 32000, 'm48': 33000, 'm54': 34000, 'm56': 35000, 'm63': 38000 };\r\n\r\n                state.items.forEach(i => { \r\n                    if(i.included && !i.selected) sub += i.price; \r\n                    if(!i.included && i.selected) {\r\n                        let itemPrice = i.price;\r\n                        if(i.id === 'ext_3' && roofPricesPln[state.selectedModelId]) {\r\n                            itemPrice = getConvertedPrice(roofPricesPln[state.selectedModelId]);\r\n                        }\r\n\r\n                        if(!i.unit || i.unit === 'pcs' || i.unit === '' || (i.id === 'ext_3' && roofPricesPln[state.selectedModelId])) {\r\n                            add += itemPrice;\r\n                        }\r\n                    } \r\n                });\r\n                \r\n                const total = base - sub + add;\r\n\r\n                document.getElementById('summary-model-name').textContent = modelName;\r\n                document.getElementById('summary-subtractions').textContent = sub > 0 ? \"- \" + formatCurrencyNetto(sub) : \"-\";\r\n                document.getElementById('summary-subtractions').className = sub > 0 ? \"red-text\" : \"\";\r\n                document.getElementById('summary-additions').textContent = add > 0 ? \"+ \" + formatCurrencyNetto(add) : \"-\";\r\n                document.getElementById('summary-additions').className = add > 0 ? \"green-text\" : \"\";\r\n                \r\n                prepareEmailData(model ? modelName : 'Custom', base, sub, add, total, customArea);\r\n            }\r\n\r\n            function prepareEmailData(mName, base, sub, add, total, customArea) {\r\n                const clientName = document.getElementById('client_name').value || 'Not provided';\r\n                const clientEmail = document.getElementById('client_email').value || 'Not provided';\r\n                const clientPhone = document.getElementById('client_phone').value || 'Not provided';\r\n                const contactHours = document.getElementById('contact_hours').value || 'Not provided';\r\n                const postalCode = document.getElementById('postal_code_input').value || 'Not provided';\r\n                const plannedDate = document.getElementById('planned_date').value || 'Not provided';\r\n                const clientMessage = document.getElementById('client_message').value || 'None';\r\n\r\n                const now = new Date();\r\n                const idWyceny = `QUOTE-VERO-${now.getFullYear()}${(now.getMonth()+1).toString().padStart(2,'0')}${now.getDate().toString().padStart(2,'0')}-${now.getHours().toString().padStart(2,'0')}${now.getMinutes().toString().padStart(2,'0')}`;\r\n                \r\n                const dateStr = now.toLocaleDateString('en-GB');\r\n                let areaStr = (state.selectedModelId === 'custom' && customArea > 0) ? customArea : mName.replace(' m\u00b2', '');\r\n\r\n                let bodyText = `======================================\\n`;\r\n                bodyText += `  VERO HOMES MOBILE HOUSE QUOTE\\n`;\r\n                bodyText += `======================================\\n\\n`;\r\n                \r\n                bodyText += `DATE: ${dateStr}\\n`;\r\n                bodyText += `QUOTE ID: ${idWyceny}\\n`;\r\n                bodyText += `MODEL: ${areaStr} m\u00b2\\n\\n`;\r\n\r\n                bodyText += `--- CLIENT DETAILS ---\\n`;\r\n                bodyText += `Name: ${clientName}\\n`;\r\n                bodyText += `Email: ${clientEmail}\\n`;\r\n                bodyText += `Phone: ${clientPhone}\\n`;\r\n                bodyText += `Preferred contact hours: ${contactHours}\\n`;\r\n                bodyText += `Postal code (delivery): ${postalCode}\\n`;\r\n                bodyText += `Planned realization date: ${plannedDate}\\n\\n`;\r\n\r\n                if(clientMessage !== 'None') {\r\n                    bodyText += `INQUIRY CONTENT:\\n${clientMessage}\\n\\n`;\r\n                }\r\n\r\n                const dodatki = state.items.filter(i => !i.included && i.selected);\r\n                if(dodatki.length) {\r\n                    bodyText += `ADDITIONS (+ ${formatCurrencyNetto(add)})\\n`;\r\n                    \r\n                    dodatki.forEach(i => {\r\n                        let unitStr = (i.unit && i.unit !== 'custom pricing') ? ` (${i.unit})` : '';\r\n                        bodyText += `${i.name}${unitStr}\\n`;\r\n                    });\r\n                    \r\n                    bodyText += `\\n`; \r\n                    \r\n                    dodatki.forEach(i => {\r\n                        let p = '';\r\n                        if(i.id === 'ext_3') {\r\n                            const roofPricesPln = { 'm40': 29000, 'm44': 31000, 'm45': 32000, 'm48': 33000, 'm54': 34000, 'm56': 35000, 'm63': 38000 };\r\n                            if(roofPricesPln[state.selectedModelId]) {\r\n                                p = `+ ${formatCurrencyNetto(getConvertedPrice(roofPricesPln[state.selectedModelId]))}`;\r\n                            } else {\r\n                                p = 'Custom pricing';\r\n                            }\r\n                        } else if(i.unit && (i.unit === 'm2' || i.unit === 'lm' || i.unit === 'custom pricing')) {\r\n                            p = 'Custom pricing';\r\n                        } else {\r\n                            p = `+ ${formatCurrencyNetto(i.price)}`;\r\n                        }\r\n                        bodyText += `${p}\\n`;\r\n                    });\r\n                    bodyText += `\\n\\n`;\r\n                }\r\n\r\n                const rezygnacje = state.items.filter(i => i.included && !i.selected);\r\n                if(rezygnacje.length) {\r\n                    bodyText += `CANCELLATIONS (- ${formatCurrencyNetto(sub)})\\n`;\r\n                    \r\n                    rezygnacje.forEach(i => {\r\n                        bodyText += `${i.name}\\n`;\r\n                    });\r\n                    \r\n                    bodyText += `\\n`; \r\n                    \r\n                    rezygnacje.forEach(i => {\r\n                        bodyText += `- ${formatCurrencyNetto(i.price)}\\n`;\r\n                    });\r\n                    \r\n                    bodyText += `\\n\\n`;\r\n                    \r\n                    const groups = {};\r\n                    rezygnacje.forEach(i => {\r\n                        let catName = i.category;\r\n                        if(!groups[catName]) groups[catName] = { sum: 0, items: [] };\r\n                        groups[catName].sum += i.price;\r\n                        groups[catName].items.push(i);\r\n                    });\r\n\r\n                    bodyText += `Cancellations:\\n`;\r\n                    for (const [cat, data] of Object.entries(groups)) {\r\n                        const namesList = data.items.map(item => item.name).join(', ');\r\n                        bodyText += `${cat}: ${namesList}\\n`;\r\n                    }\r\n                    bodyText += `\\n`;\r\n\r\n                    for (const [cat, data] of Object.entries(groups)) {\r\n                        bodyText += `- ${formatCurrencyNetto(data.sum)}\\n`;\r\n                    }\r\n                    bodyText += `\\n`;\r\n                }\r\n\r\n                const itemsWithNotes = state.items.filter(i => i.note && i.note.trim() !== '');\r\n                if(itemsWithNotes.length) {\r\n                    bodyText += `--- ITEM NOTES ---\\n`;\r\n                    itemsWithNotes.forEach(i => {\r\n                        bodyText += `\u2022 ${i.name}:\\n  ${i.note}\\n\\n`;\r\n                    });\r\n                }\r\n\r\n                bodyText += `======================================\\n`;\r\n                bodyText += `PRELIMINARY NET PRICE: ${formatCurrencyNetto(total)}\\n`;\r\n                bodyText += `Exchange rate applied: 1 EUR = ${exchangeRate.toFixed(4)} PLN (NBP API)\\n`;\r\n                bodyText += `======================================\\n`;\r\n\r\n                let finalHtml = `<div style=\"background-color: #f0fdf4; padding: 25px; font-family: Arial, sans-serif; font-size: 14px; color: #0f172a; border-radius: 8px; max-width: 800px; border: 1px solid #bbf7d0;\">`;\r\n                finalHtml += bodyText.replace(\/\\n\/g, '<br>');\r\n                finalHtml += `<\/div>`;\r\n\r\n                document.getElementById('hidden_summary_field').value = finalHtml;\r\n            }\r\n\r\n            const form = document.getElementById('config-form-main');\r\n            const submitButton = document.getElementById('submit-btn');\r\n            const result = document.getElementById('result');\r\n            \r\n            form.addEventListener('change', e => {\r\n                if(e.target.name === 'model') { state.selectedModelId = e.target.value; renderModels(); }\r\n                if(e.target.classList.contains('item-trigger')) {\r\n                    const id = e.target.dataset.id;\r\n                    const item = state.items.find(i => i.id === id);\r\n                    if(item) item.selected = e.target.checked;\r\n                    if(id === 'ext_22' && item.selected) { const prep = state.items.find(x => x.id === 'ext_24'); if(prep) prep.selected = false; renderExtras(); }\r\n                    else if (id === 'ext_22' && !item.selected) { renderExtras(); }\r\n                }\r\n                updateSummary();\r\n            });\r\n\r\n            form.addEventListener('input', e => {\r\n                if(e.target.classList.contains('note-input')) { state.items.find(i => i.id === e.target.dataset.id).note = e.target.value; }\r\n                if(e.target.id === 'customMetrazInput') { updateSummary(); }\r\n                updateSummary();\r\n            });\r\n\r\n            document.addEventListener('click', function(e) {\r\n                const row = e.target.closest('tr');\r\n                if (!row) return;\r\n                if (!row.closest('.config-table')) return;\r\n                if (e.target.tagName === 'INPUT' || \r\n                    e.target.closest('.toggle-switch') || \r\n                    e.target.closest('.details-link') || \r\n                    e.target.closest('.note-input')) {\r\n                    return;\r\n                }\r\n                const checkbox = row.querySelector('input[type=\"checkbox\"].item-trigger');\r\n                if (checkbox && !checkbox.disabled) {\r\n                    checkbox.checked = !checkbox.checked;\r\n                    checkbox.dispatchEvent(new Event('change', { bubbles: true }));\r\n                }\r\n            });\r\n\r\n            form.addEventListener('submit', function(e) {\r\n                e.preventDefault(); \r\n                updateSummary();\r\n                \r\n                submitButton.innerText = \"Sending...\"; \r\n                submitButton.disabled = true;\r\n                result.innerHTML = \"Sending your request...\";\r\n                result.style.color = \"#666\";\r\n\r\n                const formData = new FormData(form);\r\n                const data = new URLSearchParams(formData);\r\n\r\n                fetch(GOOGLE_SCRIPT_URL, {\r\n                    method: 'POST',\r\n                    body: data \r\n                })\r\n                .then(response => response.json())\r\n                .then(json => {\r\n                    if (json.result === 'success') {\r\n                        result.innerHTML = \"\u2705 Your request has been sent successfully. Thank you!<br>The Vero Homes sales team will send you a personalized offer shortly.\";\r\n                        result.style.color = \"green\";\r\n                        submitButton.innerText = \"Sent!\";\r\n                    } else {\r\n                        throw new Error(json.error || 'Unknown error');\r\n                    }\r\n                })\r\n                .catch(error => {\r\n                    console.error('Error:', error);\r\n                    result.innerHTML = \"\u274c Sending failed. Please try again later or contact us by phone.\";\r\n                    result.style.color = \"red\";\r\n                    submitButton.innerText = \"Try again\";\r\n                    submitButton.disabled = false;\r\n                });\r\n            });\r\n\r\n            document.getElementById('reset-btn').addEventListener('click', () => { if(confirm('Reset the form?')) location.reload(); });\r\n\r\n            renderModels(); renderIncluded(); renderExtras(); updateSummary();\r\n        });\r\n    <\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>VERO HOMES Configurator Mobile Home Configurator Choose the size, customize the equipment, and get a quote for your house. 1. Choose house size Enter custom dimensions: 2. Equipment included in the price Fixed elements The items below are also included in the price. You can uncheck them (opt out) to reduce the cost. 3. Additional &hellip;<\/p>\n<p class=\"read-more\"> <a class=\"\" href=\"https:\/\/verohomes.pl\/en\/mobile-homes-configurator\/\"> <span class=\"screen-reader-text\">Configurator<\/span> Read More &raquo;<\/a><\/p>\n","protected":false},"author":5,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"inline_featured_image":false,"site-sidebar-layout":"no-sidebar","site-content-layout":"page-builder","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","footnotes":""},"class_list":["post-16561","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/verohomes.pl\/en\/wp-json\/wp\/v2\/pages\/16561","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/verohomes.pl\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/verohomes.pl\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/verohomes.pl\/en\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/verohomes.pl\/en\/wp-json\/wp\/v2\/comments?post=16561"}],"version-history":[{"count":157,"href":"https:\/\/verohomes.pl\/en\/wp-json\/wp\/v2\/pages\/16561\/revisions"}],"predecessor-version":[{"id":19344,"href":"https:\/\/verohomes.pl\/en\/wp-json\/wp\/v2\/pages\/16561\/revisions\/19344"}],"wp:attachment":[{"href":"https:\/\/verohomes.pl\/en\/wp-json\/wp\/v2\/media?parent=16561"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}