{"id":963,"date":"2026-07-02T08:19:40","date_gmt":"2026-07-02T08:19:40","guid":{"rendered":"https:\/\/elecrest.dreamhosters.com\/?page_id=963"},"modified":"2026-07-07T03:26:48","modified_gmt":"2026-07-07T03:26:48","slug":"configurator","status":"publish","type":"page","link":"https:\/\/elecrest.energy\/fr\/configurator\/","title":{"rendered":"Configurator"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"963\" class=\"elementor elementor-963\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d8267bb e-flex e-con-boxed e-con e-parent\" data-id=\"d8267bb\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5ed4095 elementor-widget elementor-widget-html\" data-id=\"5ed4095\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<div class=\"hc-configurator\" id=\"hc-configurator-app\">\n    <!-- Visualizer (Left) -->\n    <div class=\"visualizer\">\n        <div class=\"product-preview\" id=\"product-preview\">\n\n            <!-- [Closed Door Group] (Step 1, 3) -->\n            <div id=\"closed-door-group\" class=\"layer-group active\">\n                <img decoding=\"async\" id=\"base-image\" src=\"\" class=\"layer base-layer\" alt=\"Base\">\n                <img decoding=\"async\" id=\"gun-layer-1\" src=\"\" class=\"layer gun-layer hidden\" alt=\"Connector 1\">\n                <img decoding=\"async\" id=\"gun-layer-2\" src=\"\" class=\"layer gun-layer hidden\" alt=\"Connector 2\">\n                <img decoding=\"async\" id=\"gun-layer-3\" src=\"\" class=\"layer gun-layer hidden\" alt=\"Connector 3\">\n                <img decoding=\"async\" id=\"gun-layer-4\" src=\"\" class=\"layer gun-layer hidden\" alt=\"Connector 4\">\n            <\/div>\n\n            <!-- [Open Door Group] (Step 2) -->\n            <div id=\"open-door-group\" class=\"layer-group hidden\">\n                <img decoding=\"async\" id=\"power-layer\" src=\"\" class=\"layer base-layer\" alt=\"Power Modules\">\n            <\/div>\n\n            <!-- [Colour Select Group] (Step 4) -->\n            <div id=\"color-select-group\" class=\"layer-group hidden\">\n                <img decoding=\"async\" id=\"color-base-image\" src=\"\" class=\"layer base-layer\" alt=\"Colour Base\">\n                \n                <!-- SVG Colour Overlay - Main Body -->\n                <svg id=\"svg-body\" class=\"layer svg-color-layer\" viewBox=\"0 0 2400 2400\" preserveAspectRatio=\"none\">\n                    <defs>\n                        <mask id=\"body-mask-240\" maskContentUnits=\"userSpaceOnUse\">\n                            <image id=\"mask-img-240-body\" href=\"\" x=\"0\" y=\"0\" width=\"2400\" height=\"2400\" preserveAspectRatio=\"none\"\/>\n                        <\/mask>\n                        <mask id=\"body-mask-480\" maskContentUnits=\"userSpaceOnUse\">\n                            <image id=\"mask-img-480-body\" href=\"\" x=\"0\" y=\"0\" width=\"2400\" height=\"2400\" preserveAspectRatio=\"none\"\/>\n                        <\/mask>\n                    <\/defs>\n                    <rect id=\"svg-body-rect\" x=\"0\" y=\"0\" width=\"2400\" height=\"2400\" fill=\"#ffffff\" mask=\"url(#body-mask-240)\" style=\"mix-blend-mode: multiply;\"\/>\n                <\/svg>\n                \n                <!-- SVG Colour Overlay - Stripe -->\n                <svg id=\"svg-stripe\" class=\"layer svg-color-layer\" viewBox=\"0 0 2400 2400\" preserveAspectRatio=\"none\">\n                    <defs>\n                        <mask id=\"stripe-mask-240\" maskContentUnits=\"userSpaceOnUse\">\n                            <image id=\"mask-img-240-stripe\" href=\"\" x=\"0\" y=\"0\" width=\"2400\" height=\"2400\" preserveAspectRatio=\"none\"\/>\n                        <\/mask>\n                        <mask id=\"stripe-mask-480\" maskContentUnits=\"userSpaceOnUse\">\n                            <image id=\"mask-img-480-stripe\" href=\"\" x=\"0\" y=\"0\" width=\"2400\" height=\"2400\" preserveAspectRatio=\"none\"\/>\n                        <\/mask>\n                    <\/defs>\n                    <rect id=\"svg-stripe-rect\" x=\"0\" y=\"0\" width=\"2400\" height=\"2400\" fill=\"#00e5ff\" mask=\"url(#stripe-mask-240)\" style=\"mix-blend-mode: multiply;\"\/>\n                <\/svg>\n            <\/div>\n\n        <\/div>\n    <\/div>\n\n    <!-- Wizard Panel (Right) -->\n    <div class=\"controls wizard-panel\">\n        \n        <!-- Progress Indicators -->\n        <div class=\"wizard-header\">\n            <div class=\"step-indicator active\" data-step=\"1\">\n                <span class=\"step-num\">1<\/span>\n                <span class=\"step-label\">Model<\/span>\n            <\/div>\n            <div class=\"step-connector\"><\/div>\n            <div class=\"step-indicator\" data-step=\"2\">\n                <span class=\"step-num\">2<\/span>\n                <span class=\"step-label\">Power<\/span>\n            <\/div>\n            <div class=\"step-connector\"><\/div>\n            <div class=\"step-indicator\" data-step=\"3\">\n                <span class=\"step-num\">3<\/span>\n                <span class=\"step-label\">Config<\/span>\n            <\/div>\n            <div class=\"step-connector\"><\/div>\n            <div class=\"step-indicator\" data-step=\"4\">\n                <span class=\"step-num\">4<\/span>\n                <span class=\"step-label\">Colour<\/span>\n            <\/div>\n            <div class=\"step-connector\"><\/div>\n            <div class=\"step-indicator\" data-step=\"5\">\n                <span class=\"step-num\">5<\/span>\n                <span class=\"step-label\">Summary<\/span>\n            <\/div>\n        <\/div>\n\n        <!-- Content Area -->\n        <div class=\"wizard-content\">\n            \n            <!-- STEP 1: Model -->\n            <div class=\"step-pane active\" id=\"step-1\">\n                <h2>Select Product Model<\/h2>\n                <p class=\"step-desc\">Please select the base model. This determines the maximum power and number of connectors.<\/p>\n                <div class=\"model-cards\">\n                    <label class=\"model-card\">\n                        <input type=\"radio\" name=\"model\" value=\"240kW\" checked>\n                        <div class=\"card-content\">\n                            <h3>HYC 240<\/h3>\n                            <p>Up to 240 kW<br>Dual connector<\/p>\n                        <\/div>\n                    <\/label>\n                    <label class=\"model-card\">\n                        <input type=\"radio\" name=\"model\" value=\"480kW\">\n                        <div class=\"card-content\">\n                            <h3>HYC 480<\/h3>\n                            <p>Up to 480 kW<br>Quad connector<\/p>\n                        <\/div>\n                    <\/label>\n                <\/div>\n            <\/div>\n\n            <!-- STEP 2: Power -->\n            <div class=\"step-pane\" id=\"step-2\">\n                <h2>Select Power Modules<\/h2>\n                <p class=\"step-desc\">View the internal architecture and select the number of power modules to install (120 kW per module).<\/p>\n                <div class=\"control-group\">\n                    <h3>Power Options<\/h3>\n                    <div class=\"radio-group vertical\" id=\"power-options-container\">\n                        <!-- JS renders this -->\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            <!-- STEP 3: Config & Cables -->\n            <div class=\"step-pane\" id=\"step-3\">\n                <h2>Detailed Configuration<\/h2>\n                <p class=\"step-desc\">Select the screen type, additional equipment, and cable specifications for each connector.<\/p>\n                \n                <div class=\"control-group\">\n                    <h3>Additional Options<\/h3>\n                    <div class=\"checkbox-group\">\n                        <label><input type=\"checkbox\" id=\"opt-payment\"> Payment Terminal (POS)<\/label>\n                        <label><input type=\"checkbox\" id=\"opt-accessible\"> Accessible Screen Version<\/label>\n                        <label><input type=\"checkbox\" id=\"opt-doorcontact\"> Door Contact Switch<\/label>\n                    <\/div>\n                <\/div>\n\n                <div class=\"control-group\" id=\"guns-container\">\n                    <h3>Connector Configuration<\/h3>\n                    <p class=\"hint-text\" id=\"hint-5m\" style=\"display:none;\">Note: Inner positions (2 & 3) on the 480 kW model do not support 5m cables.<\/p>\n                    <!-- JS renders this -->\n                <\/div>\n            <\/div>\n\n            <!-- STEP 4: Colours -->\n            <div class=\"step-pane\" id=\"step-4\">\n                <h2>Customise Appearance<\/h2>\n                <p class=\"step-desc\">Select fixed professional body and accent colour presets suitable for real charging sites, or fine tune exact colours for project branding.<\/p>\n                \n                <div class=\"control-group\">\n                    <h3>Body Finish<\/h3>\n                    <div class=\"color-dropdown\" id=\"body-color-dropdown\">\n                        <button type=\"button\" class=\"color-dropdown-trigger\" id=\"body-dropdown-trigger\">\n                            <span class=\"color-dropdown-swatch\" id=\"body-dropdown-swatch\"><\/span>\n                            <span class=\"color-dropdown-text\" id=\"body-dropdown-text\">Glacier White<\/span>\n                            <span class=\"color-dropdown-arrow\">&#9662;<\/span>\n                        <\/button>\n                        <div class=\"color-dropdown-panel\" id=\"body-dropdown-panel\">\n                            <div class=\"color-swatch-grid\" id=\"body-swatch-grid\"><\/div>\n                        <\/div>\n                    <\/div>\n                <\/div>\n\n                <div class=\"control-group\">\n                    <h3>Accent Stripe<\/h3>\n                    <div class=\"color-dropdown\" id=\"stripe-color-dropdown\">\n                        <button type=\"button\" class=\"color-dropdown-trigger\" id=\"stripe-dropdown-trigger\">\n                            <span class=\"color-dropdown-swatch\" id=\"stripe-dropdown-swatch\"><\/span>\n                            <span class=\"color-dropdown-text\" id=\"stripe-dropdown-text\">Electric Cyan<\/span>\n                            <span class=\"color-dropdown-arrow\">&#9662;<\/span>\n                        <\/button>\n                        <div class=\"color-dropdown-panel\" id=\"stripe-dropdown-panel\">\n                            <div class=\"color-swatch-grid\" id=\"stripe-swatch-grid\"><\/div>\n                        <\/div>\n                    <\/div>\n                <\/div>\n\n                <div class=\"control-group\">\n                    <h3>Custom Fine Tuning<\/h3>\n                    <p class=\"step-hint\">Use custom colours only when a site brand guideline requires exact matching.<\/p>\n                    <div class=\"custom-color-grid\">\n                        <div class=\"custom-color-card\">\n                            <span class=\"custom-color-label\">Body Colour<\/span>\n                            <div class=\"custom-color-controls\">\n                                <input type=\"color\" id=\"custom-body-color\" value=\"#f8fafc\" title=\"Custom Body Colour\">\n                                <input type=\"text\" id=\"custom-body-hex\" class=\"hex-input\" value=\"#F8FAFC\" maxlength=\"7\" spellcheck=\"false\" aria-label=\"Body hex colour\">\n                            <\/div>\n                        <\/div>\n                        <div class=\"custom-color-card\">\n                            <span class=\"custom-color-label\">Stripe Colour<\/span>\n                            <div class=\"custom-color-controls\">\n                                <input type=\"color\" id=\"custom-stripe-color\" value=\"#00e5ff\" title=\"Custom Stripe Colour\">\n                                <input type=\"text\" id=\"custom-stripe-hex\" class=\"hex-input\" value=\"#00E5FF\" maxlength=\"7\" spellcheck=\"false\" aria-label=\"Stripe hex colour\">\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            <!-- SUMMARY -->\n            <div class=\"summary-pane hidden\" id=\"summary-pane\">\n                <h2>Configuration Summary<\/h2>\n                <p class=\"step-desc\">Review the final charger configuration, download the configuration sheet, or contact Elecrest for the next step.<\/p>\n                <div class=\"summary-details\" id=\"summary-details\"><\/div>\n                <div class=\"summary-actions\">\n                    <button id=\"btn-download-pdf\" class=\"btn primary\" type=\"button\">Download Configuration PDF<\/button>\n                    <button id=\"btn-contact\" class=\"btn secondary\" type=\"button\">Contact Us<\/button>\n                <\/div>\n                <div id=\"contact-template-fallback\" class=\"contact-template-fallback hidden\">\n                    \t\t<div data-elementor-type=\"popup\" data-elementor-id=\"452\" class=\"elementor elementor-452\" data-elementor-settings=\"{&quot;entrance_animation&quot;:&quot;fadeIn&quot;,&quot;exit_animation&quot;:&quot;fadeIn&quot;,&quot;entrance_animation_duration&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:0.5,&quot;sizes&quot;:[]},&quot;prevent_close_on_background_click&quot;:&quot;yes&quot;,&quot;prevent_close_on_esc_key&quot;:&quot;yes&quot;,&quot;prevent_scroll&quot;:&quot;yes&quot;,&quot;avoid_multiple_popups&quot;:&quot;yes&quot;,&quot;a11y_navigation&quot;:&quot;yes&quot;,&quot;timing&quot;:[]}\" data-elementor-post-type=\"elementor_library\">\n\t\t\t<div class=\"elementor-element elementor-element-8fbd20b e-flex e-con-boxed e-con e-parent\" data-id=\"8fbd20b\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4103b65 elementor-widget elementor-widget-heading\" data-id=\"4103b65\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<div class=\"elementor-heading-title elementor-size-default\">\u2014 REQUEST A QUOTE<\/div>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8f63f7a elementor-widget elementor-widget-heading\" data-id=\"8f63f7a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<div class=\"elementor-heading-title elementor-size-default\">Tell us about your project<\/div>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e03bd0e elementor-widget elementor-widget-text-editor\" data-id=\"e03bd0e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>A streamlined enquiry \u2014 we&#8217;ll reply with a tailored configuration and indicative pricing within one business day.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-51e2343 elementor-button-align-stretch elementor-widget elementor-widget-form\" data-id=\"51e2343\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Next&quot;,&quot;step_previous_label&quot;:&quot;Previous&quot;,&quot;button_width&quot;:&quot;100&quot;,&quot;step_type&quot;:&quot;number_text&quot;,&quot;step_icon_shape&quot;:&quot;circle&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" name=\"Contact Us\" aria-label=\"Contact Us\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"452\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"51e2343\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"Home - Elecrest\" \/>\n\n\t\t\t\t\t\t\t<input type=\"hidden\" name=\"queried_id\" value=\"15\"\/>\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-above\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-text elementor-field-group elementor-column elementor-field-group-name elementor-col-50 elementor-field-required elementor-mark-required\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-name\" class=\"elementor-field-label\">\n\t\t\t\t\t\t\t\tFull Name\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input size=\"1\" type=\"text\" name=\"form_fields[name]\" id=\"form-field-name\" class=\"elementor-field elementor-size-sm  elementor-field-textual\" required=\"required\">\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-email elementor-field-group elementor-column elementor-field-group-field_acca534 elementor-col-50 elementor-field-required elementor-mark-required\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-field_acca534\" class=\"elementor-field-label\">\n\t\t\t\t\t\t\t\tEmail\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input size=\"1\" type=\"email\" name=\"form_fields[field_acca534]\" id=\"form-field-field_acca534\" class=\"elementor-field elementor-size-sm  elementor-field-textual\" required=\"required\">\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-tel elementor-field-group elementor-column elementor-field-group-field_7d773bc elementor-col-50\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-field_7d773bc\" class=\"elementor-field-label\">\n\t\t\t\t\t\t\t\tPhone Number\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t<input size=\"1\" type=\"tel\" name=\"form_fields[field_7d773bc]\" id=\"form-field-field_7d773bc\" class=\"elementor-field elementor-size-sm  elementor-field-textual\" pattern=\"[0-9()#&amp;+*-=.]+\" title=\"Only numbers and phone characters (#, -, *, etc) are accepted.\">\n\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-text elementor-field-group elementor-column elementor-field-group-field_071aeae elementor-col-50\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-field_071aeae\" class=\"elementor-field-label\">\n\t\t\t\t\t\t\t\tCompany Name\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input size=\"1\" type=\"text\" name=\"form_fields[field_071aeae]\" id=\"form-field-field_071aeae\" class=\"elementor-field elementor-size-sm  elementor-field-textual\">\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-select elementor-field-group elementor-column elementor-field-group-field_6928bde elementor-col-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-field_6928bde\" class=\"elementor-field-label\">\n\t\t\t\t\t\t\t\tCountry\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field elementor-select-wrapper remove-before \">\n\t\t\t<div class=\"select-caret-down-wrapper\">\n\t\t\t\t<svg aria-hidden=\"true\" class=\"e-font-icon-svg e-eicon-caret-down\" viewBox=\"0 0 571.4 571.4\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M571 393Q571 407 561 418L311 668Q300 679 286 679T261 668L11 418Q0 407 0 393T11 368 36 357H536Q550 357 561 368T571 393Z\"><\/path><\/svg>\t\t\t<\/div>\n\t\t\t<select name=\"form_fields[field_6928bde]\" id=\"form-field-field_6928bde\" class=\"elementor-field-textual elementor-size-sm\">\n\t\t\t\t\t\t\t\t\t<option value=\"AL\">Albania<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"AD\">Andorra<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"AT\">Austria<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"BY\">Belarus<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"BE\">Belgium<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"BA\">Bosnia and Herzegovina<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"BG\">Bulgaria<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"HR\">Croatia<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"CY\">Cyprus<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"CZ\">Czechia<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"DK\">Denmark<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"EE\">Estonia<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"FI\">Finland<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"FR\">France<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"DE\">Germany<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"GR\">Greece<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"HU\">Hungary<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"IS\">Iceland<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"IE\">Ireland<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"IT\">Italy<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"XK\">Kosovo<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"LV\">Latvia<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"LI\">Liechtenstein<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"LT\">Lithuania<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"LU\">Luxembourg<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"MT\">Malta<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"MD\">Moldova<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"MC\">Monaco<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"ME\">Montenegro<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"NL\">Netherlands<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"MK\">North Macedonia<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"NO\">Norway<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"PL\">Poland<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"PT\">Portugal<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"RO\">Romania<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"SM\">San Marino<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"RS\">Serbia<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"SK\">Slovakia<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"SI\">Slovenia<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"ES\">Spain<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"SE\">Sweden<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"CH\">Switzerland<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"UA\">Ukraine<\/option>\n\t\t\t\t\t\t\t\t\t<option value=\"GB\">United Kingdom<\/option>\n\t\t\t\t\t\t\t<\/select>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-text elementor-field-group elementor-column elementor-field-group-field_bcae086 elementor-col-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-field_bcae086\" class=\"elementor-field-label\">\n\t\t\t\t\t\t\t\tAddress\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input size=\"1\" type=\"text\" name=\"form_fields[field_bcae086]\" id=\"form-field-field_bcae086\" class=\"elementor-field elementor-size-sm  elementor-field-textual\">\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-textarea elementor-field-group elementor-column elementor-field-group-message elementor-col-100 elementor-field-required elementor-mark-required\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-message\" class=\"elementor-field-label\">\n\t\t\t\t\t\t\t\tMessage\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<textarea class=\"elementor-field-textual elementor-field  elementor-size-sm\" name=\"form_fields[message]\" id=\"form-field-message\" rows=\"4\" required=\"required\"><\/textarea>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-acceptance elementor-field-group elementor-column elementor-field-group-field_7898704 elementor-col-100 elementor-field-required elementor-mark-required\">\n\t\t\t\t\t\t\t<div class=\"elementor-field-subgroup\">\n\t\t\t<span class=\"elementor-field-option\">\n\t\t\t\t<input type=\"checkbox\" name=\"form_fields[field_7898704]\" id=\"form-field-field_7898704\" class=\"elementor-field elementor-size-sm  elementor-acceptance-field\" required=\"required\">\n\t\t\t\t<label for=\"form-field-field_7898704\">I consent to ELECREST processing my data to respond to this enquiry, in line with the <a href=\"https:\/\/elecrest.dreamhosters.com\/privacy-policy\/\" target=\"_blank\" rel=\"noopener\">Privacy Policy<\/a>. (GDPR) *\n<\/label>\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-recaptcha_v3 elementor-field-group elementor-column elementor-field-group-field_5e823fe elementor-col-100 recaptcha_v3-inline\">\n\t\t\t\t\t<div class=\"elementor-field\" id=\"form-field-field_5e823fe\"><div class=\"elementor-g-recaptcha\" data-sitekey=\"6LcS7RotAAAAAH6o-TVpQb1g7NFk8hMUa1LwB73X\" data-type=\"v3\" data-action=\"Form\" data-badge=\"inline\" data-size=\"invisible\"><\/div><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-sm\" type=\"submit\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">Send Enquiry<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5a6401c elementor-widget elementor-widget-text-editor\" data-id=\"5a6401c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>We never share your details. No online ordering \u2014 this starts a conversation.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Navigation Footer -->\n        <div class=\"wizard-footer\">\n            <button id=\"btn-prev\" class=\"btn secondary\" disabled>Previous<\/button>\n            <button id=\"btn-next\" class=\"btn primary\">Next<\/button>\n        <\/div>\n    <\/div>\n<\/div>\n\n<style>\n\/* ==========================================\n   Hypercharger Configurator Styles\n   Scoped to .hc-configurator to avoid theme conflicts\n   Dark Mode UI matched to Elecrest Reference\n========================================== *\/\n.hc-configurator {\n    --primary: #00e5ff;\n    --primary-hover: #00c6dd;\n    --primary-glow: rgba(0, 229, 255, 0.2);\n    --bg: #090c10;\n    --panel-bg: #111827; \n    --text: #f3f4f6;\n    --text-muted: #9ca3af;\n    --border: #1f2937;\n    --border-hover: #374151;\n    --success: #10b981;\n    \n    font-family: 'Inter', -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n    background-color: var(--bg);\n    color: var(--text);\n    line-height: 1.5;\n    display: flex;\n    width: 100%;\n    min-height: 0;\n    height: 85vh; \/* Takes up most of viewport, adjustable in Elementor *\/\n    max-width: 1440px;\n    margin: 0 auto;\n    border-radius: 16px;\n    overflow: hidden;\n    box-shadow: 0 20px 60px rgba(0,0,0,0.4);\n    border: 1px solid var(--border);\n}\n\n.hc-configurator * {\n    box-sizing: border-box;\n}\n\n.hc-configurator img {\n    max-width: 100%;\n    height: auto;\n    display: block;\n}\n\n\/* ---- Left: Visualizer ---- *\/\n.hc-configurator .visualizer {\n    flex: 1;\n    min-width: 0;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    padding: 2rem;\n    background: radial-gradient(circle at center, #1f2937 0%, #090c10 100%);\n    position: relative;\n    overflow: hidden;\n}\n\n.hc-configurator .product-preview {\n    position: relative;\n    width: 100%;\n    max-width: 800px;\n    aspect-ratio: 1 \/ 1;\n}\n\n.hc-configurator .layer-group {\n    position: absolute;\n    inset: 0;\n    transition: opacity 0.45s ease;\n}\n.hc-configurator .layer-group.hidden {\n    opacity: 0;\n    pointer-events: none;\n    z-index: -1;\n}\n.hc-configurator .layer-group.active {\n    opacity: 1;\n    z-index: 1;\n}\n\n.hc-configurator .layer {\n    position: absolute;\n    inset: 0;\n    width: 100%;\n    height: 100%;\n    transition: opacity 0.35s ease;\n}\n.hc-configurator .base-layer,\n.hc-configurator .gun-layer {\n    object-fit: cover;\n}\n.hc-configurator .layer.hidden {\n    opacity: 0;\n    pointer-events: none;\n}\n\n.hc-configurator .base-layer { z-index: 1; }\n.hc-configurator .gun-layer  { z-index: 20; }\n.hc-configurator .svg-color-layer {\n    z-index: 10;\n    pointer-events: none;\n}\n\n\/* ---- Right: Wizard Panel ---- *\/\n.hc-configurator .wizard-panel {\n    width: 480px;\n    min-width: 420px;\n    background: var(--panel-bg);\n    border-left: 1px solid var(--border);\n    display: flex;\n    flex-direction: column;\n    z-index: 30;\n}\n\n.hc-configurator .wizard-header {\n    display: flex;\n    align-items: center;\n    padding: 1.25rem 1.5rem;\n    border-bottom: 1px solid var(--border);\n    background: #0f141d;\n    gap: 0;\n}\n\n.hc-configurator .step-indicator {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    gap: 0.3rem;\n    cursor: default;\n    transition: all 0.3s;\n}\n.hc-configurator .step-num {\n    width: 32px;\n    height: 32px;\n    border-radius: 50%;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    font-weight: 700;\n    font-size: 0.85rem;\n    background: #1f2937;\n    color: var(--text-muted);\n    transition: all 0.3s;\n}\n.hc-configurator .step-label {\n    font-size: 0.75rem;\n    font-weight: 500;\n    color: var(--text-muted);\n    transition: color 0.3s;\n}\n\n.hc-configurator .step-indicator.active .step-num {\n    background: var(--primary);\n    color: #000;\n    box-shadow: 0 0 0 4px var(--primary-glow);\n}\n.hc-configurator .step-indicator.active .step-label { color: var(--primary); }\n\n.hc-configurator .step-indicator.completed .step-num {\n    background: var(--success);\n    color: white;\n}\n.hc-configurator .step-indicator.completed .step-label { color: var(--success); }\n\n.hc-configurator .step-connector {\n    flex: 1;\n    height: 2px;\n    background: var(--border);\n    margin: 0 0.5rem;\n    margin-bottom: 1.2rem;\n    transition: background 0.3s;\n}\n.hc-configurator .step-connector.completed { background: var(--success); }\n\n\/* Content Area *\/\n.hc-configurator .wizard-content {\n    flex: 1;\n    padding: 2rem 2.5rem;\n    overflow-y: auto;\n    overflow-x: clip;\n    position: relative;\n    min-width: 0;\n}\n.hc-configurator .wizard-content > * {\n    max-width: 100%;\n}\n.hc-configurator .wizard-content::-webkit-scrollbar { width: 6px; }\n.hc-configurator .wizard-content::-webkit-scrollbar-thumb { background: #374151; border-radius: 3px; }\n\n.hc-configurator .step-pane {\n    display: none;\n    opacity: 0;\n    transform: translateY(8px);\n    transition: opacity 0.35s ease, transform 0.35s ease;\n    max-width: 100%;\n}\n.hc-configurator .step-pane.active {\n    display: block;\n    opacity: 1;\n    transform: translateY(0);\n}\n\n.hc-configurator h2 {\n    font-size: 1.5rem;\n    font-weight: 700;\n    margin: 0 0 0.35rem 0;\n    color: var(--text);\n    line-height: 1.2;\n}\n.hc-configurator .step-desc {\n    color: var(--text-muted);\n    margin: 0 0 1.75rem 0;\n    font-size: 0.9rem;\n}\n.hc-configurator .step-hint {\n    color: var(--text-muted);\n    font-size: 0.8rem;\n    margin: 0 0 1rem 0;\n}\n\n\/* Control Group *\/\n.hc-configurator .control-group { margin-bottom: 1.75rem; }\n.hc-configurator .control-group h3 {\n    font-size: 0.95rem;\n    font-weight: 600;\n    padding-bottom: 0.5rem;\n    margin: 0 0 0.75rem 0;\n    border-bottom: 1px solid var(--border);\n    color: var(--text);\n}\n.hc-configurator .hint-text {\n    font-size: 0.8rem;\n    color: #f59e0b;\n    margin: 0 0 0.75rem 0;\n    padding: 0.5rem 0.75rem;\n    background: rgba(245, 158, 11, 0.1);\n    border-radius: 6px;\n    border-left: 3px solid #f59e0b;\n}\n\n\/* Cards & Inputs *\/\n.hc-configurator .model-cards { display: flex; gap: 1rem; }\n.hc-configurator .model-card { flex: 1; cursor: pointer; margin: 0; }\n.hc-configurator .model-card input { display: none; }\n.hc-configurator .card-content {\n    border: 1px solid var(--border);\n    border-radius: 12px;\n    padding: 1.5rem 1rem;\n    text-align: center;\n    transition: all 0.25s;\n    background: #111827;\n}\n.hc-configurator .model-card:hover .card-content { border-color: var(--border-hover); box-shadow: 0 4px 12px rgba(0,0,0,0.3); }\n.hc-configurator .model-card input:checked + .card-content {\n    border-color: var(--primary);\n    background: linear-gradient(135deg, rgba(0,229,255,0.03), rgba(0,229,255,0.08));\n    box-shadow: 0 4px 16px var(--primary-glow);\n}\n.hc-configurator .card-content h3 {\n    font-size: 1.4rem;\n    color: var(--text);\n    margin: 0 0 0.5rem 0;\n    border: none;\n    padding: 0;\n}\n.hc-configurator .card-content p { font-size: 0.85rem; color: var(--text-muted); margin: 0; }\n\n.hc-configurator .radio-group, \n.hc-configurator .checkbox-group {\n    display: flex;\n    flex-direction: column;\n    gap: 0.6rem;\n}\n.hc-configurator .radio-group label, \n.hc-configurator .checkbox-group label {\n    display: flex;\n    align-items: center;\n    gap: 0.75rem;\n    background: #111827;\n    padding: 0.85rem 1rem;\n    border-radius: 8px;\n    border: 1px solid var(--border);\n    cursor: pointer;\n    transition: all 0.2s;\n    font-size: 0.9rem;\n    margin: 0;\n    color: var(--text);\n}\n.hc-configurator .radio-group label:hover, \n.hc-configurator .checkbox-group label:hover { border-color: var(--border-hover); }\n.hc-configurator .radio-group label:has(input:checked),\n.hc-configurator .checkbox-group label:has(input:checked) {\n    border-color: var(--primary);\n    background: rgba(0,229,255,0.05);\n}\n.hc-configurator input[type=\"radio\"],\n.hc-configurator input[type=\"checkbox\"] { margin: 0; accent-color: var(--primary); }\n\n\/* Gun Selectors *\/\n.hc-configurator .gun-selector {\n    display: flex;\n    gap: 0.5rem;\n    margin-bottom: 0.6rem;\n    align-items: center;\n}\n.hc-configurator .gun-selector span {\n    font-size: 0.85rem;\n    font-weight: 600;\n    min-width: 65px;\n    color: var(--text-muted);\n}\n.hc-configurator select {\n    flex: 1;\n    min-width: 0;\n    padding: 0.5rem 0.6rem;\n    border: 1px solid var(--border);\n    border-radius: 6px;\n    outline: none;\n    font-family: inherit;\n    font-size: 0.85rem;\n    transition: border-color 0.2s;\n    background: #111827;\n    color: var(--text);\n    margin: 0;\n    height: auto;\n}\n.hc-configurator select:focus { border-color: var(--primary); }\n.hc-configurator select:disabled { background: #0f141d; color: #4b5563; border-color: var(--border); cursor: not-allowed; }\n\n\/* Colour Dropdown *\/\n.hc-configurator .color-dropdown {\n    position: relative;\n    max-width: 100%;\n    min-width: 0;\n}\n.hc-configurator .color-dropdown-trigger {\n    display: flex;\n    align-items: center;\n    gap: 12px;\n    width: 100%;\n    padding: 10px 14px;\n    border: 1px solid var(--border);\n    border-radius: 8px;\n    background: #111827;\n    cursor: pointer;\n    transition: border-color 0.2s;\n    font-family: inherit;\n    min-width: 0;\n}\n.hc-configurator .color-dropdown-trigger:hover { border-color: var(--border-hover); }\n.hc-configurator .color-dropdown.open .color-dropdown-trigger { border-color: var(--primary); }\n.hc-configurator .color-dropdown-swatch {\n    width: 28px;\n    height: 28px;\n    border-radius: 50%;\n    border: 2px solid rgba(255,255,255,0.18);\n    flex-shrink: 0;\n}\n.hc-configurator .color-dropdown-text {\n    flex: 1;\n    min-width: 0;\n    text-align: left;\n    color: var(--text);\n    font-size: 0.88rem;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n}\n.hc-configurator .color-dropdown-arrow {\n    color: var(--text-muted);\n    font-size: 0.75rem;\n    transition: transform 0.2s;\n}\n.hc-configurator .color-dropdown.open .color-dropdown-arrow { transform: rotate(180deg); }\n.hc-configurator .color-dropdown-panel {\n    display: none;\n    padding: 10px;\n    border: 1px solid var(--border);\n    border-top: none;\n    border-radius: 0 0 8px 8px;\n    background: #111827;\n    max-height: 220px;\n    overflow-y: auto;\n    overflow-x: hidden;\n    width: 100%;\n    max-width: 100%;\n}\n.hc-configurator .color-dropdown.open .color-dropdown-panel { display: block; }\n.hc-configurator .color-dropdown.open .color-dropdown-trigger { border-radius: 8px 8px 0 0; }\n\/* Swatch Grid inside Dropdown *\/\n.hc-configurator .color-swatch-grid {\n    display: grid;\n    grid-template-columns: repeat(5, minmax(0, 1fr));\n    gap: 6px;\n}\n.hc-configurator .color-swatch {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    gap: 4px;\n    cursor: pointer;\n    padding: 6px 2px 4px;\n    border-radius: 8px;\n    border: 2px solid transparent;\n    transition: border-color 0.15s, background 0.15s;\n    background: transparent;\n    min-width: 0;\n}\n.hc-configurator .color-swatch:hover {\n    background: rgba(255,255,255,0.06);\n    border-color: var(--border-hover);\n}\n.hc-configurator .color-swatch.active {\n    border-color: var(--primary);\n    background: var(--primary-glow);\n}\n.hc-configurator .color-swatch-circle {\n    width: 30px;\n    height: 30px;\n    border-radius: 50%;\n    border: 2px solid rgba(255,255,255,0.15);\n    box-shadow: 0 1px 4px rgba(0,0,0,0.3);\n    flex-shrink: 0;\n}\n.hc-configurator .color-swatch.active .color-swatch-circle {\n    border-color: var(--primary);\n    box-shadow: 0 0 0 2px var(--primary-glow);\n}\n.hc-configurator .color-swatch-name {\n    font-size: 0.6rem;\n    color: var(--text-muted);\n    text-align: center;\n    line-height: 1.15;\n    max-width: 100%;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n}\n\/* Summary colour swatches *\/\n.hc-configurator .summary-color-swatch {\n    display: inline-block;\n    width: 14px;\n    height: 14px;\n    border-radius: 50%;\n    border: 1px solid rgba(255,255,255,0.2);\n    vertical-align: middle;\n    margin-right: 6px;\n}\n\/* Custom Fine Tuning *\/\n.hc-configurator .custom-color-grid {\n    display: grid;\n    grid-template-columns: repeat(2, 1fr);\n    gap: 12px;\n}\n.hc-configurator .custom-color-card {\n    border: 1px solid var(--border);\n    border-radius: 10px;\n    background: #111827;\n    padding: 14px;\n    display: flex;\n    flex-direction: column;\n    gap: 10px;\n    min-width: 0;\n}\n.hc-configurator .custom-color-label {\n    font-size: 0.78rem;\n    color: var(--text-muted);\n    font-weight: 500;\n}\n.hc-configurator .custom-color-controls {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    min-width: 0;\n}\n.hc-configurator .hex-input {\n    flex: 1;\n    min-width: 0;\n    background: #0d1117;\n    border: 1px solid var(--border);\n    border-radius: 6px;\n    color: var(--text);\n    font-family: 'Consolas', 'Menlo', monospace;\n    font-size: 0.82rem;\n    padding: 7px 10px;\n    outline: none;\n    transition: border-color 0.2s;\n    text-transform: uppercase;\n}\n.hc-configurator .hex-input:focus {\n    border-color: var(--primary);\n}\n.hc-configurator input[type=\"color\"] {\n    flex: 0 0 auto;\n    width: 38px;\n    height: 38px;\n    border: none;\n    border-radius: 50%;\n    cursor: pointer;\n    padding: 0;\n    background: none;\n    margin: 0;\n}\n.hc-configurator input[type=\"color\"]::-webkit-color-swatch-wrapper { padding: 0; }\n.hc-configurator input[type=\"color\"]::-webkit-color-swatch { border: 2px solid var(--border); border-radius: 50%; }\n\n\/* Summary *\/\n.hc-configurator .summary-pane.hidden { display: none; }\n.hc-configurator .summary-pane {\n    display: flex;\n    flex-direction: column;\n}\n.hc-configurator .summary-details {\n    display: grid;\n    gap: 0.85rem;\n    margin: 1rem 0 0;\n    order: 2;\n}\n.hc-configurator .summary-section {\n    border: 1px solid var(--border);\n    border-radius: 8px;\n    background: #111827;\n    padding: 1rem;\n}\n.hc-configurator .summary-section h3 {\n    border: none;\n    padding: 0;\n    margin: 0 0 0.75rem 0;\n    color: var(--text);\n}\n.hc-configurator .summary-row {\n    display: flex;\n    justify-content: space-between;\n    gap: 1rem;\n    padding: 0.45rem 0;\n    border-top: 1px solid rgba(255,255,255,0.06);\n    font-size: 0.9rem;\n}\n.hc-configurator .summary-row:first-of-type { border-top: none; }\n.hc-configurator .summary-label { color: var(--text-muted); }\n.hc-configurator .summary-value { color: var(--text); text-align: right; }\n.hc-configurator .summary-actions {\n    display: flex;\n    flex-direction: column;\n    gap: 0.75rem;\n    margin: 0.25rem 0 0.75rem;\n    order: 1;\n}\n.hc-configurator .summary-actions .btn { width: 100%; }\n.hc-configurator .contact-template-fallback {\n    margin-top: 1rem;\n    padding: 1rem;\n    border: 1px solid var(--border);\n    border-radius: 8px;\n    background: #0f141d;\n    order: 3;\n}\n.hc-configurator .contact-template-fallback.hidden { display: none; }\n\/* Footer *\/\n.hc-configurator .wizard-footer {\n    padding: 1.25rem 2.5rem;\n    border-top: 1px solid var(--border);\n    display: flex;\n    justify-content: space-between;\n    background: #0f141d;\n}\n.hc-configurator .btn {\n    padding: 0.7rem 1.75rem;\n    border-radius: 8px;\n    font-weight: 600;\n    font-size: 0.9rem;\n    cursor: pointer;\n    border: none;\n    transition: all 0.2s;\n    font-family: inherit;\n    margin: 0;\n}\n.hc-configurator .btn:disabled { opacity: 0.4; cursor: not-allowed; }\n.hc-configurator .btn.primary { background: var(--primary); color: #000; }\n.hc-configurator .btn.primary:hover:not(:disabled) { background: var(--primary-hover); box-shadow: 0 4px 12px var(--primary-glow); }\n.hc-configurator .btn.secondary { background: transparent; color: var(--text); border: 1px solid var(--border); }\n.hc-configurator .btn.secondary:hover:not(:disabled) { background: #1f2937; }\n\n\/* Responsive *\/\n@media (min-width: 961px) and (min-height: 900px) {\n    .hc-configurator { min-height: 760px; }\n}\n\n@media (min-width: 961px) and (max-height: 780px) {\n    .hc-configurator .visualizer { padding: 1.25rem; }\n    .hc-configurator .wizard-header { padding: 1rem 1.25rem; }\n    .hc-configurator .wizard-content { padding: 1.35rem 1.75rem; }\n    .hc-configurator .wizard-footer { padding: 1rem 1.75rem; }\n    .hc-configurator h2 { font-size: 1.35rem; }\n    .hc-configurator .step-desc { margin-bottom: 1.1rem; }\n    .hc-configurator .control-group { margin-bottom: 1.15rem; }\n    .hc-configurator .card-content { padding: 1.2rem 0.8rem; }\n}\n\n@media (max-width: 960px) {\n    .hc-configurator { flex-direction: column; height: auto; min-height: unset; border-radius: 8px; }\n    .hc-configurator .wizard-panel { width: 100%; min-width: 0; border-left: none; border-top: 1px solid var(--border); }\n    .hc-configurator .visualizer { min-height: clamp(280px, 38vh, 420px); padding: 1rem; }\n    .hc-configurator .product-preview { max-width: min(82vw, 420px); }\n    .hc-configurator .wizard-content { padding: 1.5rem; overflow-x: clip; }\n    .hc-configurator .color-swatch-grid { grid-template-columns: repeat(4, 1fr); }\n    .hc-configurator .custom-color-grid { grid-template-columns: 1fr; }\n    .hc-configurator .wizard-header { padding: 1rem; gap: 0; }\n    .hc-configurator .wizard-footer { position: sticky; bottom: 0; z-index: 40; padding: 1rem 1.5rem; }\n    .hc-configurator .step-num { width: 26px; height: 26px; font-size: 0.75rem; }\n    .hc-configurator .step-label { font-size: 0.65rem; }\n    .hc-configurator .step-connector { margin: 0 0.25rem; }\n}\n\n@media (max-width: 520px) {\n    .hc-configurator .visualizer { min-height: clamp(250px, 34vh, 340px); }\n    .hc-configurator .wizard-content { padding: 1.35rem 1rem; }\n    .hc-configurator .wizard-footer { padding: 0.9rem 1rem; }\n    .hc-configurator .model-cards { gap: 0.75rem; }\n    .hc-configurator .card-content { padding: 1.2rem 0.75rem; }\n    .hc-configurator .card-content h3 { font-size: 1.2rem; }\n    .hc-configurator .color-dropdown-trigger { padding: 9px 10px; gap: 8px; }\n    .hc-configurator .color-swatch-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }\n    .hc-configurator .color-swatch-name { font-size: 0.58rem; }\n    .hc-configurator .custom-color-card { padding: 12px; }\n    .hc-configurator .custom-color-controls { gap: 8px; }\n    .hc-configurator .hex-input { width: 100%; padding: 7px 8px; }\n    .hc-configurator .gun-selector { display: grid; grid-template-columns: 56px minmax(0, 1fr) minmax(72px, 0.72fr); }\n    .hc-configurator .gun-selector span { min-width: 0; }\n}\n<\/style>\n\n<script>\n(function() {\n    \/\/ =====================================================================\n    \/\/ WordPress Configuration & SEO Assets (WebP format, English names)\n    \/\/ Please update BASE_URL if you upload these to a specific folder via FTP\n    \/\/ =====================================================================\n    const BASE_URL = \"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/07\/\"; \/\/ Ensure trailing slash\n\n    const ASSETS = {\n        '240kW': {\n            \/\/ Base images\n            baseNormal:       BASE_URL + 'hyc-240-base-normal.webp',\n            baseAccessible:   BASE_URL + 'hyc-240-base-accessible.webp',\n            baseNormalPos:    BASE_URL + 'hyc-240-base-normal-pos.webp',\n            baseAccessiblePos:BASE_URL + 'hyc-240-base-accessible-pos.webp',\n            \/\/ Customisation overlays\n            colorBase:        BASE_URL + 'hyc-240-color-base.webp',\n            maskBody:         BASE_URL + 'hyc-240-mask-body.webp',\n            maskStripe:       BASE_URL + 'hyc-240-mask-stripe.webp',\n            \/\/ Power modules\n            power1:           BASE_URL + 'hyc-240-power-1.webp',\n            power2:           BASE_URL + 'hyc-240-power-2.webp',\n            powerEmpty:       BASE_URL + 'hyc-240-power-empty.webp'\n        },\n        '480kW': {\n            \/\/ Base images\n            baseNormal:       BASE_URL + 'hyc-480-base-normal.webp',\n            baseAccessible:   BASE_URL + 'hyc-480-base-accessible.webp',\n            baseNormalPos:    BASE_URL + 'hyc-480-base-normal-pos.webp',\n            baseAccessiblePos:BASE_URL + 'hyc-480-base-accessible-pos.webp',\n            \/\/ Customisation overlays\n            colorBase:        BASE_URL + 'hyc-480-color-base.webp',\n            maskBody:         BASE_URL + 'hyc-480-mask-body.webp',\n            maskStripe:       BASE_URL + 'hyc-480-mask-stripe.webp',\n            \/\/ Power modules\n            power3:           BASE_URL + 'hyc-240-power-3.webp',\n            power4:           BASE_URL + 'hyc-240-power-4.webp',\n            powerEmpty:       BASE_URL + 'hyc-480-power-empty.webp'\n        }\n    };\n\n    const PARAMETER_TABLES = {\n        '240kW': {\n            variants: ['120kW', '240kW'],\n            rows: [\n                { section: 'Input', item: 'Rated Voltage', values: ['400Vac +\/-10%', '400Vac +\/-10%'] },\n                { section: '', item: 'Rated Current', values: ['180A', '360A'] },\n                { section: 'Output', item: 'Power', values: ['120kW', '240kW'] },\n                { section: '', item: 'Connector type (Optional)', values: ['CCS2*2', 'CCS2*2'] },\n                { section: '', item: 'Voltage', values: ['150-1000Vdc', '150-1000Vdc'] },\n                { section: '', item: 'Current', values: ['250A', '250A'] },\n                { section: '', item: 'Efficiency', values: ['>=97%', '>=97%'] },\n                { section: '', item: 'Connector Qty', values: ['CCS2*2 (Optional, Max 2)', 'CCS2*2 (Optional, Max 2)'] },\n                { section: 'Interaction Mode', item: 'Status LED', values: ['Support (for each connector)', 'Support (for each connector)'] },\n                { section: '', item: 'Meter', values: ['MID', 'MID'] },\n                { section: '', item: 'Activation Method', values: ['RFID\/APP\/POS', 'RFID\/APP\/POS'] },\n                { section: '', item: 'Network', values: ['Ethernet;4G', 'Ethernet;4G'] },\n                { section: '', item: 'Screen', values: ['10 inch screen with 4 buttons', '10 inch screen with 4 buttons'] },\n                { section: '', item: 'Language', values: ['English (optional)', 'English (optional)'] },\n                { section: '', item: 'POS', values: ['Optional', 'Optional'] },\n                { section: '', item: 'Protocol', values: ['OCPP 1.6J', 'OCPP 1.6J'] },\n                { section: 'Operating Conditions', item: 'Operating Temperature', values: ['-30C~55C', '-30C~55C'] },\n                { section: '', item: 'Storage Temperature', values: ['-30C~70C', '-30C~70C'] },\n                { section: '', item: 'Relative Humidity (RH)', values: ['5%~95% Non-condensing', '5%~95% Non-condensing'] },\n                { section: '', item: 'Operating Altitude', values: ['<=2000m', '<=2000m'] },\n                { section: 'Mechanical Parameters', item: 'IP Rating', values: ['IP55', 'IP55'] },\n                { section: '', item: 'IK Rating', values: ['Cabinet IK10, Screen IK08', 'Cabinet IK10, Screen IK08'] },\n                { section: '', item: 'Noise', values: ['<=55dB', '<=55dB'] },\n                { section: '', item: 'Cooling Mode', values: ['Air-cooled', 'Air-cooled'] },\n                { section: '', item: 'Charging Cable Length', values: ['5m (optional)', '5m (optional)'] },\n                { section: '', item: 'Material', values: ['Stainless steel', 'Stainless steel'] },\n                { section: '', item: 'Size Parameters', values: ['2300mm * 860mm * 590mm', '2300mm * 860mm * 590mm'] },\n                { section: '', item: 'Weight', values: ['approx 340kg', 'approx 420kg'] },\n                { section: '', item: 'Installation Method', values: ['Floor-mounted installation', 'Floor-mounted installation'] }\n            ]\n        },\n        '480kW': {\n            variants: ['240kW', '360kW', '480kW'],\n            rows: [\n                { section: 'Input', item: 'Rated Voltage', values: ['400Vac +\/-10%', '400Vac +\/-10%', '400Vac +\/-10%'] },\n                { section: '', item: 'Rated Current', values: ['360A', '540A', '720A'] },\n                { section: 'Output', item: 'Power', values: ['240kW', '360kW', '480kW'] },\n                { section: '', item: 'Connector type (Optional)', values: ['CCS2*2', 'CCS2*2', 'CCS2*2'] },\n                { section: '', item: 'Voltage', values: ['150-1000Vdc', '150-1000Vdc', '150-1000Vdc'] },\n                { section: '', item: 'Current', values: ['250A', '375A', '375A'] },\n                { section: '', item: 'Efficiency', values: ['>=97%', '>=97%', '>=97%'] },\n                { section: '', item: 'Connector Qty', values: ['CCS2*2 (Optional, Max 4)', 'CCS2*2 (Optional, Max 4)', 'CCS2*2 (Optional, Max 4)'] },\n                { section: 'Interaction Mode', item: 'Status LED', values: ['Support (for each connector)', 'Support (for each connector)', 'Support (for each connector)'] },\n                { section: '', item: 'Meter', values: ['MID', 'MID', 'MID'] },\n                { section: '', item: 'Activation Method', values: ['RFID\/APP\/POS', 'RFID\/APP\/POS', 'RFID\/APP\/POS'] },\n                { section: '', item: 'Network', values: ['Ethernet;4G', 'Ethernet;4G', 'Ethernet;4G'] },\n                { section: '', item: 'Screen', values: ['10 inch screen with 4 buttons', '10 inch screen with 4 buttons', '10 inch screen with 4 buttons'] },\n                { section: '', item: 'Language', values: ['English (optional)', 'English (optional)', 'English (optional)'] },\n                { section: '', item: 'POS', values: ['Optional', 'Optional', 'Optional'] },\n                { section: '', item: 'Protocol', values: ['OCPP 1.6J', 'OCPP 1.6J', 'OCPP 1.6J'] },\n                { section: 'Operating Conditions', item: 'Operating Temperature', values: ['-30C~55C', '-30C~55C', '-30C~55C'] },\n                { section: '', item: 'Storage Temperature', values: ['-30C~70C', '-30C~70C', '-30C~70C'] },\n                { section: '', item: 'Relative Humidity (RH)', values: ['5%~95% Non-condensing', '5%~95% Non-condensing', '5%~95% Non-condensing'] },\n                { section: '', item: 'Operating Altitude', values: ['<=2000m', '<=2000m', '<=2000m'] },\n                { section: 'Mechanical Parameters', item: 'IP Rating', values: ['IP55', 'IP55', 'IP55'] },\n                { section: '', item: 'IK Rating', values: ['Cabinet IK10, Screen IK08', 'Cabinet IK10, Screen IK08', 'Cabinet IK10, Screen IK08'] },\n                { section: '', item: 'Noise', values: ['<=55dB', '<=55dB', '<=55dB'] },\n                { section: '', item: 'Cooling Mode', values: ['Air-cooled (liquid-cooled optional)', 'Air-cooled (liquid-cooled optional)', 'Air-cooled (liquid-cooled optional)'] },\n                { section: '', item: 'Charging Cable Length', values: ['5m (optional)', '5m (optional)', '5m (optional)'] },\n                { section: '', item: 'Material', values: ['Stainless steel', 'Stainless steel', 'Stainless steel'] },\n                { section: '', item: 'Size Parameters', values: ['2300mm * 860mm * 890mm', '2300mm * 860mm * 890mm', '2300mm * 860mm * 890mm'] },\n                { section: '', item: 'Weight', values: ['approx 460kg', 'approx 540kg', 'approx 620kg'] },\n                { section: '', item: 'Installation Method', values: ['Floor-mounted installation', 'Floor-mounted installation', 'Floor-mounted installation'] }\n            ]\n        }\n    };\n\n    \/\/ Helper to generate gun cable webp URLs matching WordPress media library\n    \/\/ Original files had spaces replaced by hyphens, and 480kW positions 1 & 2 have _1 suffix.\n    \/\/ Example: CCS2-1-3.5m.webp (240kW) or CCS2-1-3.5m_1.webp (480kW)\n    function getGunImageUrl(model, type, pos, cable) {\n        if (model === '480kW' && (pos === 1 || pos === 2)) {\n            return BASE_URL + `${type}-${pos}-${cable}_1.webp`;\n        } else {\n            return BASE_URL + `${type}-${pos}-${cable}.webp`;\n        }\n    }\n\n    \/\/ =====================================================================\n    \/\/ Core Application Logic\n    \/\/ =====================================================================\n    document.addEventListener('DOMContentLoaded', () => {\n        const container = document.getElementById('hc-configurator-app');\n        if (!container) return; \n        \n        const stepPanes      = container.querySelectorAll('.step-pane');\n        const stepIndicators  = container.querySelectorAll('.step-indicator');\n        const stepConnectors  = container.querySelectorAll('.step-connector');\n        const btnNext         = container.querySelector('#btn-next');\n        const btnPrev         = container.querySelector('#btn-prev');\n        const summaryPane     = container.querySelector('#summary-pane');\n        const summaryDetails  = container.querySelector('#summary-details');\n        const btnDownloadPdf  = container.querySelector('#btn-download-pdf');\n        const btnContact      = container.querySelector('#btn-contact');\n        const contactTemplateFallback = container.querySelector('#contact-template-fallback');\n        const wizardContent   = container.querySelector('.wizard-content');\n\n        const closedDoorGroup  = container.querySelector('#closed-door-group');\n        const openDoorGroup    = container.querySelector('#open-door-group');\n        const colorSelectGroup = container.querySelector('#color-select-group');\n\n        const baseImage      = container.querySelector('#base-image');\n        const powerLayer     = container.querySelector('#power-layer');\n        const colorBaseImage = container.querySelector('#color-base-image');\n\n        const svgBodyRect   = container.querySelector('#svg-body-rect');\n        const svgStripeRect = container.querySelector('#svg-stripe-rect');\n        const maskImg240Body   = container.querySelector('#mask-img-240-body');\n        const maskImg480Body   = container.querySelector('#mask-img-480-body');\n        const maskImg240Stripe = container.querySelector('#mask-img-240-stripe');\n        const maskImg480Stripe = container.querySelector('#mask-img-480-stripe');\n\n        const modelRadios          = container.querySelectorAll('input[name=\"model\"]');\n        const powerOptionsContainer = container.querySelector('#power-options-container');\n        const optPayment           = container.querySelector('#opt-payment');\n        const optAccessible        = container.querySelector('#opt-accessible');\n        const optDoorContact       = container.querySelector('#opt-doorcontact');\n        const gunsContainer        = container.querySelector('#guns-container');\n        const hint5m               = container.querySelector('#hint-5m');\n\n        const bodySwatchGrid    = container.querySelector('#body-swatch-grid');\n        const stripeSwatchGrid  = container.querySelector('#stripe-swatch-grid');\n        const bodyDropdown      = container.querySelector('#body-color-dropdown');\n        const bodyDropdownSwatch = container.querySelector('#body-dropdown-swatch');\n        const bodyDropdownText  = container.querySelector('#body-dropdown-text');\n        const stripeDropdown    = container.querySelector('#stripe-color-dropdown');\n        const stripeDropdownSwatch = container.querySelector('#stripe-dropdown-swatch');\n        const stripeDropdownText = container.querySelector('#stripe-dropdown-text');\n        const customBodyInput   = container.querySelector('#custom-body-color');\n        const customStripeInput = container.querySelector('#custom-stripe-color');\n        const customBodyHex     = container.querySelector('#custom-body-hex');\n        const customStripeHex   = container.querySelector('#custom-stripe-hex');\n\n        const BODY_COLOR_PRESETS = [\n            { name: 'Glacier White', value: '#f8fafc' },\n            { name: 'Signal White', value: '#ffffff' },\n            { name: 'Warm White', value: '#f3f0e8' },\n            { name: 'Pearl Silver', value: '#d7dce2' },\n            { name: 'Cloud Grey', value: '#cbd5e1' },\n            { name: 'Titanium Grey', value: '#8a95a3' },\n            { name: 'Basalt Grey', value: '#4b5563' },\n            { name: 'Graphite Grey', value: '#374151' },\n            { name: 'Charcoal Blue', value: '#263241' },\n            { name: 'Carbon Black', value: '#111827' },\n            { name: 'Obsidian Black', value: '#05070a' },\n            { name: 'Deep Navy', value: '#172554' },\n            { name: 'Midnight Blue', value: '#1e3a5f' },\n            { name: 'Slate Blue', value: '#334e68' },\n            { name: 'Steel Blue', value: '#486581' },\n            { name: 'Forest Green', value: '#1f4d3a' },\n            { name: 'Pine Green', value: '#18392b' },\n            { name: 'Sage Grey', value: '#7c8a7a' },\n            { name: 'Urban Bronze', value: '#5c5146' },\n            { name: 'Champagne Silver', value: '#c7b99b' }\n        ];\n\n        const STRIPE_COLOR_PRESETS = [\n            { name: 'Electric Cyan', value: '#00e5ff' },\n            { name: 'Ice Blue', value: '#67e8f9' },\n            { name: 'Clean Blue', value: '#0ea5e9' },\n            { name: 'Azure Blue', value: '#2563eb' },\n            { name: 'Deep Blue', value: '#1d4ed8' },\n            { name: 'Indigo Accent', value: '#4f46e5' },\n            { name: 'Violet Tech', value: '#7c3aed' },\n            { name: 'Teal Pulse', value: '#14b8a6' },\n            { name: 'Aqua Green', value: '#2dd4bf' },\n            { name: 'Mint Glow', value: '#5eead4' },\n            { name: 'Emerald Green', value: '#22c55e' },\n            { name: 'Lime Signal', value: '#84cc16' },\n            { name: 'Solar Yellow', value: '#facc15' },\n            { name: 'Amber Signal', value: '#f59e0b' },\n            { name: 'Safety Orange', value: '#f97316' },\n            { name: 'Copper Orange', value: '#ea580c' },\n            { name: 'Crimson Red', value: '#dc2626' },\n            { name: 'Ruby Red', value: '#b91c1c' },\n            { name: 'Magenta Signal', value: '#db2777' },\n            { name: 'White Line', value: '#f8fafc' }\n        ];\n\n        const configData = {\n            '240kW': {\n                bodyMaskId:   'body-mask-240',\n                stripeMaskId: 'stripe-mask-240',\n                powers: [\n                    { value: '1', label: '1 Module - 120 kW', get file() { return ASSETS['240kW'].power1; } },\n                    { value: '2', label: '2 Modules - 240 kW', get file() { return ASSETS['240kW'].power2; } }\n                ],\n                gunPositions: [1, 2]\n            },\n            '480kW': {\n                bodyMaskId:   'body-mask-480',\n                stripeMaskId: 'stripe-mask-480',\n                powers: [\n                    { value: '3', label: '3 Modules - 360 kW', get file() { return ASSETS['480kW'].power3; } },\n                    { value: '4', label: '4 Modules - 480 kW', get file() { return ASSETS['480kW'].power4; } }\n                ],\n                gunPositions: [1, 2, 3, 4]\n            }\n        };\n\n        const gunTypes = ['CCS2', 'CHAdeMO', 'GB', 'Type2'];\n        let currentStep = 1;\n        const totalSteps = 4;\n        const summaryStep = 5;\n\n        let state = {\n            model:       '240kW',\n            power:       '2',\n            payment:     false,\n            accessible:  false,\n            doorContact: false,\n            guns: { 1: null, 2: null, 3: null, 4: null },\n            colorBodyName: 'Glacier White',\n            colorStripeName: 'Electric Cyan',\n            colorBody:   '#f8fafc',\n            colorStripe: '#00e5ff'\n        };\n\n        init();\n\n        function init() {\n            maskImg240Body.setAttribute('href', ASSETS['240kW'].maskBody);\n            maskImg480Body.setAttribute('href', ASSETS['480kW'].maskBody);\n            maskImg240Stripe.setAttribute('href', ASSETS['240kW'].maskStripe);\n            maskImg480Stripe.setAttribute('href', ASSETS['480kW'].maskStripe);\n            wizardContent.addEventListener('scroll', resetWizardContentX, { passive: true });\n            wizardContent.addEventListener('focusin', queueResetWizardContentX);\n            wizardContent.addEventListener('change', queueResetWizardContentX);\n\n            btnNext.addEventListener('click', () => {\n                if (currentStep < totalSteps) goToStep(currentStep + 1);\n                else if (currentStep === totalSteps) showSummary();\n            });\n            btnPrev.addEventListener('click', () => {\n                if (currentStep === summaryStep) goToStep(totalSteps);\n                else if (currentStep > 1) goToStep(currentStep - 1);\n            });\n\n            modelRadios.forEach(r => r.addEventListener('change', e => {\n                state.model = e.target.value;\n                const md = configData[state.model];\n                state.power = md.powers[md.powers.length - 1].value;\n                [1,2,3,4].forEach(pos => {\n                    if (!md.gunPositions.includes(pos)) state.guns[pos] = null;\n                    if (state.model === '480kW' && (pos === 2 || pos === 3) && state.guns[pos]?.cable === '5m') {\n                        state.guns[pos].cable = '3.5m';\n                    }\n                });\n                renderPowerOptions();\n                renderGunsOptions();\n                updateVisuals();\n            }));\n\n            powerOptionsContainer.addEventListener('change', e => {\n                if (e.target.name === 'power') { state.power = e.target.value; updateVisuals(); }\n            });\n\n            optPayment.addEventListener('change', e => { state.payment = e.target.checked; updateVisuals(); });\n            optAccessible.addEventListener('change', e => { state.accessible = e.target.checked; updateVisuals(); });\n            optDoorContact.addEventListener('change', e => { state.doorContact = e.target.checked; });\n\n            container.querySelector('#body-dropdown-trigger').addEventListener('click', () => {\n                bodyDropdown.classList.toggle('open');\n                stripeDropdown.classList.remove('open');\n            });\n            container.querySelector('#stripe-dropdown-trigger').addEventListener('click', () => {\n                stripeDropdown.classList.toggle('open');\n                bodyDropdown.classList.remove('open');\n            });\n            document.addEventListener('click', e => {\n                if (!e.target.closest('#body-color-dropdown')) bodyDropdown.classList.remove('open');\n                if (!e.target.closest('#stripe-color-dropdown')) stripeDropdown.classList.remove('open');\n            });\n            bodySwatchGrid.addEventListener('click', e => {\n                const swatch = e.target.closest('.color-swatch');\n                if (!swatch) return;\n                state.colorBody = swatch.dataset.value;\n                state.colorBodyName = swatch.dataset.name;\n                bodyDropdown.classList.remove('open');\n                updateColorUI();\n            });\n            stripeSwatchGrid.addEventListener('click', e => {\n                const swatch = e.target.closest('.color-swatch');\n                if (!swatch) return;\n                state.colorStripe = swatch.dataset.value;\n                state.colorStripeName = swatch.dataset.name;\n                stripeDropdown.classList.remove('open');\n                updateColorUI();\n            });\n            customBodyInput.addEventListener('input', e => {\n                state.colorBody = e.target.value;\n                state.colorBodyName = getPresetColorName(BODY_COLOR_PRESETS, state.colorBody, 'Custom Body');\n                updateColorUI();\n            });\n            customStripeInput.addEventListener('input', e => {\n                state.colorStripe = e.target.value;\n                state.colorStripeName = getPresetColorName(STRIPE_COLOR_PRESETS, state.colorStripe, 'Custom Stripe');\n                updateColorUI();\n            });\n            customBodyHex.addEventListener('input', e => {\n                const v = e.target.value.trim();\n                if (\/^#[0-9a-fA-F]{6}$\/.test(v)) {\n                    state.colorBody = v.toLowerCase();\n                    state.colorBodyName = getPresetColorName(BODY_COLOR_PRESETS, state.colorBody, 'Custom Body');\n                    customBodyInput.value = state.colorBody;\n                    updateColorUI();\n                }\n            });\n            customStripeHex.addEventListener('input', e => {\n                const v = e.target.value.trim();\n                if (\/^#[0-9a-fA-F]{6}$\/.test(v)) {\n                    state.colorStripe = v.toLowerCase();\n                    state.colorStripeName = getPresetColorName(STRIPE_COLOR_PRESETS, state.colorStripe, 'Custom Stripe');\n                    customStripeInput.value = state.colorStripe;\n                    updateColorUI();\n                }\n            });\n\n            btnDownloadPdf.addEventListener('click', downloadSummaryPdf);\n            btnContact.addEventListener('click', openContactForm);\n\n            renderPowerOptions();\n            renderGunsOptions();\n            renderColorPresets();\n            updateColorUI();\n            updateVisuals();\n        }\n\n        function goToStep(step) {\n            summaryPane.classList.add('hidden');\n            resetWizardContentX();\n            currentStep = step;\n            stepPanes.forEach((pane, i) => {\n                pane.classList.toggle('active', i + 1 === currentStep);\n            });\n            stepIndicators.forEach((ind, i) => {\n                ind.classList.remove('active', 'completed');\n                if (i + 1 < currentStep) ind.classList.add('completed');\n                else if (i + 1 === currentStep) ind.classList.add('active');\n            });\n            stepConnectors.forEach((conn, i) => { conn.classList.toggle('completed', i + 1 < currentStep); });\n            btnPrev.disabled = currentStep === 1;\n            btnPrev.textContent = 'Previous';\n            btnNext.style.display = '';\n            btnNext.textContent = currentStep === totalSteps ? 'Complete Configuration' : 'Next';\n\n            const groups = [closedDoorGroup, openDoorGroup, colorSelectGroup];\n            groups.forEach(g => { g.classList.remove('active'); g.classList.add('hidden'); });\n            if (currentStep === 2) { openDoorGroup.classList.remove('hidden'); openDoorGroup.classList.add('active'); }\n            else if (currentStep === 4) { colorSelectGroup.classList.remove('hidden'); colorSelectGroup.classList.add('active'); }\n            else { closedDoorGroup.classList.remove('hidden'); closedDoorGroup.classList.add('active'); }\n            updateVisuals();\n        }\n\n        function resetWizardContentX() {\n            if (wizardContent.scrollLeft !== 0) wizardContent.scrollLeft = 0;\n        }\n\n        function queueResetWizardContentX() {\n            requestAnimationFrame(resetWizardContentX);\n        }\n\n        function findPresetColor(list, value) {\n            return list.find(color => color.value.toLowerCase() === String(value).toLowerCase());\n        }\n\n        function getPresetColorName(list, value, fallback) {\n            const match = findPresetColor(list, value);\n            return match ? match.name : fallback;\n        }\n\n        function renderColorPresets() {\n            const renderSwatches = (grid, list) => {\n                grid.innerHTML = list.map(c =>\n                    `<div class=\"color-swatch\" data-value=\"${c.value}\" data-name=\"${c.name}\">` +\n                    `<span class=\"color-swatch-circle\" style=\"background:${c.value}\"><\/span>` +\n                    `<span class=\"color-swatch-name\">${c.name}<\/span><\/div>`\n                ).join('');\n            };\n            renderSwatches(bodySwatchGrid, BODY_COLOR_PRESETS);\n            renderSwatches(stripeSwatchGrid, STRIPE_COLOR_PRESETS);\n        }\n\n        function renderPowerOptions() {\n            const md = configData[state.model];\n            powerOptionsContainer.innerHTML = '';\n            md.powers.forEach(p => {\n                const checked = state.power === p.value ? 'checked' : '';\n                powerOptionsContainer.insertAdjacentHTML('beforeend', `<label><input type=\"radio\" name=\"power\" value=\"${p.value}\" ${checked}> ${p.label}<\/label>`);\n            });\n        }\n\n        function renderGunsOptions() {\n            const md = configData[state.model];\n            const h3 = gunsContainer.querySelector('h3');\n            const hint = gunsContainer.querySelector('.hint-text');\n            gunsContainer.innerHTML = '';\n            gunsContainer.appendChild(h3);\n            gunsContainer.appendChild(hint);\n            hint5m.style.display = state.model === '480kW' ? 'block' : 'none';\n\n            md.gunPositions.forEach(pos => {\n                const wrapper = document.createElement('div');\n                wrapper.className = 'gun-selector';\n                const label = document.createElement('span');\n                label.textContent = `Pos ${pos}`;\n                wrapper.appendChild(label);\n\n                const typeSelect = document.createElement('select');\n                typeSelect.innerHTML = `<option value=\"none\">None<\/option>`;\n                gunTypes.forEach(t => { typeSelect.innerHTML += `<option value=\"${t}\">${t}<\/option>`; });\n                typeSelect.value = state.guns[pos]?.type || 'none';\n\n                const cableSelect = document.createElement('select');\n                const restrict5m = state.model === '480kW' && (pos === 2 || pos === 3);\n                cableSelect.innerHTML = `<option value=\"3.5m\">3.5m<\/option>`;\n                if (!restrict5m) cableSelect.innerHTML += `<option value=\"5m\">5m<\/option>`;\n                cableSelect.value = state.guns[pos]?.cable || '3.5m';\n                cableSelect.disabled = typeSelect.value === 'none';\n\n                typeSelect.addEventListener('change', e => {\n                    const v = e.target.value;\n                    cableSelect.disabled = v === 'none';\n                    state.guns[pos] = v === 'none' ? null : { type: v, cable: cableSelect.value };\n                    updateVisuals();\n                });\n                cableSelect.addEventListener('change', e => {\n                    if (state.guns[pos]) { state.guns[pos].cable = e.target.value; updateVisuals(); }\n                });\n\n                wrapper.appendChild(typeSelect);\n                wrapper.appendChild(cableSelect);\n                gunsContainer.appendChild(wrapper);\n            });\n        }\n\n        function updateVisuals() {\n            const mdAssets = ASSETS[state.model];\n            const mdData = configData[state.model];\n\n            if (state.payment) {\n                baseImage.src = state.accessible ? mdAssets.baseAccessiblePos : mdAssets.baseNormalPos;\n            } else {\n                baseImage.src = state.accessible ? mdAssets.baseAccessible : mdAssets.baseNormal;\n            }\n\n            const powerObj = mdData.powers.find(p => p.value === state.power);\n            powerLayer.src = powerObj ? powerObj.file : mdAssets.powerEmpty;\n            colorBaseImage.src = mdAssets.colorBase;\n\n            svgBodyRect.setAttribute('mask', `url(#${mdData.bodyMaskId})`);\n            svgStripeRect.setAttribute('mask', `url(#${mdData.stripeMaskId})`);\n\n            [1, 2, 3, 4].forEach(pos => {\n                const gunImg = container.querySelector(`#gun-layer-${pos}`);\n                const gc = state.guns[pos];\n                if (!gc || !mdData.gunPositions.includes(pos)) {\n                    gunImg.classList.add('hidden');\n                    return;\n                }\n                gunImg.src = getGunImageUrl(state.model, gc.type, pos, gc.cable);\n                gunImg.onload = () => gunImg.classList.remove('hidden');\n                gunImg.onerror = () => gunImg.classList.add('hidden');\n            });\n        }\n\n\n        function showSummary() {\n            currentStep = summaryStep;\n            resetWizardContentX();\n            stepPanes.forEach(pane => pane.classList.remove('active'));\n            summaryPane.classList.remove('hidden');\n            stepIndicators.forEach((ind, i) => {\n                ind.classList.remove('active', 'completed');\n                if (i + 1 < summaryStep) ind.classList.add('completed');\n                else if (i + 1 === summaryStep) ind.classList.add('active');\n            });\n            stepConnectors.forEach(conn => conn.classList.add('completed'));\n            btnPrev.disabled = false;\n            btnPrev.textContent = 'Back';\n            btnNext.style.display = 'none';\n            const groups = [closedDoorGroup, openDoorGroup, colorSelectGroup];\n            groups.forEach(g => { g.classList.remove('active'); g.classList.add('hidden'); });\n            colorSelectGroup.classList.remove('hidden');\n            colorSelectGroup.classList.add('active');\n            updateVisuals();\n            renderSummary();\n        }\n\n        function getSummaryData() {\n            const md = configData[state.model];\n            const powerObj = md.powers.find(p => p.value === state.power);\n            const connectors = md.gunPositions.map(pos => {\n                const gun = state.guns[pos];\n                return {\n                    label: `Position ${pos}`,\n                    value: gun ? `${gun.type}, ${gun.cable}` : 'None'\n                };\n            });\n            return {\n                model: state.model === '240kW' ? 'HYC 240' : 'HYC 480',\n                power: powerObj ? powerObj.label : 'Not selected',\n                options: [\n                    { label: 'Payment Terminal (POS)', value: state.payment ? 'Yes' : 'No' },\n                    { label: 'Accessible Screen Version', value: state.accessible ? 'Yes' : 'No' },\n                    { label: 'Door Contact Switch', value: state.doorContact ? 'Yes' : 'No' }\n                ],\n                connectors,\n                colourName: `${state.colorBodyName} \/ ${state.colorStripeName}`,\n                colorBodyName: state.colorBodyName,\n                colorStripeName: state.colorStripeName,\n                colorBody: state.colorBody.toUpperCase(),\n                colorStripe: state.colorStripe.toUpperCase(),\n                colours: [\n                    { label: 'Body Finish', value: `${state.colorBodyName} (${state.colorBody.toUpperCase()})` },\n                    { label: 'Accent Stripe', value: `${state.colorStripeName} (${state.colorStripe.toUpperCase()})` }\n                ]\n            };\n        }\n\n        function escapeHtml(value) {\n            return String(value).replace(\/[&<>\"]\/g, ch => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;' }[ch]));\n        }\n\n        function renderSummary() {\n            const data = getSummaryData();\n            const section = (title, rows) => `\n                <div class=\"summary-section\">\n                    <h3>${escapeHtml(title)}<\/h3>\n                    ${rows.map(row => `\n                        <div class=\"summary-row\">\n                            <span class=\"summary-label\">${escapeHtml(row.label)}<\/span>\n                            <span class=\"summary-value\">${row.html || escapeHtml(row.value)}<\/span>\n                        <\/div>\n                    `).join('')}\n                <\/div>\n            `;\n            const colorRow = (label, name, hex) => ({\n                label,\n                html: `<span class=\"summary-color-swatch\" style=\"background:${escapeHtml(hex)}\"><\/span>${escapeHtml(name)} (${escapeHtml(hex)})`\n            });\n            summaryDetails.innerHTML = [\n                section('Charger', [\n                    { label: 'Model', value: data.model },\n                    { label: 'Power Modules', value: data.power }\n                ]),\n                section('Additional Options', data.options),\n                section('Connectors', data.connectors),\n                section('Colours', [\n                    colorRow('Body Finish', data.colorBodyName, data.colorBody),\n                    colorRow('Accent Stripe', data.colorStripeName, data.colorStripe)\n                ])\n            ].join('');\n        }\n\n        function getSummaryLines() {\n            const data = getSummaryData();\n            return [\n                'Elecrest Configuration Summary',\n                '',\n                `Model: ${data.model}`,\n                `Power Modules: ${data.power}`,\n                '',\n                'Additional Options:',\n                ...data.options.map(row => `- ${row.label}: ${row.value}`),\n                '',\n                'Connectors:',\n                ...data.connectors.map(row => `- ${row.label}: ${row.value}`),\n                '',\n                'Colours:',\n                ...data.colours.map(row => `- ${row.label}: ${row.value}`)\n            ];\n        }\n\n        function pdfEscape(value) {\n            return String(value).replace(\/[\\\\()]\/g, ch => '\\\\' + ch);\n        }\n\n        function pdfText(value) {\n            return String(value).replace(\/[\\u2013\\u2014]\/g, '-').replace(\/[^\\x20-\\x7E]\/g, '');\n        }\n\n        function textOp(text, x, y, size, color) {\n            const rgb = color || [0.08, 0.11, 0.16];\n            return [\n                'BT',\n                `${rgb[0]} ${rgb[1]} ${rgb[2]} rg`,\n                `\/F1 ${size} Tf`,\n                `1 0 0 1 ${x} ${y} Tm`,\n                `(${pdfEscape(pdfText(text))}) Tj`,\n                'ET'\n            ].join('\\n');\n        }\n\n        function rectOp(x, y, w, h, color) {\n            return `q ${color.join(' ')} rg ${x} ${y} ${w} ${h} re f Q`;\n        }\n\n        function lineOp(x1, y1, x2, y2, color) {\n            return `q ${color.join(' ')} RG 1 w ${x1} ${y1} m ${x2} ${y2} l S Q`;\n        }\n\n        function truncatePdfText(value, maxChars) {\n            const clean = pdfText(value);\n            if (clean.length <= maxChars) return clean;\n            return clean.slice(0, Math.max(0, maxChars - 3)) + '...';\n        }\n\n        function tableText(text, x, y, maxChars, size, color) {\n            return textOp(truncatePdfText(text, maxChars), x, y, size, color);\n        }\n\n        function hexToRgb01(hex) {\n            const h = (hex || '#000000').replace('#', '');\n            return [parseInt(h.substring(0,2),16)\/255, parseInt(h.substring(2,4),16)\/255, parseInt(h.substring(4,6),16)\/255];\n        }\n\n        async function capturePreviewJpeg() {\n            try {\n                const mdAssets = ASSETS[state.model];\n                const sz = 600;\n                const cv = document.createElement('canvas');\n                cv.width = sz; cv.height = sz;\n                const cx = cv.getContext('2d');\n                cx.fillStyle = '#ffffff';\n                cx.fillRect(0, 0, sz, sz);\n                const load = src => new Promise((ok, no) => { const i = new Image(); i.crossOrigin = 'anonymous'; i.onload = () => ok(i); i.onerror = no; i.src = src; });\n                cx.drawImage(await load(mdAssets.colorBase), 0, 0, sz, sz);\n                const tp = document.createElement('canvas');\n                tp.width = sz; tp.height = sz;\n                const tc = tp.getContext('2d');\n                tc.drawImage(await load(mdAssets.maskBody), 0, 0, sz, sz);\n                tc.globalCompositeOperation = 'source-in';\n                tc.fillStyle = state.colorBody;\n                tc.fillRect(0, 0, sz, sz);\n                cx.globalCompositeOperation = 'multiply';\n                cx.drawImage(tp, 0, 0);\n                tc.clearRect(0, 0, sz, sz);\n                tc.globalCompositeOperation = 'source-over';\n                tc.drawImage(await load(mdAssets.maskStripe), 0, 0, sz, sz);\n                tc.globalCompositeOperation = 'source-in';\n                tc.fillStyle = state.colorStripe;\n                tc.fillRect(0, 0, sz, sz);\n                cx.drawImage(tp, 0, 0);\n                cx.globalCompositeOperation = 'source-over';\n                return new Promise(ok => {\n                    cv.toBlob(b => {\n                        if (!b) { ok(null); return; }\n                        const r = new FileReader();\n                        r.onload = () => ok({ bytes: new Uint8Array(r.result), w: sz, h: sz });\n                        r.readAsArrayBuffer(b);\n                    }, 'image\/jpeg', 0.9);\n                });\n            } catch (e) { return null; }\n        }\n\n        function buildConfigPageContent(data, hasImage) {\n            const W = 612, m = 36, cw = W - 2 * m;\n            const ops = [];\n            ops.push(rectOp(0, 750, W, 42, [0.02, 0.07, 0.13]));\n            ops.push(textOp('Elecrest Configuration Sheet', m, 772, 18, [1, 1, 1]));\n            ops.push(textOp('Generated from the HYC configurator', m, 756, 9, [0.72, 0.82, 0.92]));\n            ops.push(textOp(pdfText(data.model + ' Final Configuration'), m, 722, 16, [0.05, 0.09, 0.16]));\n            ops.push(textOp('Review the selected charger specification before contacting Elecrest.', m, 704, 9, [0.38, 0.45, 0.55]));\n            var boxX = m, boxY = 380, boxW = 210, boxH = 310;\n            var imgW = 200, imgH = 200, imgX = boxX + 5, imgY = boxY + (boxH - imgH) \/ 2;\n            var rX = m + boxW + 20, rW = cw - boxW - 20;\n            ops.push(rectOp(boxX, boxY, boxW, boxH, [0.96, 0.97, 0.98]));\n            if (hasImage) ops.push('q ' + imgW + ' 0 0 ' + imgH + ' ' + imgX + ' ' + imgY + ' cm \/Im1 Do Q');\n            else ops.push(textOp('Product Preview', boxX + 55, boxY + boxH \/ 2, 10, [0.7, 0.75, 0.8]));\n            var ry = boxY + boxH - 55;\n            ops.push(rectOp(rX, ry, rW, 50, [0.92, 0.97, 1]));\n            ops.push(textOp('Selected Model', rX + 14, ry + 36, 9, [0.35, 0.42, 0.53]));\n            ops.push(textOp(pdfText(data.model), rX + 14, ry + 12, 20, [0.02, 0.07, 0.13]));\n            ry -= 58;\n            ops.push(rectOp(rX, ry, rW, 50, [0.94, 0.96, 1]));\n            ops.push(textOp('Power Configuration', rX + 14, ry + 36, 9, [0.35, 0.42, 0.53]));\n            ops.push(textOp(pdfText(data.power), rX + 14, ry + 12, 14, [0.02, 0.07, 0.13]));\n            ry -= 52;\n            ops.push(textOp('Body Finish', rX, ry + 34, 9, [0.35, 0.42, 0.53]));\n            var bc = hexToRgb01(data.colorBody);\n            ops.push(rectOp(rX, ry + 6, 16, 16, bc));\n            ops.push(lineOp(rX, ry + 6, rX + 16, ry + 6, [0.75, 0.75, 0.75]));\n            ops.push(lineOp(rX, ry + 22, rX + 16, ry + 22, [0.75, 0.75, 0.75]));\n            ops.push(lineOp(rX, ry + 6, rX, ry + 22, [0.75, 0.75, 0.75]));\n            ops.push(lineOp(rX + 16, ry + 6, rX + 16, ry + 22, [0.75, 0.75, 0.75]));\n            ops.push(textOp(pdfText(data.colorBodyName + ' (' + data.colorBody + ')'), rX + 22, ry + 9, 10, [0.05, 0.09, 0.16]));\n            ry -= 42;\n            ops.push(textOp('Accent Stripe', rX, ry + 34, 9, [0.35, 0.42, 0.53]));\n            var sc = hexToRgb01(data.colorStripe);\n            ops.push(rectOp(rX, ry + 6, 16, 16, sc));\n            ops.push(lineOp(rX, ry + 6, rX + 16, ry + 6, [0.75, 0.75, 0.75]));\n            ops.push(lineOp(rX, ry + 22, rX + 16, ry + 22, [0.75, 0.75, 0.75]));\n            ops.push(lineOp(rX, ry + 6, rX, ry + 22, [0.75, 0.75, 0.75]));\n            ops.push(lineOp(rX + 16, ry + 6, rX + 16, ry + 22, [0.75, 0.75, 0.75]));\n            ops.push(textOp(pdfText(data.colorStripeName + ' (' + data.colorStripe + ')'), rX + 22, ry + 9, 10, [0.05, 0.09, 0.16]));\n            var detailRows = data.options.concat(data.connectors);\n            var dY0 = boxY - 30;\n            ops.push(textOp('Additional Options & Connectors', m, dY0, 12, [0.05, 0.09, 0.16]));\n            ops.push(lineOp(m, dY0 - 6, m + cw, dY0 - 6, [0.82, 0.86, 0.91]));\n            var dy = dY0 - 30, drH = 28;\n            detailRows.forEach(function(row, i) {\n                if (i % 2 === 0) ops.push(rectOp(m, dy - 6, cw, drH, [0.98, 0.99, 1]));\n                ops.push(textOp(pdfText(row.label), m + 14, dy, 10, [0.35, 0.42, 0.53]));\n                ops.push(textOp(pdfText(String(row.value)), m + 300, dy, 10, [0.05, 0.09, 0.16]));\n                dy -= drH;\n            });\n            ops.push(lineOp(m, 60, m + cw, 60, [0.82, 0.86, 0.91]));\n            ops.push(textOp('Final availability and compliance should be confirmed by Elecrest sales engineering.', m, 42, 8, [0.38, 0.45, 0.55]));\n            return ops.join('\\n');\n        }\n\n        function buildParameterPageContent(data) {\n            var spec = PARAMETER_TABLES[data.model] || PARAMETER_TABLES['240kW'];\n            var variants = spec.variants;\n            var rows = spec.rows;\n            var W = 612, tX = 30, tW = W - 60;\n            var secW = 84, itemW = 156;\n            var valAreaW = tW - secW - itemW;\n            var vW = valAreaW \/ variants.length;\n            var hH = 24, rH = 22;\n            var tTop = 740, hY = tTop - hH;\n            var itemX = tX + secW, valX = itemX + itemW;\n            var tBot = hY - rows.length * rH;\n            var ops = [];\n\n            function approxTW(text, size) { return pdfText(text).length * size * 0.48; }\n            function cText(text, x, y, w, sz, col) {\n                var c = truncatePdfText(text, Math.max(4, Math.floor(w \/ (sz * 0.42))));\n                return textOp(c, x + Math.max(2, (w - approxTW(c, sz)) \/ 2), y, sz, col);\n            }\n            function mText(text, x, y, w, h, sz, col) {\n                var words = pdfText(text).split(' ');\n                var lines = [], line = '';\n                var mc = Math.max(6, Math.floor(w \/ (sz * 0.46)));\n                words.forEach(function(word) {\n                    var n = line ? line + ' ' + word : word;\n                    if (n.length > mc && line) { lines.push(line); line = word; }\n                    else { line = n; }\n                });\n                if (line) lines.push(line);\n                var vis = lines.slice(0, 3);\n                var sy = y + (h + (vis.length - 1) * sz * 1.2) \/ 2 - sz * 0.35;\n                return vis.map(function(r, i) { return cText(r, x, sy - i * sz * 1.2, w, sz, col); }).join('\\n');\n            }\n            function allEq(v) { return v.every(function(x) { return x === v[0]; }); }\n            function sEnd(si) { for (var i = si + 1; i < rows.length; i++) { if (rows[i].section) return i; } return rows.length; }\n\n            ops.push(rectOp(0, 750, W, 42, [0.02, 0.07, 0.13]));\n            ops.push(textOp('Technical Parameter Table', 30, 774, 16, [1, 1, 1]));\n            ops.push(textOp(pdfText(data.model + ' reference specification'), 30, 758, 8, [0.72, 0.82, 0.92]));\n\n            ops.push(rectOp(tX, hY, tW, hH, [0.13, 0.69, 0.79]));\n            ops.push(cText('Category', tX, hY + 8, secW, 8.5, [1, 1, 1]));\n            ops.push(cText('Parameter', itemX, hY + 8, itemW, 8.5, [1, 1, 1]));\n            variants.forEach(function(v, i) {\n                ops.push(cText(v, valX + vW * i, hY + 8, vW, 8, [1, 1, 1]));\n                if (i > 0) ops.push(lineOp(valX + vW * i, hY, valX + vW * i, hY + hH, [1, 1, 1]));\n            });\n\n            rows.forEach(function(row, idx) {\n                var y = hY - rH * (idx + 1);\n                if (idx % 2 === 0) ops.push(rectOp(itemX, y, itemW + valAreaW, rH, [0.97, 0.99, 1]));\n                if (row.section) {\n                    var end = sEnd(idx);\n                    var gH = rH * (end - idx);\n                    var gY = hY - rH * end;\n                    ops.push(rectOp(tX, gY, secW, gH, [0.95, 0.99, 1]));\n                    ops.push(mText(row.section, tX + 3, gY, secW - 6, gH, 7.5, [0.04, 0.09, 0.16]));\n                    ops.push(lineOp(tX, y + rH, tX + tW, y + rH, [0.13, 0.69, 0.79]));\n                }\n                ops.push(tableText(row.item, itemX + 6, y + 7, 30, 8, [0.22, 0.28, 0.36]));\n                if (allEq(row.values)) {\n                    ops.push(cText(row.values[0], valX, y + 7, valAreaW, 8, [0.05, 0.09, 0.16]));\n                } else {\n                    row.values.forEach(function(val, vi) {\n                        ops.push(cText(val, valX + vW * vi, y + 7, vW, 8, [0.05, 0.09, 0.16]));\n                    });\n                    for (var i = 1; i < variants.length; i++) {\n                        ops.push(lineOp(valX + vW * i, y, valX + vW * i, y + rH, [0.78, 0.82, 0.87]));\n                    }\n                }\n                ops.push(lineOp(itemX, y, tX + tW, y, [0.78, 0.82, 0.87]));\n            });\n\n            [tX, itemX, valX, tX + tW].forEach(function(x) {\n                ops.push(lineOp(x, tBot, x, tTop, [0.78, 0.82, 0.87]));\n            });\n            ops.push(lineOp(tX, tTop, tX + tW, tTop, [0.78, 0.82, 0.87]));\n            ops.push(lineOp(tX, hY, tX + tW, hY, [0.78, 0.82, 0.87]));\n            ops.push(lineOp(tX, tBot, tX + tW, tBot, [0.78, 0.82, 0.87]));\n            ops.push(lineOp(30, 42, W - 30, 42, [0.82, 0.86, 0.91]));\n            ops.push(textOp('Specification data for reference only. Contact Elecrest sales engineering for confirmation.', 30, 26, 7.5, [0.38, 0.45, 0.55]));\n            return ops.join('\\n');\n        }\n        function encodePart(part) {\n            if (part instanceof Uint8Array) return part;\n            return new TextEncoder().encode(part);\n        }\n\n        function buildPdfBinary(objects) {\n            const chunks = [];\n            const offsets = [0];\n            let length = 0;\n            const push = part => {\n                const encoded = encodePart(part);\n                chunks.push(encoded);\n                length += encoded.length;\n            };\n            push('%PDF-1.4\\n');\n            objects.forEach((object, index) => {\n                offsets.push(length);\n                push(`${index + 1} 0 obj\\n`);\n                object.parts.forEach(push);\n                push('\\nendobj\\n');\n            });\n            const xrefOffset = length;\n            push(`xref\\n0 ${objects.length + 1}\\n0000000000 65535 f \\n`);\n            offsets.slice(1).forEach(offset => push(`${String(offset).padStart(10, '0')} 00000 n \\n`));\n            push(`trailer\\n<< \/Size ${objects.length + 1} \/Root 1 0 R >>\\nstartxref\\n${xrefOffset}\\n%%EOF`);\n            const output = new Uint8Array(length);\n            let cursor = 0;\n            chunks.forEach(chunk => { output.set(chunk, cursor); cursor += chunk.length; });\n            return output;\n        }\n\n        async function buildConfigurationPdf() {\n            var data = getSummaryData();\n            var img = await capturePreviewJpeg();\n            var p1 = buildConfigPageContent(data, !!img);\n            var p2 = buildParameterPageContent(data);\n            var p1Len = new TextEncoder().encode(p1).length;\n            var p2Len = new TextEncoder().encode(p2).length;\n            if (img) {\n                return buildPdfBinary([\n                    { parts: ['<< \/Type \/Catalog \/Pages 2 0 R >>'] },\n                    { parts: ['<< \/Type \/Pages \/Kids [3 0 R 4 0 R] \/Count 2 >>'] },\n                    { parts: ['<< \/Type \/Page \/Parent 2 0 R \/MediaBox [0 0 612 792] \/Resources << \/Font << \/F1 5 0 R >> \/XObject << \/Im1 6 0 R >> >> \/Contents 7 0 R >>'] },\n                    { parts: ['<< \/Type \/Page \/Parent 2 0 R \/MediaBox [0 0 612 792] \/Resources << \/Font << \/F1 5 0 R >> >> \/Contents 8 0 R >>'] },\n                    { parts: ['<< \/Type \/Font \/Subtype \/Type1 \/BaseFont \/Helvetica >>'] },\n                    { parts: ['<< \/Type \/XObject \/Subtype \/Image \/Width ' + img.w + ' \/Height ' + img.h + ' \/BitsPerComponent 8 \/ColorSpace \/DeviceRGB \/Filter \/DCTDecode \/Length ' + img.bytes.length + ' >>\\nstream\\n', img.bytes, '\\nendstream'] },\n                    { parts: ['<< \/Length ' + p1Len + ' >>\\nstream\\n' + p1 + '\\nendstream'] },\n                    { parts: ['<< \/Length ' + p2Len + ' >>\\nstream\\n' + p2 + '\\nendstream'] }\n                ]);\n            }\n            return buildPdfBinary([\n                { parts: ['<< \/Type \/Catalog \/Pages 2 0 R >>'] },\n                { parts: ['<< \/Type \/Pages \/Kids [3 0 R 4 0 R] \/Count 2 >>'] },\n                { parts: ['<< \/Type \/Page \/Parent 2 0 R \/MediaBox [0 0 612 792] \/Resources << \/Font << \/F1 5 0 R >> >> \/Contents 6 0 R >>'] },\n                { parts: ['<< \/Type \/Page \/Parent 2 0 R \/MediaBox [0 0 612 792] \/Resources << \/Font << \/F1 5 0 R >> >> \/Contents 7 0 R >>'] },\n                { parts: ['<< \/Type \/Font \/Subtype \/Type1 \/BaseFont \/Helvetica >>'] },\n                { parts: ['<< \/Length ' + p1Len + ' >>\\nstream\\n' + p1 + '\\nendstream'] },\n                { parts: ['<< \/Length ' + p2Len + ' >>\\nstream\\n' + p2 + '\\nendstream'] }\n            ]);\n        }\n\n        async function downloadSummaryPdf() {\n            const originalText = btnDownloadPdf.textContent;\n            btnDownloadPdf.disabled = true;\n            btnDownloadPdf.textContent = 'Preparing PDF...';\n            try {\n                const pdfBytes = await buildConfigurationPdf();\n                const blob = new Blob([pdfBytes], { type: 'application\/pdf' });\n                const url = URL.createObjectURL(blob);\n                const link = document.createElement('a');\n                link.href = url;\n                link.download = `Elecrest-${state.model}-configuration.pdf`;\n                document.body.appendChild(link);\n                link.click();\n                link.remove();\n                setTimeout(() => URL.revokeObjectURL(url), 1500);\n            } catch (error) {\n                console.error(error);\n                alert('The PDF could not be generated. Please try again or contact Elecrest directly.');\n            } finally {\n                btnDownloadPdf.disabled = false;\n                btnDownloadPdf.textContent = originalText;\n            }\n        }\n\n        function openContactForm() {\n            if (window.elementorProFrontend?.modules?.popup) {\n                window.elementorProFrontend.modules.popup.showPopup({ id: 452 });\n                return;\n            }\n            contactTemplateFallback.classList.toggle('hidden');\n        }\n        function updateColorUI() {\n            svgBodyRect.setAttribute('fill', state.colorBody);\n            svgStripeRect.setAttribute('fill', state.colorStripe);\n            const bodyMatch = findPresetColor(BODY_COLOR_PRESETS, state.colorBody);\n            const stripeMatch = findPresetColor(STRIPE_COLOR_PRESETS, state.colorStripe);\n            state.colorBodyName = bodyMatch ? bodyMatch.name : (state.colorBodyName || 'Custom Body');\n            state.colorStripeName = stripeMatch ? stripeMatch.name : (state.colorStripeName || 'Custom Stripe');\n            bodySwatchGrid.querySelectorAll('.color-swatch').forEach(s => {\n                s.classList.toggle('active', s.dataset.value.toLowerCase() === state.colorBody.toLowerCase());\n            });\n            stripeSwatchGrid.querySelectorAll('.color-swatch').forEach(s => {\n                s.classList.toggle('active', s.dataset.value.toLowerCase() === state.colorStripe.toLowerCase());\n            });\n            bodyDropdownSwatch.style.background = state.colorBody;\n            bodyDropdownText.textContent = state.colorBodyName;\n            stripeDropdownSwatch.style.background = state.colorStripe;\n            stripeDropdownText.textContent = state.colorStripeName;\n            customBodyInput.value = state.colorBody;\n            customStripeInput.value = state.colorStripe;\n            customBodyHex.value = state.colorBody.toUpperCase();\n            customStripeHex.value = state.colorStripe.toUpperCase();\n        }\n    });\n})();\n<\/script>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>1 Model 2 Power 3 Config 4 Colour 5 Summary Select Product Model Please select the base model. This determines the maximum power and number of connectors. HYC 240 Up to 240 kWDual connector HYC 480 Up to 480 kWQuad connector Select Power Modules View the internal architecture and select the number of power modules [&hellip;]<\/p>\n","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-963","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/elecrest.energy\/fr\/wp-json\/wp\/v2\/pages\/963","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/elecrest.energy\/fr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/elecrest.energy\/fr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/elecrest.energy\/fr\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/elecrest.energy\/fr\/wp-json\/wp\/v2\/comments?post=963"}],"version-history":[{"count":0,"href":"https:\/\/elecrest.energy\/fr\/wp-json\/wp\/v2\/pages\/963\/revisions"}],"wp:attachment":[{"href":"https:\/\/elecrest.energy\/fr\/wp-json\/wp\/v2\/media?parent=963"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}