{"id":2478,"date":"2026-08-10T05:45:40","date_gmt":"2026-08-10T03:45:40","guid":{"rendered":"https:\/\/elecrest.energy\/?page_id=2478"},"modified":"2026-10-22T11:34:41","modified_gmt":"2026-10-22T09:34:41","slug":"home","status":"publish","type":"page","link":"https:\/\/elecrest.energy\/fr\/","title":{"rendered":"Home"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"2478\" class=\"elementor elementor-2478\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7d52f96 e-flex e-con-boxed e-con e-parent\" data-id=\"7d52f96\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;video&quot;,&quot;background_video_link&quot;:&quot;https:\\\/\\\/elecrest.energy\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/Homepage-Hero-Background-video-new.mp4&quot;,&quot;background_video_start&quot;:0,&quot;background_privacy_mode&quot;:&quot;yes&quot;,&quot;background_video_end&quot;:10}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-background-video-container elementor-hidden-mobile\">\n\t\t\t\t\t\t\t<video class=\"elementor-background-video-hosted\" role=\"presentation\" autoplay muted playsinline loop><\/video>\n\t\t\t\t\t<\/div><div class=\"elementor-element elementor-element-83453b8 e-con-full e-flex e-con e-child\" data-id=\"83453b8\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-be2a65e elementor-widget__width-initial elementor-widget-mobile__width-initial elementor-widget elementor-widget-heading\" data-id=\"be2a65e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">Rethink the economics of DC fast charging<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4c04cb4 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"4c04cb4\" 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>HIMA DC fast chargers combine efficiency, serviceable design and connected operations to manage whole-life cost.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-0334268 e-con-full e-flex e-con e-child\" data-id=\"0334268\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6f37082 elementor-align-justify elementor-widget__width-initial elementor-widget elementor-widget-button\" data-id=\"6f37082\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"button.default\">\n\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-button elementor-button-link elementor-size-sm\" href=\"#elementor-action%3Aaction%3Dpopup%3Aopen%26settings%3DeyJpZCI6IjQ1MiIsInRvZ2dsZSI6ZmFsc2V9\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">Request a Quote<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a65a885 elementor-align-justify elementor-widget__width-initial elementor-widget elementor-widget-button\" data-id=\"a65a885\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"button.default\">\n\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-button elementor-button-link elementor-size-sm\" href=\"https:\/\/elecrest.energy\/configurator\/\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">Configure<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-ef028cc e-flex e-con-boxed e-con e-parent\" data-id=\"ef028cc\" 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-6504c65 elementor-widget elementor-widget-html\" data-id=\"6504c65\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<div class=\"elecrest-model-showcase-host\" id=\"elecrest-product-model-showcase\">\r\n  <script type=\"application\/json\" class=\"elecrest-model-showcase-config\">\r\n  {\r\n    \"defaultProduct\": \"hima-480\",\r\n    \"sectionHeading\": \"One platform for every charging scenario\",\r\n    \"labels\": {\r\n      \"productSelector\": \"Select product model\",\r\n      \"previousProduct\": \"Previous product\",\r\n      \"nextProduct\": \"Next product\",\r\n      \"learnMore\": \"Learn more\",\r\n      \"configure\": \"Configure\",\r\n      \"caption\": \"360\u00b0 rotation view\",\r\n      \"loading\": \"Loading 360\u00b0 view\u2026\",\r\n      \"loadingProduct\": \"Loading {product} 360\u00b0 view\u2026\",\r\n      \"unavailable\": \"360\u00b0 view unavailable.\",\r\n      \"retry\": \"Retry\",\r\n      \"rotateModel\": \"Rotate {product} model\",\r\n      \"rotationValue\": \"{angle}\u00b0 rotation\",\r\n      \"dragInstruction\": \"Drag horizontally or use the arrow keys to rotate {product}.\"\r\n    },\r\n    \"interaction\": {\r\n      \"degreesPerFrameWidth\": 360,\r\n      \"keyboardStepDegrees\": 5\r\n    },\r\n    \"products\": [\r\n      {\r\n        \"id\": \"hima-240\",\r\n        \"name\": \"HIMA 240\",\r\n        \"videoDesktop\": \"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Hima-240kW-360-video.mp4\",\r\n        \"videoMobile\": \"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Hima-240kW-360-video.mp4\",\r\n        \"poster\": \"\",\r\n        \"description\": \"Available in 120 kW and 240 kW configurations, with two CCS2 charging connectors as standard.\",\r\n        \"learnMoreUrl\": \"https:\/\/elecrest.energy\/products\/hima240\/\",\r\n        \"configureUrl\": \"https:\/\/elecrest.energy\/configurator\/\",\r\n        \"videoAccessibleLabel\": \"Rotating view of the HIMA 240\",\r\n        \"initialAngle\": 0,\r\n        \"enabled\": true\r\n      },\r\n      {\r\n        \"id\": \"hima-480\",\r\n        \"name\": \"HIMA 480\",\r\n        \"videoDesktop\": \"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Hima-480KW-360-video.mp4\",\r\n        \"videoMobile\": \"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Hima-480KW-360-video.mp4\",\r\n        \"poster\": \"\",\r\n        \"description\": \"Available in 240 kW, 360 kW and 480 kW configurations, with up to four charging connectors.\",\r\n        \"learnMoreUrl\": \"https:\/\/elecrest.energy\/products\/hima480\/\",\r\n        \"configureUrl\": \"https:\/\/elecrest.energy\/configurator\/\",\r\n        \"videoAccessibleLabel\": \"Rotating view of the HIMA 480\",\r\n        \"initialAngle\": 0,\r\n        \"enabled\": true\r\n      }\r\n    ]\r\n  }\r\n  <\/script>\r\n\r\n  <style>\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host,\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host * {\r\n      box-sizing: border-box;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host {\r\n      display: block;\r\n      width: 100%;\r\n      background: #000000;\r\n      color: #ffffff;\r\n      font-family: \"Noto Sans\", Inter, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase {\r\n      --elecrest-model-accent: #00ffff;\r\n      --elecrest-model-text: #ffffff;\r\n      --elecrest-model-text-dim: #a9aeb9;\r\n      --elecrest-model-text-muted: #5f6570;\r\n      --elecrest-model-line: rgba(156, 165, 181, 0.48);\r\n      --elecrest-model-background: #000000;\r\n      --elecrest-model-transition-duration: 360ms;\r\n      --elecrest-model-copy-duration: 220ms;\r\n      --elecrest-model-visual-height: 22.5rem;\r\n      --elecrest-model-orbit-extension: 2.2rem;\r\n      position: relative;\r\n      display: grid;\r\n      grid-template-columns: minmax(0, 36rem) minmax(0, 33rem);\r\n      grid-template-rows: 2rem 27.4rem;\r\n      column-gap: 4rem;\r\n      align-content: center;\r\n      width: 73rem;\r\n      max-width: 100%;\r\n      min-height: 100vh;\r\n      margin: 0 auto;\r\n      padding: 4.2rem 0 2rem;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__heading {\r\n      grid-column: 2;\r\n      grid-row: 2;\r\n      align-self: start;\r\n      margin: 3.7rem 0 0;\r\n      color: var(--elecrest-model-text);\r\n      font-family: \"Montserrat\", Inter, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;\r\n      font-size: 3rem;\r\n      font-weight: 600;\r\n      line-height: 1.25em;\r\n      letter-spacing: -0.035em;\r\n      text-wrap: balance;\r\n      border: 0;\r\n      padding: 0;\r\n      background: transparent;\r\n      text-transform: none;\r\n      opacity: 1;\r\n      transform: translateY(0);\r\n      transition:\r\n        opacity var(--elecrest-model-copy-duration) ease,\r\n        transform var(--elecrest-model-copy-duration) ease;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__heading.is-changing {\r\n      opacity: 0;\r\n      transform: translateY(0.4rem);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__selector {\r\n      grid-column: 1;\r\n      grid-row: 1;\r\n      display: flex;\r\n      align-items: center;\r\n      justify-content: center;\r\n      gap: 2.3rem;\r\n      min-width: 0;\r\n      overflow-x: auto;\r\n      overflow-y: hidden;\r\n      scrollbar-width: none;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__selector::-webkit-scrollbar {\r\n      display: none;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__product-button {\r\n      appearance: none;\r\n      -webkit-appearance: none;\r\n      flex: 0 0 auto;\r\n      width: auto;\r\n      min-width: 0;\r\n      min-height: 0;\r\n      margin: 0;\r\n      border: 0;\r\n      border-bottom: 0.1rem solid transparent;\r\n      border-radius: 0;\r\n      padding: 0.45rem 0;\r\n      background: transparent;\r\n      box-shadow: none;\r\n      color: var(--elecrest-model-text-muted);\r\n      font: inherit;\r\n      font-size: 0.82rem;\r\n      font-weight: 400;\r\n      line-height: 1;\r\n      letter-spacing: 0;\r\n      white-space: nowrap;\r\n      text-align: center;\r\n      text-decoration: none;\r\n      text-transform: none;\r\n      cursor: pointer;\r\n      transition:\r\n        color var(--elecrest-model-copy-duration) ease,\r\n        border-color var(--elecrest-model-copy-duration) ease,\r\n        opacity var(--elecrest-model-copy-duration) ease,\r\n        transform var(--elecrest-model-copy-duration) ease;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__product-button:hover,\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__product-button[aria-pressed=\"true\"] {\r\n      color: var(--elecrest-model-accent);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__product-button.is-pending {\r\n      opacity: 0.72;\r\n      transform: translateY(-0.1rem);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__media-frame:focus,\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__product-button:focus,\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__arrow:focus,\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__retry:focus,\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__action:focus {\r\n      outline: none;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase.is-keyboard-navigation .elecrest-model-showcase__media-frame:focus,\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase.is-keyboard-navigation .elecrest-model-showcase__arrow:focus,\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase.is-keyboard-navigation .elecrest-model-showcase__retry:focus,\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase.is-keyboard-navigation .elecrest-model-showcase__action:focus {\r\n      outline: 0.1rem solid var(--elecrest-model-accent);\r\n      outline-offset: 0.25rem;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase.is-keyboard-navigation .elecrest-model-showcase__product-button:focus {\r\n      outline: none;\r\n      box-shadow: inset 0 0 0 0.08rem var(--elecrest-model-accent);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__figure {\r\n      grid-column: 1;\r\n      grid-row: 2;\r\n      width: 35rem;\r\n      max-width: 100%;\r\n      margin: 1.1rem auto 0;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__media-frame {\r\n      position: relative;\r\n      width: 100%;\r\n      height: calc(var(--elecrest-model-visual-height) + var(--elecrest-model-orbit-extension));\r\n      overflow: hidden;\r\n      background: transparent;\r\n      cursor: grab;\r\n      touch-action: pan-y;\r\n      user-select: none;\r\n      -webkit-user-select: none;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__media-frame.is-dragging {\r\n      cursor: grabbing;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__video {\r\n      position: absolute;\r\n      inset: 0 auto auto 0;\r\n      z-index: 2;\r\n      display: block;\r\n      width: 100%;\r\n      height: var(--elecrest-model-visual-height);\r\n      object-fit: cover;\r\n      object-position: center;\r\n      background: transparent;\r\n      mix-blend-mode: screen;\r\n      opacity: 0;\r\n      pointer-events: none;\r\n      transform: scale(1.62);\r\n      transition:\r\n        opacity var(--elecrest-model-transition-duration) ease,\r\n        transform var(--elecrest-model-transition-duration) ease;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__video.is-visible {\r\n      opacity: 1;\r\n      transform: scale(1.6);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__video.is-entering {\r\n      z-index: 2;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit,\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit-marker-stage {\r\n      position: absolute;\r\n      left: 50%;\r\n      bottom: 0.7rem;\r\n      width: 29rem;\r\n      height: 3.2rem;\r\n      pointer-events: none;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit {\r\n      border: 0.06rem solid var(--elecrest-model-line);\r\n      border-radius: 50%;\r\n      transform: translateX(-50%);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit--back {\r\n      z-index: 0;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit--front {\r\n      z-index: 3;\r\n      clip-path: inset(50% 0 0 0);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit-occluder {\r\n      position: absolute;\r\n      z-index: 1;\r\n      left: 50%;\r\n      bottom: 0.7rem;\r\n      width: 11.5rem;\r\n      height: 3.2rem;\r\n      background: var(--elecrest-model-background);\r\n      transform: translateX(-50%);\r\n      pointer-events: none;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit-marker-stage {\r\n      left: 50%;\r\n      z-index: 4;\r\n      margin-left: -14.5rem;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit-marker-stage.is-behind {\r\n      z-index: 0;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit-marker-stage.is-occluded .elecrest-model-showcase__orbit-marker {\r\n      opacity: 0;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit-marker {\r\n      position: absolute;\r\n      z-index: auto;\r\n      left: 50%;\r\n      top: 100%;\r\n      width: 0.72rem;\r\n      height: 0.72rem;\r\n      border: 0.08rem solid var(--elecrest-model-accent);\r\n      border-radius: 50%;\r\n      background: #020711;\r\n      box-shadow: 0 0 0.55rem rgba(0, 231, 239, 0.36);\r\n      transform: translate(-50%, -50%);\r\n      will-change: left, top;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit-marker::after {\r\n      content: \"\";\r\n      position: absolute;\r\n      inset: 50% auto auto 50%;\r\n      width: 0.22rem;\r\n      height: 0.22rem;\r\n      border-radius: 50%;\r\n      background: var(--elecrest-model-accent);\r\n      transform: translate(-50%, -50%);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__status {\r\n      position: absolute;\r\n      inset: 0 0 var(--elecrest-model-orbit-extension) 0;\r\n      z-index: 4;\r\n      display: flex;\r\n      flex-direction: column;\r\n      align-items: center;\r\n      justify-content: center;\r\n      gap: 0.9rem;\r\n      padding: 2rem;\r\n      background: rgba(0, 0, 0, 0.26);\r\n      color: var(--elecrest-model-text-dim);\r\n      font-size: 0.82rem;\r\n      line-height: 1.4;\r\n      text-align: center;\r\n      opacity: 0;\r\n      visibility: hidden;\r\n      pointer-events: none;\r\n      transition:\r\n        opacity var(--elecrest-model-copy-duration) ease,\r\n        visibility 0s linear var(--elecrest-model-copy-duration);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase.is-loading .elecrest-model-showcase__status,\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase.has-error .elecrest-model-showcase__status {\r\n      opacity: 1;\r\n      visibility: visible;\r\n      transition-delay: 0s;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase.has-error .elecrest-model-showcase__status {\r\n      pointer-events: auto;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__status-mark {\r\n      width: 1rem;\r\n      height: 1rem;\r\n      border: 0.1rem solid rgba(255, 255, 255, 0.18);\r\n      border-top-color: var(--elecrest-model-accent);\r\n      border-radius: 50%;\r\n      animation: elecrest-model-status-spin 0.9s linear infinite;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase.has-error .elecrest-model-showcase__status-mark {\r\n      animation: none;\r\n      border-color: var(--elecrest-model-text-muted);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__retry {\r\n      appearance: none;\r\n      -webkit-appearance: none;\r\n      display: none;\r\n      min-width: 5rem;\r\n      min-height: 2rem;\r\n      border: 0.08rem solid var(--elecrest-model-text-dim);\r\n      border-radius: 0;\r\n      padding: 0.45rem 0.9rem;\r\n      background: transparent;\r\n      box-shadow: none;\r\n      color: var(--elecrest-model-text);\r\n      font: inherit;\r\n      font-size: 0.72rem;\r\n      cursor: pointer;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase.has-error .elecrest-model-showcase__retry {\r\n      display: inline-flex;\r\n      align-items: center;\r\n      justify-content: center;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__caption {\r\n      display: flex;\r\n      align-items: center;\r\n      justify-content: center;\r\n      gap: 0.45rem;\r\n      margin: 1.35rem 0 0;\r\n      color: var(--elecrest-model-text-muted);\r\n      font-size: 0.76rem;\r\n      line-height: 1.35;\r\n      text-align: center;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__angle {\r\n      color: var(--elecrest-model-accent);\r\n      font-variant-numeric: tabular-nums;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__copy {\r\n      grid-column: 2;\r\n      grid-row: 2;\r\n      align-self: start;\r\n      min-width: 0;\r\n      margin-top: 12.5rem;\r\n      opacity: 1;\r\n      transform: translateY(0);\r\n      transition:\r\n        opacity var(--elecrest-model-copy-duration) ease,\r\n        transform var(--elecrest-model-copy-duration) ease;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__copy.is-changing {\r\n      opacity: 0;\r\n      transform: translateY(0.4rem);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__description-row {\r\n      position: relative;\r\n      display: block;\r\n      width: 100%;\r\n      min-width: 0;\r\n      padding-right: 3.5rem;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__description-row .elecrest-model-showcase__arrow {\r\n      position: absolute;\r\n      top: 50%;\r\n      transform: translateY(-50%);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__description-row .elecrest-model-showcase__arrow--previous {\r\n      left: -3.5rem;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__description-row .elecrest-model-showcase__arrow--next {\r\n      right: 0.2rem;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__description-row .elecrest-model-showcase__arrow--previous:hover {\r\n      transform: translate(-0.2rem, -50%);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__description-row .elecrest-model-showcase__arrow--next:hover {\r\n      transform: translate(0.2rem, -50%);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__description {\r\n      width: 100%;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__description {\r\n      min-height: 4.9rem;\r\n      margin: 0;\r\n      color: var(--elecrest-model-text-dim);\r\n      font-size: 1.2rem;\r\n      font-weight: 300;\r\n      line-height: 1.5em;\r\n      text-transform: none;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__arrow {\r\n      appearance: none;\r\n      -webkit-appearance: none;\r\n      display: inline-flex;\r\n      align-items: center;\r\n      justify-content: center;\r\n      width: 2.2rem;\r\n      height: 2.2rem;\r\n      min-width: 0;\r\n      min-height: 0;\r\n      margin: 0;\r\n      border: 0;\r\n      border-radius: 0;\r\n      padding: 0;\r\n      background: transparent;\r\n      box-shadow: none;\r\n      color: #a8adb8;\r\n      cursor: pointer;\r\n      transition:\r\n        color var(--elecrest-model-copy-duration) ease,\r\n        transform var(--elecrest-model-copy-duration) ease;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__arrow:hover {\r\n      color: var(--elecrest-model-accent);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__arrow--previous:hover {\r\n      transform: translateX(-0.2rem);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__arrow--next:hover {\r\n      transform: translateX(0.2rem);\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__arrow svg {\r\n      display: block;\r\n      width: 0.85rem;\r\n      height: 1.45rem;\r\n      fill: none;\r\n      stroke: currentColor;\r\n      stroke-linecap: round;\r\n      stroke-linejoin: round;\r\n      stroke-width: 1;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__actions {\r\n      display: flex;\r\n      gap: 0.85rem;\r\n      width: 25.85rem;\r\n      max-width: 100%;\r\n      margin-top: 2.55rem;\r\n      padding: 0;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__action {\r\n      appearance: none;\r\n      -webkit-appearance: none;\r\n      display: inline-flex;\r\n      flex: 0 0 12.5rem;\r\n      align-items: center;\r\n      justify-content: center;\r\n      width: 12.5rem;\r\n      min-width: 12.5rem;\r\n      max-width: 12.5rem;\r\n      min-height: 0;\r\n      border: 0.06rem solid #ffffff;\r\n      border-radius: 0;\r\n      padding: 1rem 0;\r\n      background: #ffffff;\r\n      box-shadow: none;\r\n      color: #101114;\r\n      font-size: 0.83rem;\r\n      font-weight: 600;\r\n      line-height: 1;\r\n      text-align: center;\r\n      text-decoration: none;\r\n      text-transform: none;\r\n      transition:\r\n        background-color var(--elecrest-model-copy-duration) ease,\r\n        border-color var(--elecrest-model-copy-duration) ease,\r\n        color var(--elecrest-model-copy-duration) ease;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__action--primary {\r\n      border-color: var(--elecrest-model-accent);\r\n      background: var(--elecrest-model-accent);\r\n      color: #001315;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__action--primary:hover {\r\n      border-color: #00c7cc;\r\n      background: #00c7cc;\r\n      color: #001315;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__action:not(.elecrest-model-showcase__action--primary):hover {\r\n      border-color: #DBDBDB;\r\n      background: #DBDBDB;\r\n      color: #101114;\r\n    }\r\n\r\n    #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__accessible-label {\r\n      position: absolute;\r\n      width: 0.1rem;\r\n      height: 0.1rem;\r\n      overflow: hidden;\r\n      clip: rect(0 0 0 0);\r\n      clip-path: inset(50%);\r\n      white-space: nowrap;\r\n    }\r\n\r\n    @keyframes elecrest-model-status-spin {\r\n      to {\r\n        transform: rotate(360deg);\r\n      }\r\n    }\r\n\r\n    @media (max-width: 767px) {\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase {\r\n        --elecrest-model-visual-height: 90rem;\r\n        --elecrest-model-orbit-extension: 6.2rem;\r\n        display: grid;\r\n        grid-template-columns: minmax(0, 1fr);\r\n        grid-template-rows: auto auto auto auto;\r\n        grid-template-areas:\r\n          \"heading\"\r\n          \"selector\"\r\n          \"figure\"\r\n          \"copy\";\r\n        width: 100%;\r\n        min-height: 100vh;\r\n        padding: 3.4rem 5.2rem 6rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__heading {\r\n        grid-area: heading;\r\n        margin: 0 auto;\r\n        font-size: 5.9rem;\r\n        line-height: 1.16;\r\n        text-align: center;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__heading.is-changing {\r\n        transform: translateY(1.2rem);\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__selector {\r\n        grid-area: selector;\r\n        justify-content: center;\r\n        gap: 8.2rem;\r\n        width: 100%;\r\n        margin-top: 7.2rem;\r\n        padding: 0;\r\n        scroll-padding-inline: 5rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__product-button {\r\n        border-bottom-width: 0.2rem;\r\n        padding: 1rem 0;\r\n        font-size: 3rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__figure {\r\n        grid-area: figure;\r\n        width: 100%;\r\n        margin: 4.2rem auto 0;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__media-frame {\r\n        height: calc(var(--elecrest-model-visual-height) + var(--elecrest-model-orbit-extension));\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit {\r\n        bottom: 2.2rem;\r\n        width: 78rem;\r\n        height: 9.4rem;\r\n        border-width: 0.14rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit-marker-stage {\r\n        bottom: 2.2rem;\r\n        width: 78rem;\r\n        height: 9.4rem;\r\n        margin-left: -39rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit-occluder {\r\n        bottom: 2.2rem;\r\n        width: 48rem;\r\n        height: 9.4rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit-marker {\r\n        width: 2.5rem;\r\n        height: 2.5rem;\r\n        border-width: 0.24rem;\r\n        box-shadow: 0 0 1.5rem rgba(0, 231, 239, 0.4);\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__orbit-marker::after {\r\n        width: 0.8rem;\r\n        height: 0.8rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__status {\r\n        gap: 2.4rem;\r\n        padding: 6rem;\r\n        font-size: 3rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__status-mark {\r\n        width: 3.4rem;\r\n        height: 3.4rem;\r\n        border-width: 0.3rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__retry {\r\n        min-width: 18rem;\r\n        min-height: 7rem;\r\n        border-width: 0.2rem;\r\n        padding: 1.6rem 3rem;\r\n        font-size: 3.7209rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__caption {\r\n        gap: 1.6rem;\r\n        margin-top: 2.5rem;\r\n        font-size: 2.9rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__copy {\r\n        grid-area: copy;\r\n        margin-top: 10rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__copy.is-changing {\r\n        transform: translateY(1.2rem);\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__description-row {\r\n        position: static;\r\n        display: grid;\r\n        grid-template-columns: 6rem minmax(0, 1fr) 6rem;\r\n        align-items: center;\r\n        gap: 2rem;\r\n        padding-right: 0;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__description-row .elecrest-model-showcase__arrow {\r\n        position: static;\r\n        transform: none;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__description-row .elecrest-model-showcase__arrow--previous:hover,\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__description-row .elecrest-model-showcase__arrow--next:hover {\r\n        transform: none;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__description {\r\n        min-height: 18rem;\r\n        font-size: 3.25rem;\r\n        line-height: 1.36;\r\n        text-align: center;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__arrow {\r\n        width: 6rem;\r\n        height: 8rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__arrow--previous:hover,\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__arrow--next:hover {\r\n        transform: none;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__arrow svg {\r\n        width: 2.5rem;\r\n        height: 4.4rem;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__actions {\r\n        width: 100%;\r\n        gap: 5.2rem;\r\n        margin-top: 5.2rem;\r\n        padding: 0;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__action {\r\n        flex: 1 1 0;\r\n        width: auto;\r\n        min-width: 0;\r\n        max-width: none;\r\n        min-height: 8.2rem;\r\n        border-width: 0.2rem;\r\n        padding: 1.8rem 2rem;\r\n        font-size: 3.7209rem;\r\n      }\r\n    }\r\n\r\n    @media (prefers-reduced-motion: reduce) {\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__video,\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__status,\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__copy,\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__product-button,\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__arrow,\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__action {\r\n        transition-duration: 0s;\r\n      }\r\n\r\n      #elecrest-product-model-showcase.elecrest-model-showcase-host .elecrest-model-showcase__status-mark {\r\n        animation: none;\r\n      }\r\n    }\r\n  <\/style>\r\n\r\n  <section class=\"elecrest-model-showcase is-loading\" aria-labelledby=\"elecrest-model-showcase-heading\">\r\n    <h2 class=\"elecrest-model-showcase__heading\" id=\"elecrest-model-showcase-heading\">One platform for every charging scenario<\/h2>\r\n\r\n    <div class=\"elecrest-model-showcase__selector\" role=\"group\" aria-label=\"Select product model\"><\/div>\r\n\r\n    <figure class=\"elecrest-model-showcase__figure\">\r\n      <div class=\"elecrest-model-showcase__media-frame\" role=\"slider\" tabindex=\"0\" aria-label=\"Rotate HIMA 480 model\" aria-valuemin=\"0\" aria-valuemax=\"359\" aria-valuenow=\"0\" aria-valuetext=\"0\u00b0 rotation\" aria-describedby=\"elecrest-model-showcase-drag-instruction\" aria-busy=\"true\">\r\n        <span class=\"elecrest-model-showcase__orbit elecrest-model-showcase__orbit--back\" aria-hidden=\"true\"><\/span>\r\n        <span class=\"elecrest-model-showcase__orbit-marker-stage\" aria-hidden=\"true\"><span class=\"elecrest-model-showcase__orbit-marker\"><\/span><\/span>\r\n        <span class=\"elecrest-model-showcase__orbit-occluder\" aria-hidden=\"true\"><\/span>\r\n        <video class=\"elecrest-model-showcase__video\" muted playsinline preload=\"none\" disablepictureinpicture disableremoteplayback controlslist=\"nodownload nofullscreen noremoteplayback noplaybackrate\" aria-hidden=\"true\"><\/video>\r\n        <video class=\"elecrest-model-showcase__video\" muted playsinline preload=\"none\" disablepictureinpicture disableremoteplayback controlslist=\"nodownload nofullscreen noremoteplayback noplaybackrate\" aria-hidden=\"true\"><\/video>\r\n        <span class=\"elecrest-model-showcase__accessible-label\">Rotating view of the HIMA 480<\/span>\r\n        <span class=\"elecrest-model-showcase__orbit elecrest-model-showcase__orbit--front\" aria-hidden=\"true\"><\/span>\r\n        <div class=\"elecrest-model-showcase__status\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\r\n          <span class=\"elecrest-model-showcase__status-mark\" aria-hidden=\"true\"><\/span>\r\n          <span class=\"elecrest-model-showcase__status-text\">Loading 360\u00b0 view\u2026<\/span>\r\n          <button class=\"elecrest-model-showcase__retry\" type=\"button\">Retry<\/button>\r\n        <\/div>\r\n      <\/div>\r\n      <figcaption class=\"elecrest-model-showcase__caption\"><span class=\"elecrest-model-showcase__caption-label\">360\u00b0 rotation view<\/span><span class=\"elecrest-model-showcase__angle\">0\u00b0<\/span><\/figcaption>\r\n      <span class=\"elecrest-model-showcase__accessible-label\" id=\"elecrest-model-showcase-drag-instruction\">Drag horizontally or use the arrow keys to rotate HIMA 480.<\/span>\r\n    <\/figure>\r\n\r\n    <div class=\"elecrest-model-showcase__copy\">\r\n      <div class=\"elecrest-model-showcase__description-row\">\r\n        <button class=\"elecrest-model-showcase__arrow elecrest-model-showcase__arrow--previous\" type=\"button\" aria-label=\"Previous product\">\r\n          <svg viewBox=\"0 0 12 22\" aria-hidden=\"true\"><path d=\"M10.5 1.5 1.5 11l9 9.5\"><\/path><\/svg>\r\n        <\/button>\r\n        <p class=\"elecrest-model-showcase__description\">Available in 240 kW, 360 kW and 480 kW configurations, with up to four charging connectors.<\/p>\r\n        <button class=\"elecrest-model-showcase__arrow elecrest-model-showcase__arrow--next\" type=\"button\" aria-label=\"Next product\">\r\n          <svg viewBox=\"0 0 12 22\" aria-hidden=\"true\"><path d=\"m1.5 1.5 9 9.5-9 9.5\"><\/path><\/svg>\r\n        <\/button>\r\n      <\/div>\r\n\r\n      <div class=\"elecrest-model-showcase__actions\">\r\n        <a class=\"elecrest-model-showcase__action elecrest-model-showcase__action--primary\" href=\"https:\/\/elecrest.energy\/hima480\/\">Learn more<\/a>\r\n        <a class=\"elecrest-model-showcase__action\" href=\"https:\/\/elecrest.energy\/configurator\/\">Configure<\/a>\r\n      <\/div>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <script>\r\n    (function () {\r\n      'use strict';\r\n\r\n      var currentScript = document.currentScript;\r\n      var host = currentScript ? currentScript.closest('.elecrest-model-showcase-host') : null;\r\n\r\n      if (!host || host.dataset.elecrestModelShowcaseReady === 'true') {\r\n        return;\r\n      }\r\n\r\n      var configElement = host.querySelector('.elecrest-model-showcase-config');\r\n      var root = host.querySelector('.elecrest-model-showcase');\r\n\r\n      if (!configElement || !root) {\r\n        return;\r\n      }\r\n\r\n      var config;\r\n\r\n      try {\r\n        config = JSON.parse(configElement.textContent);\r\n      } catch (error) {\r\n        root.classList.remove('is-loading');\r\n        root.classList.add('has-error');\r\n        return;\r\n      }\r\n\r\n      var products = (config.products || []).filter(function (product) {\r\n        return product && product.enabled !== false;\r\n      });\r\n\r\n      if (!products.length) {\r\n        root.classList.remove('is-loading');\r\n        root.classList.add('has-error');\r\n        return;\r\n      }\r\n\r\n      host.dataset.elecrestModelShowcaseReady = 'true';\r\n\r\n      var labels = config.labels || {};\r\n      var interaction = config.interaction || {};\r\n      var selector = root.querySelector('.elecrest-model-showcase__selector');\r\n      var heading = root.querySelector('.elecrest-model-showcase__heading');\r\n      var mediaFrame = root.querySelector('.elecrest-model-showcase__media-frame');\r\n      var videos = Array.prototype.slice.call(root.querySelectorAll('.elecrest-model-showcase__video'));\r\n      var accessibleLabel = root.querySelector('.elecrest-model-showcase__accessible-label');\r\n      var dragInstruction = root.querySelector('#elecrest-model-showcase-drag-instruction');\r\n      var captionLabel = root.querySelector('.elecrest-model-showcase__caption-label');\r\n      var angleElement = root.querySelector('.elecrest-model-showcase__angle');\r\n      var orbitMarkerStage = root.querySelector('.elecrest-model-showcase__orbit-marker-stage');\r\n      var orbitMarker = root.querySelector('.elecrest-model-showcase__orbit-marker');\r\n      var statusText = root.querySelector('.elecrest-model-showcase__status-text');\r\n      var retryButton = root.querySelector('.elecrest-model-showcase__retry');\r\n      var copy = root.querySelector('.elecrest-model-showcase__copy');\r\n      var description = root.querySelector('.elecrest-model-showcase__description');\r\n      var previousButton = root.querySelector('.elecrest-model-showcase__arrow--previous');\r\n      var nextButton = root.querySelector('.elecrest-model-showcase__arrow--next');\r\n      var learnMoreLink = root.querySelector('.elecrest-model-showcase__action--primary');\r\n      var configureLink = root.querySelector('.elecrest-model-showcase__action:not(.elecrest-model-showcase__action--primary)');\r\n      var mobileMedia = window.matchMedia('(max-width: 767px)');\r\n      var reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');\r\n      var buttonElements = [];\r\n      var activeVideo = videos[0];\r\n      var standbyVideo = videos[1];\r\n      var activeIndex = Math.max(0, products.findIndex(function (product) {\r\n        return product.id === config.defaultProduct;\r\n      }));\r\n      var pendingIndex = activeIndex;\r\n      var switchSequence = 0;\r\n      var switchStatusTimer = 0;\r\n      var hasStarted = false;\r\n      var idleHandle = 0;\r\n      var productAngles = {};\r\n      var currentAngle = 0;\r\n      var dragging = false;\r\n      var activePointerId = null;\r\n      var dragStartX = 0;\r\n      var dragStartAngle = 0;\r\n      var seekFrame = 0;\r\n      var pendingSeek = false;\r\n\r\n      if (\r\n        !selector || !heading || !mediaFrame || videos.length !== 2\r\n        || !accessibleLabel || !dragInstruction || !captionLabel || !angleElement\r\n        || !orbitMarkerStage || !orbitMarker || !statusText || !retryButton\r\n        || !copy || !description || !previousButton || !nextButton\r\n        || !learnMoreLink || !configureLink\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      var componentCount = Number(window.elecrestModelShowcaseCount || 0) + 1;\r\n      window.elecrestModelShowcaseCount = componentCount;\r\n      var panelId = 'elecrest-model-showcase-panel-' + componentCount;\r\n      var instructionId = 'elecrest-model-showcase-drag-instruction-' + componentCount;\r\n      mediaFrame.id = panelId;\r\n      dragInstruction.id = instructionId;\r\n      mediaFrame.setAttribute('aria-describedby', instructionId);\r\n\r\n      products.forEach(function (product) {\r\n        productAngles[product.id] = normaliseAngle(Number(product.initialAngle || 0));\r\n      });\r\n\r\n      function productSource(product) {\r\n        if (mobileMedia.matches && product.videoMobile) {\r\n          return product.videoMobile;\r\n        }\r\n\r\n        return product.videoDesktop || product.videoMobile || '';\r\n      }\r\n\r\n      function formatLabel(template, product, angle) {\r\n        return String(template || '')\r\n          .replace('{product}', product && product.name ? product.name : '')\r\n          .replace('{angle}', String(Math.round(Number(angle || 0))));\r\n      }\r\n\r\n      function normaliseAngle(angle) {\r\n        return ((Number(angle || 0) % 360) + 360) % 360;\r\n      }\r\n\r\n      function videoDuration(video) {\r\n        return video && Number.isFinite(video.duration) && video.duration > 0\r\n          ? video.duration\r\n          : 0;\r\n      }\r\n\r\n      function updateOrbitMarker(angle) {\r\n        var radians = (Math.PI \/ 2) + (normaliseAngle(angle) \/ 360) * Math.PI * 2;\r\n        var x = 50 + Math.cos(radians) * 50;\r\n        var y = 50 + Math.sin(radians) * 50;\r\n\r\n        orbitMarker.style.left = x.toFixed(3) + '%';\r\n        orbitMarker.style.top = y.toFixed(3) + '%';\r\n        var isBehind = Math.sin(radians) < 0;\r\n        var centralOcclusionHalfWidth = mobileMedia.matches ? 31 : 20;\r\n        orbitMarkerStage.classList.toggle('is-behind', isBehind);\r\n        orbitMarkerStage.classList.toggle(\r\n          'is-occluded',\r\n          isBehind && Math.abs(x - 50) < centralOcclusionHalfWidth\r\n        );\r\n      }\r\n\r\n      function updateRotationUI(angle) {\r\n        var product = products[activeIndex];\r\n        var roundedAngle = Math.round(normaliseAngle(angle)) % 360;\r\n        var valueText = formatLabel(labels.rotationValue || '{angle}\u00b0 rotation', product, roundedAngle);\r\n\r\n        angleElement.textContent = roundedAngle + '\u00b0';\r\n        mediaFrame.setAttribute('aria-valuenow', String(roundedAngle));\r\n        mediaFrame.setAttribute('aria-valuetext', valueText);\r\n        updateOrbitMarker(angle);\r\n      }\r\n\r\n      function targetTimeForAngle(video, angle) {\r\n        var length = videoDuration(video);\r\n        var reversedAngle = normaliseAngle(360 - normaliseAngle(angle));\r\n        return length > 0 ? (reversedAngle \/ 360) * length : 0;\r\n      }\r\n\r\n      function flushSeek() {\r\n        seekFrame = 0;\r\n\r\n        if (!activeVideo || activeVideo.dataset.loadState !== 'ready') {\r\n          return;\r\n        }\r\n\r\n        activeVideo.pause();\r\n        var nextTime = targetTimeForAngle(activeVideo, currentAngle);\r\n\r\n        if (activeVideo.seeking) {\r\n          pendingSeek = true;\r\n          return;\r\n        }\r\n\r\n        if (Math.abs(activeVideo.currentTime - nextTime) < 0.018) {\r\n          return;\r\n        }\r\n\r\n        try {\r\n          activeVideo.currentTime = nextTime;\r\n        } catch (error) {\r\n          \/* Metadata may not be ready during a source change. *\/\r\n        }\r\n      }\r\n\r\n      function scheduleSeek() {\r\n        if (!seekFrame) {\r\n          seekFrame = window.requestAnimationFrame(flushSeek);\r\n        }\r\n      }\r\n\r\n      function setAngle(nextAngle, immediate) {\r\n        currentAngle = normaliseAngle(nextAngle);\r\n        productAngles[products[activeIndex].id] = currentAngle;\r\n        updateRotationUI(currentAngle);\r\n\r\n        if (immediate) {\r\n          flushSeek();\r\n        } else {\r\n          scheduleSeek();\r\n        }\r\n      }\r\n\r\n      function seekVideoToAngle(video, angle) {\r\n        video.pause();\r\n        var targetTime = targetTimeForAngle(video, angle);\r\n\r\n        if (Math.abs(video.currentTime - targetTime) < 0.018) {\r\n          return Promise.resolve(video);\r\n        }\r\n\r\n        return new Promise(function (resolve) {\r\n          var settled = false;\r\n          var timeout = window.setTimeout(finish, 1600);\r\n\r\n          function cleanup() {\r\n            window.clearTimeout(timeout);\r\n            video.removeEventListener('seeked', finish);\r\n            video.removeEventListener('error', finish);\r\n          }\r\n\r\n          function finish() {\r\n            if (settled) {\r\n              return;\r\n            }\r\n\r\n            settled = true;\r\n            cleanup();\r\n            video.pause();\r\n            resolve(video);\r\n          }\r\n\r\n          video.addEventListener('seeked', finish);\r\n          video.addEventListener('error', finish);\r\n\r\n          try {\r\n            video.currentTime = targetTime;\r\n          } catch (error) {\r\n            finish();\r\n          }\r\n        });\r\n      }\r\n\r\n      function setStatus(message, isError) {\r\n        statusText.textContent = message || '';\r\n        root.classList.toggle('has-error', Boolean(isError));\r\n        root.classList.toggle('is-loading', !isError && Boolean(message));\r\n        mediaFrame.setAttribute('aria-busy', message && !isError ? 'true' : 'false');\r\n      }\r\n\r\n      function clearStatus() {\r\n        root.classList.remove('is-loading');\r\n        root.classList.remove('has-error');\r\n        mediaFrame.setAttribute('aria-busy', 'false');\r\n        statusText.textContent = '';\r\n      }\r\n\r\n      function beginProductSwitch(product, sequence) {\r\n        if (switchStatusTimer) {\r\n          window.clearTimeout(switchStatusTimer);\r\n        }\r\n\r\n        heading.classList.remove('is-changing');\r\n        copy.classList.remove('is-changing');\r\n        root.classList.add('is-switching');\r\n        clearStatus();\r\n        mediaFrame.setAttribute('aria-busy', 'true');\r\n        switchStatusTimer = window.setTimeout(function () {\r\n          if (sequence !== switchSequence || !root.classList.contains('is-switching')) {\r\n            return;\r\n          }\r\n\r\n          setStatus(formatLabel(labels.loadingProduct || labels.loading, product), false);\r\n        }, reducedMotion.matches ? 0 : 420);\r\n      }\r\n\r\n      function finishProductSwitch(sequence) {\r\n        if (sequence !== switchSequence) {\r\n          return;\r\n        }\r\n\r\n        if (switchStatusTimer) {\r\n          window.clearTimeout(switchStatusTimer);\r\n          switchStatusTimer = 0;\r\n        }\r\n\r\n        root.classList.remove('is-switching');\r\n        clearStatus();\r\n      }\r\n\r\n      function failProductSwitch(sequence) {\r\n        if (sequence !== switchSequence) {\r\n          return;\r\n        }\r\n\r\n        if (switchStatusTimer) {\r\n          window.clearTimeout(switchStatusTimer);\r\n          switchStatusTimer = 0;\r\n        }\r\n\r\n        heading.classList.remove('is-changing');\r\n        copy.classList.remove('is-changing');\r\n        root.classList.remove('is-switching');\r\n        setStatus(labels.unavailable || '360\u00b0 view unavailable.', true);\r\n      }\r\n\r\n      function setButtonStates(index, pending) {\r\n        buttonElements.forEach(function (button, buttonIndex) {\r\n          var isActive = buttonIndex === index;\r\n          var isPending = buttonIndex === pending && pending !== index;\r\n          button.setAttribute('aria-pressed', isActive ? 'true' : 'false');\r\n          button.classList.toggle('is-pending', isPending);\r\n        });\r\n      }\r\n\r\n      function updateProductContent(index) {\r\n        var product = products[index];\r\n\r\n        activeIndex = index;\r\n        pendingIndex = index;\r\n        root.dataset.activeProduct = product.id;\r\n        delete root.dataset.pendingProduct;\r\n        heading.textContent = product.heading || config.sectionHeading || '';\r\n        description.textContent = product.description || '';\r\n        learnMoreLink.textContent = labels.learnMore || 'Learn more';\r\n        learnMoreLink.href = product.learnMoreUrl || '#';\r\n        configureLink.textContent = labels.configure || 'Configure';\r\n        configureLink.href = product.configureUrl || '#';\r\n        captionLabel.textContent = product.caption || labels.caption || '';\r\n        accessibleLabel.textContent = product.videoAccessibleLabel || product.name || '';\r\n        dragInstruction.textContent = formatLabel(\r\n          labels.dragInstruction || 'Drag horizontally or use the arrow keys to rotate {product}.',\r\n          product\r\n        );\r\n        mediaFrame.setAttribute('aria-label', formatLabel(labels.rotateModel || 'Rotate {product} model', product));\r\n        currentAngle = productAngles[product.id];\r\n        updateRotationUI(currentAngle);\r\n        setButtonStates(index, index);\r\n\r\n        var activeButton = buttonElements[index];\r\n        if (activeButton) {\r\n          var buttonLeft = activeButton.offsetLeft;\r\n          var buttonRight = buttonLeft + activeButton.offsetWidth;\r\n          var visibleLeft = selector.scrollLeft;\r\n          var visibleRight = visibleLeft + selector.clientWidth;\r\n\r\n          if (buttonLeft < visibleLeft) {\r\n            selector.scrollTo({ left: buttonLeft, behavior: 'smooth' });\r\n          } else if (buttonRight > visibleRight) {\r\n            selector.scrollTo({ left: buttonRight - selector.clientWidth, behavior: 'smooth' });\r\n          }\r\n        }\r\n      }\r\n\r\n      function renderProductButtons() {\r\n        selector.textContent = '';\r\n        selector.setAttribute('aria-label', labels.productSelector || 'Select product model');\r\n\r\n        products.forEach(function (product, index) {\r\n          var button = document.createElement('button');\r\n          button.type = 'button';\r\n          button.className = 'elecrest-model-showcase__product-button';\r\n          button.textContent = product.name;\r\n          button.setAttribute('aria-controls', panelId);\r\n          button.setAttribute('aria-pressed', index === activeIndex ? 'true' : 'false');\r\n          button.addEventListener('click', function () {\r\n            activateProduct(index);\r\n          });\r\n          button.addEventListener('keydown', function (event) {\r\n            var targetIndex = index;\r\n\r\n            if (event.key === 'ArrowLeft') {\r\n              targetIndex = (index - 1 + products.length) % products.length;\r\n            } else if (event.key === 'ArrowRight') {\r\n              targetIndex = (index + 1) % products.length;\r\n            } else if (event.key === 'Home') {\r\n              targetIndex = 0;\r\n            } else if (event.key === 'End') {\r\n              targetIndex = products.length - 1;\r\n            } else {\r\n              return;\r\n            }\r\n\r\n            event.preventDefault();\r\n            buttonElements[targetIndex].focus();\r\n            activateProduct(targetIndex);\r\n          });\r\n          selector.appendChild(button);\r\n          buttonElements.push(button);\r\n        });\r\n      }\r\n\r\n      function clearVideoLoad(video) {\r\n        video.dataset.loadToken = String(Number(video.dataset.loadToken || 0) + 1);\r\n        video.removeAttribute('data-load-state');\r\n        video.elecrestReadyPromise = null;\r\n      }\r\n\r\n      function prepareVideo(video, product) {\r\n        var source = productSource(product);\r\n\r\n        if (!source) {\r\n          return Promise.reject(new Error('Missing video source'));\r\n        }\r\n\r\n        if (\r\n          video.dataset.productId === product.id\r\n          && video.dataset.source === source\r\n          && video.dataset.loadState === 'ready'\r\n          && video.readyState >= 2\r\n        ) {\r\n          return Promise.resolve(video);\r\n        }\r\n\r\n        if (\r\n          video.dataset.productId === product.id\r\n          && video.dataset.source === source\r\n          && video.dataset.loadState === 'loading'\r\n          && video.elecrestReadyPromise\r\n        ) {\r\n          return video.elecrestReadyPromise;\r\n        }\r\n\r\n        clearVideoLoad(video);\r\n        var token = Number(video.dataset.loadToken || 0);\r\n        video.pause();\r\n        video.classList.remove('is-visible');\r\n        video.classList.remove('is-entering');\r\n        video.dataset.productId = product.id;\r\n        video.dataset.source = source;\r\n        video.dataset.loadState = 'loading';\r\n        video.preload = 'auto';\r\n\r\n        if (product.poster) {\r\n          video.poster = product.poster;\r\n        } else {\r\n          video.removeAttribute('poster');\r\n        }\r\n\r\n        video.src = source;\r\n\r\n        video.elecrestReadyPromise = new Promise(function (resolve, reject) {\r\n          var timeout = window.setTimeout(function () {\r\n            finish(new Error('Video loading timed out'));\r\n          }, 25000);\r\n\r\n          function cleanup() {\r\n            window.clearTimeout(timeout);\r\n            video.removeEventListener('canplay', handleReady);\r\n            video.removeEventListener('error', handleError);\r\n          }\r\n\r\n          function finish(error) {\r\n            if (Number(video.dataset.loadToken || 0) !== token) {\r\n              cleanup();\r\n              return;\r\n            }\r\n\r\n            cleanup();\r\n\r\n            if (error) {\r\n              video.dataset.loadState = 'error';\r\n              video.elecrestReadyPromise = null;\r\n              reject(error);\r\n              return;\r\n            }\r\n\r\n            video.dataset.loadState = 'ready';\r\n            resolve(video);\r\n          }\r\n\r\n          function handleReady() {\r\n            finish(null);\r\n          }\r\n\r\n          function handleError() {\r\n            finish(new Error('Video could not be loaded'));\r\n          }\r\n\r\n          video.addEventListener('canplay', handleReady);\r\n          video.addEventListener('error', handleError);\r\n          video.load();\r\n\r\n          if (video.readyState >= 3) {\r\n            handleReady();\r\n          }\r\n        });\r\n\r\n        return video.elecrestReadyPromise;\r\n      }\r\n\r\n      function pauseAllVideos() {\r\n        videos.forEach(function (video) {\r\n          video.pause();\r\n        });\r\n      }\r\n\r\n      function connectionAllowsPreload() {\r\n        var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;\r\n\r\n        if (!connection) {\r\n          return true;\r\n        }\r\n\r\n        return !connection.saveData\r\n          && connection.effectiveType !== 'slow-2g'\r\n          && connection.effectiveType !== '2g';\r\n      }\r\n\r\n      function cancelIdlePreload() {\r\n        if (!idleHandle) {\r\n          return;\r\n        }\r\n\r\n        if ('cancelIdleCallback' in window) {\r\n          window.cancelIdleCallback(idleHandle);\r\n        } else {\r\n          window.clearTimeout(idleHandle);\r\n        }\r\n\r\n        idleHandle = 0;\r\n      }\r\n\r\n      function scheduleNextPreload() {\r\n        cancelIdlePreload();\r\n\r\n        if (products.length < 2 || !connectionAllowsPreload()) {\r\n          return;\r\n        }\r\n\r\n        var preload = function () {\r\n          idleHandle = 0;\r\n          var nextIndex = (activeIndex + 1) % products.length;\r\n\r\n          if (nextIndex === activeIndex) {\r\n            return;\r\n          }\r\n\r\n          prepareVideo(standbyVideo, products[nextIndex]).catch(function () {\r\n            \/* A background preload failure is surfaced only if the user selects it. *\/\r\n          });\r\n        };\r\n\r\n        if ('requestIdleCallback' in window) {\r\n          idleHandle = window.requestIdleCallback(preload, { timeout: 2200 });\r\n        } else {\r\n          idleHandle = window.setTimeout(preload, 1400);\r\n        }\r\n      }\r\n\r\n      function finishVideoSwap(targetVideo, previousVideo, sequence) {\r\n        if (sequence !== switchSequence) {\r\n          return;\r\n        }\r\n\r\n        targetVideo.classList.add('is-entering');\r\n        targetVideo.classList.add('is-visible');\r\n        previousVideo.classList.remove('is-visible');\r\n        activeVideo = targetVideo;\r\n        standbyVideo = previousVideo;\r\n        activeVideo.pause();\r\n\r\n        window.setTimeout(function () {\r\n          if (sequence !== switchSequence) {\r\n            return;\r\n          }\r\n\r\n          previousVideo.pause();\r\n          targetVideo.classList.remove('is-entering');\r\n          scheduleNextPreload();\r\n        }, reducedMotion.matches ? 0 : 380);\r\n      }\r\n\r\n      function commitProduct(index, targetVideo, sequence) {\r\n        var previousVideo = activeVideo;\r\n        heading.classList.add('is-changing');\r\n        copy.classList.add('is-changing');\r\n\r\n        window.setTimeout(function () {\r\n          if (sequence !== switchSequence) {\r\n            return;\r\n          }\r\n\r\n          updateProductContent(index);\r\n          finishProductSwitch(sequence);\r\n          finishVideoSwap(targetVideo, previousVideo, sequence);\r\n\r\n          window.requestAnimationFrame(function () {\r\n            heading.classList.remove('is-changing');\r\n            copy.classList.remove('is-changing');\r\n          });\r\n        }, reducedMotion.matches ? 0 : 200);\r\n      }\r\n\r\n      function activateProduct(index, forceReload) {\r\n        if (index < 0 || index >= products.length) {\r\n          return;\r\n        }\r\n\r\n        if (!hasStarted) {\r\n          activeIndex = index;\r\n          pendingIndex = index;\r\n          updateProductContent(index);\r\n          startInitialVideo();\r\n          return;\r\n        }\r\n\r\n        if (index === activeIndex && !forceReload) {\r\n          activeVideo.pause();\r\n          setAngle(productAngles[products[index].id], true);\r\n          return;\r\n        }\r\n\r\n        var product = products[index];\r\n        var targetVideo = standbyVideo;\r\n        var sequence = switchSequence + 1;\r\n        switchSequence = sequence;\r\n        pendingIndex = index;\r\n        root.dataset.pendingProduct = product.id;\r\n        setButtonStates(activeIndex, index);\r\n        beginProductSwitch(product, sequence);\r\n\r\n        prepareVideo(targetVideo, product).then(function () {\r\n          if (sequence !== switchSequence) {\r\n            return Promise.reject(new Error('Superseded product switch'));\r\n          }\r\n\r\n          return seekVideoToAngle(targetVideo, productAngles[product.id]);\r\n        }).then(function () {\r\n          if (sequence !== switchSequence) {\r\n            return;\r\n          }\r\n\r\n          commitProduct(index, targetVideo, sequence);\r\n        }).catch(function () {\r\n          if (sequence !== switchSequence) {\r\n            return;\r\n          }\r\n\r\n          pendingIndex = index;\r\n          setButtonStates(activeIndex, index);\r\n          failProductSwitch(sequence);\r\n        });\r\n      }\r\n\r\n      function startInitialVideo() {\r\n        if (hasStarted) {\r\n          return;\r\n        }\r\n\r\n        hasStarted = true;\r\n        var sequence = switchSequence + 1;\r\n        switchSequence = sequence;\r\n        var product = products[activeIndex];\r\n        setStatus(formatLabel(labels.loadingProduct || labels.loading, product), false);\r\n\r\n        prepareVideo(activeVideo, product).then(function () {\r\n          if (sequence !== switchSequence) {\r\n            return Promise.reject(new Error('Superseded initial load'));\r\n          }\r\n\r\n          return seekVideoToAngle(activeVideo, productAngles[product.id]);\r\n        }).then(function () {\r\n          if (sequence !== switchSequence) {\r\n            return;\r\n          }\r\n\r\n          activeVideo.classList.add('is-visible');\r\n          root.classList.add('is-ready');\r\n          updateProductContent(activeIndex);\r\n          clearStatus();\r\n          activeVideo.pause();\r\n          setAngle(productAngles[product.id], true);\r\n          scheduleNextPreload();\r\n        }).catch(function () {\r\n          if (sequence !== switchSequence) {\r\n            return;\r\n          }\r\n\r\n          setStatus(labels.unavailable || '360\u00b0 view unavailable.', true);\r\n        });\r\n      }\r\n\r\n      function beginDrag(event) {\r\n        if (event.pointerType === 'mouse' && event.button !== 0) {\r\n          return;\r\n        }\r\n\r\n        if (!hasStarted) {\r\n          startInitialVideo();\r\n        }\r\n\r\n        dragging = true;\r\n        activePointerId = event.pointerId;\r\n        dragStartX = event.clientX;\r\n        dragStartAngle = currentAngle;\r\n        mediaFrame.classList.add('is-dragging');\r\n\r\n        try {\r\n          mediaFrame.setPointerCapture(event.pointerId);\r\n        } catch (error) {\r\n          \/* Pointer capture is optional on older embedded browsers. *\/\r\n        }\r\n\r\n        if (event.pointerType === 'mouse') {\r\n          event.preventDefault();\r\n        }\r\n      }\r\n\r\n      function continueDrag(event) {\r\n        if (!dragging || event.pointerId !== activePointerId) {\r\n          return;\r\n        }\r\n\r\n        var frameWidth = Math.max(mediaFrame.getBoundingClientRect().width, 1);\r\n        var degreesPerFrameWidth = Number(interaction.degreesPerFrameWidth || 360);\r\n        var deltaX = event.clientX - dragStartX;\r\n        setAngle(dragStartAngle + (deltaX \/ frameWidth) * degreesPerFrameWidth, false);\r\n      }\r\n\r\n      function endDrag(event) {\r\n        if (!dragging || event.pointerId !== activePointerId) {\r\n          return;\r\n        }\r\n\r\n        dragging = false;\r\n        activePointerId = null;\r\n        mediaFrame.classList.remove('is-dragging');\r\n\r\n        try {\r\n          if (mediaFrame.hasPointerCapture(event.pointerId)) {\r\n            mediaFrame.releasePointerCapture(event.pointerId);\r\n          }\r\n        } catch (error) {\r\n          \/* The browser may already have released pointer capture. *\/\r\n        }\r\n\r\n        setAngle(currentAngle, true);\r\n      }\r\n\r\n      function handleRotationKeydown(event) {\r\n        var step = Number(interaction.keyboardStepDegrees || 5);\r\n\r\n        if (event.shiftKey) {\r\n          step *= 3;\r\n        }\r\n\r\n        if (event.key === 'ArrowLeft') {\r\n          setAngle(currentAngle - step, true);\r\n        } else if (event.key === 'ArrowRight') {\r\n          setAngle(currentAngle + step, true);\r\n        } else if (event.key === 'Home') {\r\n          setAngle(0, true);\r\n        } else if (event.key === 'End') {\r\n          setAngle(359, true);\r\n        } else {\r\n          return;\r\n        }\r\n\r\n        event.preventDefault();\r\n      }\r\n\r\n      videos.forEach(function (video) {\r\n        video.addEventListener('play', function () {\r\n          video.pause();\r\n        });\r\n        video.addEventListener('seeked', function () {\r\n          if (video === activeVideo && pendingSeek) {\r\n            pendingSeek = false;\r\n            scheduleSeek();\r\n          }\r\n        });\r\n      });\r\n\r\n      mediaFrame.setAttribute('aria-orientation', 'horizontal');\r\n      mediaFrame.addEventListener('pointerdown', beginDrag);\r\n      mediaFrame.addEventListener('pointermove', continueDrag);\r\n      mediaFrame.addEventListener('pointerup', endDrag);\r\n      mediaFrame.addEventListener('pointercancel', endDrag);\r\n      mediaFrame.addEventListener('keydown', handleRotationKeydown);\r\n      mediaFrame.addEventListener('contextmenu', function (event) {\r\n        event.preventDefault();\r\n      });\r\n\r\n      root.addEventListener('keydown', function () {\r\n        root.classList.add('is-keyboard-navigation');\r\n      }, true);\r\n\r\n      root.addEventListener('pointerdown', function () {\r\n        root.classList.remove('is-keyboard-navigation');\r\n      }, true);\r\n\r\n      previousButton.setAttribute('aria-label', labels.previousProduct || 'Previous product');\r\n      nextButton.setAttribute('aria-label', labels.nextProduct || 'Next product');\r\n      retryButton.textContent = labels.retry || 'Retry';\r\n\r\n      previousButton.addEventListener('click', function () {\r\n        activateProduct((activeIndex - 1 + products.length) % products.length);\r\n      });\r\n\r\n      nextButton.addEventListener('click', function () {\r\n        activateProduct((activeIndex + 1) % products.length);\r\n      });\r\n\r\n      retryButton.addEventListener('click', function () {\r\n        if (!hasStarted) {\r\n          startInitialVideo();\r\n          return;\r\n        }\r\n\r\n        clearVideoLoad(standbyVideo);\r\n        activateProduct(pendingIndex, true);\r\n      });\r\n\r\n      document.addEventListener('visibilitychange', pauseAllVideos);\r\n\r\n      if ('addEventListener' in reducedMotion) {\r\n        reducedMotion.addEventListener('change', pauseAllVideos);\r\n      } else {\r\n        reducedMotion.addListener(pauseAllVideos);\r\n      }\r\n\r\n      if ('addEventListener' in mobileMedia) {\r\n        mobileMedia.addEventListener('change', function () {\r\n          if (!hasStarted) {\r\n            return;\r\n          }\r\n\r\n          clearVideoLoad(standbyVideo);\r\n          activateProduct(activeIndex, true);\r\n        });\r\n      } else {\r\n        mobileMedia.addListener(function () {\r\n          if (!hasStarted) {\r\n            return;\r\n          }\r\n\r\n          clearVideoLoad(standbyVideo);\r\n          activateProduct(activeIndex, true);\r\n        });\r\n      }\r\n\r\n      renderProductButtons();\r\n      updateProductContent(activeIndex);\r\n\r\n      if ('IntersectionObserver' in window) {\r\n        var preloadObserver = new IntersectionObserver(function (entries) {\r\n          if (entries.some(function (entry) { return entry.isIntersecting; })) {\r\n            startInitialVideo();\r\n            preloadObserver.disconnect();\r\n          }\r\n        }, {\r\n          rootMargin: '640px 0px',\r\n          threshold: 0\r\n        });\r\n\r\n        preloadObserver.observe(root);\r\n      } else {\r\n        startInitialVideo();\r\n      }\r\n    }());\r\n  <\/script>\r\n<\/div>\r\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-fe8357e e-flex e-con-boxed e-con e-parent\" data-id=\"fe8357e\" 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<div class=\"elementor-element elementor-element-c89d799 e-con-full e-flex e-con e-child\" data-id=\"c89d799\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f0f40b8 elementor-widget__width-initial elementor-widget-mobile__width-initial elementor-widget elementor-widget-heading\" data-id=\"f0f40b8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Your partner in Europe<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e49b3f9 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"e49b3f9\" 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>Elecrest combines DC fast charging hardware, connected operations and energy management for commercial and industrial partners.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-86e9223 e-con-full e-flex e-con e-child\" data-id=\"86e9223\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8319c7c special elementor-widget elementor-widget-counter\" data-id=\"8319c7c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"counter.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-counter\">\n\t\t\t<div class=\"elementor-counter-title\">Developed in-house<\/div>\t\t\t<div class=\"elementor-counter-number-wrapper\">\n\t\t\t\t<span class=\"elementor-counter-number-prefix\"><\/span>\n\t\t\t\t<span class=\"elementor-counter-number\" data-duration=\"500\" data-to-value=\"100\" data-from-value=\"100\" data-delimiter=\",\">100<\/span>\n\t\t\t\t<span class=\"elementor-counter-number-suffix\">%<\/span>\n\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ba71b45 elementor-widget elementor-widget-counter\" data-id=\"ba71b45\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"counter.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-counter\">\n\t\t\t<div class=\"elementor-counter-title\">Patents across the platform<\/div>\t\t\t<div class=\"elementor-counter-number-wrapper\">\n\t\t\t\t<span class=\"elementor-counter-number-prefix\"><\/span>\n\t\t\t\t<span class=\"elementor-counter-number\" data-duration=\"500\" data-to-value=\"100\" data-from-value=\"100\" data-delimiter=\",\">100<\/span>\n\t\t\t\t<span class=\"elementor-counter-number-suffix\">+<\/span>\n\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b2c4e3a special elementor-widget elementor-widget-counter\" data-id=\"b2c4e3a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"counter.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-counter\">\n\t\t\t<div class=\"elementor-counter-title\">Dedicated R&amp;D heritage<\/div>\t\t\t<div class=\"elementor-counter-number-wrapper\">\n\t\t\t\t<span class=\"elementor-counter-number-prefix\"><\/span>\n\t\t\t\t<span class=\"elementor-counter-number\" data-duration=\"500\" data-to-value=\"7\" data-from-value=\"7\" data-delimiter=\",\">7<\/span>\n\t\t\t\t<span class=\"elementor-counter-number-suffix\">yrs<\/span>\n\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-46c176a elementor-widget elementor-widget-counter\" data-id=\"46c176a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"counter.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-counter\">\n\t\t\t<div class=\"elementor-counter-title\">DC Charging sites<\/div>\t\t\t<div class=\"elementor-counter-number-wrapper\">\n\t\t\t\t<span class=\"elementor-counter-number-prefix\"><\/span>\n\t\t\t\t<span class=\"elementor-counter-number\" data-duration=\"500\" data-to-value=\"600\" data-from-value=\"600\" data-delimiter=\",\">600<\/span>\n\t\t\t\t<span class=\"elementor-counter-number-suffix\">+<\/span>\n\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-7309f47 e-con-full e-flex e-con e-child\" data-id=\"7309f47\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<section class=\"elementor-element elementor-element-c871d14 core-tech  e-flex e-con-boxed e-con e-parent\" data-id=\"c871d14\" data-element_type=\"container\" data-e-type=\"container\" id=\"elecrest-pillars\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-544e8b2 e-con-full ep-copy e-flex e-con e-child\" data-id=\"544e8b2\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-539a272 elementor-widget__width-initial elementor-widget-mobile__width-initial elementor-widget elementor-widget-heading\" data-id=\"539a272\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Your competitive edge, Our core technology<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8dd6f8e elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"8dd6f8e\" 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>Lower total cost. Higher energy yield. Built-in risk protection.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-92eb495 e-con-full ep-viewport e-flex e-con e-child\" data-id=\"92eb495\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-1e69609 e-con-full ep-track e-flex e-con e-child\" data-id=\"1e69609\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e90454b elementor-widget__width-initial ep-slide elementor-widget elementor-widget-image\" data-id=\"e90454b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"800\" height=\"534\" src=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Outdoor-exposure-1024x683.webp\" class=\"attachment-large size-large wp-image-4743\" alt=\"Outdoor exposure\" srcset=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Outdoor-exposure-1024x683.webp 1024w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Outdoor-exposure-300x200.webp 300w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Outdoor-exposure-768x512.webp 768w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Outdoor-exposure-18x12.webp 18w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Outdoor-exposure.webp 1536w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6b4eb0c elementor-widget__width-initial ep-slide elementor-widget elementor-widget-image\" data-id=\"6b4eb0c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"800\" height=\"534\" src=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/On-site-repairs-1024x683.webp\" class=\"attachment-large size-large wp-image-4744\" alt=\"\" srcset=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/On-site-repairs-1024x683.webp 1024w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/On-site-repairs-300x200.webp 300w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/On-site-repairs-768x512.webp 768w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/On-site-repairs-18x12.webp 18w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/On-site-repairs.webp 1536w\" sizes=\"(max-width: 800px) 100vw, 800px\">\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ac02ffc elementor-widget__width-initial ep-slide elementor-widget elementor-widget-image\" data-id=\"ac02ffc\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"800\" height=\"534\" src=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Fault-visibility-1024x683.webp\" class=\"attachment-large size-large wp-image-4745\" alt=\"Fault visibility\" srcset=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Fault-visibility-1024x683.webp 1024w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Fault-visibility-300x200.webp 300w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Fault-visibility-768x512.webp 768w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Fault-visibility-18x12.webp 18w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Fault-visibility.webp 1536w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fdfa3e4 elementor-widget__width-initial ep-controller elementor-widget elementor-widget-html\" data-id=\"fdfa3e4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<style>\r\n\/* \u53ea\u63a7\u5236\u8f6e\u64ad\u8f68\u9053\u548c\u4ee3\u7801\u751f\u6210\u7684\u4e09\u4e2a\u6587\u5b57\u6309\u94ae\u3002\u5176\u4f59\u6837\u5f0f\u7531 Elementor \u8bbe\u7f6e\u3002 *\/\r\n#elecrest-pillars {\r\n  --ep-slide-duration: 480ms;\r\n  --ep-slide-ease: cubic-bezier(0.22, 0.61, 0.36, 1);\r\n  --ep-tab-accent: #00c7cc;\r\n  --ep-tab-text: #bcbcbc;\r\n  --ep-tab-line: #303238;\r\n  --ep-tab-size: 1.4rem;\r\n  --ep-tab-padding: 1rem;\r\n}\r\n\r\n#elecrest-pillars .ep-row {\r\n  transition: transform var(--ep-slide-duration) var(--ep-slide-ease);\r\n}\r\n#elecrest-pillars .ep-row.ep-jump {\r\n  transition: none;\r\n}\r\n#elecrest-pillars .ep-row.ep-moving {\r\n  will-change: transform;\r\n}\r\n#elecrest-pillars .ep-slide {\r\n  cursor: pointer;\r\n}\r\n#elecrest-pillars .ep-slide.is-current.ep-no-link {\r\n  cursor: default;\r\n}\r\n#elecrest-pillars .ep-slide a {\r\n  display: block;\r\n}\r\n#elecrest-pillars .ep-tabs {\r\n  display: flex;\r\n  align-items: stretch;\r\n  border-bottom: 1px solid var(--ep-tab-line);\r\n}\r\n#elecrest-pillars .ep-tabs .ep-tab {\r\n  box-sizing: border-box;\r\n  flex: 1 1 0;\r\n  min-width: 0;\r\n  margin: 0 0 -1px;\r\n  padding: var(--ep-tab-padding) 0;\r\n  border: 0;\r\n  border-bottom: 2px solid transparent;\r\n  border-radius: 0;\r\n  background: transparent;\r\n  box-shadow: none;\r\n  color: var(--ep-tab-text);\r\n  font-family: \"Noto Sans\", sans-serif;\r\n  font-size: var(--ep-tab-size);\r\n  font-weight: 500;\r\n  line-height: 1.5;\r\n  letter-spacing: normal;\r\n  text-transform: none;\r\n  white-space: normal;\r\n  text-align: center;\r\n  cursor: pointer;\r\n}\r\n#elecrest-pillars .ep-tabs .ep-tab.is-current {\r\n  color: var(--ep-tab-accent);\r\n  border-bottom-color: var(--ep-tab-accent);\r\n}\r\n@media (max-width: 767px) {\r\n  #elecrest-pillars {\r\n    --ep-tab-size: 2.8rem;\r\n    --ep-tab-padding: 3rem;\r\n  }\r\n}\r\n<\/style>\r\n\r\n<div class=\"ep-tabs\" role=\"group\" aria-label=\"Three pillars\">\r\n  <button class=\"ep-tab\" type=\"button\" aria-pressed=\"false\">Super Fast Charging<\/button>\r\n  <button class=\"ep-tab is-current\" type=\"button\" aria-pressed=\"true\">Super Durable<\/button>\r\n  <button class=\"ep-tab\" type=\"button\" aria-pressed=\"false\">Super Easy To Repair<\/button>\r\n<\/div>\r\n\r\n<script>\r\n\/* \u4ec5\u7528\u4e8e\u4e0b\u65b9\u7ed3\u6784\uff1a3 \u4e2a\u539f\u751f Image + 1 \u4e2a HTML\u3002\u56fe\u7247 URL\/\u94fe\u63a5\u7ee7\u7eed\u7531 Image \u7ba1\u7406\u3002 *\/\r\n(() => {\r\n  const ROOT_ID = 'elecrest-pillars';\r\n  const INITIAL_INDEX = 1; \/\/ 0 = Super Fast Charging\uff1b1 = Super Durable\uff1b2 = Super Easy To Repair\u3002\r\n\r\n  function init() {\r\n    const root = document.getElementById(ROOT_ID);\r\n    if (!root) return;\r\n    \/\/ \u7f16\u8f91\u753b\u5e03\u4e2d\u4fdd\u7559\u539f\u751f Widget\uff1b\u4ea4\u4e92\u5728\u72ec\u7acb\u7684\u524d\u53f0\u9884\u89c8\u4e2d\u8fd0\u884c\u3002\r\n    if (document.body.classList.contains('elementor-editor-active') ||\r\n        (window.elementorFrontend && typeof window.elementorFrontend.isEditMode === 'function' &&\r\n         window.elementorFrontend.isEditMode())) return;\r\n    if (typeof root.epPillarsDestroy === 'function') root.epPillarsDestroy();\r\n\r\n    const viewport = root.querySelector('.ep-viewport');\r\n    const track = root.querySelector('.ep-track');\r\n    const row = track && (track.querySelector(':scope > .e-con-inner') || track);\r\n    const tabs = Array.from(root.querySelectorAll('.ep-tabs .ep-tab'));\r\n    const originals = row && Array.from(row.children).filter(node => node.classList.contains('ep-slide'));\r\n    if (!viewport || !row || originals.length !== 3 || tabs.length !== 3) {\r\n      console.warn('Three Pillars\uff1a\u9700\u8981 ep-viewport\u3001ep-track\u30013 \u4e2a\u76f4\u63a5\u5b50\u7ea7 ep-slide \u548c 3 \u4e2a ep-tab\u3002');\r\n      return;\r\n    }\r\n\r\n    const count = originals.length;\r\n    let active = INITIAL_INDEX;\r\n    let physical = count + active;\r\n    let moving = false;\r\n    let queued = null;\r\n    let fallbackTimer = 0;\r\n    let disposed = false;\r\n    const originalAttributes = new Map();\r\n    originals.forEach((slide, index) => {\r\n      slide.dataset.epIndex = String(index);\r\n      [slide, ...slide.querySelectorAll('a')].forEach(node => {\r\n        originalAttributes.set(node, ['aria-hidden', 'tabindex'].map(name => [name, node.getAttribute(name)]));\r\n      });\r\n    });\r\n\r\n    function copySlide(slide, index) {\r\n      const clone = slide.cloneNode(true);\r\n      clone.dataset.epClone = 'true';\r\n      clone.dataset.epIndex = String(index);\r\n      clone.setAttribute('aria-hidden', 'true');\r\n      [clone, ...clone.querySelectorAll('*')].forEach(node => {\r\n        node.removeAttribute('id');\r\n        node.removeAttribute('data-id');\r\n        node.removeAttribute('data-element_type');\r\n        node.removeAttribute('data-widget_type');\r\n        node.removeAttribute('data-settings');\r\n        if (node.matches('a, button, input, select, textarea, [tabindex]')) node.setAttribute('tabindex', '-1');\r\n      });\r\n      return clone;\r\n    }\r\n\r\n    \/\/ \u4e34\u65f6\u955c\u50cf\u53ea\u5b58\u5728\u4e8e\u524d\u53f0 DOM\uff0c\u7528\u4e8e\u9996\u5c3e\u8fde\u7eed\u6ed1\u52a8\uff1bElementor \u4e2d\u4ecd\u53ea\u6709 3 \u4e2a Image\u3002\r\n    const before = document.createDocumentFragment();\r\n    const after = document.createDocumentFragment();\r\n    originals.forEach((slide, index) => {\r\n      before.append(copySlide(slide, index));\r\n      after.append(copySlide(slide, index));\r\n    });\r\n    row.prepend(before);\r\n    row.append(after);\r\n    row.classList.add('ep-row', 'ep-jump');\r\n    const cells = Array.from(row.children).filter(node => node.classList.contains('ep-slide'));\r\n\r\n    function usableLink(slide) {\r\n      const anchor = slide.querySelector('a[href]');\r\n      const href = anchor && anchor.getAttribute('href').trim();\r\n      return anchor && href && href !== '#' ? anchor : null;\r\n    }\r\n\r\n    function sync() {\r\n      root.dataset.epIndex = String(active);\r\n      tabs.forEach((tab, index) => {\r\n        tab.classList.toggle('is-current', index === active);\r\n        tab.setAttribute('aria-pressed', String(index === active));\r\n      });\r\n      cells.forEach(slide => {\r\n        const selected = Number(slide.dataset.epIndex) === active;\r\n        const clone = slide.dataset.epClone === 'true';\r\n        slide.classList.toggle('is-current', selected);\r\n        slide.classList.toggle('ep-no-link', !usableLink(slide));\r\n        slide.setAttribute('aria-hidden', String(clone || !selected));\r\n        slide.querySelectorAll('a').forEach(anchor => {\r\n          anchor.setAttribute('tabindex', !clone && selected && usableLink(slide) ? '0' : '-1');\r\n        });\r\n      });\r\n    }\r\n\r\n    function centreCell(position) {\r\n      const cell = cells[position];\r\n      const windowBox = viewport.getBoundingClientRect();\r\n      const cellBox = cell.getBoundingClientRect();\r\n      const transform = getComputedStyle(row).transform;\r\n      const currentX = transform === 'none' ? 0 : new DOMMatrixReadOnly(transform).m41;\r\n      const x = currentX + windowBox.left + windowBox.width \/ 2 - cellBox.left - cellBox.width \/ 2;\r\n      const rem = parseFloat(getComputedStyle(document.documentElement).fontSize);\r\n      row.style.transform = 'translate3d(' + (x \/ rem) + 'rem, 0, 0)';\r\n    }\r\n\r\n    function jump() {\r\n      row.classList.add('ep-jump');\r\n      physical = count + active;\r\n      centreCell(physical);\r\n      \/\/ \u53ea\u5728\u5207\u6362\/\u5c3a\u5bf8\u53d8\u5316\u65f6\u8bfb\u53d6\u5e03\u5c40\uff0c\u4e0d\u8fd0\u884c\u6301\u7eed\u7684\u9010\u5e27\u5faa\u73af\u3002\r\n      row.getBoundingClientRect();\r\n      row.classList.remove('ep-jump');\r\n    }\r\n\r\n    function finish() {\r\n      if (disposed || !moving) return;\r\n      clearTimeout(fallbackTimer);\r\n      moving = false;\r\n      row.classList.remove('ep-moving');\r\n      jump();\r\n      if (queued !== null) {\r\n        const target = queued;\r\n        queued = null;\r\n        select(target);\r\n      }\r\n    }\r\n\r\n    function select(index) {\r\n      if (index < 0 || index >= count) return;\r\n      if (moving) {\r\n        queued = index; \/\/ \u5feb\u901f\u8fde\u7eed\u70b9\u51fb\u4fdd\u7559\u6700\u540e\u4e00\u6b21\u9009\u62e9\u3002\r\n        return;\r\n      }\r\n      if (index === active) return;\r\n      const forward = (index - active + count) % count;\r\n      const step = forward <= count \/ 2 ? forward : forward - count;\r\n      physical += step;\r\n      active = index;\r\n      moving = true;\r\n      row.classList.add('ep-moving');\r\n      sync();\r\n      centreCell(physical);\r\n      const duration = getComputedStyle(row).transitionDuration.split(',').reduce((max, value) => {\r\n        const time = parseFloat(value) * (value.trim().endsWith('ms') ? 1 : 1000);\r\n        return Math.max(max, Number.isFinite(time) ? time : 0);\r\n      }, 0);\r\n      fallbackTimer = setTimeout(finish, duration + 80);\r\n    }\r\n\r\n    function onTabClick(event) {\r\n      const tab = event.target.closest('.ep-tab');\r\n      const index = tabs.indexOf(tab);\r\n      if (index >= 0) select(index);\r\n    }\r\n\r\n    function onImageClick(event) {\r\n      if (event.type === 'auxclick' && event.button !== 1) return;\r\n      const slide = event.target.closest('.ep-slide');\r\n      if (!slide || !row.contains(slide)) return;\r\n      const index = Number(slide.dataset.epIndex);\r\n      const current = index === active;\r\n      if (!current || moving || !usableLink(slide)) {\r\n        event.preventDefault();\r\n        event.stopImmediatePropagation();\r\n        if (!current) select(index);\r\n      }\r\n      \/\/ \u5f53\u524d\u56fe\u4fdd\u7559 Image \u539f\u751f <a> \u884c\u4e3a\uff0c\u5305\u62ec\u76ee\u6807\u7a97\u53e3\u548c\u4fee\u9970\u952e\u3002\r\n    }\r\n\r\n    function onTransitionEnd(event) {\r\n      if (event.target === row && event.propertyName === 'transform') finish();\r\n    }\r\n\r\n    function onResize() {\r\n      clearTimeout(fallbackTimer);\r\n      moving = false;\r\n      row.classList.remove('ep-moving');\r\n      if (queued !== null) {\r\n        active = queued;\r\n        queued = null;\r\n        sync();\r\n      }\r\n      jump();\r\n    }\r\n\r\n    const nav = root.querySelector('.ep-tabs');\r\n    nav.addEventListener('click', onTabClick);\r\n    viewport.addEventListener('click', onImageClick, true);\r\n    viewport.addEventListener('auxclick', onImageClick, true);\r\n    row.addEventListener('transitionend', onTransitionEnd);\r\n    const observer = new ResizeObserver(onResize);\r\n    sync();\r\n    jump();\r\n    observer.observe(viewport);\r\n\r\n    root.epPillarsDestroy = () => {\r\n      disposed = true;\r\n      clearTimeout(fallbackTimer);\r\n      observer.disconnect();\r\n      nav.removeEventListener('click', onTabClick);\r\n      viewport.removeEventListener('click', onImageClick, true);\r\n      viewport.removeEventListener('auxclick', onImageClick, true);\r\n      row.removeEventListener('transitionend', onTransitionEnd);\r\n      cells.filter(node => node.dataset.epClone === 'true').forEach(node => node.remove());\r\n      row.classList.remove('ep-row', 'ep-jump', 'ep-moving');\r\n      row.style.removeProperty('transform');\r\n      originals.forEach(slide => {\r\n        delete slide.dataset.epIndex;\r\n        slide.classList.remove('is-current', 'ep-no-link');\r\n      });\r\n      originalAttributes.forEach((attributes, node) => attributes.forEach(([name, value]) => {\r\n        if (value === null) node.removeAttribute(name);\r\n        else node.setAttribute(name, value);\r\n      }));\r\n      delete root.dataset.epIndex;\r\n      delete root.epPillarsDestroy;\r\n    };\r\n  }\r\n\r\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init, { once: true });\r\n  else init();\r\n})();\r\n<\/script>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-a392ca4 e-con-full core-tech-track elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile e-flex e-con e-child\" data-id=\"a392ca4\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-5efc1c9 e-con-full core-tech-card e-flex e-con e-child\" data-id=\"5efc1c9\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\" tabindex=\"0\">\n\t\t<div class=\"elementor-element elementor-element-eb0e40e e-con-full core-tech-card__media e-flex e-con e-child\" data-id=\"eb0e40e\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;position&quot;:&quot;absolute&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6703738 core-tech-card__image elementor-widget elementor-widget-image\" data-id=\"6703738\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"846\" src=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/01-Isolated-airflow-cooling-module-968x1024.webp\" class=\"attachment-large size-large wp-image-4691\" alt=\"01-Isolated airflow cooling module\" srcset=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/01-Isolated-airflow-cooling-module-968x1024.webp 968w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/01-Isolated-airflow-cooling-module-284x300.webp 284w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/01-Isolated-airflow-cooling-module-768x813.webp 768w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/01-Isolated-airflow-cooling-module-1452x1536.webp 1452w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/01-Isolated-airflow-cooling-module-11x12.webp 11w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/01-Isolated-airflow-cooling-module.webp 1500w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-3755367 e-con-full core-tech-card__content e-flex e-con e-child\" data-id=\"3755367\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;position&quot;:&quot;absolute&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-30263e1 core-tech-card__title elementor-widget elementor-widget-heading\" data-id=\"30263e1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Super Durable<\/h3>\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-85e0b02 e-con-full core-tech-card__hover-text e-flex e-con e-child\" data-id=\"85e0b02\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5e8d0ea core-tech-card__description elementor-widget elementor-widget-text-editor\" data-id=\"5e8d0ea\" 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>Sensitive electronics are separated from external airflow, while a dedicated cooling path removes heat from the power modules and reduces exposure to dust, salt mist and moisture.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-5455e70 e-con-full core-tech-card e-flex e-con e-child\" data-id=\"5455e70\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\" tabindex=\"0\">\n\t\t<div class=\"elementor-element elementor-element-54c5ab2 e-con-full core-tech-card__media e-flex e-con e-child\" data-id=\"54c5ab2\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;position&quot;:&quot;absolute&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-66e4212 core-tech-card__image elementor-widget elementor-widget-image\" data-id=\"66e4212\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"846\" src=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/02-3-Box-Plug-in-Architecture-968x1024.webp\" class=\"attachment-large size-large wp-image-4692\" alt=\"02-3-Box Plug-in Architecture\" srcset=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/02-3-Box-Plug-in-Architecture-968x1024.webp 968w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/02-3-Box-Plug-in-Architecture-284x300.webp 284w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/02-3-Box-Plug-in-Architecture-768x813.webp 768w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/02-3-Box-Plug-in-Architecture-1452x1536.webp 1452w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/02-3-Box-Plug-in-Architecture-11x12.webp 11w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/02-3-Box-Plug-in-Architecture.webp 1500w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-65757c3 e-con-full core-tech-card__content e-flex e-con e-child\" data-id=\"65757c3\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;position&quot;:&quot;absolute&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4ecafe3 core-tech-card__title elementor-widget elementor-widget-heading\" data-id=\"4ecafe3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Super Easy To Repair<\/h3>\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-ee6abf5 e-con-full core-tech-card__hover-text e-flex e-con e-child\" data-id=\"ee6abf5\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1221c33 core-tech-card__description elementor-widget elementor-widget-text-editor\" data-id=\"1221c33\" 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>Power, control and communication functions are physically separated. Pluggable modules support faster fault isolation and module replacement.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1d75e9e e-con-full core-tech-card e-flex e-con e-child\" data-id=\"1d75e9e\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\" tabindex=\"0\">\n\t\t<div class=\"elementor-element elementor-element-d238834 e-con-full core-tech-card__media e-flex e-con e-child\" data-id=\"d238834\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;position&quot;:&quot;absolute&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-a70c3c3 core-tech-card__image elementor-widget elementor-widget-image\" data-id=\"a70c3c3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"846\" src=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/03-Ai-operations-maintenance-968x1024.webp\" class=\"attachment-large size-large wp-image-4690\" alt=\"03-Ai operations &amp; maintenance\" srcset=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/03-Ai-operations-maintenance-968x1024.webp 968w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/03-Ai-operations-maintenance-284x300.webp 284w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/03-Ai-operations-maintenance-768x813.webp 768w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/03-Ai-operations-maintenance-1452x1536.webp 1452w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/03-Ai-operations-maintenance-11x12.webp 11w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/03-Ai-operations-maintenance.webp 1500w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-79d7c1f e-con-full core-tech-card__content e-flex e-con e-child\" data-id=\"79d7c1f\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;position&quot;:&quot;absolute&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-acbef1b core-tech-card__title elementor-widget elementor-widget-heading\" data-id=\"acbef1b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Super Fast Charging<\/h3>\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-30e9a3c e-con-full core-tech-card__hover-text e-flex e-con e-child\" data-id=\"30e9a3c\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3cd22aa core-tech-card__description elementor-widget elementor-widget-text-editor\" data-id=\"3cd22aa\" 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>Device and platform monitoring supports component-level diagnostics, predictive alerts, remote reset and over-the-air updates, helping service teams identify issues before a site visit.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/section>\n\t\t<div class=\"elementor-element elementor-element-227aef5 elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile e-flex e-con-boxed e-con e-parent\" data-id=\"227aef5\" 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<div class=\"elementor-element elementor-element-03bd240 e-con-full e-flex e-con e-child\" data-id=\"03bd240\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3452eeb elementor-widget elementor-widget-image\" data-id=\"3452eeb\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"1884\" height=\"2304\" src=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Elecrest-employee-work-with-us.webp\" class=\"attachment-full size-full wp-image-4574\" alt=\"\" srcset=\"https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Elecrest-employee-work-with-us.webp 1884w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Elecrest-employee-work-with-us-245x300.webp 245w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Elecrest-employee-work-with-us-837x1024.webp 837w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Elecrest-employee-work-with-us-768x939.webp 768w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Elecrest-employee-work-with-us-1256x1536.webp 1256w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Elecrest-employee-work-with-us-1675x2048.webp 1675w, https:\/\/elecrest.energy\/wp-content\/uploads\/2026\/09\/Elecrest-employee-work-with-us-10x12.webp 10w\" sizes=\"(max-width: 1884px) 100vw, 1884px\">\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-c3f86f4 e-con-full e-flex e-con e-child\" data-id=\"c3f86f4\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-a2e6718 elementor-widget-mobile__width-initial elementor-widget elementor-widget-heading\" data-id=\"a2e6718\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Build better charging with us<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8c9dc30 elementor-widget-mobile__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"8c9dc30\" 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>Elecrest is building a team of engineers, and field specialists who care about reliable charging and precise execution. If that sounds like you, we would like to hear from you.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3b15152 elementor-align-justify elementor-widget__width-initial elementor-widget elementor-widget-button\" data-id=\"3b15152\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"button.default\">\n\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-button elementor-button-link elementor-size-sm\" href=\"https:\/\/elecrest.energy\/join-us\/\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">Join us<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-0f18e99 elecrest-dot-wave-section e-flex e-con-boxed e-con e-parent\" data-id=\"0f18e99\" 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-55fdca2 elementor-widget elementor-widget-html\" data-id=\"55fdca2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t\r\n\r\n<style>\r\n  .elecrest-dot-wave-section {\r\n    position: relative;\r\n    isolation: isolate;\r\n  }\r\n\r\n  .elecrest-dot-wave-section > .elecrest-dot-wave-canvas {\r\n    position: absolute;\r\n    inset: 0;\r\n    z-index: -1;\r\n    display: block;\r\n    width: 100%;\r\n    height: 100%;\r\n    pointer-events: none;\r\n  }\r\n<\/style>\r\n\r\n<span data-elecrest-dot-wave-anchor hidden aria-hidden=\"true\"><\/span>\r\n\r\n<script>\r\n(() => {\r\n  'use strict';\r\n\r\n  const currentScript = document.currentScript;\r\n  const anchor = currentScript ? currentScript.previousElementSibling : null;\r\n  const section = anchor\r\n    ? anchor.closest('.elecrest-dot-wave-section')\r\n    : null;\r\n\r\n  if (!section || section.dataset.elecrestDotWaveReady === 'true') {\r\n    return;\r\n  }\r\n\r\n  section.dataset.elecrestDotWaveReady = 'true';\r\n\r\n  const canvas = document.createElement('canvas');\r\n  canvas.className = 'elecrest-dot-wave-canvas';\r\n  canvas.setAttribute('aria-hidden', 'true');\r\n  section.prepend(canvas);\r\n\r\n  const context = canvas.getContext('2d', { alpha: true });\r\n\r\n  if (!context) {\r\n    canvas.remove();\r\n    delete section.dataset.elecrestDotWaveReady;\r\n    return;\r\n  }\r\n\r\n  const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');\r\n  const fullTurn = Math.PI * 2;\r\n\r\n  let width = 1;\r\n  let height = 1;\r\n  let pixelRatio = 1;\r\n  let frameDuration = 1000 \/ 30;\r\n  let terrain = null;\r\n  let isNearViewport = false;\r\n  let isRunning = false;\r\n  let animationFrame = 0;\r\n  let lastFrameTime = 0;\r\n\r\n  const clamp = (value, minimum, maximum) => (\r\n    Math.min(maximum, Math.max(minimum, value))\r\n  );\r\n\r\n  const smoothStep = (minimum, maximum, value) => {\r\n    const normalised = clamp((value - minimum) \/ (maximum - minimum), 0, 1);\r\n    return normalised * normalised * (3 - 2 * normalised);\r\n  };\r\n\r\n  const noise = (column, row) => {\r\n    const value = Math.sin(\r\n      (column + 1) * 12.9898\r\n      + (row + 1) * 78.233\r\n    ) * 43758.5453;\r\n\r\n    return value - Math.floor(value);\r\n  };\r\n\r\n  const buildTerrain = () => {\r\n    const isMobile = width < 768;\r\n    const horizon = height * (isMobile ? 0.50 : 0.47);\r\n    const floorHeight = height - horizon;\r\n    const columns = isMobile\r\n      ? Math.round(clamp(width \/ 5.8, 60, 82))\r\n      : Math.round(clamp(width \/ 14, 92, 160));\r\n    const rows = isMobile\r\n      ? Math.round(clamp(height \/ 14, 30, 42))\r\n      : Math.round(clamp(height \/ 13, 32, 46));\r\n    const waveAmplitude = height * (isMobile ? 0.118 : 0.132);\r\n    const centreX = width * 0.5;\r\n    const loopSpan = 2.6;\r\n    const terrainRows = [];\r\n\r\n    frameDuration = 1000 \/ (isMobile ? 24 : 30);\r\n\r\n    for (let row = 0; row < rows; row += 1) {\r\n      const depth = (row + 0.45) \/ rows;\r\n      const perspective = Math.pow(depth, 1.55);\r\n      const baseY = horizon + perspective * floorHeight * 1.10;\r\n      const depthSlope = (\r\n        1.55\r\n        * Math.pow(depth, 0.55)\r\n        * floorHeight\r\n        * 1.10\r\n      );\r\n      const depthEnvelope = Math.sin(Math.PI * clamp(depth, 0, 1));\r\n\r\n      if (baseY > height + waveAmplitude) {\r\n        continue;\r\n      }\r\n\r\n      const rowWidth = width * (1.34 + depth * 0.44);\r\n      const pointSpacing = loopSpan \/ columns;\r\n      const rowStagger = row % 2 === 0 ? 0 : pointSpacing * 0.5;\r\n      const baseRadius = 0.48 + depth * (isMobile ? 0.76 : 0.90);\r\n      const topFade = smoothStep(0.015, 0.24, depth);\r\n      const bottomFade = 1 - smoothStep(0.91, 1, depth);\r\n      const baseAlpha = (0.085 + depth * 0.39) * topFade * bottomFade;\r\n      const points = [];\r\n\r\n      for (let column = 0; column < columns; column += 1) {\r\n        const randomValue = noise(column, row);\r\n        const sourceX = (\r\n          (column \/ columns) * loopSpan\r\n          - loopSpan * 0.5\r\n          + rowStagger\r\n        );\r\n        const sourceAngle = (\r\n          (sourceX + loopSpan * 0.5) \/ loopSpan\r\n        ) * fullTurn;\r\n        const staticWave = (\r\n          Math.sin(sourceAngle + depth * 5.2) * 0.42\r\n          + Math.sin(sourceAngle * 2 - depth * 3.6) * 0.23\r\n          + Math.sin(sourceAngle * 3 + depth * 6.4) * 0.10\r\n        );\r\n\r\n        points.push({\r\n          sourceX,\r\n          sourceAngle,\r\n          jitterX: (randomValue - 0.5) * pointSpacing * 0.34,\r\n          jitterY: (noise(column + 41, row + 17) - 0.5) * 0.8,\r\n          radius: baseRadius * (0.88 + randomValue * 0.22),\r\n          staticWave\r\n        });\r\n      }\r\n\r\n      terrainRows.push({\r\n        depth,\r\n        baseY,\r\n        depthSlope,\r\n        depthEnvelope,\r\n        rowWidth,\r\n        pointSpacing,\r\n        baseAlpha,\r\n        points\r\n      });\r\n    }\r\n\r\n    terrain = {\r\n      horizon,\r\n      waveAmplitude,\r\n      centreX,\r\n      loopSpan,\r\n      rows: terrainRows\r\n    };\r\n  };\r\n\r\n  const draw = (timeInSeconds) => {\r\n    context.clearRect(0, 0, width, height);\r\n\r\n    if (!terrain) {\r\n      return;\r\n    }\r\n\r\n    const {\r\n      horizon,\r\n      waveAmplitude,\r\n      centreX,\r\n      loopSpan,\r\n      rows\r\n    } = terrain;\r\n    const loopDuration = 64;\r\n    const loopPhase = (\r\n      (timeInSeconds % loopDuration) \/ loopDuration\r\n    ) * fullTurn;\r\n    const flowOffset = (\r\n      loopSpan * (loopPhase \/ fullTurn)\r\n      + Math.sin(loopPhase * 2) * 0.032\r\n      + loopSpan\r\n    ) % loopSpan;\r\n    for (let row = 0; row < rows.length; row += 1) {\r\n      const rowData = rows[row];\r\n      const {\r\n        depth,\r\n        baseY,\r\n        depthSlope,\r\n        depthEnvelope,\r\n        rowWidth,\r\n        pointSpacing,\r\n        baseAlpha,\r\n        points\r\n      } = rowData;\r\n      const inversionStrength = Math.sin(\r\n        loopPhase * 3\r\n        + depth * 2.8\r\n      );\r\n      const rowFloat = Math.sin(\r\n        loopPhase * 6\r\n        + depth * 6.2\r\n      ) * height * 0.032 * (0.30 + depth * 0.70);\r\n      const rowTwist = Math.sin(\r\n        loopPhase * 5\r\n        + depth * 5.1\r\n      ) * width * 0.012 * (0.25 + depth * 0.75);\r\n      const buckets = [[], [], []];\r\n\r\n      for (let point = 0; point < points.length; point += 1) {\r\n        const pointData = points[point];\r\n        const {\r\n          sourceX,\r\n          sourceAngle,\r\n          jitterX,\r\n          jitterY,\r\n          radius,\r\n          staticWave\r\n        } = pointData;\r\n        let flowingX = sourceX - flowOffset;\r\n\r\n        flowingX = (\r\n          (flowingX + loopSpan * 0.5 + loopSpan) % loopSpan\r\n        ) - loopSpan * 0.5;\r\n\r\n        const spatialAngle = (\r\n          (flowingX + loopSpan * 0.5) \/ loopSpan\r\n        ) * fullTurn;\r\n\r\n        const horizontalTwist = Math.sin(\r\n          spatialAngle * 2\r\n          + depth * 5.4\r\n          + loopPhase * 5\r\n        ) * pointSpacing * 0.75;\r\n\r\n        const breathingWave = Math.sin(\r\n          spatialAngle\r\n          - depth * 4.8\r\n          + loopPhase * 7\r\n        );\r\n        const foldingWave = Math.sin(\r\n          spatialAngle * 3\r\n          + depth * 7.2\r\n          - loopPhase * 6\r\n        ) * inversionStrength;\r\n        const densityWave = Math.sin(\r\n          loopPhase * 4\r\n          + depth * 8.0\r\n          - spatialAngle\r\n        );\r\n        const densityWarp = (\r\n          breathingWave * 0.070\r\n          + foldingWave * 0.050\r\n          + densityWave * 0.020\r\n        ) * depthEnvelope;\r\n        const horizontalDensityWarp = (\r\n          breathingWave * 0.080\r\n          + foldingWave * 0.050\r\n        ) * pointSpacing * depthEnvelope;\r\n        const x = (\r\n          centreX\r\n          + (\r\n            (\r\n              flowingX\r\n              + jitterX\r\n              + horizontalTwist\r\n              + horizontalDensityWarp\r\n            ) \/ loopSpan\r\n          ) * rowWidth\r\n          + rowTwist\r\n        );\r\n\r\n        if (x < -3 || x > width + 3) {\r\n          continue;\r\n        }\r\n\r\n        const wave = (\r\n          staticWave * 0.62\r\n          + breathingWave * 0.36\r\n          + foldingWave * 0.24\r\n        );\r\n        const depthStrength = 0.38 + depth * 0.62;\r\n        const verticalFloat = (\r\n          Math.sin(\r\n            loopPhase * 5\r\n            + depth * 6.2\r\n            + spatialAngle\r\n          ) * 0.68\r\n          + Math.sin(\r\n            loopPhase * 3\r\n            - depth * 3.8\r\n            + spatialAngle * 2\r\n          ) * 0.32\r\n        ) * height * 0.024 * (0.30 + depth * 0.70);\r\n        const densityOffsetY = densityWarp * depthSlope;\r\n        const y = (\r\n          baseY\r\n          + densityOffsetY\r\n          + rowFloat\r\n          - wave * waveAmplitude * depthStrength\r\n          + verticalFloat\r\n          + jitterY\r\n        );\r\n\r\n        if (y < horizon - 3 || y > height + 3) {\r\n          continue;\r\n        }\r\n\r\n        const crest = clamp((wave + 1) * 0.5, 0, 1);\r\n        const densityLift = clamp(Math.abs(densityWarp) * 3.2, 0, 0.32);\r\n        const brightness = clamp(crest * 0.82 + densityLift, 0, 0.999);\r\n        const brightnessBucket = Math.min(2, Math.floor(brightness * 3));\r\n        const renderRadius = radius * (1 + crest * 0.12);\r\n\r\n        buckets[brightnessBucket].push({ x, y, radius: renderRadius });\r\n      }\r\n\r\n      for (let bucket = 0; bucket < buckets.length; bucket += 1) {\r\n        const points = buckets[bucket];\r\n\r\n        if (!points.length) {\r\n          continue;\r\n        }\r\n\r\n        context.beginPath();\r\n\r\n        for (let point = 0; point < points.length; point += 1) {\r\n          const item = points[point];\r\n          context.moveTo(item.x + item.radius, item.y);\r\n          context.arc(\r\n            item.x,\r\n            item.y,\r\n            item.radius,\r\n            0,\r\n            fullTurn\r\n          );\r\n        }\r\n\r\n        const alpha = baseAlpha * (0.82 + bucket * 0.28);\r\n        const red = 16 + bucket * 8;\r\n        const green = 160 + bucket * 24;\r\n        const blue = 190 + bucket * 20;\r\n\r\n        context.fillStyle = `rgba(${red}, ${green}, ${blue}, ${alpha.toFixed(3)})`;\r\n        context.fill();\r\n      }\r\n    }\r\n  };\r\n\r\n  const resize = () => {\r\n    const bounds = section.getBoundingClientRect();\r\n    const nextWidth = Math.max(1, Math.round(bounds.width));\r\n    const nextHeight = Math.max(1, Math.round(bounds.height));\r\n    const maxPixelRatio = nextWidth < 768 ? 1.25 : 1.5;\r\n    const nextPixelRatio = Math.min(window.devicePixelRatio || 1, maxPixelRatio);\r\n\r\n    if (\r\n      nextWidth === width\r\n      && nextHeight === height\r\n      && nextPixelRatio === pixelRatio\r\n    ) {\r\n      return;\r\n    }\r\n\r\n    width = nextWidth;\r\n    height = nextHeight;\r\n    pixelRatio = nextPixelRatio;\r\n\r\n    canvas.width = Math.round(width * pixelRatio);\r\n    canvas.height = Math.round(height * pixelRatio);\r\n    context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);\r\n    buildTerrain();\r\n    draw(reducedMotion.matches ? 0 : performance.now() \/ 1000);\r\n  };\r\n\r\n  const stop = () => {\r\n    isRunning = false;\r\n\r\n    if (animationFrame) {\r\n      cancelAnimationFrame(animationFrame);\r\n      animationFrame = 0;\r\n    }\r\n  };\r\n\r\n  const tick = (time) => {\r\n    if (!isRunning) {\r\n      return;\r\n    }\r\n\r\n    if (!section.isConnected) {\r\n      stop();\r\n      return;\r\n    }\r\n\r\n    if (time - lastFrameTime >= frameDuration) {\r\n      draw(time \/ 1000);\r\n      lastFrameTime = time;\r\n    }\r\n\r\n    animationFrame = requestAnimationFrame(tick);\r\n  };\r\n\r\n  const synchroniseAnimation = () => {\r\n    const shouldRun = (\r\n      isNearViewport\r\n      && !document.hidden\r\n      && !reducedMotion.matches\r\n    );\r\n\r\n    if (shouldRun && !isRunning) {\r\n      isRunning = true;\r\n      lastFrameTime = 0;\r\n      animationFrame = requestAnimationFrame(tick);\r\n      return;\r\n    }\r\n\r\n    if (!shouldRun) {\r\n      stop();\r\n      draw(reducedMotion.matches ? 0 : performance.now() \/ 1000);\r\n    }\r\n  };\r\n\r\n  if ('ResizeObserver' in window) {\r\n    const resizeObserver = new ResizeObserver(resize);\r\n    resizeObserver.observe(section);\r\n  } else {\r\n    window.addEventListener('resize', resize, { passive: true });\r\n  }\r\n\r\n  if ('IntersectionObserver' in window) {\r\n    const intersectionObserver = new IntersectionObserver((entries) => {\r\n      isNearViewport = entries[0].isIntersecting;\r\n      synchroniseAnimation();\r\n    }, {\r\n      rootMargin: '300px 0px',\r\n      threshold: 0\r\n    });\r\n\r\n    intersectionObserver.observe(section);\r\n  } else {\r\n    isNearViewport = true;\r\n  }\r\n\r\n  document.addEventListener('visibilitychange', synchroniseAnimation);\r\n\r\n  if ('addEventListener' in reducedMotion) {\r\n    reducedMotion.addEventListener('change', synchroniseAnimation);\r\n  } else {\r\n    reducedMotion.addListener(synchroniseAnimation);\r\n  }\r\n\r\n  resize();\r\n  synchroniseAnimation();\r\n})();\r\n<\/script>\r\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d23309f elementor-widget__width-initial elementor-widget elementor-widget-heading\" data-id=\"d23309f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Charging solution tailored for you<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a023665 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"a023665\" 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 data-v-d4a49cff=\"\">\u00a0Lower TCO. Higher ROI.\u00a0<\/p><p data-v-d4a49cff=\"\">Engineered for CPOs who value every euro.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-e0c9694 e-con-full e-flex e-con e-child\" data-id=\"e0c9694\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-18e5f9b elementor-align-justify elementor-widget__width-initial elementor-widget elementor-widget-button\" data-id=\"18e5f9b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"button.default\">\n\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-button elementor-button-link elementor-size-sm\" href=\"#elementor-action%3Aaction%3Dpopup%3Aopen%26settings%3DeyJpZCI6IjQ1MiIsInRvZ2dsZSI6ZmFsc2V9\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">Discuss your project<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-be2bea1 elementor-align-justify elementor-widget__width-initial elementor-widget elementor-widget-button\" data-id=\"be2bea1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"button.default\">\n\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-button elementor-button-link elementor-size-sm\" href=\"https:\/\/elecrest.energy\/configurator\/\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> Configure<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t<\/div>\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>Rethink the economics of DC fast charging HIMA DC fast chargers combine efficiency, serviceable design and connected operations to manage whole-life cost. Request a Quote Configure One platform for every charging scenario Rotating view of the HIMA 480 Loading 360\u00b0 view\u2026 Retry360\u00b0 rotation view0\u00b0Drag horizontally or use the arrow keys to rotate HIMA 480. Available [&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-2478","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/elecrest.energy\/fr\/wp-json\/wp\/v2\/pages\/2478","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=2478"}],"version-history":[{"count":129,"href":"https:\/\/elecrest.energy\/fr\/wp-json\/wp\/v2\/pages\/2478\/revisions"}],"predecessor-version":[{"id":5416,"href":"https:\/\/elecrest.energy\/fr\/wp-json\/wp\/v2\/pages\/2478\/revisions\/5416"}],"wp:attachment":[{"href":"https:\/\/elecrest.energy\/fr\/wp-json\/wp\/v2\/media?parent=2478"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}