{"id":42006,"date":"2026-03-30T16:00:09","date_gmt":"2026-03-30T16:00:09","guid":{"rendered":"https:\/\/nofloods.com\/easywall-rechner\/"},"modified":"2026-10-15T18:33:46","modified_gmt":"2026-10-15T18:33:46","slug":"easywall-products-2","status":"publish","type":"page","link":"https:\/\/nofloods.com\/de\/easywall-products-2\/","title":{"rendered":"EasyWall-Rechner"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"42006\" class=\"elementor elementor-42006 elementor-38811\">\n\t\t\t\t<div class=\"elementor-element elementor-element-dfe8f10 e-con-full e-flex e-con e-parent\" data-id=\"dfe8f10\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-91f104f elementor-widget elementor-widget-html\" data-id=\"91f104f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"custom-video-wrapper\">\r\n  <video autoplay=\"\" muted=\"\" loop=\"\" playsinline=\"\">\r\n    <source src=\"https:\/\/nofloods.com\/wp-content\/uploads\/2025\/10\/Banner_anim-1.mp4\" type=\"video\/mp4\">\r\n  <\/source><\/video>\r\n  <div class=\"video-overlay\"><\/div>\r\n<\/div>\r\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-11c45c1d e-flex e-con-boxed e-con e-parent\" data-id=\"11c45c1d\" 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-5432775c e-con-full e-flex e-con e-child\" data-id=\"5432775c\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4c7ed852 elementor-widget elementor-widget-heading\" data-id=\"4c7ed852\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">EasyWall-Hochwasserschutzbarrieren \u2013 Modulrechner<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-200a060 elementor-widget elementor-widget-eael-breadcrumbs\" data-id=\"200a060\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"eael-breadcrumbs.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"eael-breadcrumbs\">\n\t\t\t<div class=\"eael-breadcrumbs__content\"><a href=\"https:\/\/nofloods.com\/de\/\">Startseite<\/a> <span class=\"eael-breadcrumb-separator\">&gt;<\/span> <span class = \"eael-current\">Seite<\/span><\/div>\t\t<\/div>\n\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-1c2d7cb e-flex e-con-boxed e-con e-parent\" data-id=\"1c2d7cb\" 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-a88364f e-con-full e-flex e-con e-child\" data-id=\"a88364f\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c254ce6 elementor-widget__width-inherit elementor-widget elementor-widget-heading\" data-id=\"c254ce6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Planen Sie Ihre EasyWall-Absperrung ganz einfach<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6897595 elementor-widget elementor-widget-text-editor\" data-id=\"6897595\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Mit unserem Rechner k\u00f6nnen Sie ganz einfach die richtige Absperrkonfiguration f\u00fcr Ihr Projekt entwerfen. Geben Sie einfach die gew\u00fcnschte Absperrl\u00e4nge ein, w\u00e4hlen Sie ein Modell aus und f\u00fcgen Sie gegebenenfalls optionale Extras hinzu. Die Modellnummern geben die H\u00f6he in Zentimetern an (nicht die Breite). \u00dcberlappungen zwischen den Modulen werden automatisch in die Berechnung einbezogen.<br\/>Bitte beachten Sie: Eckmodule sind f\u00fcr Kurven oder Hindernisse vorgesehen \u2013 sie verl\u00e4ngern Ihre Absperrung zwar physisch, werden jedoch nicht in die berechnete Gesamtl\u00e4nge der Absperrung einbezogen.<br\/>Sobald Ihre Konfiguration fertig ist, k\u00f6nnen Sie diese direkt in unserem Webshop erwerben oder an unser Team senden, um Unterst\u00fctzung zu erhalten.   <\/p>\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-76c99b8 elementor-widget__width-inherit elementor-widget elementor-widget-html\" data-id=\"76c99b8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\n<html lang=\"de\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/leaflet\/1.9.4\/leaflet.min.css\"\/>\n<title>NoFloods EasyWall Rechner<\/title>\n<style>\n*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}\n:root{\n  --bg1:#fff;--bg2:#f5f5f3;--bg3:#eeede9;\n  --t1:#1a1a18;--t2:#6b6b67;--t3:#9e9d99;\n  --bd:rgba(0,0,0,0.12);--bd2:rgba(0,0,0,0.22);\n  --rm:8px;--rl:12px;\n  --br:#D85A30;--brd:#993C1D;--brb:#FAECE7;--brl:#F5C4B3;\n  --ok:#3B6D11;--okb:#EAF3DE;--okl:#C0DD97;\n  --wn:#BA7517;--wnb:#FAEEDA;\n  --bl:#185FA5;--blb:#E6F1FB;--bll:#B5D4F4;\n}\n\n.calc{max-width:100%;margin:0 auto}\n.lang-bar{display:flex;justify-content:flex-end;gap:6px;margin-bottom:1rem}\n.lang-btn{padding:4px 12px;font-size:12px;font-weight:600;font-family:inherit;border:0.5px solid var(--bd);border-radius:var(--rm);background:var(--bg1);color:var(--t2);cursor:pointer}\n.lang-btn.active{border:2px solid var(--br);background:var(--brb);color:var(--brd)}\n.hdr{display:flex;align-items:center;gap:12px;margin-bottom:1.75rem}\n.hdr-logo{width:40px;height:40px;background:var(--br);border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:13px;flex-shrink:0}\n.hdr h1{font-size:18px;font-weight:700;color:var(--t1);line-height:1.2}\n.hdr p{font-size:13px;color:var(--t2);margin-top:2px}\n.card{background:var(--bg1);border:0.5px solid var(--bd);border-radius:var(--rl);padding:1.25rem;margin-bottom:14px}\n\/* Map tool *\/\n.map-mode-row{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px}\n.map-mode-btn{border:0.5px solid var(--bd);border-radius:var(--rm);padding:12px;cursor:pointer;background:var(--bg1);text-align:left;font-family:inherit}\n.map-mode-btn.active{border:2px solid var(--br);background:var(--brb)}\n.map-mode-btn .mm-label{font-size:13px;font-weight:700;color:var(--t1);margin-bottom:3px}\n.map-mode-btn .mm-sub{font-size:11px;color:var(--t2);line-height:1.4}\n.map-mode-btn .mm-badge{display:inline-block;font-size:10px;background:var(--okb);color:var(--ok);border-radius:4px;padding:1px 6px;margin-bottom:5px;font-weight:700}\n.map-panel{display:none;margin-bottom:12px}\n.map-panel.open{display:block}\n#ew-map{height:320px;border-radius:var(--rm);overflow:hidden}\n.map-tb{display:flex;gap:6px;margin-bottom:8px;flex-wrap:wrap}\n.map-tb-btn{padding:5px 10px;font-size:11px;font-weight:600;font-family:inherit;border:0.5px solid var(--bd);border-radius:var(--rm);background:var(--bg1);color:var(--t2);cursor:pointer}\n.map-tb-btn:hover{background:var(--bg2)}\n.map-tb-btn.active{border:1.5px solid var(--br);background:var(--brb);color:var(--brd)}\n.map-tb-btn.danger{color:#A32D2D;border-color:#F09595}\n.map-import-bar{background:var(--okb);border:0.5px solid var(--okl);border-radius:var(--rm);padding:10px 12px;display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-top:8px}\n.map-import-bar.hidden{display:none}\n.map-import-text{font-size:12px;font-weight:700;color:var(--ok);line-height:1.6}\n.map-import-text span{font-weight:400;color:#3B6D11;font-size:11px}\n.map-import-btn{padding:7px 14px;background:var(--br);color:#fff;border:none;border-radius:var(--rm);font-size:12px;font-weight:700;font-family:inherit;cursor:pointer;white-space:nowrap}\n.map-imported-badge{display:inline-flex;align-items:center;gap:4px;font-size:10px;background:var(--okb);color:var(--ok);border-radius:4px;padding:2px 7px;font-weight:700;margin-left:8px}\n.map-close-popup{display:none;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:9999;background:var(--bg1);border:0.5px solid var(--bd);border-radius:12px;padding:20px 24px;min-width:280px;max-width:340px;box-shadow:0 4px 24px rgba(0,0,0,.18)}\n.map-close-popup h3{font-size:14px;font-weight:700;color:var(--t1);margin-bottom:6px}\n.map-close-popup p{font-size:13px;color:var(--t2);margin-bottom:14px;line-height:1.5}\n.map-popup-btns{display:flex;flex-direction:column;gap:8px}\n.mcp-btn{padding:10px 14px;border:none;border-radius:8px;font-size:13px;font-weight:700;font-family:inherit;cursor:pointer;text-align:left}\n.mcp-btn.green{background:var(--ok);color:#fff}\n.mcp-btn.orange{background:var(--brb);color:var(--brd);border:1.5px solid var(--brl)}\n.mcp-btn.neutral{background:none;color:var(--t2);border:0.5px solid var(--bd);font-weight:400;font-size:12px}\n.sh{display:flex;align-items:center;gap:10px;margin-bottom:6px}\n.sn{width:26px;height:26px;border-radius:50%;background:var(--br);color:#fff;font-size:12px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}\n.st{font-size:15px;font-weight:700;color:var(--t1)}\n.ss{font-size:13px;color:var(--t2);margin-left:36px;margin-bottom:14px}\n.ser-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}\n@media(max-width:560px){.ser-grid{grid-template-columns:1fr}}\n.ser-btn{border:0.5px solid var(--bd);border-radius:var(--rl);padding:12px 10px;cursor:pointer;background:var(--bg1);text-align:left;width:100%}\n.ser-btn:hover{border-color:var(--bd2)}\n.ser-btn.active{border:2px solid var(--br);background:var(--brb)}\n.pill{display:inline-block;font-size:10px;font-weight:700;padding:2px 8px;border-radius:10px;margin-bottom:6px}\n.pt{background:var(--brl);color:var(--brd)}.ps{background:var(--bll);color:#0C447C}.pd{background:var(--okl);color:#27500A}\n.sn2{font-size:14px;font-weight:700;color:var(--t1)}\n.sd{font-size:11px;color:var(--t2);margin-top:3px;line-height:1.45}\n.ht-grid{display:grid;gap:8px}\n.ht-btn{border:0.5px solid var(--bd);border-radius:var(--rm);padding:12px 8px;cursor:pointer;background:var(--bg1);text-align:center;width:100%}\n.ht-btn:hover{border-color:var(--bd2)}\n.ht-btn.active{border:2px solid var(--br);background:var(--brb)}\n.ht-h{font-size:20px;font-weight:700;color:var(--t1)}\n.ht-btn.active .ht-h{color:var(--brd)}\n.ht-p{font-size:11px;color:var(--t2);margin-top:3px}\n.ht-c{font-size:10px;color:var(--t3);margin-top:3px;font-family:inherit}\n.guide-tog{display:flex;align-items:center;gap:8px;cursor:pointer;padding:9px 12px;background:var(--blb);border-radius:var(--rm);margin-bottom:14px;border:0.5px solid var(--bll);user-select:none}\n.guide-tog-lbl{font-size:13px;color:var(--bl);font-weight:600;flex:1}\n.guide-arr{width:16px;height:16px;flex-shrink:0;transition:transform .2s;color:var(--bl)}\n.guide-arr.open{transform:rotate(180deg)}\n.guide-body{overflow:hidden;max-height:0;transition:max-height .3s ease}\n.guide-body.open{max-height:700px}\n.guide-inner{padding:4px 0 14px;display:flex;flex-direction:column;gap:10px}\n.guide-step{display:flex;gap:12px;align-items:flex-start}\n.guide-sn{width:22px;height:22px;border-radius:50%;background:var(--br);color:#fff;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:1px}\n.guide-st{font-size:13px;color:var(--t2);line-height:1.55}\n.guide-st strong{color:var(--t1);font-weight:600}\n.gdiv{height:0.5px;background:var(--bd)}\n.dims{border-top:0.5px solid var(--bd);padding-top:14px;margin-top:12px}\n.dtit{font-size:11px;font-weight:700;color:var(--t2);text-transform:uppercase;letter-spacing:.05em;margin-bottom:10px}\n.dgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}\n.dg{background:var(--bg2);border-radius:var(--rm);padding:10px 12px}\n.dgl{font-size:11px;color:var(--t2);margin-bottom:8px;font-weight:700}\n.dfr{display:flex;align-items:center;justify-content:space-between;font-size:13px;margin-bottom:6px;color:var(--t2)}\n.dfr:last-child{margin-bottom:0}\n.ds{font-size:11px;color:var(--t2)}\n.muted{opacity:.38;pointer-events:none}\n.ni{width:80px;height:36px;border:0.5px solid var(--bd);border-radius:var(--rm);background:var(--bg1);color:var(--t1);font-size:14px;font-family:inherit;padding:0 10px;text-align:center;transition:box-shadow .15s}\n.ni:focus{outline:none;box-shadow:0 0 0 2px rgba(216,90,48,.25);border-color:var(--br)}\n.ni:disabled{opacity:.4;background:var(--bg2)}\n.frow{display:flex;align-items:center;gap:12px;margin-bottom:12px;flex-wrap:wrap}\n.flbl{font-size:13px;color:var(--t2);min-width:160px;flex-shrink:0}\n.fhint{font-size:11px;color:var(--t3)}\n.sec-tabs-row{display:flex;align-items:center;border-bottom:0.5px solid var(--bd);margin:0 0 0 0;flex-wrap:wrap;gap:0}\n.sec-tab{padding:8px 14px;font-size:12px;font-family:inherit;color:var(--t2);cursor:pointer;border:none;border-bottom:2px solid transparent;background:transparent}\n.sec-tab.active{color:var(--br);border-bottom-color:var(--br);font-weight:700}\n.sec-add{padding:8px 10px;font-size:12px;color:var(--br);cursor:pointer;border:none;background:transparent;font-family:inherit;font-weight:600}\n.sec-panel{padding-top:12px;display:none}\n.sec-panel.active{display:block}\n.mbg{display:flex;gap:6px;margin-bottom:10px}\n.mb{flex:1;padding:7px 6px;font-size:12px;font-weight:600;font-family:inherit;border:0.5px solid var(--bd);border-radius:var(--rm);background:var(--bg1);color:var(--t2);cursor:pointer;text-align:center}\n.mb.active{border:2px solid var(--br);background:var(--brb);color:var(--brd)}\n.mb.muted{opacity:.38;pointer-events:none}\n.cfb{margin-top:6px;padding:7px 10px;border-radius:var(--rm);font-size:12px;line-height:1.5;display:none}\n.cfb.ok{background:var(--okb);color:#27500A}\n.cfb.info{background:var(--blb);color:#0C447C}\n.cfb.warn{background:var(--wnb);color:#633806}\n.situation-btn{background:var(--bg2);border:0.5px solid var(--bd);border-radius:var(--rm);padding:10px 8px;cursor:pointer;font-family:inherit;text-align:center;transition:border-color .15s,background .15s;width:100%}\n.situation-btn:hover{border-color:var(--bd2);background:#ebebea}\n.situation-btn.active{border:2px solid var(--br);background:var(--brb)}\n.sit-icon{font-size:20px;margin-bottom:4px;line-height:1}\n.sit-label{font-size:12px;font-weight:700;color:var(--t1);margin-bottom:2px}\n.sit-sub{font-size:10px;color:var(--t3);line-height:1.3}\n.ewr{display:none;margin-top:8px;padding:5px 8px;background:var(--blb);border-radius:var(--rm);font-size:12px;color:#0C447C}\n.action-bar{display:flex;gap:8px;justify-content:flex-end;margin-bottom:14px;flex-wrap:wrap}\n.act-btn{padding:8px 16px;font-size:12px;font-weight:600;font-family:inherit;border:0.5px solid var(--bd);border-radius:var(--rm);background:var(--bg1);color:var(--t2);cursor:pointer;display:flex;align-items:center;gap:6px;overflow:visible}\n.act-btn svg{overflow:visible;flex-shrink:0}\n.act-btn:hover{background:var(--bg2)}\n.act-btn.pri{background:var(--br);color:#fff;border-color:var(--br)}\n.act-btn.pri:hover{background:var(--brd)}\n.res{background:var(--bg2);border:0.5px solid var(--bd);border-radius:var(--rl);overflow:hidden;margin-bottom:14px}\n.res-hdr{padding:1rem 1.25rem;border-bottom:0.5px solid var(--bd);display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px;background:var(--bg1)}\n.res-t{font-size:15px;font-weight:700;color:var(--t1)}\n.res-tag{font-size:12px;background:var(--brl);color:var(--brd);border-radius:10px;padding:3px 10px;font-weight:700}\n.fit-tabs{display:flex;border-bottom:0.5px solid var(--bd);background:var(--bg1)}\n.fit-tab{flex:1;padding:10px 8px;font-size:12px;font-family:inherit;color:var(--t2);cursor:pointer;border:none;border-bottom:2px solid transparent;background:transparent;text-align:center}\n.fit-tab:hover:not(.active):not(.disabled){color:var(--t1)}\n.fit-tab.active{color:var(--br);border-bottom-color:var(--br);font-weight:700}\n.fit-tab.disabled{opacity:.38;cursor:not-allowed}\n.exact-info-trigger{display:inline-flex;align-items:center;font-size:10px;font-weight:700;font-family:inherit;background:#FAEEDA;color:#854F0B;border:1px solid #FAC775;border-radius:10px;padding:2px 7px;margin-left:6px;cursor:pointer;vertical-align:middle;white-space:nowrap;transition:background .15s}\n.exact-info-trigger:hover{background:#FAC775}\n.fit-body{padding:1.25rem}\n.barlbl{font-size:12px;color:var(--t2);margin-bottom:6px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}\n.barwrap{position:relative;height:36px;background:var(--bg1);border:0.5px solid var(--bd);border-radius:var(--rm);overflow:hidden;margin-bottom:6px}\n.bar-req{position:absolute;left:0;top:0;height:100%;background:var(--blb);border-right:2px dashed #378ADD}\n.bar-act{position:absolute;left:0;top:0;height:100%;background:var(--brb)}\n.bar-ov{position:absolute;top:0;height:100%;background:var(--brl)}\n.bleg{display:flex;flex-wrap:wrap;gap:10px;font-size:11px;color:var(--t2);margin-bottom:1rem}\n.bleg span{display:flex;align-items:center;gap:4px}\n.bdot{width:10px;height:10px;border-radius:2px;flex-shrink:0;display:inline-block}\n.scards{display:grid;gap:10px;margin-bottom:1.25rem}\n@media(max-width:540px){.scards{grid-template-columns:1fr 1fr}}\n.sc{background:var(--bg1);border:0.5px solid var(--bd);border-radius:var(--rm);padding:10px 12px}\n.sv{font-size:20px;font-weight:700;color:var(--t1)}\n.sv.ok{color:var(--ok)}.sv.over{color:var(--br)}\n.sl{font-size:11px;color:var(--t2);margin-top:3px;line-height:1.4}\n.bkwrap{border-top:0.5px solid var(--bd);padding-top:12px}\n.bkr{display:flex;justify-content:space-between;align-items:baseline;font-size:13px;color:var(--t1);padding:5px 0;border-bottom:0.5px solid var(--bd)}\n.bkr:last-child{border-bottom:none;font-weight:700;padding-top:8px}\n.bkc{font-family:inherit;font-size:11px;color:var(--t2);margin-left:7px}\n.bkr2{display:flex;align-items:center;gap:8px}\n.bkq{color:var(--t2);white-space:nowrap}\n.notice{font-size:12px;color:var(--t2);border-left:2px solid var(--bd2);padding:6px 10px;margin-top:10px;line-height:1.6}\n.notice.warn{border-left-color:var(--wn);background:var(--wnb);color:#633806;border-radius:var(--rm);margin-top:8px}\n.notice.info{border-left-color:var(--bl);background:var(--blb);color:#0C447C;border-radius:var(--rm)}\n.avail-badge{display:none;margin-left:5px;font-size:10px;padding:1px 6px;border-radius:8px;background:var(--okl);color:#27500A;font-weight:700;vertical-align:middle}\n.wt-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:10px;margin-top:4px}\n.wt-card{background:var(--bg1);border:0.5px solid var(--bd);border-radius:var(--rm);padding:10px 12px}\n.wt-v{font-size:20px;font-weight:700;color:var(--t1)}\n.wt-l{font-size:11px;color:var(--t2);margin-top:2px}\n.wt-sub{font-size:10px;color:var(--t3);margin-top:2px}\n.ei{font-size:13px;color:var(--t2);line-height:1.6;padding:10px 12px;background:var(--bg1);border-radius:var(--rm);border-left:2px solid var(--br);margin-bottom:14px}\n.eo{background:var(--bg1);border:0.5px solid var(--bd);border-radius:var(--rm);padding:12px 14px;margin-bottom:10px}\n.eo.best{border:2px solid var(--ok)}\n.eo-hd{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;margin-bottom:10px;flex-wrap:wrap}\n.eo-t{font-size:13px;font-weight:700;color:var(--t1)}\n.eo-b{font-size:10px;padding:2px 8px;border-radius:10px;font-weight:700;white-space:nowrap}\n.b-ex{background:var(--okl);color:#27500A}.b-cl{background:#FAC775;color:#633806}.b-al{background:#D3D1C7;color:#444441}\n.eo-st{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:8px;margin-bottom:10px}\n.eo-sc{background:var(--bg2);border-radius:var(--rm);padding:7px 10px}\n.eo-sl{font-size:11px;color:var(--t2)}.eo-sv{font-size:14px;font-weight:700;color:var(--t1);margin-top:1px}\n.eo-sv.ex{color:var(--ok)}.eo-sv.nr{color:var(--wn)}\n.eo-ms{border-top:0.5px solid var(--bd);padding-top:8px;display:flex;flex-direction:column;gap:4px}\n.eo-m{display:flex;justify-content:space-between;font-size:12px;color:var(--t2)}\n.eo-m strong{color:var(--t1);font-weight:700}\n.set-note{font-size:11px;color:var(--ok);background:var(--okb);border-radius:var(--rm);padding:5px 9px;margin-top:6px;font-weight:700}\n.saved-list{display:flex;flex-direction:column;gap:8px;margin-top:10px}\n.saved-item{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--bg2);border-radius:var(--rm);font-size:13px;flex-wrap:wrap;gap:8px}\n.saved-name{color:var(--t1);font-weight:600}\n.saved-meta{font-size:11px;color:var(--t2);margin-top:2px}\n.saved-acts{display:flex;gap:6px}\n.saved-act{padding:4px 10px;font-size:11px;font-weight:600;border:0.5px solid var(--bd);border-radius:var(--rm);background:var(--bg1);cursor:pointer;font-family:inherit;color:var(--t2)}\n.saved-act.del{color:#A32D2D;border-color:#F09595}\n.no-saved{font-size:13px;color:var(--t3);text-align:center;padding:16px}\n.qwrap{background:var(--bg1);border:0.5px solid var(--bd);border-radius:var(--rl);overflow:hidden;margin-bottom:14px}\n.qhdr{padding:1.25rem 1.25rem 0}\n.qhdr h2{font-size:16px;font-weight:700;color:var(--t1);margin-bottom:4px}\n.qhdr p{font-size:13px;color:var(--t2);margin-bottom:1.25rem}\n.qsum{background:var(--bg2);border-radius:var(--rm);padding:14px 16px;margin:0 1.25rem 1.25rem;border-left:3px solid var(--br)}\n.qs-t{font-size:11px;font-weight:700;color:var(--t2);text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px}\n.qs-m{font-size:15px;font-weight:700;color:var(--t1);margin-bottom:12px}\n.qs-g{display:grid;grid-template-columns:1fr;gap:4px}\n@media(max-width:480px){.qs-g{grid-template-columns:repeat(2,1fr)}}\n.qs-i{font-size:13px;color:var(--t2);padding:6px 0;border-bottom:0.5px solid var(--bd);display:flex;align-items:baseline;gap:8px}\n.qs-i:last-child{border-bottom:none}\n.qs-i strong{color:var(--t1);font-weight:700}\n.qs-c{font-size:11px;color:var(--t3);font-family:inherit;margin-top:10px;padding-top:10px;border-top:0.5px solid var(--bd);line-height:1.8}\n.qform{padding:0 1.25rem 1.25rem;display:flex;flex-direction:column;gap:14px}\n.fr{display:grid;grid-template-columns:1fr 1fr;gap:12px}\n@media(max-width:520px){.fr{grid-template-columns:1fr}}\n.ff{display:flex;flex-direction:column;gap:5px}\n.ff label{font-size:12px;font-weight:600;color:var(--t2)}\n.ff label .req{color:var(--br);margin-left:2px}\n.fi,.fta,.fse{width:100%;border:0.5px solid var(--bd);border-radius:var(--rm);background:var(--bg1);color:var(--t1);font-size:13px;font-family:inherit;padding:9px 12px;transition:box-shadow .15s}\n.fi:focus,.fta:focus,.fse:focus{outline:none;box-shadow:0 0 0 2px rgba(216,90,48,.2);border-color:var(--br)}\n.fta{resize:vertical;min-height:90px;line-height:1.5}\n.fse{appearance:none;background-image:url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%236b6b67' d='M6 8L1 3h10z'\/%3E%3C\/svg%3E\");background-repeat:no-repeat;background-position:right 10px center;padding-right:28px}\n.loc-row{display:flex;gap:8px}\n.loc-row .fi{flex:1}\n.loc-btn{height:38px;padding:0 12px;background:var(--bg2);border:0.5px solid var(--bd);border-radius:var(--rm);font-size:11px;font-weight:600;color:var(--t2);cursor:pointer;white-space:nowrap;display:flex;align-items:center;gap:5px;font-family:inherit;flex-shrink:0}\n.loc-btn:hover{background:var(--bg3)}\n.loc-btn.blu{background:var(--blb);border-color:var(--bll);color:var(--bl)}\n.mapwrap{width:100%;height:200px;border-radius:var(--rm);border:0.5px solid var(--bd);overflow:hidden;display:none;margin-top:8px}\n.mapwrap iframe{width:100%;height:100%;border:none}\n.coords{font-size:11px;color:var(--ok);background:var(--okb);padding:4px 10px;border-radius:var(--rm);display:none;font-family:inherit;margin-top:4px}\n.urg-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}\n@media(max-width:420px){.urg-grid{grid-template-columns:1fr}}\n.urg-btn{border:0.5px solid var(--bd);border-radius:var(--rm);padding:10px 8px;cursor:pointer;background:var(--bg1);text-align:center;width:100%;font-family:inherit}\n.urg-btn:hover{border-color:var(--bd2)}\n.urg-btn.active{border:2px solid var(--br);background:var(--brb)}\n.urg-ic{font-size:18px;margin-bottom:4px}\n.urg-lb{font-size:12px;font-weight:600;color:var(--t1)}\n.urg-sb{font-size:10px;color:var(--t2);margin-top:2px}\n.photo-note{background:var(--blb);border-left:3px solid var(--bl);border-radius:0 var(--rm) var(--rm) 0;padding:10px 14px;font-size:12px;color:#0C447C;line-height:1.6}\n.qfooter{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;padding-top:4px}\n.qfooter small{font-size:11px;color:var(--t3);line-height:1.5}\n.sub-btn{background:var(--ok);color:#fff;border:none;border-radius:var(--rm);padding:12px 28px;font-size:14px;font-weight:700;font-family:inherit;cursor:pointer;transition:background .15s;white-space:nowrap;display:inline-flex;align-items:center;gap:8px}\n.sub-btn:hover{background:#2d540d}\n.copy-quote-btn{background:var(--bg1);color:var(--t2);border:0.5px solid var(--bd);border-radius:var(--rm);padding:9px 16px;font-size:12px;font-weight:700;font-family:inherit;cursor:pointer;display:inline-flex;align-items:center;gap:5px}\n.copy-quote-btn:hover{background:var(--brb);color:var(--brd);border-color:var(--brl)}\n.copy-quote-btn.copied{background:var(--okb);color:var(--ok);border-color:var(--okl)}\n@media print{\n  body{background:#fff;padding:0}\n  .action-bar,.lang-bar,.qwrap,.guide-tog,.fit-tabs{display:none!important}\n  .card,.res{border:1px solid #ccc;break-inside:avoid}\n}\n<\/style>\n\n<!-- German version: all calculator UI text is translated; calculation logic and product data are unchanged. -->\n<\/head>\n<body>\n<div class=\"calc\">\n\n<div class=\"lang-bar\" style=\"display:none\"><\/div>\n\n<div class=\"card\">\n  <div class=\"sh\"><div class=\"sn\">1<\/div><div class=\"st\" data-t=\"s1title\">Choose your series<\/div><\/div>\n  <div class=\"ss\" data-t=\"s1sub\">Each series is optimised for different site conditions<\/div>\n  <div class=\"ser-grid\">\n    <button class=\"ser-btn\" id=\"sb-T\" onclick=\"setSeries('T')\">\n      <span class=\"pill pt\" data-t=\"pill-t\">Premium \u00b7 T-series<\/span>\n      <div class=\"sn2\">T-series<\/div>\n      <div class=\"sd\" data-t=\"ser-t-desc\">HydroFoam\u2122 base &amp; HydroSeal\u2122 edge. Best watertight performance. Adjustable units verf\u00fcgbar.<\/div>\n    <\/button>\n    <button class=\"ser-btn\" id=\"sb-S\" onclick=\"setSeries('S')\">\n      <span class=\"pill ps\" data-t=\"pill-s\">Flexible \u00b7 S-series<\/span>\n      <div class=\"sn2\">S-series<\/div>\n      <div class=\"sd\" data-t=\"ser-s-desc\">Slide connection allows 3\u20135\u00b0 adjustment. Ideal for urban &amp; irregular layouts.<\/div>\n    <\/button>\n    <button class=\"ser-btn\" id=\"sb-D\" onclick=\"setSeries('D')\">\n      <span class=\"pill pd\" data-t=\"pill-d\">Uneven ground \u00b7 D-series<\/span>\n      <div class=\"sn2\">D-series<\/div>\n      <div class=\"sd\" data-t=\"ser-d-desc\">Detachable membrane for gravel, soil &amp; mixed terrain. Not verf\u00fcgbar in USA, UK, IE, CA &amp; QA.<\/div>\n    <\/button>\n  <\/div>\n<\/div>\n\n<div class=\"card\">\n  <div class=\"sh\"><div class=\"sn\">2<\/div><div class=\"st\" data-t=\"s2title\">Select height<\/div><\/div>\n  <div class=\"ss\" data-t=\"s2sub\">Protection height in cm<\/div>\n  <div class=\"ht-grid\" id=\"ht-grid\"><\/div>\n<\/div>\n\n<div class=\"card\">\n  <div class=\"sh\"><div class=\"sn\">3<\/div><div class=\"st\" data-t=\"s3title\">Barrier length &amp; accessories<\/div><\/div>\n  <div class=\"ss\" data-t=\"s3sub\">Enter your straight-run lengths and accessories below<\/div>\n\n  <div class=\"guide-tog\" onclick=\"toggleGuide()\">\n    <svg class=\"guide-arr\" id=\"guide-arr\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"3,6 8,11 13,6\"\/><\/svg>\n    <span class=\"guide-tog-lbl\" data-t=\"guide-toggle\">How to measure your site<\/span>\n    <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" style=\"width:14px;height:14px;flex-shrink:0;color:var(--bl)\"><circle cx=\"8\" cy=\"8\" r=\"6.5\"\/><line x1=\"8\" y1=\"7\" x2=\"8\" y2=\"11\"\/><circle cx=\"8\" cy=\"5\" r=\".8\" fill=\"currentColor\" stroke=\"none\"\/><\/svg>\n  <\/div>\n  <div class=\"guide-body\" id=\"guide-body\">\n    <div class=\"guide-inner\">\n      <div class=\"guide-step\"><div class=\"guide-sn\">1<\/div><div class=\"guide-st\"><strong data-t=\"g1h\">Measure straight sections only.<\/strong> <span data-t=\"g1b\">Walk each straight run and measure it independently. Do not include corners or turns in the length. You can add multiple separate sections below.<\/span><\/div><\/div>\n      <div class=\"gdiv\"><\/div>\n      <div class=\"guide-step\"><div class=\"guide-sn\">2<\/div><div class=\"guide-st\"><strong data-t=\"g2h\">Identify your turns.<\/strong> <span data-t=\"g2b\">Sanfte Kurves (a few degrees per joint) need no corner modules \u2014 just connect modules in a slight arc. The S-series handles up to 3\u20135\u00b0 per joint by design. For distinct bends, use corner modules. Enter your turn angle in the corners section and the calculator tells you exactly how many modules you need.<\/span><\/div><\/div>\n      <div class=\"gdiv\"><\/div>\n      <div class=\"guide-step\"><div class=\"guide-sn\">3<\/div><div class=\"guide-st\"><strong data-t=\"g3h\">Check for walls and open ends.<\/strong> <span data-t=\"g3b\">If the barrier runs against a wall, you need a wall connector. Each open end needs an end module (left or right).<\/span><\/div><\/div>\n      <div class=\"gdiv\"><\/div>\n      <div class=\"guide-step\"><div class=\"guide-sn\">4<\/div><div class=\"guide-st\"><strong data-t=\"g4h\">Consider your ground surface.<\/strong> <span data-t=\"g4b\">All EasyWall series can handle uneven ground \u2014 a detachable membrane can be added to any model. The D-series has it built in as standard. Mention surface conditions in your quote request.<\/span><\/div><\/div>\n      <div class=\"gdiv\"><\/div>\n      <div class=\"guide-step\"><div class=\"guide-sn\">5<\/div><div class=\"guide-st\"><strong data-t=\"g5h\">Allow a small tolerance in installed length.<\/strong> <span data-t=\"g5b\">The calculator uses the NoFloods modules-per-metre rate for each model to give you the right number of modules. Depending on ground conditions and installation angle, expect \u00b12\u20133% variation in the final installed length.<\/span><\/div><\/div>\n    <\/div>\n  <\/div>\n\n  <div class=\"dims\">\n    <div class=\"dtit\" data-t=\"sections-title\">Gerade sections<\/div>\n\n    <!-- Map tool -->\n    <div class=\"map-mode-row\">\n      <button class=\"map-mode-btn active\" id=\"map-mode-map\" onclick=\"setInputMode('map')\">\n        <div class=\"mm-badge\">Empfohlen<\/div>\n        <div class=\"mm-label\">Auf Karte zeichnen<\/div>\n        <div class=\"mm-sub\">Zeichnen Sie den Verlauf Ihrer Barriere auf der Karte. L\u00e4ngen und Ecken werden automatisch berechnet.<\/div>\n      <\/button>\n      <button class=\"map-mode-btn\" id=\"map-mode-manual\" onclick=\"setInputMode('manual')\">\n        <div style=\"height:18px\"><\/div>\n        <div class=\"mm-label\">Manuell eingeben<\/div>\n        <div class=\"mm-sub\">Geben Sie die Streckenl\u00e4ngen in Metern ein. Verwenden Sie diese Option, wenn Sie bereits Messungen haben.<\/div>\n      <\/button>\n    <\/div>\n\n    <!-- Map panel -->\n    <div class=\"map-panel\" id=\"map-panel\">\n      <!-- Address search row -->\n      <div style=\"position:relative;margin-bottom:6px\" onclick=\"event.stopPropagation()\">\n        <div style=\"display:flex;gap:6px\">\n          <input type=\"text\" id=\"map-search-input\" placeholder=\"Adresse oder Ort suchen\u2026\" \n            style=\"flex:1;padding:7px 10px;font-size:12px;font-family:var(--fn);border:0.5px solid var(--bd);border-radius:var(--rm);background:var(--bg1);color:var(--t1);outline:none\"\n            onkeydown=\"if(event.key==='Enter'){event.stopPropagation();mapSearchAddress();}if(event.key==='Escape'){const sr=document.getElementById('map-search-results');if(sr)sr.style.display='none';}\"\n            onfocus=\"this.style.borderColor='var(--br)'\" onblur=\"this.style.borderColor='var(--bd)'\">\n          <button onclick=\"event.stopPropagation();mapSearchAddress()\" style=\"padding:7px 12px;background:var(--br);color:#fff;border:none;border-radius:var(--rm);font-size:12px;font-weight:700;font-family:var(--fn);cursor:pointer;white-space:nowrap\">Los<\/button>\n        <\/div>\n        <div id=\"map-search-results\" style=\"display:none;position:absolute;top:calc(100% + 2px);left:0;right:0;background:var(--bg1);border:0.5px solid var(--bd);border-radius:var(--rm);max-height:200px;overflow-y:auto;font-size:12px;z-index:10000;box-shadow:0 4px 12px rgba(0,0,0,.12)\" onclick=\"event.stopPropagation()\"><\/div>\n      <\/div>\n      <div class=\"map-tb\">\n        <button class=\"map-tb-btn active\" id=\"map-btn-draw\" onclick=\"mapSetMode('draw')\">Punkte zeichnen<\/button>\n        <button class=\"map-tb-btn\" id=\"map-btn-pan\" onclick=\"mapSetMode('pan')\">Karte verschieben<\/button>\n        <button class=\"map-tb-btn\" id=\"map-btn-sat\" onclick=\"mapToggleSat()\">Satellit<\/button>\n        <button class=\"map-tb-btn\" onclick=\"mapGoToStandort()\">Mein Standort<\/button>\n        <button class=\"map-tb-btn\" onclick=\"mapR\u00fcckg\u00e4ngig()\">R\u00fcckg\u00e4ngig<\/button>\n        <button class=\"map-tb-btn danger\" onclick=\"mapClearAll()\">Alles l\u00f6schen<\/button>\n      <\/div>\n      <div id=\"ew-map\"><\/div>\n      <div id=\"map-drawing-btns\" style=\"display:none;margin-top:8px;display:none;gap:8px;flex-wrap:wrap\">\n        <button onclick=\"mapFinishShape(false)\" style=\"padding:7px 14px;background:var(--br);color:#fff;border:none;border-radius:20px;font-size:12px;font-weight:700;font-family:var(--fn);cursor:pointer\">Offene Linie abschlie\u00dfen<\/button>\n        <button onclick=\"mapFinishShape(true)\" style=\"padding:7px 14px;background:var(--ok);color:#fff;border:none;border-radius:20px;font-size:12px;font-weight:700;font-family:var(--fn);cursor:pointer\">Als Polygon schlie\u00dfen<\/button>\n        <span style=\"font-size:11px;color:var(--t3);align-self:center\" id=\"map-points-count\"><\/span>\n      <\/div>\n      <div class=\"map-import-bar hidden\" id=\"map-import-bar\">\n        <div class=\"map-import-text\" id=\"map-import-text\">\u2013<span id=\"map-import-sub\"><\/span><\/div>\n        <button class=\"map-import-btn\" onclick=\"mapUseMeasurements()\">Diese Messungen verwenden<\/button>\n      <\/div>\n      <div style=\"font-size:11px;color:var(--t3);margin-top:6px;line-height:1.5\" id=\"map-hint-text\">Click on the map to place points along your barrier. Click \"Diese Messungen verwenden\" when done.<\/div>\n      <div style=\"font-size:11px;color:var(--t3);margin-top:4px;line-height:1.5\">\ud83d\udccd Der Kartenstandort wird nicht in Ihre Anfrage \u00fcbernommen \u2014 geben Sie die Standortadresse im <strong>Site location<\/strong> Feld im Anfragebereich unten ein.<\/div>\n    <\/div>\n\n    <!-- Close shape popup -->\n    <div class=\"map-close-popup\" id=\"map-close-popup\">\n      <h3>M\u00f6chten Sie die Form schlie\u00dfen?<\/h3>\n      <p>Sie haben offenbar in der N\u00e4he des Startpunkts geklickt. Was m\u00f6chten Sie tun?<\/p>\n      <div class=\"map-popup-btns\">\n        <button class=\"mcp-btn green\" onclick=\"mapPopupClose(true)\">Als Polygon schlie\u00dfen \u2014 full perimeter, no open ends<\/button>\n        <button class=\"mcp-btn orange\" onclick=\"mapPopupClose(false)\">Als offene Linie abschlie\u00dfen \u2014 Barriere mit offenen Enden<\/button>\n        <button class=\"mcp-btn neutral\" onclick=\"mapPopupCancel()\">Abbrechen \u2014 weiterzeichnen<\/button>\n      <\/div>\n    <\/div>\n\n    <!-- Imported badge shown when map data is active -->\n    <div id=\"map-imported-note\" style=\"display:none;margin-bottom:8px;padding:8px 10px;background:var(--okb);border:0.5px solid var(--okl);border-radius:var(--rm);flex-direction:column;gap:6px\">\n      <div style=\"display:flex;align-items:center;justify-content:space-between;gap:8px\">\n        <span style=\"font-size:12px;color:#27500A;font-weight:600;display:flex;align-items:center;gap:6px\">\n          <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\"><path d=\"M2 6l3 3 5-5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg>\n          Messungen aus der Karte \u00fcbernommen\n        <\/span>\n        <button onclick=\"clearMapImport()\" style=\"font-size:11px;color:#A32D2D;background:none;border:0.5px solid #F09595;border-radius:4px;cursor:pointer;padding:3px 8px;font-family:var(--fn);flex-shrink:0\">Alles l\u00f6schen &amp; start over<\/button>\n      <\/div>\n      <div style=\"font-size:11px;color:#3B6D11\">Scrollen Sie nach unten, um Ihre Ergebnisse zu sehen und die Konfiguration zu speichern \u2193<\/div>\n    <\/div>\n\n    <div id=\"sec-summary\" style=\"display:none;margin-bottom:10px;padding:10px 12px;background:var(--okb);border:0.5px solid var(--okl);border-radius:var(--rm);font-size:12px;color:var(--ok)\"><\/div>\n    <div class=\"sec-tabs-row\" id=\"sec-tabs-row\"><\/div>\n    <div id=\"sec-panels\"><\/div>\n    <button class=\"act-btn\" style=\"margin-top:10px;font-size:11px;padding:6px 12px\" id=\"add-sec-btn\" onclick=\"addSection()\">+ <span data-t=\"add-section\">Add another section<\/span><\/button>\n  <\/div>\n\n  <div class=\"dims\">\n    <div class=\"dtit\" data-t=\"acc-title\">Corners &amp; accessories<\/div>\n    <div class=\"dgrid\">\n\n      <div class=\"dg\" id=\"grp-corners\">\n        <div class=\"dgl\" data-t=\"corners-lbl\">Turns &amp; corners<\/div>\n\n        <!-- Situation picker -->\n        <div style=\"display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;margin-bottom:12px\">\n          <button class=\"situation-btn active\" id=\"sit-90\" onclick=\"setSituation('90')\">\n            <div class=\"sit-icon\">\u2310<\/div>\n            <div class=\"sit-label\">Scharfe 90\u00b0-Wende<\/div>\n            <div class=\"sit-sub\">Wie eine Geb\u00e4udeecke<\/div>\n          <\/button>\n          <button class=\"situation-btn\" id=\"sit-angle\" onclick=\"setSituation('angle')\">\n            <div class=\"sit-icon\">\u2220<\/div>\n            <div class=\"sit-label\">Anderer Winkel<\/div>\n            <div class=\"sit-sub\">Nicht genau 90\u00b0<\/div>\n          <\/button>\n          <button class=\"situation-btn\" id=\"sit-curve\" onclick=\"setSituation('curve')\">\n            <div class=\"sit-icon\">\u2312<\/div>\n            <div class=\"sit-label\">Sanfte Kurve<\/div>\n            <div class=\"sit-sub\">Allm\u00e4hliche Biegung, keine scharfe Wende<\/div>\n          <\/button>\n        <\/div>\n\n        <!-- 90\u00b0 mode -->\n        <div id=\"corner-mode-count\">\n          <div class=\"dfr\"><span data-t=\"inward-corners\">Inneneckes<\/span><div style=\"display:flex;align-items:center;gap:6px\"><input class=\"ni\" type=\"number\" id=\"f-cin\" min=\"0\" value=\"0\" oninput=\"calc()\" style=\"width:60px\"><span class=\"ds\" data-t=\"corners-unit\">corners<\/span><\/div><\/div>\n          <div class=\"dfr\" id=\"row-cout\"><span data-t=\"outward-corners\">Au\u00dfeneckes<\/span><div style=\"display:flex;align-items:center;gap:6px\"><input class=\"ni\" type=\"number\" id=\"f-cout\" min=\"0\" value=\"0\" oninput=\"calc()\" style=\"width:60px\"><span class=\"ds\" data-t=\"corners-unit\">corners<\/span><\/div><\/div>\n          <div class=\"cfb\" id=\"corner-fb-count\"><\/div>\n          <div id=\"t100-out-type\" style=\"display:none;margin-top:8px;padding:8px 10px;background:var(--wnb);border:0.5px solid #FAC775;border-radius:var(--rm)\">\n            <div style=\"font-size:11px;font-weight:700;color:#633806;margin-bottom:8px\">Au\u00dfeneckentyp ausw\u00e4hlen:<\/div>\n            <div style=\"display:flex;gap:8px\">\n              <button id=\"cout-type-modules\" onclick=\"setCoutType('modules')\" style=\"flex:1;padding:8px;font-size:11px;font-weight:600;font-family:var(--fn);border:1.5px solid #FAC775;border-radius:6px;background:#fff8ee;color:#633806;cursor:pointer;text-align:left\">\n                <strong style=\"display:block;margin-bottom:2px\">4 \u00d7 22,5\u00b0-Module<\/strong>\n                <span style=\"font-weight:400;color:#8B6914\">20-3221 \u00b7 Flexibler<\/span>\n              <\/button>\n              <button id=\"cout-type-fixed\" onclick=\"setCoutType('fixed')\" style=\"flex:1;padding:8px;font-size:11px;font-weight:600;font-family:var(--fn);border:0.5px solid var(--bd);border-radius:6px;background:var(--bg2);color:var(--t2);cursor:pointer;text-align:left\">\n                <strong style=\"display:block;margin-bottom:2px\">1 \u00d7 festes 90\u00b0-Doppelmodul<\/strong>\n                <span style=\"font-weight:400\">20-3230 \u00b7 Einfachere Montage<\/span>\n              <\/button>\n            <\/div>\n          <\/div>\n          <div id=\"t120-out-note\" style=\"display:none;margin-top:8px;padding:6px 9px;background:var(--wnb);border-radius:var(--rm);font-size:11px;color:#633806;line-height:1.5\">Bei T120 wird f\u00fcr Au\u00dfenecken ausschlie\u00dflich ein festes 90\u00b0-Doppelmodul (20-3243) verwendet \u2014 1 Modul pro 90\u00b0-Wende. Andere Au\u00dfenwinkel sind nicht verf\u00fcgbar.<\/div>\n          <div id=\"corner-fixed-note\" style=\"display:none;margin-top:8px;padding:6px 9px;background:var(--wnb);border-radius:var(--rm);font-size:11px;color:#633806;line-height:1.5\" data-t=\"corner-fixed-note\">Bei T100 werden f\u00fcr Au\u00dfenecken 22,5\u00b0-Module (20-3221) verwendet \u2014 4 Module pro 90\u00b0-Wende. Alternativ ist ein festes 90\u00b0-Doppelmodul (20-3230) verf\u00fcgbar.<\/div>\n          <div id=\"no-corner-note\" style=\"display:none;margin-top:8px;padding:6px 9px;background:var(--bg3);border-radius:var(--rm);font-size:11px;color:var(--t3);line-height:1.5\" data-t=\"no-corner-note\">No corner modules verf\u00fcgbar for S110. Use natural flex for gentle curves.<\/div>\n        <\/div>\n\n        <!-- Anderer Winkel mode -->\n        <div id=\"corner-mode-angle\" style=\"display:none\">\n          <div style=\"background:var(--blb);border-radius:var(--rm);padding:10px 12px;font-size:12px;color:#0C447C;line-height:1.6;margin-bottom:10px\">\n            Geben Sie Ihren tats\u00e4chlichen Wende-Winkel ein. Der Rechner zeigt Ihnen die ben\u00f6tigte Anzahl an Eckmodulen und wie genau die Passung ist.\n          <\/div>\n          <div class=\"dfr\"><span data-t=\"my-angle\">My turn angle<\/span><div style=\"display:flex;align-items:center;gap:6px\"><input class=\"ni\" type=\"number\" id=\"f-angle\" min=\"1\" max=\"180\" value=\"90\" oninput=\"calcAngle()\" style=\"width:70px\"><span class=\"ds\">\u00b0<\/span><\/div><\/div>\n          <div class=\"dfr\"><span data-t=\"turn-dir\">Turn direction<\/span><div style=\"display:flex;gap:6px\"><button class=\"mb\" id=\"adir-in\" onclick=\"setAdir('in')\" style=\"padding:4px 10px;font-size:11px\" data-t=\"inward\">Inward<\/button><button class=\"mb active\" id=\"adir-out\" onclick=\"setAdir('out')\" style=\"padding:4px 10px;font-size:11px\" data-t=\"outward\">Outward<\/button><\/div><\/div>\n          <div class=\"cfb\" id=\"corner-fb-angle\"><\/div>\n        <\/div>\n\n        <!-- Sanfte Kurve mode -->\n        <div id=\"corner-mode-curve\" style=\"display:none\">\n          <div id=\"curve-note\" style=\"background:var(--okb);border-left:3px solid var(--ok);border-radius:0 var(--rm) var(--rm) 0;padding:12px 14px;font-size:12px;color:#27500A;line-height:1.7\"><\/div>\n        <\/div>\n      <\/div>\n\n      <div class=\"dg\" id=\"grp-ends\">\n        <div class=\"dgl\" style=\"display:flex;align-items:center;gap:6px\">\n          <span data-t=\"end-modules-lbl\">End modules<\/span>\n          <span class=\"exact-info-trigger\" onclick=\"toggleEndInfo(event)\" style=\"font-size:10px\">? Was ist das?<\/span>\n        <\/div>\n        <div class=\"dfr\"><span data-t=\"left\">Left<\/span><div style=\"display:flex;align-items:center;gap:6px\"><input class=\"ni\" type=\"number\" id=\"f-el\" min=\"0\" value=\"0\" oninput=\"calc()\" style=\"width:60px\"><span class=\"ds\" data-t=\"pcs\">pcs<\/span><\/div><\/div>\n        <div class=\"dfr\" style=\"margin-top:6px\"><span data-t=\"right\">Right<\/span><div style=\"display:flex;align-items:center;gap:6px\"><input class=\"ni\" type=\"number\" id=\"f-er\" min=\"0\" value=\"0\" oninput=\"calc()\" style=\"width:60px\"><span class=\"ds\" data-t=\"pcs\">pcs<\/span><\/div><\/div>\n        <input type=\"hidden\" id=\"el-type\" value=\"std\">\n        <input type=\"hidden\" id=\"er-type\" value=\"std\">\n        <input type=\"hidden\" id=\"f-ael\" value=\"0\">\n        <input type=\"hidden\" id=\"f-aer\" value=\"0\">\n      <\/div>\n\n      <div class=\"dg\" id=\"grp-wall\">\n        <div class=\"dgl\" style=\"display:flex;align-items:center;gap:6px\">\n          <span data-t=\"wall-conn-lbl\">Wall connectors<\/span>\n          <span class=\"exact-info-trigger\" onclick=\"toggleWallInfo(event)\" style=\"font-size:10px\">? Was ist das?<\/span>\n        <\/div>\n        <div class=\"dfr\"><span data-t=\"left\">Left<\/span><div style=\"display:flex;align-items:center;gap:6px\"><input class=\"ni\" type=\"number\" id=\"f-wl\" min=\"0\" value=\"0\" oninput=\"calc()\" style=\"width:60px\"><span class=\"ds\" data-t=\"pcs\">pcs<\/span><\/div><\/div>\n        <div class=\"dfr\"><span data-t=\"right\">Right<\/span><div style=\"display:flex;align-items:center;gap:6px\"><input class=\"ni\" type=\"number\" id=\"f-wr\" min=\"0\" value=\"0\" oninput=\"calc()\" style=\"width:60px\"><span class=\"ds\" data-t=\"pcs\">pcs<\/span><\/div><\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n\n\n<!-- Cart moved to after results -->\n<div class=\"res\">\n  <div class=\"res-hdr\">\n    <span class=\"res-t\" data-t=\"results-title\">Ergebnisse<\/span>\n    <span class=\"res-tag\" id=\"r-tag\">\u2013<\/span>\n  <\/div>\n  <div class=\"fit-tabs\">\n    <button class=\"fit-tab active\" id=\"tab-std\" onclick=\"switchTab('std')\" data-t=\"standard-fit\">Standardpassung<\/button>\n    <button class=\"fit-tab\" id=\"tab-exact\" onclick=\"switchTab('exact')\">\n      <span data-t=\"exact-fit\">Exakte Passung<\/span>\n      <span class=\"avail-badge\" id=\"badge-exact\" data-t=\"verf\u00fcgbar\">verf\u00fcgbar<\/span>\n      <span class=\"exact-info-trigger\" onclick=\"toggleExactInfo(event)\" title=\"What is Exakte Passung?\">? Was ist das?<\/span>\n    <\/button>\n    <button class=\"fit-tab\" id=\"tab-weight\" onclick=\"switchTab('weight')\" data-t=\"weight-tab\">Weight &amp; storage <span id=\"badge-weight\" style=\"margin-left:5px;font-size:10px;padding:1px 7px;border-radius:8px;background:#E8E8E4;color:var(--t2);font-weight:700;vertical-align:middle\"><\/span><\/button>\n  <\/div>\n\n  <!-- Exakte Passung info popover -->\n  <div id=\"exact-info-popover\" style=\"display:none;position:relative;z-index:10\">\n    <div style=\"margin:0;background:var(--blb);border:0.5px solid var(--bll);border-top:none;padding:14px 16px;font-size:12px;color:#0C447C;line-height:1.7\">\n      <div style=\"display:flex;justify-content:space-between;align-items:flex-start;gap:10px;margin-bottom:10px\">\n        <strong style=\"font-size:13px;color:#0C447C\">When to use Exakte Passung<\/strong>\n        <button onclick=\"toggleExactInfo()\" style=\"background:none;border:none;cursor:pointer;color:#0C447C;font-size:16px;line-height:1;padding:0;flex-shrink:0\">\u00d7<\/button>\n      <\/div>\n      <p style=\"margin-bottom:8px\"><strong>Standardpassung<\/strong> is right for most installations. It gives you the correct number of modules \u2014 the last one may extend a few centimetres past your target, which is fine for open-ended runs.<\/p>\n      <p style=\"margin-bottom:8px\"><strong>Use Exakte Passung if<\/strong> your barrier needs to finish flush against a wall, a post, or another fixed obstacle. The calculator works out exactly which module to place at the end of the run to close the gap \u2014 and tells you what to set it to (not all options are verf\u00fcgbar for every series and model):<\/p>\n      <ul style=\"padding-left:16px;margin-bottom:8px;display:flex;flex-direction:column;gap:4px\">\n        <li><strong>Verstellbares gerades Modul module<\/strong> \u2014 slides between 57\u201370.5 cm. Used when the remaining gap is in that range. You set it on site.<\/li>\n        <li><strong>Adjustable end module<\/strong> (T50 only) \u2014 slides between 44\u201352 cm. Used for mid-range gaps.<\/li>\n        <li><strong>End module<\/strong> \u2014 fixed width, may need a small trim on site. Used for small gaps.<\/li>\n        <li><strong>Wall connector<\/strong> \u2014 mounts the barrier end directly to the wall. Used for very small gaps.<\/li>\n      <\/ul>\n      <p style=\"color:#185FA5;opacity:.8\">If you don't need a flush finish, just use Standardpassung and ignore this tab.<\/p>\n    <\/div>\n  <\/div>\n\n  <div class=\"fit-body\" id=\"body-std\">\n    <div class=\"barlbl\" data-t=\"length-comparison\">L\u00e4ngenvergleich<\/div>\n    <div class=\"barwrap\"><div class=\"bar-req\" id=\"bar-req\"><\/div><div class=\"bar-act\" id=\"bar-act\"><\/div><div class=\"bar-ov\" id=\"bar-ov\"><\/div><\/div>\n    <div class=\"bleg\">\n      <span><span class=\"bdot\" style=\"background:var(--blb);border:1px dashed #378ADD\"><\/span><span data-t=\"required\">Ben\u00f6tigt:<\/span> <strong id=\"lbl-req\">\u2013<\/strong><\/span>\n      <span><span class=\"bdot\" style=\"background:var(--brb)\"><\/span><span data-t=\"actual\">Tats\u00e4chlich:<\/span> <strong id=\"lbl-act\">\u2013<\/strong><\/span>\n      <span id=\"lbl-ov-wrap\"><span class=\"bdot\" style=\"background:var(--brl)\"><\/span><span data-t=\"over-by\">\u00dcberma\u00df:<\/span> <strong id=\"lbl-ov\">\u2013<\/strong><\/span>\n    <\/div>\n    <div class=\"scards\" id=\"r-sum\"><\/div>\n    <div class=\"bkwrap\"><div class=\"dtit\" data-t=\"breakdown\">Breakdown &amp; product codes<\/div><div id=\"r-bk\"><\/div><\/div>\n    <div class=\"notice\" id=\"r-note\"><\/div>\n    <div class=\"notice warn\" id=\"r-warn\" style=\"display:none\"><\/div>\n  <\/div>\n\n  <div class=\"fit-body\" id=\"body-weight\" style=\"display:none\">\n    <div class=\"notice info\" style=\"margin-top:0;margin-bottom:12px\" data-t=\"weight-note\">All weights are verified per module type. Pallet estimates are approximate \u2014 verify with NoFloods for exact logistics.<\/div>\n    <div class=\"wt-grid\" id=\"wt-grid\"><\/div>\n  <\/div>\n\n  <div class=\"fit-body\" id=\"body-exact\" style=\"display:none\">\n    <div class=\"ei\" id=\"ei\"><\/div>\n    <div id=\"eo-list\"><\/div>\n    <div class=\"notice\" id=\"en\"><\/div>\n  <\/div>\n\n<\/div><!-- end .res -->\n\n  <!-- Ergebnisse action bar \u2014 sticky at bottom once results are shown -->\n  <div id=\"results-action-bar\" style=\"display:none;position:sticky;bottom:0;z-index:100;padding:10px 16px;border-top:0.5px solid var(--bd);background:var(--bg2);box-shadow:0 -4px 12px rgba(0,0,0,.08)\">\n    <!-- Primary actions only -->\n    <div style=\"display:flex;gap:8px;flex-wrap:wrap;align-items:center\">\n      <button id=\"btn-save-another\" onclick=\"addToQuoteAndAnother()\" style=\"flex:1;min-width:140px;padding:10px 14px;background:var(--br);color:#fff;border:none;border-radius:var(--rm);font-size:13px;font-weight:700;font-family:var(--fn);cursor:pointer;display:flex;align-items:center;gap:7px;justify-content:center\">\n        <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" style=\"width:14px;height:14px;flex-shrink:0\"><path d=\"M8 3v10M3 8h10\" stroke-linecap=\"round\"\/><\/svg>\n        Save &amp; add another\n      <\/button>\n      <button id=\"btn-save-quote\" onclick=\"addToQuoteAndFinish()\" style=\"flex:1;min-width:140px;padding:10px 14px;background:var(--ok);color:#fff;border:none;border-radius:var(--rm);font-size:13px;font-weight:700;font-family:var(--fn);cursor:pointer;display:flex;align-items:center;gap:7px;justify-content:center\">\n        <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" style=\"width:14px;height:14px;flex-shrink:0\"><path d=\"M2.5 8.5l3.5 3.5 7-7\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg>\n        Save &amp; go to quote\n      <\/button>\n      <button onclick=\"if(cart.length>0){if(!confirm('This will clear all '+cart.length+' saved configuration'+(cart.length>1?'s':'')+' and start over. Are you sure?'))return;}resetConfig()\" style=\"padding:10px 14px;background:#fff;color:#A32D2D;border:1.5px solid #F09595;border-radius:var(--rm);font-size:12px;font-weight:700;font-family:var(--fn);cursor:pointer;white-space:nowrap\">\n        Alles l\u00f6schen &amp; start over\n      <\/button>\n    <\/div>\n  <\/div><!-- end results-action-bar -->\n\n<!-- Cart \u2014 always visible once something added -->\n<div id=\"cart-section\" style=\"display:none;margin-bottom:14px\">\n  <div class=\"card\" style=\"padding:0;overflow:hidden\">\n    <div style=\"padding:16px;border-bottom:0.5px solid var(--bd);display:flex;align-items:center;justify-content:space-between;gap:12px\">\n      <div>\n        <div style=\"font-size:15px;font-weight:700;color:var(--t1)\">Ihre Anfrage <span id=\"cart-count\" style=\"font-size:12px;font-weight:600;background:var(--br);color:#fff;border-radius:10px;padding:2px 9px;margin-left:6px\">0<\/span><\/div>\n        <div style=\"font-size:12px;color:var(--t2);margin-top:2px\">Jede Konfiguration ist unten aufgef\u00fchrt \u2014 entfernen Sie Eintr\u00e4ge oder f\u00fcgen Sie weitere hinzu<\/div>\n      <\/div>\n    <\/div>\n    <div id=\"cart-items\" style=\"padding:14px 16px;display:flex;flex-direction:column;gap:10px\"><\/div>\n    <div style=\"padding:14px 16px;border-top:0.5px solid var(--bd);background:var(--bg2);display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap\">\n      <div style=\"font-size:13px;color:var(--t2)\">\n        <strong id=\"cart-total-pcs\" style=\"color:var(--t1);font-size:15px\">0<\/strong> Module insgesamt\n        <span style=\"margin:0 8px;color:var(--bd)\">\u00b7<\/span>\n        <strong id=\"cart-total-kg\" style=\"color:var(--t1)\">0 kg<\/strong> Gesamtgewicht\n      <\/div>\n      <button onclick=\"scrollToQuote()\" style=\"padding:9px 20px;background:var(--br);color:#fff;border:none;border-radius:var(--rm);font-size:13px;font-weight:700;font-family:var(--fn);cursor:pointer;display:flex;align-items:center;gap:6px\">\n        <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" style=\"width:13px;height:13px\"><rect x=\"1\" y=\"3\" width=\"14\" height=\"10\" rx=\"1.5\"\/><path d=\"M1 4l7 5 7-5\" stroke-linecap=\"round\"\/><\/svg>\n        Angebot anfragen\n      <\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<div class=\"qwrap\" id=\"quote-section\">\n  <div class=\"qhdr\">\n    <h2>Angebotsanfrage senden<\/h2>\n   \n  <\/div>\n  <!-- Cart summary in quote -->\n  <div id=\"quote-cart-summary\" style=\"margin-bottom:0\">\n    <div id=\"quote-cart-items\" style=\"display:flex;flex-direction:column;gap:8px;margin:0 1.25rem 1rem\"><\/div>\n    <div id=\"quote-single-config\">\n      <div class=\"qsum\">\n        <div class=\"qs-t\">Ihre Konfiguration<\/div>\n        <div class=\"qs-m\" id=\"qs-model\">\u2013<\/div>\n        <div class=\"qs-g\" id=\"qs-grid\"><\/div>\n        <div class=\"qs-c\" id=\"qs-codes\"><\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n  <div class=\"qform\" id=\"qform\">\n\n    <!-- Dringlichkeit -->\n    <div class=\"ff\">\n      <label>Wann ben\u00f6tigen Sie es?<\/label>\n      <div class=\"urg-grid\">\n        <button class=\"urg-btn\" id=\"urg-asap\" onclick=\"setUrg('asap')\">\n          <div class=\"urg-ic\">\u26a1<\/div>\n          <div class=\"urg-lb\">So schnell wie m\u00f6glich<\/div>\n          <div class=\"urg-sb\">Dringend \u2014 Hochwasserrisiko<\/div>\n        <\/button>\n        <button class=\"urg-btn\" id=\"urg-weeks\" onclick=\"setUrg('weeks')\">\n          <div class=\"urg-ic\">\ud83d\udcc5<\/div>\n          <div class=\"urg-lb\">Innerhalb weniger Wochen<\/div>\n          <div class=\"urg-sb\">Planung im Voraus<\/div>\n        <\/button>\n        <button class=\"urg-btn\" id=\"urg-exploring\" onclick=\"setUrg('exploring')\">\n          <div class=\"urg-ic\">\ud83d\udd0d<\/div>\n          <div class=\"urg-lb\">Nur zur Orientierung<\/div>\n          <div class=\"urg-sb\">Noch kein fester Termin<\/div>\n        <\/button>\n      <\/div>\n    <\/div>\n\n    <!-- Standort -->\n    <div class=\"ff\">\n      <label>Site location <span style=\"font-weight:400;color:var(--t3);font-size:11px\">\u2014 wird in die E-Mail aufgenommen<\/span><\/label>\n      <div class=\"loc-row\">\n        <input class=\"fi\" type=\"text\" id=\"q-address\" placeholder=\"Adresse oder Beschreibung des Standorts\" oninput=\"onStandortInput()\">\n        <button class=\"loc-btn blu\" onclick=\"useGPS()\">\n          <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" style=\"width:13px;height:13px\"><circle cx=\"8\" cy=\"7\" r=\"3\"\/><path d=\"M8 1v2M8 12v2M1 7h2M12 7h2\"\/><\/svg>\n          Meinen Standort verwenden\n        <\/button>\n      <\/div>\n      <div id=\"coords\" style=\"display:none;font-size:11px;color:var(--ok);background:var(--okb);padding:4px 10px;border-radius:var(--rm);font-family:var(--fm);margin-top:4px\"><\/div>\n    <\/div>\n\n    <!-- Notizen -->\n    <div class=\"ff\">\n      <label>Zus\u00e4tzliche Hinweise oder Fragen<\/label>\n      <textarea class=\"fta\" id=\"q-notes\" placeholder=\"Ihr Name, Untergrundbedingungen, Hindernisse, besondere Anforderungen oder Fragen an NoFloods\u2026\" style=\"min-height:90px\" oninput=\"onNotizenChange()\"><\/textarea>\n    <\/div>\n\n  \n\n    <!-- Three CTAs -->\n    <div style=\"display:flex;gap:10px;flex-wrap:wrap;margin-bottom:8px\">\n      <button onclick=\"openCallbackModal()\" style=\"flex:1;min-width:160px;padding:12px 14px;background:#185FA5;color:#fff;border:none;border-radius:var(--rm);font-size:13px;font-weight:700;font-family:var(--fn);cursor:pointer;display:flex;align-items:center;justify-content:center;gap:7px\">\n        <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" style=\"width:14px;height:14px;flex-shrink:0\"><path d=\"M2 2.5C2 8.85 7.15 14 13.5 14h.5a1 1 0 001-1v-2a1 1 0 00-1-1l-2-.4a1 1 0 00-1 .5l-.6 1A8 8 0 014.9 6.6l1-.6a1 1 0 00.5-1L6 2.5a1 1 0 00-1-1H3a1 1 0 00-1 1z\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg>\n        R\u00fcckruf anfordern\n      <\/button>\n      <button onclick=\"openEmailMeModal()\" style=\"flex:1;min-width:160px;padding:12px 14px;background:var(--bg1);color:#185FA5;border:1.5px solid #B5D4F4;border-radius:var(--rm);font-size:13px;font-weight:700;font-family:var(--fn);cursor:pointer;display:flex;align-items:center;justify-content:center;gap:7px\">\n        <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" style=\"width:14px;height:14px;flex-shrink:0\"><rect x=\"1\" y=\"3\" width=\"14\" height=\"10\" rx=\"1.5\"\/><path d=\"M1 4l7 5 7-5\" stroke-linecap=\"round\"\/><\/svg>\n        Per E-Mail senden\n      <\/button>\n      <button onclick=\"sendEasyWallEmail()\" style=\"flex:1;min-width:160px;padding:12px 14px;background:var(--ok);color:#fff;border:none;border-radius:var(--rm);font-size:13px;font-weight:700;font-family:var(--fn);cursor:pointer;display:flex;align-items:center;justify-content:center;gap:7px\">\n        <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\"><rect x=\"1\" y=\"3\" width=\"14\" height=\"10\" rx=\"1.5\" stroke=\"white\" stroke-width=\"1.3\"\/><path d=\"M1 4l7 5 7-5\" stroke=\"white\" stroke-width=\"1.3\" stroke-linecap=\"round\"\/><\/svg>\n        Send quote request\n      <\/button>\n    <\/div>\n    \n\n    <!-- Hinweis -->\n    <div style=\"font-size:11px;color:var(--t3);line-height:1.7;padding-top:14px;border-top:0.5px solid var(--bd)\">\n      Nur Richtwert. Die Modulanzahl basiert auf Standardmessungen und dem \u00dcberlappungsmodell von 7 cm. Der tats\u00e4chliche Bedarf kann je nach Standortbedingungen, Unebenheiten des Untergrunds und Montageart abweichen. Pr\u00fcfen Sie die Ma\u00dfe vor der Bestellung immer vor Ort. NoFloods \u00fcbernimmt keine Haftung f\u00fcr Fehler, die aus der Nutzung des Rechners entstehen.\n    <\/div>\n  <\/div>\n<\/div>\n\n<\/div>\n<!-- \u2500\u2500 CALLBACK MODAL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n<div id=\"modal-callback\" style=\"display:none;position:fixed;inset:0;z-index:9999;background:rgba(0,0,0,.45);align-items:center;justify-content:center;padding:16px\">\n  <div style=\"background:var(--bg1);border-radius:16px;padding:24px;max-width:400px;width:100%;box-shadow:0 8px 32px rgba(0,0,0,.18)\">\n    <div style=\"font-size:17px;font-weight:700;color:var(--t1);margin-bottom:4px\">Mit NoFloods sprechen<\/div>\n    <div style=\"font-size:13px;color:var(--t2);margin-bottom:18px;line-height:1.5\">Ihre Konfiguration will be included. We'll call you to discuss.<\/div>\n\t\t\n<div class=\"wpcf7 no-js\" id=\"wpcf7-f42626-o1\" lang=\"de-DE\" dir=\"ltr\" data-wpcf7-id=\"42626\">\n<div class=\"screen-reader-response\"><p role=\"status\" aria-live=\"polite\" aria-atomic=\"true\"><\/p> <ul><\/ul><\/div>\n<form action=\"\/de\/wp-json\/wp\/v2\/pages\/42006#wpcf7-f42626-o1\" method=\"post\" class=\"wpcf7-form init\" aria-label=\"Kontaktformular\" novalidate=\"novalidate\" data-status=\"init\">\n<fieldset class=\"hidden-fields-container\"><input type=\"hidden\" name=\"_wpcf7\" value=\"42626\" \/><input type=\"hidden\" name=\"_wpcf7_version\" value=\"6.2.3\" \/><input type=\"hidden\" name=\"_wpcf7_locale\" value=\"de_DE\" \/><input type=\"hidden\" name=\"_wpcf7_unit_tag\" value=\"wpcf7-f42626-o1\" \/><input type=\"hidden\" name=\"_wpcf7_container_post\" value=\"0\" \/><input type=\"hidden\" name=\"_wpcf7_posted_data_hash\" value=\"\" \/><input type=\"hidden\" name=\"_wpcf7cf_hidden_group_fields\" value=\"[]\" \/><input type=\"hidden\" name=\"_wpcf7cf_hidden_groups\" value=\"[]\" \/><input type=\"hidden\" name=\"_wpcf7cf_visible_groups\" value=\"[]\" \/><input type=\"hidden\" name=\"_wpcf7cf_repeaters\" value=\"[]\" \/><input type=\"hidden\" name=\"_wpcf7cf_steps\" value=\"{}\" \/><input type=\"hidden\" name=\"_wpcf7cf_options\" value=\"{&quot;form_id&quot;:42626,&quot;conditions&quot;:[],&quot;settings&quot;:{&quot;animation&quot;:&quot;yes&quot;,&quot;animation_intime&quot;:&quot;200&quot;,&quot;animation_outtime&quot;:&quot;200&quot;,&quot;conditions_ui&quot;:&quot;normal&quot;,&quot;notice_dismissed&quot;:&quot;&quot;,&quot;repeater_remove_button&quot;:&quot;bottom&quot;,&quot;notice_dismissed_rollback-cf7-6.1.7&quot;:true}}\" \/><input type=\"hidden\" name=\"_wpcf7_recaptcha_response\" value=\"\" \/>\n<\/fieldset>\n<div class=\"uacf7-form-wrapper-container uacf7-form-42626  \"><div style=\"display:none;\"><span class=\"wpcf7-form-control-wrap\" data-name=\"calc_summary\"><textarea cols=\"40\" rows=\"10\" maxlength=\"2000\" class=\"wpcf7-form-control wpcf7-textarea wpcf7-validates-as-required\" id=\"calc_summary_2\" readonly=\"readonly\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Bitte f\u00fcllen Sie zuerst das Feld mit dem Rechner aus\" name=\"calc_summary\"><\/textarea><\/span><\/div>\n\n  <label> Name*\n    <span class=\"wpcf7-form-control-wrap\" data-name=\"your-name\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" autocomplete=\"name\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"your-name\" \/><\/span> <\/label> \n Telefonnummer*\n    <span class=\"wpcf7-form-control-wrap\" data-name=\"your-phone\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-tel wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-tel\" autocomplete=\"tel\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"tel\" name=\"your-phone\" \/><\/span> <\/label>\n\n<label>  Beste Zeit f\u00fcr den Anruf (optional)\n    <span class=\"wpcf7-form-control-wrap\" data-name=\"your-time\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"your-time\" \/><\/span> <\/label>\n<br><input class=\"wpcf7-form-control wpcf7-submit has-spinner\" type=\"submit\" value=\"Senden\" \/><\/div><input type=\"text\" class=\"wpcf7_hp_field\" name=\"wpcf7_hp_field\" value=\"\" tabindex=\"-1\" autocomplete=\"off\" \/><div class=\"wpcf7-response-output\" aria-hidden=\"true\"><\/div>\n<\/form>\n<\/div>\n\n  <\/div>\n<\/div>\n\n<!-- \u2500\u2500 EMAIL ME MODAL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n<div id=\"modal-email-me\" style=\"display:none;position:fixed;inset:0;z-index:9999;background:rgba(0,0,0,.45);align-items:center;justify-content:center;padding:16px\">\n  <div style=\"background:var(--bg1);border-radius:16px;padding:24px;max-width:400px;width:100%;box-shadow:0 8px 32px rgba(0,0,0,.18)\">\n    <div style=\"font-size:17px;font-weight:700;color:var(--t1);margin-bottom:4px\">Ihre Konfiguration speichern<\/div>\n    <div style=\"font-size:13px;color:var(--t2);margin-bottom:18px;line-height:1.5\">Wir senden Ihnen die vollst\u00e4ndige Aufschl\u00fcsselung per E-Mail, damit Sie sie sp\u00e4ter pr\u00fcfen oder mit anderen teilen k\u00f6nnen.<\/div>\n\t\n\t\n<div class=\"wpcf7 no-js\" id=\"wpcf7-f42627-o2\" lang=\"de-DE\" dir=\"ltr\" data-wpcf7-id=\"42627\">\n<div class=\"screen-reader-response\"><p role=\"status\" aria-live=\"polite\" aria-atomic=\"true\"><\/p> <ul><\/ul><\/div>\n<form action=\"\/de\/wp-json\/wp\/v2\/pages\/42006#wpcf7-f42627-o2\" method=\"post\" class=\"wpcf7-form init\" aria-label=\"Kontaktformular\" novalidate=\"novalidate\" data-status=\"init\">\n<fieldset class=\"hidden-fields-container\"><input type=\"hidden\" name=\"_wpcf7\" value=\"42627\" \/><input type=\"hidden\" name=\"_wpcf7_version\" value=\"6.2.3\" \/><input type=\"hidden\" name=\"_wpcf7_locale\" value=\"de_DE\" \/><input type=\"hidden\" name=\"_wpcf7_unit_tag\" value=\"wpcf7-f42627-o2\" \/><input type=\"hidden\" name=\"_wpcf7_container_post\" value=\"0\" \/><input type=\"hidden\" name=\"_wpcf7_posted_data_hash\" value=\"\" \/><input type=\"hidden\" name=\"_wpcf7cf_hidden_group_fields\" value=\"[]\" \/><input type=\"hidden\" name=\"_wpcf7cf_hidden_groups\" value=\"[]\" \/><input type=\"hidden\" name=\"_wpcf7cf_visible_groups\" value=\"[]\" \/><input type=\"hidden\" name=\"_wpcf7cf_repeaters\" value=\"[]\" \/><input type=\"hidden\" name=\"_wpcf7cf_steps\" value=\"{}\" \/><input type=\"hidden\" name=\"_wpcf7cf_options\" value=\"{&quot;form_id&quot;:42627,&quot;conditions&quot;:[],&quot;settings&quot;:{&quot;animation&quot;:&quot;yes&quot;,&quot;animation_intime&quot;:&quot;200&quot;,&quot;animation_outtime&quot;:&quot;200&quot;,&quot;conditions_ui&quot;:&quot;normal&quot;,&quot;notice_dismissed&quot;:&quot;&quot;,&quot;repeater_remove_button&quot;:&quot;bottom&quot;,&quot;notice_dismissed_rollback-cf7-6.1.7&quot;:true}}\" \/><input type=\"hidden\" name=\"_wpcf7_recaptcha_response\" value=\"\" \/>\n<\/fieldset>\n<div class=\"uacf7-form-wrapper-container uacf7-form-42627  \"><div style=\"display:none;\"><span class=\"wpcf7-form-control-wrap\" data-name=\"calc_summary\"><textarea cols=\"40\" rows=\"10\" maxlength=\"2000\" class=\"wpcf7-form-control wpcf7-textarea wpcf7-validates-as-required\" id=\"calc_summary_3\" readonly=\"readonly\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Bitte f\u00fcllen Sie das Feld zuerst mithilfe des Kalkulators aus.\" name=\"calc_summary\"><\/textarea><\/span><\/div>\n\n <label>  Name*\n    <span class=\"wpcf7-form-control-wrap\" data-name=\"your-name\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" autocomplete=\"name\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"your-name\" \/><\/span> <\/label> \n\n  E-Mail*\n    <span class=\"wpcf7-form-control-wrap\" data-name=\"your-email\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-email wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-email\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"email\" name=\"your-email\" \/><\/span> <\/label>\n\n<br><input class=\"wpcf7-form-control wpcf7-submit has-spinner\" type=\"submit\" value=\"AN MICH SENDEN\" \/><\/div><input type=\"text\" class=\"wpcf7_hp_field\" name=\"wpcf7_hp_field\" value=\"\" tabindex=\"-1\" autocomplete=\"off\" \/><div class=\"wpcf7-response-output\" aria-hidden=\"true\"><\/div>\n<\/form>\n<\/div>\n\n\t\n  <\/div>\n<\/div>\n\n<!-- \u2500\u2500 SUCCESS MODAL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n<div id=\"modal-success\" style=\"display:none;position:fixed;inset:0;z-index:9999;background:rgba(0,0,0,.45);align-items:center;justify-content:center;padding:16px\">\n  <div style=\"background:var(--bg1);border-radius:16px;padding:28px;max-width:360px;width:100%;box-shadow:0 8px 32px rgba(0,0,0,.18);text-align:center\">\n    <div style=\"font-size:32px;margin-bottom:12px\">\u2713<\/div>\n    <div id=\"success-title\" style=\"font-size:17px;font-weight:700;color:var(--t1);margin-bottom:6px\"><\/div>\n    <div id=\"success-body\" style=\"font-size:13px;color:var(--t2);line-height:1.6;margin-bottom:20px\"><\/div>\n    <button onclick=\"closeModal('modal-success')\" style=\"padding:10px 24px;background:var(--ok);color:#fff;border:none;border-radius:var(--rm);font-size:13px;font-weight:700;font-family:var(--fn);cursor:pointer\">Fertig<\/button>\n  <\/div>\n<\/div>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/leaflet\/1.9.4\/leaflet.min.js\"><\/script>\n<script>\n\/\/ \u2500\u2500 MAP TOOL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nlet ewMap=null, mapMode='draw', mapSatOn=false;\nlet mapCurrentPoints=[], mapCurrentMarkers=[], mapCurrentPolyline=null, mapCurrentPreview=null;\nlet mapShapes=[];\nconst mapStreetLayer=()=>L.tileLayer('https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png',{attribution:'\u00a9 OpenStreetMap',maxZoom:20});\nconst mapSatLayer=()=>L.tileLayer('https:\/\/server.arcgisonline.com\/ArcGIS\/rest\/services\/World_Imagery\/MapServer\/tile\/{z}\/{y}\/{x}',{attribution:'\u00a9 Esri',maxZoom:20});\nlet _streetL=null,_satL=null;\nconst mapColors=['#D85A30','#185FA5','#3B6D11','#BA7517','#993556'];\nconst SNAP_ANGLES_EW=[45,90,135];\nconst SNAP_TOL=15;\n\nfunction mapSearchAddress(){\n  const q=(document.getElementById('map-search-input').value||'').trim();\n  if(!q)return;\n  const resultsEl=document.getElementById('map-search-results');\n  resultsEl.style.display='block';\n  resultsEl.innerHTML='<div style=\"padding:8px 12px;color:var(--t3)\">Suche\u2026<\/div>';\n  const url='https:\/\/nominatim.openstreetmap.org\/search?format=json&limit=5&accept-language=en&q='+encodeURIComponent(q);\n  fetch(url,{mode:'cors'})\n    .then(r=>{if(!r.ok)throw new Error('HTTP '+r.status);return r.json();})\n    .then(data=>{\n      if(!data||!data.length){resultsEl.innerHTML='<div style=\"padding:8px 12px;color:var(--t3)\">Keine Ergebnisse gefunden<\/div>';return;}\n      resultsEl.innerHTML=data.map(r=>{\n        const parts=(r.display_name||'').split(',');\n        \/\/ Build a meaningful short name: first 2-3 parts (street+number, city)\n        const name=parts.slice(0,3).map(p=>p.trim()).filter(Boolean).join(', ');\n        const sub=parts.slice(3,5).map(p=>p.trim()).filter(Boolean).join(', ');\n        const lat=parseFloat(r.lat),lng=parseFloat(r.lon);\n        return`<div onclick=\"mapGoToResult(${lat},${lng},'${name.replace(\/'\/g,\"\\\\'\")}')\"\n          style=\"padding:8px 12px;cursor:pointer;border-bottom:0.5px solid var(--bd);line-height:1.4\"\n          onmouseover=\"this.style.background='var(--bg2)'\" onmouseout=\"this.style.background=''\">\n          <div style=\"font-weight:600;color:var(--t1);font-size:12px\">${name}<\/div>\n          ${sub?`<div style=\"font-size:10px;color:var(--t3)\">${sub}<\/div>`:''}\n        <\/div>`;\n      }).join('');\n    })\n    .catch(err=>{\n      \/\/ Fallback: try loading via a script tag (JSONP-style workaround)\n      resultsEl.innerHTML='<div style=\"padding:8px 12px;color:var(--t3)\">Alternative Methode wird versucht\u2026<\/div>';\n      const s=document.createElement('script');\n      window._nominatimCB=function(data){\n        document.head.removeChild(s);\n        if(!data||!data.length){resultsEl.innerHTML='<div style=\"padding:8px 12px;color:var(--t3)\">Keine Ergebnisse gefunden<\/div>';return;}\n        resultsEl.innerHTML=data.map(r=>{\n          const parts=(r.display_name||'').split(',');\n          const name=parts.slice(0,3).map(p=>p.trim()).filter(Boolean).join(', ');\n          const sub=parts.slice(3,5).map(p=>p.trim()).filter(Boolean).join(', ');\n          const lat=parseFloat(r.lat),lng=parseFloat(r.lon);\n          return`<div onclick=\"mapGoToResult(${lat},${lng},'${name.replace(\/'\/g,\"\\\\'\")}')\"\n            style=\"padding:8px 12px;cursor:pointer;border-bottom:0.5px solid var(--bd);line-height:1.4\"\n            onmouseover=\"this.style.background='var(--bg2)'\" onmouseout=\"this.style.background=''\">\n            <div style=\"font-weight:600;color:var(--t1);font-size:12px\">${name}<\/div>\n            ${sub?`<div style=\"font-size:10px;color:var(--t3)\">${sub}<\/div>`:''}\n          <\/div>`;\n        }).join('');\n      };\n      s.onerror=()=>{resultsEl.innerHTML='<div style=\"padding:8px 12px;color:var(--t3);line-height:1.6\">Die Suche wird vom Browser blockiert.<br>Geben Sie Ihre Adresse stattdessen im Feld <strong>Standort<\/strong> im Anfragebereich unten ein \u2014 sie wird in die E-Mail aufgenommen.<\/div>';};\n      s.src='https:\/\/nominatim.openstreetmap.org\/search?format=json&limit=5&accept-language=en&json_callback=_nominatimCB&q='+encodeURIComponent(q);\n      document.head.appendChild(s);\n    });\n}\n\nfunction mapGoToResult(lat,lng,name){\n  if(!ewMap)return;\n  ewMap.setView([parseFloat(lat),parseFloat(lng)],17);\n  document.getElementById('map-search-results').style.display='none';\n  document.getElementById('map-search-input').value=name;\n}\n\nfunction mapCloseSearch(){\n  const sr=document.getElementById('map-search-results');\n  if(sr)sr.style.display='none';\n}\n\nfunction initMap(){\n  if(ewMap)return;\n  ewMap=L.map('ew-map',{center:[55.676,12.568],zoom:15,zoomControl:true,doubleClickZoom:false});\n  _streetL=mapStreetLayer().addTo(ewMap);\n  ewMap.on('click',mapOnClick);\n  ewMap.on('mousemove',mapOnMove);\n  mapSetMode('draw');\n}\n\nfunction setInputMode(m){\n  document.getElementById('map-mode-map').classList.toggle('active',m==='map');\n  document.getElementById('map-mode-manual').classList.toggle('active',m==='manual');\n  const panel=document.getElementById('map-panel');\n  if(m==='map'){\n    panel.classList.add('open');\n    setTimeout(()=>{initMap();ewMap.invalidateSize();},50);\n  } else {\n    panel.classList.remove('open');\n  }\n}\n\nfunction mapSetMode(m){\n  mapMode=m;\n  document.getElementById('map-btn-draw').classList.toggle('active',m==='draw');\n  document.getElementById('map-btn-pan').classList.toggle('active',m==='pan');\n  document.getElementById('ew-map').style.cursor=m==='draw'?'crosshair':'grab';\n  if(m==='pan')ewMap.dragging.enable();\n  else ewMap.dragging.disable();\n  if(m==='pan'&&mapCurrentPreview){ewMap.removeLayer(mapCurrentPreview);mapCurrentPreview=null;}\n}\n\nfunction mapToggleSat(){\n  mapSatOn=!mapSatOn;\n  if(mapSatOn){ewMap.removeLayer(_streetL);_satL=mapSatLayer().addTo(ewMap);}\n  else{ewMap.removeLayer(_satL);_streetL=mapStreetLayer().addTo(ewMap);}\n  document.getElementById('map-btn-sat').classList.toggle('active',mapSatOn);\n}\n\nfunction mapGoToStandort(){\n  if(!navigator.geolocation){return;}\n  navigator.geolocation.getCurrentPosition(p=>{\n    ewMap.setView([p.coords.latitude,p.coords.longitude],18);\n  });\n}\n\nfunction mapSnapAngle(raw){\n  for(const t of SNAP_ANGLES_EW){if(Math.abs(raw-t)<=SNAP_TOL)return{angle:t,snapped:true,raw};}\n  return{angle:raw,snapped:false,raw};\n}\n\nfunction mapHaversine(a,b){\n  const R=6371000,\u03c61=a.lat*Math.PI\/180,\u03c62=b.lat*Math.PI\/180;\n  const \u0394\u03c6=(b.lat-a.lat)*Math.PI\/180,\u0394\u03bb=(b.lng-a.lng)*Math.PI\/180;\n  const x=Math.sin(\u0394\u03c6\/2)**2+Math.cos(\u03c61)*Math.cos(\u03c62)*Math.sin(\u0394\u03bb\/2)**2;\n  return R*2*Math.atan2(Math.sqrt(x),Math.sqrt(1-x));\n}\n\nfunction mapAngleBetween(p1,v,p2){\n  const a={x:p1.lat-v.lat,y:p1.lng-v.lng},b={x:p2.lat-v.lat,y:p2.lng-v.lng};\n  const dot=a.x*b.x+a.y*b.y,mA=Math.sqrt(a.x**2+a.y**2),mB=Math.sqrt(b.x**2+b.y**2);\n  if(!mA||!mB)return 180;\n  return Math.round(180-Math.acos(Math.max(-1,Math.min(1,dot\/(mA*mB))))*180\/Math.PI);\n}\n\nfunction mapGetCorners(pts,closed){\n  const corners=[],n=pts.length;\n  if(closed){\n    for(let i=0;i<n;i++){\n      const raw=mapAngleBetween(pts[(i-1+n)%n],pts[i],pts[(i+1)%n]);\n      corners.push({index:i,...mapSnapAngle(raw)});\n    }\n  } else {\n    for(let i=1;i<n-1;i++){\n      const raw=mapAngleBetween(pts[i-1],pts[i],pts[i+1]);\n      corners.push({index:i,...mapSnapAngle(raw)});\n    }\n  }\n  return corners;\n}\n\nfunction mapOnClick(e){\n  if(mapMode!=='draw')return;\n  if(mapCurrentPoints.length>=3){\n    const fp=mapCurrentPoints[0];\n    const cp=ewMap.latLngToContainerPoint(e.latlng);\n    const fp2=ewMap.latLngToContainerPoint(fp);\n    if(Math.sqrt((cp.x-fp2.x)**2+(cp.y-fp2.y)**2)<20){\n      document.getElementById('map-close-popup').style.display='block';\n      return;\n    }\n  }\n  mapAddPoint(e.latlng);\n}\n\nfunction mapOnMove(e){\n  if(mapMode!=='draw'||!mapCurrentPoints.length)return;\n  if(mapCurrentPreview)ewMap.removeLayer(mapCurrentPreview);\n  mapCurrentPreview=L.polyline([...mapCurrentPoints,e.latlng],{color:'#D85A30',weight:2,dashArray:'5 5',opacity:.5}).addTo(ewMap);\n}\n\nfunction mapUpdateDrawingBtns(){\n  const btns=document.getElementById('map-drawing-btns');\n  const count=document.getElementById('map-points-count');\n  if(mapCurrentPoints.length>=2){\n    btns.style.display='flex';\n    count.textContent=mapCurrentPoints.length+' Punkt'+(mapCurrentPoints.length!==1?'e':'')+' gesetzt';\n  } else {\n    btns.style.display='none';\n  }\n}\n\nfunction mapAddPoint(ll){\n  mapCurrentPoints.push(ll);\n  const m=L.circleMarker(ll,{radius:mapCurrentPoints.length===1?8:6,color:'#fff',weight:2,fillColor:'#D85A30',fillOpacity:1}).addTo(ewMap);\n  if(mapCurrentPoints.length===1)m.bindTooltip('Start point \u2014 click here again to close',{permanent:false,direction:'top'});\n  mapCurrentMarkers.push(m);\n  if(mapCurrentPolyline)ewMap.removeLayer(mapCurrentPolyline);\n  if(mapCurrentPoints.length>1)mapCurrentPolyline=L.polyline(mapCurrentPoints,{color:'#D85A30',weight:3}).addTo(ewMap);\n  mapUpdateDrawingBtns();\n  mapUpdateImportBar();\n}\n\nfunction mapPopupClose(closed){\n  document.getElementById('map-close-popup').style.display='none';\n  mapFinishShape(closed);\n}\nfunction mapPopupCancel(){document.getElementById('map-close-popup').style.display='none';}\n\nfunction mapFinishShape(closed){\n  if(mapCurrentPoints.length<2)return;\n  const color=mapColors[mapShapes.length%mapColors.length];\n  const layers=[];\n  if(mapCurrentPolyline){ewMap.removeLayer(mapCurrentPolyline);mapCurrentPolyline=null;}\n  if(mapCurrentPreview){ewMap.removeLayer(mapCurrentPreview);mapCurrentPreview=null;}\n  const coords=closed?[...mapCurrentPoints,mapCurrentPoints[0]]:mapCurrentPoints;\n  layers.push(L.polyline(coords,{color,weight:3,opacity:.9}).addTo(ewMap));\n  mapCurrentMarkers.forEach(m=>{m.setStyle({fillColor:color});layers.push(m);});\n  \/\/ Segment length labels\n  const allPts=closed?[...mapCurrentPoints,mapCurrentPoints[0]]:mapCurrentPoints;\n  for(let i=0;i<allPts.length-1;i++){\n    const mid={lat:(allPts[i].lat+allPts[i+1].lat)\/2,lng:(allPts[i].lng+allPts[i+1].lng)\/2};\n    const d=mapHaversine(allPts[i],allPts[i+1]);\n    const lbl=L.divIcon({html:`<div style=\"background:rgba(255,255,255,.9);border:0.5px solid #ddd;border-radius:3px;padding:1px 5px;font-size:10px;color:#1a1a18;white-space:nowrap\">${Math.round(d*10)\/10}m<\/div>`,className:'',iconAnchor:[20,8]});\n    layers.push(L.marker(mid,{icon:lbl}).addTo(ewMap));\n  }\n  \/\/ Corner angle labels\n  const corners=mapGetCorners(mapCurrentPoints,closed);\n  corners.forEach(c=>{\n    const pt=mapCurrentPoints[c.index];\n    const lbl=L.divIcon({html:`<div style=\"background:${c.snapped?'#EAF3DE':'#FAEEDA'};border:1px solid ${c.snapped?'#C0DD97':'#FAC775'};border-radius:4px;padding:2px 6px;font-size:10px;font-weight:700;color:${c.snapped?'#27500A':'#633806'};white-space:nowrap\">${c.angle}\u00b0${c.snapped?'\u2713':''}<\/div>`,className:'',iconAnchor:[-4,8]});\n    layers.push(L.marker(pt,{icon:lbl}).addTo(ewMap));\n  });\n  mapShapes.push({points:[...mapCurrentPoints],closed,layers,corners});\n  mapCurrentPoints=[];mapCurrentMarkers=[];\n  document.getElementById('map-close-popup').style.display='none';\n  document.getElementById('map-drawing-btns').style.display='none';\n  mapUpdateImportBar();\n}\n\nfunction mapR\u00fcckg\u00e4ngig(){\n  if(!mapCurrentPoints.length)return;\n  ewMap.removeLayer(mapCurrentMarkers.pop());\n  mapCurrentPoints.pop();\n  if(mapCurrentPolyline){ewMap.removeLayer(mapCurrentPolyline);mapCurrentPolyline=null;}\n  if(mapCurrentPoints.length>1)mapCurrentPolyline=L.polyline(mapCurrentPoints,{color:'#D85A30',weight:3}).addTo(ewMap);\n  if(mapCurrentPreview){ewMap.removeLayer(mapCurrentPreview);mapCurrentPreview=null;}\n  mapUpdateDrawingBtns();\n  mapUpdateImportBar();\n}\n\nfunction mapClearAll(){\n  mapCurrentPoints=[];\n  mapCurrentMarkers.forEach(m=>ewMap.removeLayer(m));\n  mapCurrentMarkers=[];\n  if(mapCurrentPolyline){ewMap.removeLayer(mapCurrentPolyline);mapCurrentPolyline=null;}\n  if(mapCurrentPreview){ewMap.removeLayer(mapCurrentPreview);mapCurrentPreview=null;}\n  mapShapes.forEach(s=>s.layers.forEach(l=>ewMap.removeLayer(l)));\n  mapShapes=[];\n  document.getElementById('map-close-popup').style.display='none';\n  document.getElementById('map-drawing-btns').style.display='none';\n  document.getElementById('map-import-bar').classList.add('hidden');\n  resetCalculatorInputs();\n}\n\nfunction mapUpdateImportBar(){\n  const bar=document.getElementById('map-import-bar');\n  const txt=document.getElementById('map-import-text');\n  const sub=document.getElementById('map-import-sub');\n  if(!mapShapes.length&&!mapCurrentPoints.length){bar.classList.add('hidden');return;}\n  if(!mapShapes.length){bar.classList.add('hidden');return;}\n  let totalLen=0,totalSec=0,totalCor=0,totalEnd=0,segsAll=[];\n  mapShapes.forEach(s=>{\n    const allPts=s.closed?[...s.points,s.points[0]]:s.points;\n    for(let i=0;i<allPts.length-1;i++){const d=mapHaversine(allPts[i],allPts[i+1]);totalLen+=d;totalSec++;segsAll.push(Math.round(d*10)\/10);}\n    totalCor+=s.corners.length;\n    if(!s.closed)totalEnd+=2;\n  });\n  bar.classList.remove('hidden');\n  txt.innerHTML=\n    '<span style=\"font-weight:700;color:var(--ok)\">'+totalSec+' section'+(totalSec!==1?'s':'')+' \u00b7 '+totalCor+' corner'+(totalCor!==1?'s':'')+' \u00b7 '+totalEnd+' open end'+(totalEnd!==1?'s':'')+'<\/span>'+\n    '<span style=\"display:block;font-size:11px;color:#3B6D11;margin-top:3px\">'+segsAll.map(s=>s+'m').join(' + ')+' = '+Math.round(totalLen*10)\/10+'m total<\/span>';\n}\n\nfunction mapUseMeasurements(){\n  if(!mapShapes.length)return;\n  const newSections=[];\n  let totalCorners=0;\n  let newEnds=0;\n  mapShapes.forEach(s=>{\n    const allPts=s.closed?[...s.points,s.points[0]]:s.points;\n    for(let i=0;i<allPts.length-1;i++){\n      newSections.push(Math.round(mapHaversine(allPts[i],allPts[i+1])*10)\/10);\n    }\n    totalCorners+=s.corners.length;\n    if(!s.closed)newEnds+=2;\n  });\n  \/\/ Import sections\n  sections=newSections.map((len)=>({id:secNextId++,len}));\n  activeSec=0;\n  renderSections();\n  \/\/ Import corners \u2014 set to inward 90\u00b0 count (most common)\n  \/\/ User can adjust in the corners section if needed\n  document.getElementById('f-cin').value=totalCorners;\n  document.getElementById('f-cout').value=0;\n  \/\/ Switch to 90\u00b0 corner mode so the input is visible\n  setCornerMode('count');\n  \/\/ End modules: leave at 0 \u2014 user can add them manually if needed\n  \/\/ Show imported badge, collapse map\n  document.getElementById('map-imported-note').style.display='flex';\n  document.getElementById('map-panel').classList.remove('open');\n  document.getElementById('map-mode-map').classList.remove('active');\n  document.getElementById('map-mode-manual').classList.add('active');\n  calc();\n  \/\/ Scroll to results so user can see the Save buttons\n  setTimeout(()=>{\n    const res=document.querySelector('.res');\n    if(res)res.scrollIntoView({behavior:'smooth',block:'start'});\n  },200);\n}\n\nfunction resetCalculatorInputs(){\n  sections=[{id:secNextId++,len:0}];activeSec=0;renderSections();\n  document.getElementById('f-cin').value=0;\n  document.getElementById('f-cout').value=0;\n  document.getElementById('f-el').value=0;\n  document.getElementById('f-er').value=0;\n  document.getElementById('f-wl').value=0;\n  document.getElementById('f-wr').value=0;\n  document.getElementById('map-imported-note').style.display='none';\n  calc();\n}\n\nfunction clearMapImport(){\n  \/\/ Reset all calculator inputs\n  resetCalculatorInputs();\n  \/\/ Clear the map drawing too\n  mapClearAll();\n  \/\/ Reopen map\n  setInputMode('map');\n}\n<\/script>\n<script>\n\/\/ \u2500\u2500 TRANSLATIONS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst LANG={\n  en:{title:'EasyWall calculator',subtitle:'Estimate modules for your flood barrier','s1title':'Choose your series','s1sub':'Each series is optimised for different site conditions','pill-t':'Premium \u00b7 T-series','pill-s':'Flexible \u00b7 S-series','pill-d':'Uneven ground \u00b7 D-series','ser-t-desc':'HydroFoam\u2122 base & HydroSeal\u2122 edge. Best watertight performance. Adjustable units verf\u00fcgbar.','ser-s-desc':'Slide connection allows 3\u20135\u00b0 adjustment. Ideal for urban & irregular layouts.','ser-d-desc':'Detachable membrane for gravel, soil & mixed terrain. Not verf\u00fcgbar in USA, UK, IE, CA & QA.','s2title':'Select height','s2sub':'Protection height in cm','s3title':'Barrier length & accessories','s3sub':'Enter your straight-run lengths and accessories below','guide-toggle':'How to measure your site','g1h':'Measure straight sections only.','g1b':'Walk each straight run and measure it independently. Do not include corners or turns in the length. You can add multiple separate sections below.','g2h':'Identify your turns.','g2b':'Sanfte Kurves (a few degrees per joint) need no corner modules \u2014 just connect modules in a slight arc. The S-series handles up to 3\u20135\u00b0 per joint by design. For distinct bends, use corner modules.','g3h':'Check for walls and open ends.','g3b':'If the barrier runs against a wall, you need a wall connector. Each open end needs an end module (left or right).','g4h':'Consider your ground surface.','g4b':'All EasyWall series can handle uneven ground \u2014 a detachable membrane can be added to any model. The D-series has it built in as standard.','g5h':'Allow a small tolerance in installed length.','g5b':'The calculator uses the NoFloods modules-per-metre rate for each model to give you the right number of modules. Depending on ground conditions and installation angle, expect \u00b12\u20133% variation in the final installed length.','sections-title':'Gerade sections','add-section':'Add another section','acc-title':'Corners & accessories','corners-lbl':'Turns & corners','corner-mode-90':'I have a 90\u00b0 corner','corner-mode-angle':'I have a different angle','inward-corners':'Inneneckes','outward-corners':'Au\u00dfeneckes','corners-unit':'corners','corner-fixed-note':'Bei T100 werden f\u00fcr Au\u00dfenecken 22,5\u00b0-Module (20-3221) verwendet \u2014 4 Module pro 90\u00b0-Wende. Alternativ ist ein festes 90\u00b0-Doppelmodul (20-3230) verf\u00fcgbar.','no-corner-note':'No corner modules verf\u00fcgbar for S110. Use natural flex for gentle curves.','my-angle':'My turn angle','turn-dir':'Turn direction','inward':'Inward','outward':'Outward','end-modules-lbl':'End modules','standard':'Standard','adjustable':'Adjustable','left':'Left','right':'Right','pcs':'pcs','settable-width':'Settable width:','set-on-site':'set on site','wall-conn-lbl':'Wall connectors','save-config':'Save configuration','load-config':'Saved configurations','print-summary':'Print \/ PDF summary','results-title':'Ergebnisse','standard-fit':'Standardpassung','exact-fit':'Exakte Passung','verf\u00fcgbar':'verf\u00fcgbar','weight-tab':'Gewicht & Lagerung','length-comparison':'L\u00e4ngenvergleich','required':'Ben\u00f6tigt:','actual':'Tats\u00e4chlich:','over-by':'\u00dcberma\u00df:','breakdown':'Aufschl\u00fcsselung & Produktcodes','weight-note':'All weights are verified per module type. Pallet estimates are approximate \u2014 verify with NoFloods for exact logistics.','saved-title':'Saved configurations','your-config':'Ihre Konfiguration'},\n  de:{title:'EasyWall Rechner',subtitle:'Module f\u00fcr Ihre Hochwasserschutzbarriere berechnen','s1title':'Serie ausw\u00e4hlen','s1sub':'Jede Serie ist f\u00fcr unterschiedliche Einsatzbedingungen optimiert','pill-t':'Premium \u00b7 T-Serie','pill-s':'Flexibel \u00b7 S-Serie','pill-d':'Unebener Untergrund \u00b7 D-Serie','ser-t-desc':'HydroFoam\u2122-Basis & HydroSeal\u2122-Kante. Beste Dichtleistung. Verstellbare Einheiten verf\u00fcgbar.','ser-s-desc':'Schiebeverbindung erm\u00f6glicht eine Anpassung von 3\u20135\u00b0. Ideal f\u00fcr st\u00e4dtische und unregelm\u00e4\u00dfige Verl\u00e4ufe.','ser-d-desc':'Abnehmbare Membran f\u00fcr Kies, Erde und gemischtes Gel\u00e4nde. Nicht verf\u00fcgbar in USA, UK, IE, CA & QA.','s2title':'H\u00f6he ausw\u00e4hlen','s2sub':'Schutzh\u00f6he in cm','s3title':'Barrierenl\u00e4nge & Zubeh\u00f6r','s3sub':'Geben Sie unten die geraden Strecken und das Zubeh\u00f6r ein','guide-toggle':'So messen Sie Ihren Standort','g1h':'Nur gerade Strecken messen.','g1b':'Gehen Sie jede gerade Strecke ab und messen Sie sie separat. Ecken und Kurven nicht in die L\u00e4nge einrechnen. Sie k\u00f6nnen unten mehrere separate Strecken hinzuf\u00fcgen.','g2h':'Kurven und Richtungs\u00e4nderungen bestimmen.','g2b':'Sanfte Kurven (einige Grad pro Verbindung) ben\u00f6tigen keine Eckmodule \u2014 verbinden Sie die Module einfach in einem leichten Bogen. Die S-Serie erlaubt konstruktionsbedingt bis zu 3\u20135\u00b0 pro Verbindung. F\u00fcr deutliche Richtungs\u00e4nderungen verwenden Sie Eckmodule. Geben Sie den Winkel im Bereich Ecken ein; der Rechner ermittelt die ben\u00f6tigte Modulanzahl.','g3h':'W\u00e4nde und offene Enden pr\u00fcfen.','g3b':'Wenn die Barriere an einer Wand endet, ben\u00f6tigen Sie einen Wandanschluss. Jedes offene Ende ben\u00f6tigt ein Endmodul (links oder rechts).','g4h':'Untergrund ber\u00fccksichtigen.','g4b':'Alle EasyWall-Serien k\u00f6nnen mit unebenem Untergrund umgehen \u2014 eine abnehmbare Membran kann bei jedem Modell erg\u00e4nzt werden. Bei der D-Serie ist sie standardm\u00e4\u00dfig integriert. Geben Sie die Untergrundbedingungen in Ihrer Anfrage an.','g5h':'Eine kleine Toleranz bei der installierten L\u00e4nge einplanen.','g5b':'Der Rechner verwendet f\u00fcr jedes Modell die NoFloods-Rate Module pro Meter, um die richtige Modulanzahl zu ermitteln. Abh\u00e4ngig von Untergrund und Installationswinkel ist eine Abweichung von \u00b12\u20133 % bei der endg\u00fcltigen installierten L\u00e4nge m\u00f6glich.','sections-title':'Gerade Strecken','add-section':'Weitere Strecke hinzuf\u00fcgen','acc-title':'Ecken & Zubeh\u00f6r','corners-lbl':'Kurven & Ecken','corner-mode-90':'Ich habe eine 90\u00b0-Ecke','corner-mode-angle':'Ich habe einen anderen Winkel','inward-corners':'Innenecken','outward-corners':'Au\u00dfenecken','corners-unit':'Ecken','corner-fixed-note':'Bei T100 verwendet die Au\u00dfenecke 22,5\u00b0-Module (20-3221) \u2014 4 Module pro 90\u00b0-Wende. Alternativ ist ein festes 90\u00b0-Doppelmodul (20-3230) verf\u00fcgbar.','no-corner-note':'F\u00fcr S110 sind keine Eckmodule verf\u00fcgbar. Verwenden Sie bei sanften Kurven die nat\u00fcrliche Flexibilit\u00e4t.','my-angle':'Mein Winkel','turn-dir':'Richtung der Wende','inward':'Innen','outward':'Au\u00dfen','end-modules-lbl':'Endmodule','standard':'Standard','adjustable':'Verstellbar','left':'Links','right':'Rechts','pcs':'Stk.','settable-width':'Einstellbare Breite:','set-on-site':'vor Ort einstellen','wall-conn-lbl':'Wandanschl\u00fcsse','save-config':'Konfiguration speichern','load-config':'Gespeicherte Konfigurationen','print-summary':'Drucken \/ PDF-Zusammenfassung','results-title':'Ergebnisse','standard-fit':'Standardpassung','exact-fit':'Exakte Passung','verf\u00fcgbar':'verf\u00fcgbar','weight-tab':'Gewicht & Lagerung','length-comparison':'L\u00e4ngenvergleich','required':'Ben\u00f6tigt:','actual':'Tats\u00e4chlich:','over-by':'\u00dcberma\u00df:','breakdown':'Aufschl\u00fcsselung & Produktcodes','weight-note':'Alle Gewichte sind je Modultyp gepr\u00fcft. Palettenangaben sind N\u00e4herungswerte \u2014 f\u00fcr genaue Logistikangaben bitte NoFloods kontaktieren.','saved-title':'Gespeicherte Konfigurationen','your-config':'Ihre Konfiguration'}\n};\nlet lang='en';\nfunction setLang(l){\n  lang=l;\n  document.querySelectorAll('[data-t]').forEach(el=>{\n    const k=el.getAttribute('data-t');\n    if(LANG[l][k]===undefined)return;\n    \/\/ Don't overwrite tab-weight \u2014 it contains a child badge span we need to keep\n    if(el.id==='tab-weight'||el.closest&&el.closest('#tab-weight'))return;\n    el.textContent=LANG[l][k];\n  });\n  \/\/ Translate tab-weight label text only, preserving the badge span\n  const tw=document.getElementById('tab-weight');\n  if(tw){\n    const badge=document.getElementById('badge-weight');\n    const badgeHTML=badge?badge.outerHTML:'';\n    tw.innerHTML=(LANG[l]['weight-tab']||'Gewicht & Lagerung')+' '+badgeHTML;\n  }\n}\nfunction t(k){return LANG[lang][k]||k;}\n\n\/\/ \u2500\u2500 CATALOGUE DATA \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\/\/ per10 = modules per 10m from NoFloods catalogue matrix (exact source of truth)\n\/\/ wS = module width (m) from catalogue specs\n\/\/ wKg = module weight (kg) from catalogue specs\n\/\/ ppallet = approx modules per pallet for logistics estimates\n\/\/ OL = 0.07m physical overlap (documented), used only for adjustable unit calculations\nconst OL=0.07;\nconst MODELS={\n  T:{label:'T-series',variants:[\n    {name:'T50',h:50,prot:50,per10:16,wS:0.705,wKg:4.2,ppallet:20,endW:0.28,adjEndW:{min:0.44,max:0.52},wallW:0.15,cornerIn:true,cornerOut:true,cornerFixed:false,adj:{min:0.57,max:0.705,code:'20-3020'},adjEnd:{min:0.44,max:0.52,cL:'20-3070',cR:'20-3080'},wall:true,ends:true,cpx:3,cpxIn:3,cpxOut:3,w:{st:4.2,ci:3.2,co:2.8,el:4.9,er:4.9,ael:6.5,aer:6.5,adj:6.8,wl:1.5,wr:1.5},c:{st:'20-3010',ci:'20-3030',co:'20-3040',el:'20-3050',er:'20-3060',wl:'20-3090',wr:'20-3100'}},\n    {name:'T80',h:80,prot:80,per10:16,wS:0.705,wKg:8.0,ppallet:10,endW:0.41,adjEndW:null,wallW:0.15,cornerIn:true,cornerOut:true,cornerFixed:false,adj:{min:0.57,max:0.705,code:'20-3130'},adjEnd:null,wall:true,ends:true,cpx:4,cpxIn:4,cpxOut:4,w:{st:8.0,ci:8.0,co:7.0,el:10.5,er:10.5,ael:0,aer:0,adj:11.5,wl:5.0,wr:5.0},c:{st:'20-3120',ci:'20-3140',co:'20-3150',el:'20-3160',er:'20-3170',wl:'20-3180',wr:'20-3190'}},\n    {name:'T100',h:100,prot:100,per10:14,wS:0.83,wKg:12.5,ppallet:8,endW:0.44,adjEndW:null,wallW:null,cornerIn:true,cornerOut:true,cornerOutFixed90:false,cornerFixed:false,adj:null,adjEnd:null,wall:false,ends:true,cpx:2,cpxIn:2,cpxOut:4,w:{st:12.5,ci:13.6,co:10.5,el:15,er:15,ael:0,aer:0,adj:0,wl:0,wr:0},c:{st:'20-3210',ci:'20-3220',co:'20-3221',co90:'20-3230',el:'20-3215',er:'20-3216',wl:'',wr:''}},\n    {name:'T120',h:120,prot:120,per10:14,wS:0.83,wKg:16.0,ppallet:6,endW:null,adjEndW:null,wallW:null,cornerIn:true,cornerOut:true,cornerOutFixed90:true,cornerFixed:false,adj:null,adjEnd:null,wall:false,ends:false,cpx:2,cpxIn:2,cpxOut:1,w:{st:16.0,ci:14.0,co:28.0,el:0,er:0,ael:0,aer:0,adj:0,wl:0,wr:0},c:{st:'20-3240',ci:'20-3241',co:'20-3243',el:'',er:'',wl:'',wr:''}},\n  ]},\n  S:{label:'S-series',variants:[\n    {name:'S50', h:50, prot:50, per10:16,wS:0.705,wKg:4.1, ppallet:20,endW:0.39,adjEndW:null,wallW:null,cornerIn:true, cornerOut:true, cornerFixed:false,adj:null,adjEnd:null,wall:false,ends:true, cpx:3,w:{st:4.1,ci:2.8,co:2.7,el:3.5,er:3.5,ael:0,aer:0,adj:0,wl:0,wr:0},c:{st:'20-3250',ci:'20-3260',co:'20-3270',el:'20-3280',er:'20-3290',wl:'',wr:''}},\n    {name:'S60', h:60, prot:60, per10:11,wS:0.95, wKg:7.2, ppallet:15,endW:0.30,adjEndW:null,wallW:null,cornerIn:true, cornerOut:true, cornerFixed:false,adj:null,adjEnd:null,wall:false,ends:true, cpx:3,w:{st:7.2,ci:3.0,co:3.1,el:3.6,er:3.6,ael:0,aer:0,adj:0,wl:0,wr:0},c:{st:'20-3310',ci:'20-3320',co:'20-3330',el:'20-3340',er:'20-3350',wl:'',wr:''}},\n    {name:'S75', h:75, prot:75, per10:11,wS:1.00, wKg:9.6, ppallet:12,endW:0.30,adjEndW:null,wallW:null,cornerIn:true, cornerOut:true, cornerFixed:false,adj:null,adjEnd:null,wall:false,ends:true, cpx:3,w:{st:9.6,ci:3.8,co:3.8,el:3.5,er:3.5,ael:0,aer:0,adj:0,wl:0,wr:0},c:{st:'20-3370',ci:'20-3380',co:'20-3390',el:'20-3400',er:'20-4310',wl:'',wr:''}},\n    {name:'S110',h:110,prot:110,per10:16,wS:0.70, wKg:13.0,ppallet:8, endW:null,adjEndW:null,wallW:null,cornerIn:false,cornerOut:false,cornerFixed:false,adj:null,adjEnd:null,wall:false,ends:false,cpx:3,w:{st:13.0,ci:0,co:0,el:0,er:0,ael:0,aer:0,adj:0,wl:0,wr:0},c:{st:'20-3440',ci:'',co:'',el:'',er:'',wl:'',wr:''}},\n  ]},\n  D:{label:'D-series',variants:[\n    {name:'D55', h:55, prot:55, per10:12,wS:0.90, wKg:5.5, ppallet:15,endW:null,adjEndW:null,wallW:null,cornerIn:true,cornerOut:true,cornerFixed:false,adj:null,adjEnd:null,wall:false,ends:false,cpx:3,w:{st:5.5,ci:7.4,co:7.4,el:0,er:0,ael:0,aer:0,adj:0,wl:0,wr:0},c:{st:'20-3450',ci:'20-3460',co:'20-3470',el:'',er:'',wl:'',wr:''}},\n    {name:'D100',h:100,prot:100,per10:11,wS:1.05, wKg:14.5,ppallet:8, endW:null,adjEndW:null,wallW:null,cornerIn:true,cornerOut:true,cornerFixed:false,adj:null,adjEnd:null,wall:false,ends:false,cpx:3,w:{st:14.5,ci:18.0,co:18.0,el:0,er:0,ael:0,aer:0,adj:0,wl:0,wr:0},c:{st:'20-3490',ci:'20-3500',co:'20-3510',el:'',er:'',wl:'',wr:''}},\n  ]}\n};\n\n\/\/ \u2500\u2500 HELPERS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction r4(x){return Math.round(x*10000)\/10000;}\nfunction perM(v){return 1\/(v.wS-OL);}\n\/\/ Physical coverage: first module = full wS, each subsequent = wS-OL net\nfunction stdCov(n,v){\n  if(n===0)return 0;\n  return r4(v.wS+(n-1)*(v.wS-OL));\n}\n\/\/ Physical sequence length for adjustable solver (uses documented 7cm overlap)\nfunction seqP(nS,wS,nA,wA){const t=nS+nA;if(!t)return 0;return r4(nS*wS+nA*wA-(t-1)*OL);}\nfunction gn(id){return Math.max(0,parseInt(document.getElementById(id).value)||0);}\nfunction gf(id){return Math.max(0,parseFloat(document.getElementById(id).value)||0);}\n\n\/\/ \u2500\u2500 STATE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nlet sel='T',selV=0,activeTab='std',cornerMode='count',angleDir='out',coutType='modules';\nfunction setCoutType(t){\n  coutType=t;\n  const mBtn=document.getElementById('cout-type-modules');\n  const fBtn=document.getElementById('cout-type-fixed');\n  if(mBtn) mBtn.style.cssText='flex:1;padding:8px;font-size:11px;font-weight:600;font-family:var(--fn);border-radius:6px;cursor:pointer;text-align:left;border:'+(t==='modules'?'1.5px solid #FAC775;background:#fff8ee;color:#633806':'0.5px solid var(--bd);background:var(--bg2);color:var(--t2)');\n  if(fBtn) fBtn.style.cssText='flex:1;padding:8px;font-size:11px;font-weight:600;font-family:var(--fn);border-radius:6px;cursor:pointer;text-align:left;border:'+(t==='fixed'?'1.5px solid #FAC775;background:#fff8ee;color:#633806':'0.5px solid var(--bd);background:var(--bg2);color:var(--t2)');\n  calc();\n}\nlet sections=[{id:1,len:0}],activeSec=0,secNextId=2;\n\n\/\/ \u2500\u2500 GUIDE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction toggleGuide(){const b=document.getElementById('guide-body'),a=document.getElementById('guide-arr');b.classList.toggle('open');a.classList.toggle('open',b.classList.contains('open'));}\n\n\/\/ \u2500\u2500 SERIES \/ HEIGHT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction setSeries(s){sel=s;selV=0;['T','S','D'].forEach(x=>document.getElementById('sb-'+x).classList.toggle('active',x===s));renderH();updateAvail();calc();}\nfunction renderH(){\n  const vs=MODELS[sel].variants,g=document.getElementById('ht-grid');\n  g.style.gridTemplateColumns='repeat('+vs.length+',1fr)';g.innerHTML='';\n  vs.forEach((v,i)=>{\n    const b=document.createElement('button');b.className='ht-btn'+(i===selV?' active':'');\n    b.innerHTML='<div class=\"ht-h\">'+v.h+' cm<\/div><div class=\"ht-p\">Schutz: '+v.prot+' cm<\/div><div class=\"ht-c\">'+v.name+'<\/div>';\n    b.onclick=()=>{selV=i;renderH();updateAvail();calc();};g.appendChild(b);\n  });\n}\n\n\/\/ \u2500\u2500 SECTIONS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction updateSecSummary(){\n  const bar=document.getElementById('sec-summary');\n  if(sections.length<=1){bar.style.display='none';return;}\n  const total=Math.round(sections.reduce((s,sec)=>s+sec.len,0)*10)\/10;\n  const parts=sections.map((sec,i)=>'<span style=\"font-weight:600;color:var(--ok)\">'+sec.len+'m<\/span>');\n  bar.style.display='block';\n  bar.innerHTML=parts.join(' <span style=\"color:var(--t3);margin:0 2px\">+<\/span> ')+\n    ' <span style=\"color:var(--t3);margin:0 4px\">=<\/span> '+\n    '<span style=\"font-size:14px;font-weight:700;color:var(--ok)\">'+total+' m total<\/span>'+\n    '<span style=\"color:var(--ok);opacity:.7;font-size:11px;margin-left:8px\">(straight sections only)<\/span>';\n}\n\nfunction renderSections(){\n  const tr=document.getElementById('sec-tabs-row'),panels=document.getElementById('sec-panels');\n  tr.innerHTML='';panels.innerHTML='';\n  sections.forEach((sec,i)=>{\n    const tab=document.createElement('button');tab.className='sec-tab'+(i===activeSec?' active':'');\n    const label=sections.length>1?'Strecke '+(i+1)+' \u00b7 '+sec.len+'m':'Length';\n    tab.textContent=label;\n    if(sections.length>1){const x=document.createElement('span');x.textContent=' \u00d7';x.style.cssText='margin-left:3px;color:var(--br);font-weight:700;cursor:pointer';x.onclick=(e)=>{e.stopPropagation();removeSection(i);};tab.appendChild(x);}\n    tab.onclick=()=>{activeSec=i;renderSections();};tr.appendChild(tab);\n    const p=document.createElement('div');p.className='sec-panel'+(i===activeSec?' active':'');\n    p.innerHTML='<div class=\"frow\"><span class=\"flbl\">Strecke '+(i+1)+' L\u00e4nge (m)<\/span><input class=\"ni\" type=\"number\" id=\"sl-'+sec.id+'\" min=\"0.5\" step=\"0.1\" value=\"'+sec.len+'\" oninput=\"secUpd('+i+')\" style=\"width:90px\"><span class=\"fhint\">nur gerade Strecke \u2014 Ecken nicht einrechnen<\/span><\/div>';\n    panels.appendChild(p);\n  });\n  updateSecSummary();\n  const ab=document.getElementById('add-sec-btn');if(ab)ab.style.display='';\n}\nfunction addSection(){sections.push({id:secNextId++,len:0});activeSec=sections.length-1;renderSections();calc();}\nfunction removeSection(i){sections.splice(i,1);activeSec=Math.min(activeSec,sections.length-1);renderSections();calc();}\nfunction secUpd(i){\n  const val=Math.max(0,parseFloat(document.getElementById('sl-'+sections[i].id).value)||0);\n  sections[i].len=val;\n  \/\/ Update this tab's label live\n  if(sections.length>1){\n    const tabs=document.querySelectorAll('.sec-tab');\n    if(tabs[i]){\n      const xBtn=tabs[i].querySelector('span');\n      tabs[i].firstChild.textContent='Strecke '+(i+1)+' \u00b7 '+val+'m';\n    }\n  }\n  updateSecSummary();\n  calc();\n}\n\n\/\/ \u2500\u2500 AVAILABILITY \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction updateAvail(){\n  const v=MODELS[sel].variants[selV];\n  document.getElementById('grp-wall').className=v.wall?'dg':'dg muted';\n  if(!v.wall){document.getElementById('f-wl').value=0;document.getElementById('f-wr').value=0;}\n  document.getElementById('grp-ends').className=v.ends?'dg':'dg muted';\n  if(!v.ends){['f-el','f-er','f-ael','f-aer'].forEach(id=>document.getElementById(id).value=0);}\n  const hae=v.adjEnd!=null;\n  \/\/ end-type-adj button removed \u2014 adj ends suggested automatically in exact fit tab\n  if(!hae)setEndTypeAll('std',true);\n  updateEndLabels();\n  updateCurveNote();\n  const hasC=v.cornerIn||v.cornerOut;\n  document.getElementById('grp-corners').className=hasC?'dg':'dg muted';\n  const rc=document.getElementById('row-cout');\n  if(rc){rc.className='dfr'+(v.cornerOut?'':' muted');if(!v.cornerOut)document.getElementById('f-cout').value=0;}\n  document.getElementById('corner-fixed-note').style.display='none';\n  const showT100Toggle=v.name==='T100'&&v.cornerOut;\n  const showT120Note=v.name==='T120'&&v.cornerOut;\n  document.getElementById('t100-out-type').style.display=showT100Toggle?'block':'none';\n  document.getElementById('t120-out-note').style.display=showT120Note?'block':'none';\n  if(showT120Note){coutType='fixed';}\n  else if(!showT100Toggle){coutType='modules';}\n  document.getElementById('no-corner-note').style.display=(!hasC)?'block':'none';\n  \/\/ Mute the \"Anderer Winkel\" and \"Sharp 90\u00b0\" options for models without corner modules\n  const sitAngle=document.getElementById('sit-angle');\n  const sit90=document.getElementById('sit-90');\n  if(sitAngle)sitAngle.classList.toggle('muted',!hasC);\n  if(sit90)sit90.classList.toggle('muted',!hasC);\n  if(!hasC&&cornerMode==='angle')setSituation('curve');\n  const ha=v.adj!=null;\n  document.getElementById('tab-exact').className='fit-tab'+(ha?'':' disabled');\n  const badge=document.getElementById('badge-exact');\n  badge.style.display=ha?'inline':'none';\n  \/\/ Reset badge to default 'verf\u00fcgbar' style \u2014 buildExact will update it after calc\n  badge.textContent='verf\u00fcgbar';\n  badge.style.background='';badge.style.color='';badge.style.borderColor='';\n  if(!ha&&activeTab==='exact')switchTab('std');\n}\n\n\/\/ \u2500\u2500 END MODULE TYPE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction setEndTypeAll(type,silent){\n  const v=MODELS[sel].variants[selV];\n  if(type==='adj'&&!v.adjEnd)return;\n  document.getElementById('el-type').value=type;document.getElementById('er-type').value=type;\n  \/\/ end-type-std \/ end-type-adj buttons removed \u2014 type tracked via hidden fields only\n  updateEndLabels();if(!silent)calc();\n}\nfunction updateEndLabels(){\n  \/\/ end-width-row removed from HTML \u2014 nothing to update\n}\n\n\/\/ \u2500\u2500 CORNER MODE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction updateCurveNote(){\n  const el=document.getElementById('curve-note');\n  if(!el)return;\n  const flexDeg=sel==='S'?'3\u20135':'3';\n  const seriesName=sel==='T'?'T-series (T50, T80, T100, T120)':sel==='S'?'S-series (S50, S60, S75, S110)':'D-series';\n  el.innerHTML=\n    '<strong>No corner modules needed for very gradual curves.<\/strong><br><br>'+\n    'Each connection between modules allows a small angular deviation. For the <strong>'+seriesName+'<\/strong>, this is approximately <strong>~'+flexDeg+'\u00b0 per connection<\/strong>.<br><br>'+\n    'If your curve requires more than ~'+flexDeg+'\u00b0 per connection, use <strong>Anderer Winkel<\/strong> above to calculate corner modules.<br><br>'+\n    '<strong>How to measure:<\/strong> Walk the curve and measure the total distance along the ground. Enter that as your section length and leave all corner inputs at 0.';\n}\n\nfunction setSituation(sit){\n  ['90','angle','curve'].forEach(s=>{const b=document.getElementById('sit-'+s);if(b)b.classList.toggle('active',s===sit);});\n  const mc=document.getElementById('corner-mode-count');if(mc)mc.style.display=sit==='90'?'block':'none';\n  const ma=document.getElementById('corner-mode-angle');if(ma)ma.style.display=sit==='angle'?'block':'none';\n  const mcu=document.getElementById('corner-mode-curve');if(mcu)mcu.style.display=sit==='curve'?'block':'none';\n  if(sit==='90'){cornerMode='count';updateCornerFeedback();}\n  else if(sit==='angle'){cornerMode='angle';calcAngle();}\n  else if(sit==='curve'){\n    cornerMode='count';\n    const cin=document.getElementById('f-cin');if(cin)cin.value=0;\n    const cout=document.getElementById('f-cout');if(cout)cout.value=0;\n    const fb=document.getElementById('corner-fb-count');if(fb)fb.style.display='none';\n    updateCurveNote();\n    calc();\n  }\n}\nfunction setCornerMode(m){\n  cornerMode=m;\n  if(m==='count')setSituation('90');\n  else if(m==='angle')setSituation('angle');\n}\nfunction setAdir(d){\n  angleDir=d;\n  document.getElementById('adir-in').classList.toggle('active',d==='in');\n  document.getElementById('adir-out').classList.toggle('active',d==='out');\n  const v=MODELS[sel].variants[selV];\n  if(!(d==='out'&&v.cornerOutFixed90))document.getElementById('f-angle').disabled=false;\n  calcAngle();\n}\nfunction updateCornerFeedback(){\n  const v=MODELS[sel].variants[selV],cin=gn('f-cin'),cout=gn('f-cout');\n  const fb=document.getElementById('corner-fb-count');\n  if(cin+cout===0){fb.style.display='none';return;}\n  const cpxIn=v.cpxIn||v.cpx,cpxOut=v.cpxOut||v.cpx;\n  const useFixed=(v.name==='T100'||v.name==='T120')&&coutType==='fixed';\n  const totalPcs=cin*cpxIn+(useFixed?cout:cout*cpxOut);\n  let lines=[];\n  if(cin>0){lines.push(cin+' \u00d7 90\u00b0 inward corner'+(cin>1?'s':'')+' = <strong>'+cin*cpxIn+' corner module'+(cin*cpxIn>1?'s':'')+'<\/strong> ('+cpxIn+' per corner)');}\n  if(cout>0){\n    const useFixed=(v.name==='T100'||v.name==='T120')&&coutType==='fixed';\n    const outPcs=useFixed?cout:cout*cpxOut;\n    const outCode=useFixed?(v.name==='T120'?'20-3243':'20-3230'):(v.c&&v.c.co||'');\n    if(useFixed) lines.push(cout+' \u00d7 90\u00b0 outward corner'+(cout>1?'s':'')+' = <strong>'+cout+' fixed 90\u00b0 double module'+(cout>1?'s':'')+'<\/strong> ('+outCode+')');\n    else if(v.cornerOutFixed90) lines.push(cout+' \u00d7 90\u00b0 outward corner'+(cout>1?'s':'')+' = <strong>'+cout+' fixed 90\u00b0 double module'+(cout>1?'s':'')+'<\/strong> (20-3243)');\n    else lines.push(cout+' \u00d7 90\u00b0 outward corner'+(cout>1?'s':'')+' = <strong>'+outPcs+' corner module'+(outPcs>1?'s':'')+'<\/strong> ('+cpxOut+' per corner)');\n  }\n  lines.push('<strong>'+totalPcs+' corner modules<\/strong> in total');\n  fb.className='cfb ok';fb.innerHTML=lines.join('<br>');fb.style.display='block';\n}\nfunction calcAngle(){\n  const v=MODELS[sel].variants[selV],fb=document.getElementById('corner-fb-angle'),ai=document.getElementById('f-angle');\n  if(angleDir==='out'&&v.cornerOutFixed90){\n    ai.value=90;ai.disabled=true;document.getElementById('f-cout').value=1;document.getElementById('f-cin').value=0;calc();\n    const coCode=v.name==='T120'?'20-3243':'20-3230';\n    fb.className='cfb info';fb.innerHTML=v.name+' outward corner ('+coCode+') is a fixed 90\u00b0 module \u2014 no other outward angles verf\u00fcgbar. <strong>1 module = 90\u00b0.<\/strong>';fb.style.display='block';return;\n  }\n  ai.disabled=false;\n  const target=Math.max(1,Math.min(180,parseFloat(ai.value)||90));\n  const cpxIn=v.cpxIn||v.cpx,cpxOut=v.cpxOut||v.cpx,cpx=angleDir==='in'?cpxIn:cpxOut,dp=90\/cpx;\n  const exact=target\/dp,fl=Math.floor(exact),ce=Math.ceil(exact);\n  const isEx=Math.abs(exact-Math.round(exact))<0.001;\n  if(angleDir==='in'){document.getElementById('f-cin').value=isEx?Math.round(exact):ce;document.getElementById('f-cout').value=0;}\n  else{document.getElementById('f-cout').value=isEx?Math.round(exact):ce;document.getElementById('f-cin').value=0;}\n  calc();\n  if(isEx){fb.className='cfb ok';fb.innerHTML='<strong>'+Math.round(exact)+' corner module'+(Math.round(exact)>1?'s':'')+'<\/strong> gives exactly <strong>'+target+'\u00b0<\/strong> \u2014 perfect fit.';}\n  else{\n    const fa=dp*0.5,g1=target-r4(fl*dp),g2=r4(ce*dp)-target;\n    let msg=target+'\u00b0 falls between module steps for '+v.name+' ('+dp+'\u00b0 per module).<br>';\n    if(fl>0)msg+='<strong>'+fl+' module'+(fl>1?'s':'')+' = '+r4(fl*dp)+'\u00b0<\/strong> \u2014 '+g1.toFixed(1)+'\u00b0 short'+(g1<=fa?', closable with natural flex':'');\n    msg+='<br><strong>'+ce+' module'+(ce>1?'s':'')+' = '+r4(ce*dp)+'\u00b0<\/strong> \u2014 '+g2.toFixed(1)+'\u00b0 over'+(g2<=fa?', closable with natural flex':'');\n    msg+='<br><span style=\"font-size:11px;opacity:.8\">Contact NoFloods to verify fit for non-standard angles.<\/span>';\n    fb.className='cfb info';fb.innerHTML=msg;\n  }\n  fb.style.display='block';\n}\n\n\/\/ \u2500\u2500 MAIN CALC \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction calc(){\n  const v=MODELS[sel].variants[selV];\n  const target=r4(sections.reduce((s,sec)=>s+sec.len,0));\n  \/\/ Hide results entirely until user has entered something\n  const resEl=document.querySelector('.res');\n  if(resEl)resEl.style.display=target>0?'block':'none';\n  const actionBar=document.getElementById('results-action-bar');\n  const saveAnother=document.getElementById('btn-save-another');\n  const saveQuote=document.getElementById('btn-save-quote');\n  if(target<=0&&!cart.length){if(actionBar)actionBar.style.display='none';return;}\n  if(actionBar)actionBar.style.display='block';\n  if(saveAnother)saveAnother.style.opacity=target>0?'1':'0.4';\n  if(saveAnother)saveAnother.style.pointerEvents=target>0?'':'none';\n  if(saveQuote)saveQuote.style.opacity=target>0?'1':'0.4';\n  if(saveQuote)saveQuote.style.pointerEvents=target>0?'':'none';\n  const cin=gn('f-cin'),cout=gn('f-cout');\n  const elType=document.getElementById('el-type').value,erType=document.getElementById('er-type').value;\n  const elQty=v.ends?gn('f-el'):0,erQty=v.ends?gn('f-er'):0;\n  const elIsAdj=elType==='adj'&&v.adjEnd!=null,erIsAdj=erType==='adj'&&v.adjEnd!=null;\n  document.getElementById('f-ael').value=elIsAdj?elQty:0;document.getElementById('f-aer').value=erIsAdj?erQty:0;\n  const el=elIsAdj?0:elQty,er=erIsAdj?0:erQty,ael=elIsAdj?elQty:0,aer=erIsAdj?erQty:0;\n  const wl=v.wall?gn('f-wl'):0,wr=v.wall?gn('f-wr'):0;\n  \/\/ Module count from catalogue rate\n  const nStd=Math.ceil(target*perM(v));\n  const actualLen=stdCov(nStd,v);\n  const diff=r4(actualLen-target);\n  const lo=r4(actualLen*0.97),hi=r4(actualLen*1.03);\n  const cpxIn=v.cpxIn||v.cpx,cpxOut=v.cpxOut||v.cpx;\n  \/\/ For T100\/T120 outward corners, check if user chose fixed 90\u00b0 double module\n  const useFixed90Out=(v.name==='T100'||v.name==='T120')&&coutType==='fixed';\n  const inPcs=cin*cpxIn;\n  const outPcs=useFixed90Out?cout*1:cout*cpxOut; \/\/ fixed=1 double module per corner, modules=cpxOut per corner\n  const outCode=useFixed90Out?(v.c.co90||v.c.co):v.c.co;\n  const outWeight=useFixed90Out?(v.name==='T100'?27.5:28.0):v.w.co;\n  const accPcs=inPcs+outPcs+el+er+ael+aer+wl+wr;\n  const total=nStd+accPcs;\n  \/\/ Accessory lengths\n  const endWL=elIsAdj?(v.adjEndW?v.adjEndW.min:0):(v.endW||0);\n  const endWR=erIsAdj?(v.adjEndW?v.adjEndW.min:0):(v.endW||0);\n  \/\/ Full-chain physics: each accessory participates in one overlap joint with the straight run.\n  \/\/ accPhys = sum of physical widths. accJoints = number of acc-to-straight joints (left + right).\n  \/\/ Net coverage added = accPhys - accJoints*OL\n  const endLL=elQty>0?r4(endWL):0,endLR=erQty>0?r4(endWR):0;\n  const wallLL=wl>0&&v.wallW?r4(wl*v.wallW):0,wallLR=wr>0&&v.wallW?r4(wr*v.wallW):0;\n  const accPhys=r4(endLL+endLR+wallLL+wallLR);\n  const leftAcc=(elQty>0||wl>0)?1:0, rightAcc=(erQty>0||wr>0)?1:0;\n  const accJoints=leftAcc+rightAcc;\n  const accLen=r4(accPhys-accJoints*OL);\n  const totalLen=r4(actualLen+accLen),totalLo=r4(lo+accLen),totalHi=r4(hi+accLen);\n  const overUnder=r4(totalLen-target);\n  \/\/ Bar\n  document.getElementById('r-tag').textContent=v.name+' \u00b7 '+v.prot+' cm protection';\n  const mx=Math.max(actualLen,target)*1.06;\n  const pR=Math.round(target\/mx*100),pA=Math.min(100,Math.round(actualLen\/mx*100));\n  document.getElementById('bar-req').style.width=pR+'%';document.getElementById('bar-act').style.width=pA+'%';\n  if(diff>0.001){document.getElementById('bar-ov').style.left=pR+'%';document.getElementById('bar-ov').style.width=(pA-pR)+'%';document.getElementById('lbl-ov-wrap').style.display='flex';}\n  else{document.getElementById('bar-ov').style.width='0';document.getElementById('lbl-ov-wrap').style.display='none';}\n  document.getElementById('lbl-req').textContent=target+' m';document.getElementById('lbl-act').textContent=actualLen+' m';document.getElementById('lbl-ov').textContent='+'+diff+' m';\n  \/\/ Cards\n  const dcls=diff<0.001?'ok':diff<0.5?'':'over',ocls=overUnder>0.5?'over':'ok';\n  const hasAccCard=accLen>0;\n  document.getElementById('r-sum').style.gridTemplateColumns=hasAccCard?'repeat(3,1fr)':'repeat(2,1fr)';\n  document.getElementById('r-sum').innerHTML=\n    '<div class=\"sc\"><div class=\"sv\">'+target+' m<\/div><div class=\"sl\">Ben\u00f6tigte L\u00e4nge'+(sections.length>1?'<br><span style=\"font-size:10px;color:var(--t3)\">'+sections.length+' sections<\/span>':'')+'<\/div><\/div>'+\n    '<div class=\"sc\"><div class=\"sv '+dcls+'\">'+actualLen+' m<\/div><div class=\"sl\">Gerade Abdeckung<br><span style=\"font-size:10px;color:var(--t3)\">'+nStd+' Module \u00b7 \u00b12\u20133 % Toleranz<\/span><\/div><\/div>'+\n    (hasAccCard?'<div class=\"sc\"><div class=\"sv '+ocls+'\">'+totalLen+' m<\/div><div class=\"sl\">Gesamt inkl. Zubeh\u00f6r<br><span style=\"font-size:10px;color:var(--t3)\">installiert: '+totalLo+'\u2013'+totalHi+' m<\/span><\/div><\/div>':'');\n  \/\/ Breakdown\n  const c=v.c;let rows='',codes=[];\n  const addR=(lbl,qty,code,note)=>{\n    if(!qty)return;if(code)codes.push(qty+'\u00d7 '+code);\n    rows+='<div class=\"bkr\"><span>'+lbl+(code?'<span class=\"bkc\">'+code+'<\/span>':'')+'<\/span><div class=\"bkr2\">'+(note?'<span style=\"font-size:11px;color:var(--t3)\">'+note+'<\/span>':'')+'<span class=\"bkq\">'+qty+' pcs<\/span><\/div><\/div>';\n  };\n  addR('Gerade modules',nStd,c.st);\n  if(cin>0)addR('Innenecke ('+cin+' \u00d7 '+cpxIn+' pcs)',inPcs,c.ci);\n  if(cout>0)addR('Au\u00dfenecke'+(useFixed90Out?' \u2014 fixed 90\u00b0 double module':''),outPcs,outCode);\n  if(el>0)addR('End \u2013 left',el,c.el);if(er>0)addR('End \u2013 right',er,c.er);\n  if(ael>0&&v.adjEnd)addR('End \u2013 adjustable left',ael,v.adjEnd.cL,v.adjEnd.min*100+'\u2013'+v.adjEnd.max*100+' cm');\n  if(aer>0&&v.adjEnd)addR('End \u2013 adjustable right',aer,v.adjEnd.cR,v.adjEnd.min*100+'\u2013'+v.adjEnd.max*100+' cm');\n  if(wl>0)addR('Wandanschluss \u2013 links',wl,c.wl);if(wr>0)addR('Wandanschluss \u2013 rechts',wr,c.wr);\n  rows+='<div class=\"bkr\"><span>Grand total<\/span><span class=\"bkq\" style=\"color:var(--br)\">'+total+' pcs<\/span><\/div>';\n  document.getElementById('r-bk').innerHTML=rows;\n  \/\/ Note\n  let note=nStd+' straight modules cover '+actualLen+' m.';\n  if(accLen>0)note+=' Accessories add ~'+r4(accLen*100)+' cm \u2192 total ~'+totalLen+' m.';\n  note+=' Installed: '+totalLo+'\u2013'+totalHi+' m (\u00b12\u20133%).';\n  if(v.name==='T80')note+=' T80: 4 corner modules per 90\u00b0 turn.';\n  if(v.name==='T100')note+=' T100 inward: 2 modules per 90\u00b0. Outward: 1 fixed-90\u00b0 module.';\n  document.getElementById('r-note').textContent=note;\n  const wEl=document.getElementById('r-warn');\n  if(sel==='D'){wEl.style.display='block';wEl.textContent='D-series not verf\u00fcgbar in USA, Canada, Puerto Rico, UK, Ireland, or Qatar.';}else wEl.style.display='none';\n  \/\/ Reset user selection when inputs change \u2014 new calc means fresh state\n  exactOptUserSelected=false;\n  \/\/ Exakte Passung (sets bestExactOpt to top option automatically)\n  if(v.adj)buildExact(v,target,nStd,inPcs+outPcs+el+er+ael+aer+wl+wr,cin>0||cout>0,accLen);\n  else{bestExactOpt=null;_exactOpts=[];}\n  \/\/ Weight (uses bestExactOpt if user has explicitly selected one)\n  buildWeight(nStd,v,total,accPcs,cin,cout,el,er,ael,aer,wl,wr,inPcs,outPcs);\n  updateAvail();updateEndLabels();\n  if(cornerMode==='count')updateCornerFeedback();\n  _lastCalc={v,target,actualLen,totalLen,nStd,accPcs,total,codes:[...codes],cin,cout,el,er,ael,aer,wl,wr,inPcs,outPcs,accLen};\n  updateQuoteSummary();\n}\n\nlet _lastCalc=null;\nfunction updateQuoteSummary(){\n  if(!_lastCalc&&!cart.length){\n    \/\/ Nothing to show \u2014 clear everything\n    const qsg=document.getElementById('qs-grid');if(qsg)qsg.innerHTML='';\n    const qsc=document.getElementById('qs-codes');if(qsc)qsc.textContent='';\n    const qsm=document.getElementById('qs-model');if(qsm)qsm.textContent='\u2013';\n    return;\n  }\n  if(!_lastCalc)return;\n  const {v,target,actualLen,totalLen,nStd,accPcs,total,codes,cin,cout,el,er,ael,aer,wl,wr,inPcs,outPcs}=_lastCalc;\n  document.getElementById('qs-model').textContent=MODELS[sel].label+' \u00b7 '+v.name+' \u00b7 '+v.prot+' cm protection';\n\n  \/\/ Helper: one summary row\n  const row=(qty,label,code,note)=>{\n    const codeTag=code?'<span style=\"font-family:var(--fm);font-size:10px;color:var(--t3);margin-left:5px\">'+code+'<\/span>':'';\n    const noteTxt=note?'<span style=\"font-size:11px;color:var(--t3);margin-left:5px\">\u2014 '+note+'<\/span>':'';\n    return '<div class=\"qs-i\" style=\"grid-column:1\/-1;display:flex;align-items:baseline;justify-content:space-between;gap:8px\">'+\n      '<span><strong style=\"font-size:15px;margin-right:6px\">'+qty+'\u00d7<\/strong>'+label+codeTag+noteTxt+'<\/span>'+\n    '<\/div>';\n  };\n  const divider='<div style=\"grid-column:1\/-1;height:0.5px;background:var(--bd);margin:4px 0\"><\/div>';\n  const totalRow=(qty,label)=>'<div class=\"qs-i\" style=\"grid-column:1\/-1;display:flex;justify-content:space-between;font-weight:700\">'+\n    '<span>'+label+'<\/span><span>'+qty+'<\/span><\/div>';\n\n  let rows='';\n  let qsCodes='';\n\n  if(exactOptUserSelected&&bestExactOpt&&bestExactOpt.modules){\n    const o=bestExactOpt;\n    \/\/ List every module from the exact fit recommendation\n    o.modules.forEach(m=>{\n      const codeClean=m.code?m.code.replace(\/<[^>]+>\/g,''):'';\n      const noteClean=m.note?m.note.replace(\/<strong[^>]*>|<\\\/strong>\/g,'').replace(\/<[^>]+>\/g,''):'';\n      rows+=row(m.qty,m.name,codeClean,noteClean);\n    });\n    \/\/ List accessories \u2014 skip fixed end modules if adj end exact fit replaces them\n    const isAdjEndSolution=o.isAdjEnd;\n    if(cin>0)rows+=row(inPcs,'Innenecke',v.c.ci,(v.cpxIn||v.cpx)+' pcs per 90\u00b0 turn');\n    if(cout>0)rows+=row(outPcs,'Au\u00dfenecke',v.c.co,'');\n    if(!isAdjEndSolution&&el>0)rows+=row(el,'Endmodul \u2013 links',v.c.el,'');\n    if(!isAdjEndSolution&&er>0)rows+=row(er,'Endmodul \u2013 rechts',v.c.er,'');\n    if(!isAdjEndSolution&&ael>0&&v.adjEnd)rows+=row(ael,'Verstellbares Endmodul \u2013 links',v.adjEnd.cL,'');\n    if(!isAdjEndSolution&&aer>0&&v.adjEnd)rows+=row(aer,'Verstellbares Endmodul \u2013 rechts',v.adjEnd.cR,'');\n    if(wl>0&&v.c.wl)rows+=row(wl,'Wandanschluss \u2013 links',v.c.wl,'');\n    if(wr>0&&v.c.wr)rows+=row(wr,'Wandanschluss \u2013 rechts',v.c.wr,'');\n    const termPcs=o.modules.reduce((s,m)=>s+(m.qty||0),0);\n    \/\/ For adj end solution, don't add accPcs (end modules are already in o.modules)\n    const grandTotal=isAdjEndSolution?termPcs:termPcs+accPcs;\n    rows+=divider+totalRow(grandTotal+' pcs','Grand total');\n    \/\/ product codes\n    const exactCodes=o.modules.filter(m=>m.qty>0&&m.code).map(m=>m.qty+'\u00d7 '+m.code.replace(\/<[^>]+>\/g,''));\n    codes.filter(c=>{\n      const baseCode=c.split('\u00d7 ')[1];\n      return !exactCodes.some(ec=>ec.includes(baseCode));\n    }).forEach(c=>exactCodes.push(c));\n    qsCodes='Product codes: '+exactCodes.join(' \u00b7 ');\n\n  } else {\n    \/\/ Standardpassung \u2014 explicit breakdown\n    rows+=row(nStd,'Standardmodule',v.c.st,'');\n    if(cin>0)rows+=row(inPcs,'Innenecke',v.c.ci,(v.cpxIn||v.cpx)+' pcs per 90\u00b0 turn');\n    if(cout>0)rows+=row(outPcs,'Au\u00dfenecke',v.c.co,'');\n    if(el>0)rows+=row(el,'Endmodul \u2013 links',v.c.el,'');\n    if(er>0)rows+=row(er,'Endmodul \u2013 rechts',v.c.er,'');\n    if(ael>0&&v.adjEnd)rows+=row(ael,'Verstellbares Endmodul \u2013 links',v.adjEnd.cL,'');\n    if(aer>0&&v.adjEnd)rows+=row(aer,'Verstellbares Endmodul \u2013 rechts',v.adjEnd.cR,'');\n    if(wl>0&&v.c.wl)rows+=row(wl,'Wandanschluss \u2013 links',v.c.wl,'');\n    if(wr>0&&v.c.wr)rows+=row(wr,'Wandanschluss \u2013 rechts',v.c.wr,'');\n    rows+=divider+totalRow(total+' pcs','Grand total');\n    rows+='<div class=\"qs-i\" style=\"grid-column:1\/-1;font-size:11px;color:var(--t2)\">'+\n      'Gerade Abdeckung: <strong>'+actualLen+' m<\/strong>'+(actualLen>target?' ('+Math.round((actualLen-target)*100)+' cm past target \u2014 fine for open runs)':'')+'<\/div>';\n    qsCodes=codes.length?'Product codes: '+codes.join(' \u00b7 '):'';\n  }\n\n  document.getElementById('qs-grid').innerHTML=rows;\n  document.getElementById('qs-codes').textContent=qsCodes;\n}\n\n\/\/ \u2500\u2500 WEIGHT \/ STORAGE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction buildWeight(nStd,v,total,accPcs,cin,cout,el,er,ael,aer,wl,wr,inPcs,outPcs){\n  const w=v.w||{};\n  const cpxIn=v.cpxIn||v.cpx, cpxOut=v.cpxOut||v.cpx;\n\n  \/\/ Use exact fit breakdown if that tab is active and an option is selected\n  const useExact=exactOptUserSelected&&bestExactOpt&&(bestExactOpt.nA>0);\n  const nSt=useExact?bestExactOpt.nS:nStd;\n  const nAdj=useExact?bestExactOpt.nA:0;\n\n  \/\/ Calculate weight for each module type\n  const stKg   = r4(nSt    * (w.st||v.wKg));\n  const adjKg  = r4(nAdj   * (w.adj||v.wKg));\n  const ciKg   = r4(inPcs  * (w.ci||0));\n  const useFixed90Out=(v.name==='T100'||v.name==='T120')&&coutType==='fixed';\n  const coKg   = r4(outPcs * (useFixed90Out?(v.name==='T100'?27.5:28.0):(w.co||0)));\n  const elKg   = r4(el     * (w.el||0));\n  const erKg   = r4(er     * (w.er||0));\n  const aelKg  = r4(ael    * (w.ael||0));\n  const aerKg  = r4(aer    * (w.aer||0));\n  const wlKg   = r4(wl     * (w.wl||0));\n  const wrKg   = r4(wr     * (w.wr||0));\n  const totalKg= r4(stKg+adjKg+ciKg+coKg+elKg+erKg+aelKg+aerKg+wlKg+wrKg);\n\n  const pallets=Math.ceil((nSt+nAdj)\/v.ppallet);\n  document.getElementById('badge-weight').textContent=totalKg+' kg';\n\n  \/\/ Build breakdown rows\n  let rows='';\n  const addW=(lbl,n,kg)=>{if(!n||!kg)return;rows+=`<div style=\"display:flex;justify-content:space-between;font-size:12px;padding:4px 0;border-bottom:0.5px solid var(--bd);color:var(--t2)\"><span>${lbl} \u00d7 ${n}<\/span><span style=\"font-weight:600;color:var(--t1)\">${r4(n*kg)} kg <span style=\"font-weight:400;color:var(--t3)\">(${kg} kg ea)<\/span><\/span><\/div>`;};\n  addW('Gerade',nSt,w.st||v.wKg);\n  if(nAdj>0) addW('Verstellbares gerades Modul',nAdj,w.adj||v.wKg);\n  if(inPcs>0) addW('Innenecke',inPcs,w.ci||0);\n  if(outPcs>0) addW('Au\u00dfenecke',outPcs,w.co||0);\n  if(el>0) addW('End left',el,w.el||0);\n  if(er>0) addW('End right',er,w.er||0);\n  if(ael>0) addW('Adj. end left',ael,w.ael||0);\n  if(aer>0) addW('Adj. end right',aer,w.aer||0);\n  if(wl>0) addW('Wandanschluss links',wl,w.wl||0);\n  if(wr>0) addW('Wandanschluss rechts',wr,w.wr||0);\n\n  document.getElementById('wt-grid').innerHTML=\n    `<div class=\"wt-card\"><div class=\"wt-v\">${totalKg} kg<\/div><div class=\"wt-l\">Total weight (all modules)<\/div><div class=\"wt-sub\">${useExact?'Basierend auf der ausgew\u00e4hlten Option f\u00fcr die exakte Passung':'All module types included'}<\/div><\/div>`+\n    `<div class=\"wt-card\"><div class=\"wt-v\">~${pallets}<\/div><div class=\"wt-l\">Estimated pallets<\/div><div class=\"wt-sub\">~${v.ppallet} straight modules per pallet<\/div><\/div>`+\n    `<div class=\"wt-card\"><div class=\"wt-v\">${v.wKg} kg<\/div><div class=\"wt-l\">Gerade module weight<\/div><div class=\"wt-sub\">${v.name} (catalogue)<\/div><\/div>`+\n    `<div class=\"wt-card\" style=\"grid-column:1\/-1\"><div style=\"font-size:11px;font-weight:700;color:var(--t2);margin-bottom:8px;text-transform:uppercase;letter-spacing:.04em\">Weight breakdown<\/div>${rows}<div style=\"display:flex;justify-content:space-between;font-size:13px;font-weight:700;padding-top:8px;color:var(--t1)\"><span>Total<\/span><span>${totalKg} kg<\/span><\/div><\/div>`;\n}\n\n\/\/ \u2500\u2500 EXACT FIT SOLVER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nlet bestExactOpt=null, _exactOpts=[], exactOptUserSelected=false;\n\nfunction buildExact(v,target,nStdBase,fixedAccPcs,hasCorners,accLen,hasAdjEnds){\n  const ae=v.adjEnd;\n  const adj=v.adj;\n  const OL2=0.07;\n  const r2=x=>Math.round(x*100);\n  const r1=x=>Math.round(x*10)\/10;\n\n  \/\/ Gerade modules only need to cover (target minus end\/wall net contributions)\n  const accNetLen=r4(accLen||0);\n  const straightTarget=r4(target-accNetLen);\n\n  \/\/ Recalculate nStd from straightTarget (not full target passed from calc)\n  const nStd=Math.ceil(straightTarget*perM(v));\n\n  const covMinus1=stdCov(nStd-1,v);\n  const gap=r4(straightTarget-covMinus1);\n  const gapCm=r2(gap);\n  const stdCovVal=stdCov(nStd,v);\n  const overCm=r2(r4(stdCovVal-straightTarget));\n\n  const endNet =v.endW ?(v.endW -OL2):null;\n  const wallNet=v.wallW?(v.wallW-OL2):null;\n  const adjEndNetMin=ae?(ae.min-OL2):null;\n  const adjEndNetMax=ae?(ae.max-OL2):null;\n  const adjNetMin=adj.min-OL2;\n  const adjNetMax=adj.max-OL2;\n\n  \/\/ If end\/wall modules already configured, don't suggest them again in exact fit\n  const alreadyHasEndOrWall=accNetLen>0;\n\n  let rec=null;\n  let recAdjEnd=null; \/\/ secondary option: adjustable end modules\n  const inR=(val,lo,hi)=>val>=lo-0.005&&val<=hi+0.005;\n\n  \/\/ \u2500\u2500 Check adjustable end modules (T50 only) \u2500\u2500\n  \/\/ When adj-end-L is present, ALL std modules lose 7cm (none is first in run)\n  \/\/ So std contribution = nS * (wS-OL), not stdCov(nS)\n  \/\/ Total = lp(receiver, full) + nS*(wS-OL) + rn(slides over, net)\n  const hasStdEnds=accNetLen>0&&!hasAdjEnds;\n  if(!hasCorners&&!hasAdjEnds&&ae){\n    const aeNetMin=r4(ae.min-OL2), aeNetMax=r4(ae.max-OL2);\n    const stdNet=r4(v.wS-OL2); \/\/ every std loses 7cm when adj-end-L is first\n    for(let nS=0;nS<=nStdBase+2;nS++){\n      const stdContrib=r4(nS*stdNet);\n      const remaining=r4(target-stdContrib);\n      const minR=r4(ae.min+aeNetMin), maxR=r4(ae.max+aeNetMax);\n      if(remaining>=minR-0.005&&remaining<=maxR+0.005){\n        let lp=r4((ae.min+ae.max)\/2);\n        let rn=r4(remaining-lp);\n        if(rn<aeNetMin){lp=r4(remaining-aeNetMin);rn=aeNetMin;}\n        if(rn>aeNetMax){lp=r4(remaining-aeNetMax);rn=aeNetMax;}\n        if(lp>=ae.min-0.005&&lp<=ae.max+0.005&&rn>=aeNetMin-0.005&&rn<=aeNetMax+0.005){\n          const lpCm=Math.round(lp*100), rpCm=Math.round((rn+OL2)*100);\n          const check=r4(stdContrib+lp+rn);\n          if(Math.abs(check-target)<=0.005){\n            \/\/ N-1 overlaps cross-check\n            const physWidths=Array(nS).fill(v.wS*100).concat([lpCm,rpCm]);\n            const physTotal=physWidths.reduce((a,b)=>a+b,0);\n            const netCheck=r4((physTotal-(nS+1)*OL2*100)\/100);\n            if(Math.abs(netCheck-target)>0.01) break; \/\/ physics check failed\n            const label=(nS>0?nS+' standard + ':'')+'adjustable end-left @ '+lpCm+' cm + adjustable end-right @ '+rpCm+' cm';\n            const modules=[];\n            if(nS>0) modules.push({qty:nS,name:'Standardmodule',code:v.c.st,note:Math.round(v.wS*1000)\/10+' cm each'});\n            modules.push({qty:1,name:'Verstellbares Endmodul \u2013 links',code:ae.cL,note:'slide to <strong>'+lpCm+' cm<\/strong> (range: '+Math.round(ae.min*100)+'\u2013'+Math.round(ae.max*100)+' cm)'});\n            modules.push({qty:1,name:'Verstellbares Endmodul \u2013 rechts',code:ae.cR,note:'slide to <strong>'+rpCm+' cm<\/strong> (range: '+Math.round(ae.min*100)+'\u2013'+Math.round(ae.max*100)+' cm)'});\n            recAdjEnd={label,modules,exact:true,nS,totalModules:nS+2};\n          }\n        }\n        break;\n      }\n    }\n  }\n\n  \/\/ \u2500\u2500 Verstellbares gerades Modul \u2014 try combinations of standard + adjustable modules \u2500\u2500\n  \/\/ Uses seqP() for correct chain physics: nS*wS + nA*wA - (nS+nA-1)*OL\n  \/\/ Allows nA up to nStd (all-adjustable when nS=0 is valid)\n  if(!rec){\n    const maxAdj=Math.max(nStd,6); \/\/ allow up to 6 adjustable-only, or as many as standard count\n    for(let nAdj=1;nAdj<=maxAdj;nAdj++){\n      const nS=nStd-nAdj; \/\/ remaining standard modules (may be 0)\n      if(nS<0) break; \/\/ can't have negative standard modules\n      \/\/ seqP(nS, wS, nA, wA) = nS*wS + nA*wA - (nS+nA-1)*OL\n      \/\/ We need seqP result = straightTarget, solve for wA:\n      \/\/ nA*wA = straightTarget - nS*wS + (nS+nA-1)*OL\n      const stdContribSeqP = r4(nS*v.wS - (nS>0?(nS-1)*OL2:0)); \/\/ partial seqP without adj term\n      \/\/ Full: stdContribSeqP + nA*wA - (nS>0?nAdj*OL2:(nAdj-1)*OL2) = straightTarget\n      \/\/ Note: seqP total overlaps = (nS+nA-1)*OL when both present\n      const totalOLSeqP = (nS+nAdj-1)*OL2;\n      \/\/ nA*wA = straightTarget + totalOLSeqP - nS*v.wS\n      const adjTotalNeeded = r4(straightTarget + totalOLSeqP - nS*v.wS);\n      const perAdjPhys = nAdj>0 ? r4(adjTotalNeeded\/nAdj) : 0;\n      const perAdjNet = r4(perAdjPhys - OL2); \/\/ net per adj = physical - OL (for display)\n      const inRange = perAdjPhys>=adj.min-0.0005 && perAdjPhys<=adj.max+0.0005;\n      if(inRange){\n        const setCm=Math.round(perAdjPhys*10000)\/100;\n        const label=nAdj===1?'1 adjustable straight module set to '+setCm+' cm':nAdj+' adjustable straight modules, each set to '+setCm+' cm';\n        const modules=[];\n        if(nS>0) modules.push({qty:nS,name:'Standardmodule',code:v.c.st,note:Math.round(v.wS*1000)\/10+' cm each'});\n        modules.push({qty:nAdj,name:'Adjustable module'+(nAdj>1?'s':''),code:adj.code,note:(nAdj>1?'each ':'')+'slide to <strong>'+setCm+' cm<\/strong> (range: '+Math.round(adj.min*100)+'\u2013'+Math.round(adj.max*100)+' cm)'});\n        rec={label,modules,exact:true};\n        _exactOpts=[{nS,nA:nAdj,wA:perAdjPhys,len:target,diff:0,feasible:true,exact:true,modules,label}];\n        break;\n      }\n    }\n  }\n  \/\/ Exakte Passung only suggests the adjustable straight module.\n  \/\/ Adjustable end modules are suggested separately when they give a cleaner\/fewer-module solution.\n\n  let html='';\n\n  if(rec){\n    \/\/ \u2500\u2500 There IS an exact fit solution \u2014 show it cleanly \u2500\u2500\n    const adjCount=rec.modules.filter(m=>m.name.toLowerCase().includes('adjustable')).reduce((s,m)=>s+m.qty,0);\n    const stdCount=rec.modules[0]?.qty||0;\n    let intro='';\n    const adjOnly=stdCount===0;\n    if(accNetLen>0){\n      if(adjOnly){\n        intro='Using '+(adjCount===1?'one adjustable':''+adjCount+' adjustable')+' module'+(adjCount>1?'s':'')+' ergibt eine exakte Passung. Ihre '+Math.round(accNetLen*100)+' cm an End-\/Wandmodulen sind bereits enthalten.';\n      } else {\n        intro='Replacing '+(adjCount===1?'one':''+adjCount)+' standard module'+(adjCount>1?'s':'')+' with '+(adjCount===1?'an adjustable':''+adjCount+' adjustable')+' module'+(adjCount>1?'s':'')+' ergibt eine exakte Passung. Ihre '+Math.round(accNetLen*100)+' cm an End-\/Wandmodulen sind bereits enthalten.';\n      }\n    } else {\n      if(adjOnly){\n        intro='Use '+(adjCount===1?'one adjustable':''+adjCount+' adjustable')+' module'+(adjCount>1?'s':'')+' to reach exactly '+target+' m.';\n      } else {\n        intro='Replace '+(adjCount===1?'one':''+adjCount)+' standard module'+(adjCount>1?'s':'')+' with '+(adjCount===1?'an adjustable':''+adjCount+' adjustable')+' module'+(adjCount>1?'s':'')+' to reach exactly '+target+' m.';\n      }\n    }\n    if(hasCorners) intro='Diese Strecke hat Ecken \u2014 platzieren Sie das verstellbare Modul'+(adjCount>1?'s':'')+' irgendwo in den geraden Strecken. '+intro;\n    html+=\n      '<div style=\"font-size:12px;color:var(--t2);margin-bottom:12px;line-height:1.6\">'+intro+'<\/div>'+\n      '<div class=\"eo best\" style=\"border:2px solid var(--ok)\">'+\n        '<div class=\"eo-hd\">'+\n          '<div>'+\n            '<div class=\"eo-t\">'+rec.label+'<\/div>'+\n            '<div style=\"font-size:11px;color:var(--t2);margin-top:3px\">Reaches exactly '+target+' m'+(accNetLen>0?' including your end\/wall modules':'')+'<\/div>'+\n          '<\/div>'+\n          '<span class=\"eo-b b-ex\">Exakte Passung<\/span>'+\n        '<\/div>'+\n        '<div class=\"eo-ms\">'+\n          rec.modules.map(m=>'<div class=\"eo-m\"><span><strong>'+m.qty+'\u00d7<\/strong> '+m.name+(m.code?' <span class=\"bkc\">'+m.code+'<\/span>':'')+'<\/span><span>'+m.note+'<\/span><\/div>').join('')+\n          (accNetLen>0?'<div class=\"eo-m\" style=\"color:var(--t3)\"><span>+ your end\/wall modules<\/span><span>already configured above<\/span><\/div>':'')+\n        '<\/div>'+\n        '<div style=\"margin-top:10px;padding-top:10px;border-top:0.5px solid var(--bd)\">'+\n          '<button class=\"eo-sel-btn\" onclick=\"selectExactOpt(0)\" style=\"width:100%;padding:10px;font-size:13px;font-weight:700;font-family:var(--fn);border:none;border-radius:var(--rm);cursor:pointer;background:var(--ok);color:#fff;letter-spacing:0.01em\">F\u00fcr meine Anfrage verwenden<\/button>'+\n        '<\/div>'+\n      '<\/div>';\n\n    \/\/ Also show adj end option if found\n    if(recAdjEnd){\n      const adjGeradeMods=rec.modules.reduce((s,m)=>s+m.qty,0);\n      const fewer=recAdjEnd.totalModules<adjGeradeMods;\n      const replaceMsg=hasStdEnds\n        ?'<strong>Simpler alternative \u2014 swap to adjustable end modules:<\/strong> replace your standard end modules with adjustable ones set to the exact widths below. No adjustable straight module needed.'\n        :'<strong>Alternative'+(fewer?' (fewer modules)':'')+':<\/strong> Use adjustable end modules \u2014 each caps the run and sets the exact length in one piece.';\n      html+='<div style=\"margin-top:16px;padding-top:14px;border-top:0.5px solid var(--bd)\">'+\n        '<div style=\"font-size:12px;color:var(--t2);margin-bottom:10px;line-height:1.6\">'+replaceMsg+'<\/div>'+\n        '<div class=\"eo\" style=\"border:1px solid var(--bd)\">'+\n          '<div class=\"eo-hd\">'+\n            '<div>'+\n              '<div class=\"eo-t\">'+recAdjEnd.label+'<\/div>'+\n              '<div style=\"font-size:11px;color:var(--t2);margin-top:3px\">'+recAdjEnd.totalModules+' Module insgesamt \u2014 reaches exactly '+target+' m<\/div>'+\n            '<\/div>'+\n            '<span class=\"eo-b\" style=\"background:'+(fewer?'var(--okb)':'var(--bg2)')+';color:'+(fewer?'var(--ok)':'var(--t2)')+'\">'+( fewer?'Fewer modules':'Exakte Passung')+'<\/span>'+\n          '<\/div>'+\n          '<div class=\"eo-ms\">'+\n            recAdjEnd.modules.map(m=>'<div class=\"eo-m\"><span><strong>'+m.qty+'\u00d7<\/strong> '+m.name+(m.code?' <span class=\"bkc\">'+m.code+'<\/span>':'')+'<\/span><span>'+m.note+'<\/span><\/div>').join('')+\n          '<\/div>'+\n          '<div style=\"margin-top:10px;padding-top:10px;border-top:0.5px solid var(--bd)\">'+\n            '<button class=\"eo-sel-btn-ae\" onclick=\"selectAdjEndOpt()\" style=\"width:100%;padding:10px;font-size:13px;font-weight:700;font-family:var(--fn);border:none;border-radius:var(--rm);cursor:pointer;background:var(--ok);color:#fff;letter-spacing:0.01em\">F\u00fcr meine Anfrage verwenden<\/button>'+\n          '<\/div>'+\n        '<\/div>'+\n      '<\/div>';\n    }\n\n  } else if(recAdjEnd&&!hasCorners&&!hasAdjEnds){\n    \/\/ \u2500\u2500 No adj straight solution but adj end modules work \u2500\u2500\n    const introMsg=hasStdEnds\n      ?'The adjustable straight module cannot fill the gap here \u2014 but switching to adjustable end modules solves it exactly, with fewer total modules.'\n      :'The adjustable straight module cannot fill the gap for this target \u2014 but adjustable end modules solve it exactly.';\n    html+='<div style=\"font-size:12px;color:var(--t2);margin-bottom:12px;line-height:1.6\">'+introMsg+'<\/div>'+\n    '<div class=\"eo best\" style=\"border:2px solid var(--ok)\">'+\n      '<div class=\"eo-hd\">'+\n        '<div>'+\n          '<div class=\"eo-t\">'+recAdjEnd.label+'<\/div>'+\n          '<div style=\"font-size:11px;color:var(--t2);margin-top:3px\">'+recAdjEnd.totalModules+' modules \u2014 reaches exactly '+target+' m<\/div>'+\n        '<\/div>'+\n        '<span class=\"eo-b b-ex\">Exakte Passung<\/span>'+\n      '<\/div>'+\n      '<div class=\"eo-ms\">'+\n        recAdjEnd.modules.map(m=>'<div class=\"eo-m\"><span><strong>'+m.qty+'\u00d7<\/strong> '+m.name+(m.code?' <span class=\"bkc\">'+m.code+'<\/span>':'')+'<\/span><span>'+m.note+'<\/span><\/div>').join('')+\n      '<\/div>'+\n      '<div style=\"margin-top:10px;padding-top:10px;border-top:0.5px solid var(--bd)\">'+\n        '<button class=\"eo-sel-btn-ae\" onclick=\"selectAdjEndOpt()\" style=\"width:100%;padding:10px;font-size:13px;font-weight:700;font-family:var(--fn);border:none;border-radius:var(--rm);cursor:pointer;background:var(--ok);color:#fff;letter-spacing:0.01em\">F\u00fcr meine Anfrage verwenden<\/button>'+\n      '<\/div>'+\n    '<\/div>';\n    \/\/ Set as primary rec for badge, and store for selectAdjEndOpt\n    rec=recAdjEnd;\n    window._adjEndRec=recAdjEnd;\n    _exactOpts=[{nS:recAdjEnd.nS,nA:0,wA:null,len:target,diff:0,feasible:true,exact:true,modules:recAdjEnd.modules,label:recAdjEnd.label,isAdjEnd:true}];\n  } else {\n    \/\/ \u2500\u2500 No exact fit solution \u2014 show clear explanation \u2500\u2500\n    const overPct2=r4((overCm\/100)\/straightTarget*100);\n    if(hasCorners||alreadyHasEndOrWall){\n      const msg=alreadyHasEndOrWall\n        ? 'Ihre End-\/Wandmodule sind bereits enthalten \u2014 die L\u00fccke der geraden Strecke ('+gapCm+' cm) is outside the adjustable module range ('+Math.round(adjNetMin*100)+'\u2013'+Math.round(adjNetMax*100)+' cm). Standardpassung with '+nStd+' geraden Modulen ist hier die richtige L\u00f6sung.'\n        : 'The gap ('+gapCm+' cm) is outside the adjustable module range ('+Math.round(adjNetMin*100)+'\u2013'+Math.round(adjNetMax*100)+' cm). Standardpassung with '+nStd+' modules is the right answer.';\n      html+='<div style=\"background:var(--okb);border-left:3px solid var(--ok);padding:10px 14px;border-radius:0 var(--rm) var(--rm) 0;font-size:12px;color:#27500A;line-height:1.6\">'+\n        '<strong>Standardpassung is the right answer here.<\/strong> '+msg+' The overshoot is only <strong>'+overCm+' cm ('+overPct2+'%)<\/strong> \u2014 well within installation tolerance.'+\n      '<\/div>';\n    } else {\n      html+='<div style=\"background:var(--okb);border-left:3px solid var(--ok);padding:10px 14px;border-radius:0 var(--rm) var(--rm) 0;font-size:12px;color:#27500A;line-height:1.6\">'+\n        '<strong>Standardpassung is the right answer here.<\/strong> '+\n        'The '+gapCm+' cm gap is outside the adjustable module range ('+Math.round(adjNetMin*100)+'\u2013'+Math.round(adjNetMax*100)+' cm net) \u2014 the adjustable wouldn\\'t fill it cleanly. '+\n        'Use '+nStd+' standard modules on the Standardpassung tab. The overshoot is only <strong>'+overCm+' cm ('+overPct2+'%)<\/strong>. '+\n        'Wenn Sie einen b\u00fcndigen Abschluss ben\u00f6tigen, f\u00fcgen Sie im Bereich Zubeh\u00f6r Endmodule oder Wandanschl\u00fcsse hinzu.'+\n      '<\/div>';\n    }\n    _exactOpts=[];bestExactOpt=null;exactOptUserSelected=false;\n  }\n\n  document.getElementById('eo-list').innerHTML=html;\n  document.getElementById('ei').textContent='';\n  document.getElementById('en').textContent='';\n  \/\/ Update badge\n  const badge=document.getElementById('badge-exact');\n  if(badge) badge.textContent=rec?'verf\u00fcgbar':'standard fit ok';\n  if(badge) badge.style.background=rec?'':'var(--okb)';\n  if(badge) badge.style.color=rec?'':'var(--ok)';\n  if(badge) badge.style.borderColor=rec?'':'var(--okl)';\n}\n\n\n\/\/ \u2500\u2500 TABS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction toggleExactInfo(e){\n  if(e)e.stopPropagation();\n  const pop=document.getElementById('exact-info-popover');\n  pop.style.display=pop.style.display==='none'?'block':'none';\n}\nfunction toggleEndInfo(e){\n  if(e)e.stopPropagation();\n  const existing=document.getElementById('end-info-popover');\n  if(existing){existing.remove();return;}\n  const pop=document.createElement('div');\n  pop.id='end-info-popover';\n  pop.style.cssText='position:relative;z-index:10;grid-column:1\/-1';\n  pop.innerHTML='<div style=\"background:var(--blb);border:0.5px solid var(--bll);border-radius:var(--rm);padding:12px 14px;font-size:12px;color:#0C447C;line-height:1.7;margin-top:6px\">'+\n    '<strong>End modules<\/strong> cap the open end of a run \u2014 for example where the barrier ends in an open space and nothing is fixed to. Use 1 per open end (left, right, or both). '+\n    '<br><strong>Standard<\/strong> end modules are fixed width; <strong>adjustable<\/strong> ones (T50 only) slide between 44\u201352 cm and let you fine-tune the length on site.'+\n  '<\/div>';\n  const grp=document.getElementById('grp-ends');\n  grp.appendChild(pop);\n}\nfunction toggleWallInfo(e){\n  if(e)e.stopPropagation();\n  const existing=document.getElementById('wall-info-popover');\n  if(existing){existing.remove();return;}\n  const pop=document.createElement('div');\n  pop.id='wall-info-popover';\n  pop.style.cssText='position:relative;z-index:10;grid-column:1\/-1';\n  pop.innerHTML='<div style=\"background:var(--blb);border:0.5px solid var(--bll);border-radius:var(--rm);padding:12px 14px;font-size:12px;color:#0C447C;line-height:1.7;margin-top:6px\">'+\n    '<strong>Wall connectors<\/strong> are used when the barrier runs up against a wall on one or both sides \u2014 for example a garage opening where both ends butt up against the garage walls. '+\n    'Use 1 per side that connects to a wall. You would use either end modules <em>or<\/em> wall connectors on a given side, not both.'+\n  '<\/div>';\n  const grp=document.getElementById('grp-wall');\n  grp.appendChild(pop);\n}\n\/\/ Close inline popovers on outside click\ndocument.addEventListener('click',()=>{\n  const pop=document.getElementById('exact-info-popover');\n  if(pop)pop.style.display='none';\n  ['end-info-popover','wall-info-popover'].forEach(id=>{const el=document.getElementById(id);if(el)el.remove();});\n});\n\nfunction switchTab(t){\n  const v=MODELS[sel].variants[selV];if(t==='exact'&&!v.adj)return;\n  activeTab=t;\n  ['std','exact','weight'].forEach(id=>{document.getElementById('tab-'+id).classList.toggle('active',id===t);document.getElementById('body-'+id).style.display=id===t?'block':'none';});\n  updateQuoteSummary();\n  if(_lastCalc){const lc=_lastCalc;buildWeight(lc.nStd,lc.v,lc.total,lc.accPcs,lc.cin,lc.cout,lc.el,lc.er,lc.ael,lc.aer,lc.wl,lc.wr,lc.inPcs,lc.outPcs);}\n}\n\nfunction selectExactOpt(i){\n  if(!_exactOpts||!_exactOpts[i])return; \/\/ guard: no option verf\u00fcgbar\n  if(exactOptUserSelected&&bestExactOpt===_exactOpts[i]){\n    \/\/ Deselect\n    bestExactOpt=null;exactOptUserSelected=false;\n    const btn=document.querySelector('.eo-sel-btn');\n    if(btn){btn.textContent='F\u00fcr meine Anfrage verwenden';btn.style.background='var(--ok)';btn.style.color='#fff';btn.style.border='none';}\n    updateQuoteSummary();\n    if(_lastCalc){const lc=_lastCalc;buildWeight(lc.nStd,lc.v,lc.total,lc.accPcs,lc.cin,lc.cout,lc.el,lc.er,lc.ael,lc.aer,lc.wl,lc.wr,lc.inPcs,lc.outPcs);}\n    return;\n  }\n  \/\/ Select\n  bestExactOpt=_exactOpts[i];exactOptUserSelected=true;\n  const btn=document.querySelector('.eo-sel-btn');\n  if(btn){btn.textContent='\u2713 F\u00fcr Anfrage ausgew\u00e4hlt \u2014 klicken zum Abw\u00e4hlen';btn.style.background='#27500A';btn.style.color='#fff';btn.style.border='none';}\n  updateQuoteSummary();\n  if(_lastCalc){const lc=_lastCalc;buildWeight(lc.nStd,lc.v,lc.total,lc.accPcs,lc.cin,lc.cout,lc.el,lc.er,lc.ael,lc.aer,lc.wl,lc.wr,lc.inPcs,lc.outPcs);}\n  \/\/ Scroll to quote section so user can see the update\n  const qs=document.getElementById('quote-section');\n  if(qs)setTimeout(()=>qs.scrollIntoView({behavior:'smooth',block:'start'}),100);\n}\n\n\/\/ \u2500\u2500 SAVE \/ LOAD \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\/\/ \u2500\u2500 CART \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nlet cart=[];\n\nfunction renameCartItem(id, newName){\n  const item=cart.find(c=>c.id===id);\n  if(item){item.label=newName||item.label;renderQuoteCartSummary();}\n}\n\nfunction addToQuote(){\n  if(!_lastCalc)return;\n  const lc=_lastCalc;\n  const v=lc.v;\n  const defaultName='Configuration '+(cart.length+1);\n  const w=v.w||{};\n  const inPcs=lc.inPcs,outPcs=lc.outPcs;\n  const useFixed=(v.name==='T100'||v.name==='T120')&&coutType==='fixed';\n  const nSt=exactOptUserSelected&&bestExactOpt?bestExactOpt.nS:lc.nStd;\n  const nAdj=exactOptUserSelected&&bestExactOpt?bestExactOpt.nA:0;\n  const totalKg=Math.round((nSt*(w.st||v.wKg)+nAdj*(w.adj||v.wKg)+inPcs*(w.ci||0)+outPcs*(useFixed?(v.name==='T100'?27.5:28):w.co||0)+(lc.el||0)*(w.el||0)+(lc.er||0)*(w.er||0)+(lc.ael||0)*(w.ael||0)+(lc.aer||0)*(w.aer||0)+(lc.wl||0)*(w.wl||0)+(lc.wr||0)*(w.wr||0))*10)\/10;\n  cart.push({\n    id:Date.now(),\n    label:defaultName,\n    model:MODELS[sel].label+' \u00b7 '+v.name+' \u00b7 '+v.prot+' cm',\n    sections:[...sections],\n    target:lc.target,\n    total:lc.total,\n    nStd:lc.nStd,\n    accPcs:lc.accPcs,\n    codes:[...lc.codes],\n    totalKg,\n    exactOpt:exactOptUserSelected?{...bestExactOpt}:null,\n    coutType\n  });\n  renderCart();\n}\n\nfunction removeFromCart(id){\n  cart=cart.filter(c=>c.id!==id);\n  renderCart();\n  updateQuoteSummary();\n}\n\nfunction renderCart(){\n  const sec=document.getElementById('cart-section');\n  if(!cart.length){sec.style.display='none';renderQuoteCartSummary();return;}\n  sec.style.display='block';\n  document.getElementById('cart-count').textContent=cart.length;\n  const totalPcs=cart.reduce((s,c)=>s+c.total,0);\n  const totalKg=Math.round(cart.reduce((s,c)=>s+c.totalKg,0)*10)\/10;\n  document.getElementById('cart-total-pcs').textContent=totalPcs;\n  document.getElementById('cart-total-kg').textContent=totalKg+' kg';\n  document.getElementById('cart-items').innerHTML=cart.map((c,idx)=>`\n    <div style=\"background:var(--bg2);border-radius:var(--rm);padding:14px 16px;border-left:4px solid var(--br)\">\n      <div style=\"display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:10px\">\n        <div style=\"flex:1\">\n          <div style=\"display:flex;align-items:center;gap:8px;margin-bottom:4px\">\n            <span style=\"font-size:11px;font-weight:700;background:var(--br);color:#fff;border-radius:4px;padding:1px 7px\">${idx+1}<\/span>\n            <input id=\"cart-name-${c.id}\" value=\"${c.label}\" onchange=\"renameCartItem(${c.id},this.value)\" style=\"font-size:14px;font-weight:700;color:var(--t1);border:none;background:transparent;font-family:var(--fn);flex:1;min-width:0;border-bottom:1px dashed var(--bd);padding-bottom:2px\" title=\"Click to rename\">\n          <\/div>\n          <div style=\"font-size:12px;color:var(--t2)\">${c.model}<\/div>\n        <\/div>\n        <button onclick=\"removeFromCart(${c.id})\" style=\"font-size:11px;color:#A32D2D;background:none;border:0.5px solid #F09595;border-radius:4px;cursor:pointer;font-family:var(--fn);padding:3px 8px;white-space:nowrap;flex-shrink:0\">Remove<\/button>\n      <\/div>\n      <div style=\"display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:8px\">\n        <div style=\"background:var(--bg1);border-radius:6px;padding:8px 10px\"><div style=\"font-size:16px;font-weight:700;color:var(--t1)\">${c.target} m<\/div><div style=\"font-size:11px;color:var(--t2)\">Ben\u00f6tigte L\u00e4nge<\/div><\/div>\n        <div style=\"background:var(--bg1);border-radius:6px;padding:8px 10px\"><div style=\"font-size:16px;font-weight:700;color:var(--t1)\">${c.total}<\/div><div style=\"font-size:11px;color:var(--t2)\">Total modules<\/div><\/div>\n        <div style=\"background:var(--bg1);border-radius:6px;padding:8px 10px\"><div style=\"font-size:16px;font-weight:700;color:var(--t1)\">${c.totalKg} kg<\/div><div style=\"font-size:11px;color:var(--t2)\">Total weight<\/div><\/div>\n      <\/div>\n      <div style=\"font-size:11px;color:var(--t3);font-family:var(--fm);line-height:1.7\">${c.codes.join(' \u00b7 ')}<\/div>\n    <\/div>\n  `).join('');\n  renderQuoteCartSummary();\n}\n\nfunction renderQuoteCartSummary(){\n  const hasCart=cart.length>0;\n  document.getElementById('quote-single-config').style.display=hasCart?'none':'block';\n  const qci=document.getElementById('quote-cart-items');\n  if(!hasCart){qci.innerHTML='';return;}\n  qci.innerHTML='<div class=\"qs-t\" style=\"margin-bottom:10px;padding-top:4px\">Ihre Konfigurations ('+cart.length+')<\/div>'+cart.map(c=>`\n    <div class=\"qsum\" style=\"border-left:3px solid var(--br)\">\n      <div class=\"qs-t\">${c.label}<\/div>\n      <div class=\"qs-m\">${c.model}<\/div>\n      <div class=\"qs-g\">\n        <div class=\"qs-i\"><span style=\"font-size:15px;font-weight:700;color:var(--t1);min-width:70px;flex-shrink:0\">${c.target} m<\/span><span>Ben\u00f6tigte L\u00e4nge<\/span><\/div>\n        ${c.exactOpt&&c.exactOpt.modules?\n          c.exactOpt.modules.map(m=>`<div class=\"qs-i\"><span style=\"font-size:15px;font-weight:700;color:var(--t1);min-width:70px;flex-shrink:0\">${m.qty}\u00d7<\/span><span>${m.name}<\/span><\/div>`).join('')+\n          `<div class=\"qs-i\"><span style=\"font-size:15px;font-weight:700;color:var(--t1);min-width:70px;flex-shrink:0\">${c.total}<\/span><span>Grand total (exact fit)<\/span><\/div>`\n          :`<div class=\"qs-i\"><span style=\"font-size:15px;font-weight:700;color:var(--t1);min-width:70px;flex-shrink:0\">${c.total}<\/span><span>Total modules<\/span><\/div>`}\n        <div class=\"qs-i\"><span style=\"font-size:15px;font-weight:700;color:var(--t1);min-width:70px;flex-shrink:0\">${c.totalKg} kg<\/span><span>Total weight<\/span><\/div>\n        ${c.sections.length>1?`<div class=\"qs-i\"><span style=\"font-size:15px;font-weight:700;color:var(--t1);min-width:70px;flex-shrink:0\">${c.sections.length}<\/span><span>Sections<\/span><\/div>`:''}\n      <\/div>\n      <div class=\"qs-c\">${c.codes.join(' \u00b7 ')}<\/div>\n    <\/div>\n  `).join('');\n}\n\nfunction resetConfig(){\n  _lastCalc=null;\n  exactOptUserSelected=false;bestExactOpt=null;_exactOpts=[];\n  cart=[];\n  sel='T';selV=0;\n  ['T','S','D'].forEach(x=>document.getElementById('sb-'+x).classList.toggle('active',x==='T'));\n  sections=[{id:secNextId++,len:0}];activeSec=0;\n  document.getElementById('f-cin').value=0;\n  document.getElementById('f-cout').value=0;\n  document.getElementById('f-el').value=0;\n  document.getElementById('f-er').value=0;\n  document.getElementById('f-wl').value=0;\n  document.getElementById('f-wr').value=0;\n  coutType='modules';\n  setSituation('90');\n  \/\/ Clear map drawings if map has been initialised\n  if(ewMap){\n    mapCurrentPoints=[];\n    mapCurrentMarkers.forEach(m=>ewMap.removeLayer(m));mapCurrentMarkers=[];\n    if(mapCurrentPolyline){ewMap.removeLayer(mapCurrentPolyline);mapCurrentPolyline=null;}\n    if(mapCurrentPreview){ewMap.removeLayer(mapCurrentPreview);mapCurrentPreview=null;}\n    mapShapes.forEach(s=>s.layers.forEach(l=>ewMap.removeLayer(l)));mapShapes=[];\n    const cp=document.getElementById('map-close-popup');if(cp)cp.style.display='none';\n    const db=document.getElementById('map-drawing-btns');if(db)db.style.display='none';\n    const ib=document.getElementById('map-import-bar');if(ib)ib.classList.add('hidden');\n  }\n  document.getElementById('map-imported-note').style.display='none';\n  \/\/ Reset map search\n  const msi=document.getElementById('map-search-input');if(msi)msi.value='';\n  const msr=document.getElementById('map-search-results');if(msr)msr.style.display='none';\n  renderH();renderSections();updateAvail();renderCart();\n  \/\/ Clear quote summary\n  const qsg=document.getElementById('qs-grid');if(qsg)qsg.innerHTML='';\n  const qsc=document.getElementById('qs-codes');if(qsc)qsc.textContent='';\n  const qsm=document.getElementById('qs-model');if(qsm)qsm.textContent='\u2013';\n  const qci=document.getElementById('quote-cart-items');if(qci)qci.innerHTML='';\n  document.getElementById('quote-single-config').style.display='block';\n  calc();\n  window.scrollTo({top:0,behavior:'smooth'});\n}\n\nfunction scrollToQuote(){\n  document.getElementById('quote-section').scrollIntoView({behavior:'smooth',block:'start'});\n}\n\n\n\/\/ \u2500\u2500 QUOTE \/ EMAIL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nlet urgency='', siteAddress='', geoLat=null, geoLng=null;\n\nfunction setUrg(u){\n  urgency=u;\n  ['asap','weeks','exploring'].forEach(x=>document.getElementById('urg-'+x).classList.toggle('active',x===u));\n}\n\nfunction onStandortInput(){\n  siteAddress=document.getElementById('q-address').value.trim();\n}\n\nfunction useGPS(){\n  if(!navigator.geolocation){alert('Standort access not supported by this browser.');return;}\n  navigator.geolocation.getCurrentPosition(pos=>{\n    geoLat=pos.coords.latitude;geoLng=pos.coords.longitude;\n    const s=geoLat.toFixed(5)+', '+geoLng.toFixed(5);\n    const coordEl=document.getElementById('coords');\n    coordEl.textContent='\ud83d\udccd '+s+' (GPS)';coordEl.style.display='block';\n    siteAddress=s;\n    const addrInput=document.getElementById('q-address');\n    if(addrInput&&!addrInput.value)addrInput.value=s;\n  },()=>alert('Could not get your location. Please enter it manually.'));\n}\n\nfunction getConfigSummaryText(){\n  const body=getEasyWallEmailBody();\n  \/\/ Strip the notes\/address section \u2014 we just want config summary\n  const lines=body.split('\\n');\n  const confStart=lines.findIndex(l=>l.includes('CONFIGURATIONS')||l.includes('MODULES'));\n  if(confStart>-1) return lines.slice(confStart).join('\\n').trim();\n  return body.trim();\n}\n\nfunction openCallbackModal(){\n\n   if(!_lastCalc&&!cart.length){\n\t\talert(\"Noch keine Konfiguration berechnet\");\n\t\treturn;\n   }\n\t\n\t\n\t       \n\t  const summary = getEasyWallEmailBody();\n\t  if (!summary){\n\t\talert(\"Noch keine Konfiguration berechnet\");\n\t  }\n\t  else{\n\t\t const formField = document.getElementById('calc_summary_2');     \/\/ hidden field inside Elementor form\n\t\t if (formField) formField.value = summary;\n\t\t document.getElementById('modal-callback').style.display='flex';\n\t\n\t  }\n\t\n\t \n\t\n\t  \n\n}\nfunction openEmailMeModal(){\n\n   if(!_lastCalc&&!cart.length){\n\t\talert(\"Noch keine Konfiguration berechnet\");\n\t\treturn;\n   }\n\t\n\t  const summary = getEasyWallEmailBody();\n\t  if (!summary){\n\t\talert(\"Noch keine Konfiguration berechnet\");\n\t  }\n\t  else{\n\t\t const formField = document.getElementById('calc_summary_3');     \/\/ hidden field inside Elementor form\n\t\t if (formField) formField.value = summary;\n\t\t document.getElementById('modal-email-me').style.display='flex';\n\t\t\n\t  }\n}\nfunction closeModal(id){\n  document.getElementById(id).style.display='none';\n}\nfunction showSuccess(title,body){\n  document.getElementById('success-title').textContent=title;\n  document.getElementById('success-body').textContent=body;\n  document.getElementById('modal-success').style.display='flex';\n}\n\nfunction submitToNoFloods(data){\n  \/\/ Submit to the NoFloods webform endpoint\n  \/\/ data = { tag, name?, phone?, bestTime?, email?, configSummary, urgency }\n  const form=new FormData();\n  Object.entries(data).forEach(([k,v])=>{if(v)form.append(k,v);});\n  \/\/ POST to the webform \u2014 update URL to match NoFloods endpoint\n  return fetch('https:\/\/nofloods.com\/wp-json\/contact-form-7\/v1\/contact-forms\/FORM_ID\/feedback',{\n    method:'POST',body:form\n  }).then(r=>r.ok).catch(()=>false);\n}\n\nfunction getDringlichkeitText(){\n  if(document.getElementById('urg-asap')?.classList.contains('active'))return'So schnell wie m\u00f6glich (urgent)';\n  if(document.getElementById('urg-weeks')?.classList.contains('active'))return'Innerhalb weniger Wochen';\n  if(document.getElementById('urg-exploring')?.classList.contains('active'))return'Nur zur Orientierung';\n  return'Not specified';\n}\n\nasync function submitCallback(){\n  const name=(document.getElementById('cb-name').value||'').trim();\n  const phone=(document.getElementById('cb-phone').value||'').trim();\n  const time=(document.getElementById('cb-time').value||'').trim();\n  const errEl=document.getElementById('cb-error');\n  if(!name||!phone){errEl.textContent='Bitte geben Sie Ihren Namen und Ihre Telefonnummer ein.';errEl.style.display='block';return;}\n  errEl.style.display='none';\n  const btn=document.querySelector('#modal-callback button');\n  const orig=btn.textContent;btn.textContent='Wird gesendet\u2026';btn.disabled=true;\n  const ok=await submitToNoFloods({\n    tag:'CALLBACK',\n    name,phone,'best-time':time,\n    'config-summary':getConfigSummaryText(),\n    urgency:getDringlichkeitText(),\n    source:'EasyWall calculator \u2014 callback request'\n  });\n  btn.textContent=orig;btn.disabled=false;\n  closeModal('modal-callback');\n  showSuccess('R\u00fcckruf angefordert','Das NoFloods-Team wird Sie in K\u00fcrze anrufen. Pr\u00fcfen Sie Ihr Telefon \u2014 der Anruf kann von einer unbekannten Nummer kommen.');\n}\n\nasync function submitEmailMe(){\n  const email=(document.getElementById('em-email').value||'').trim();\n  const errEl=document.getElementById('em-error');\n  if(!email||!email.includes('@')){errEl.textContent='Bitte geben Sie eine g\u00fcltige E-Mail-Adresse ein.';errEl.style.display='block';return;}\n  errEl.style.display='none';\n  const btn=document.querySelector('#modal-email-me button');\n  const orig=btn.textContent;btn.textContent='Wird gesendet\u2026';btn.disabled=true;\n  const ok=await submitToNoFloods({\n    tag:'SAVE-CALC',\n    email,\n    'config-summary':getConfigSummaryText(),\n    urgency:getDringlichkeitText(),\n    source:'EasyWall calculator \u2014 save configuration'\n  });\n  btn.textContent=orig;btn.disabled=false;\n  closeModal('modal-email-me');\n  showSuccess('Configuration saved','Check your inbox \u2014 we\\'ve sent your barrier summary. The NoFloods team also has a copy and may follow up.');\n}\n\n\/\/ Close modals on backdrop click\n['modal-callback','modal-email-me','modal-success'].forEach(id=>{\n  document.getElementById(id)?.addEventListener('click',e=>{\n    if(e.target.id===id)closeModal(id);\n  });\n});\n\nfunction onNotizenChange(){\/* live \u2014 body assembled on send *\/}\n\nfunction selectAdjEndOpt(){\n  if(!window._adjEndRec)return;\n  const rec=window._adjEndRec;\n  bestExactOpt={nS:rec.nS,nA:0,wA:null,len:rec.totalModules,diff:0,feasible:true,exact:true,modules:rec.modules,label:rec.label,isAdjEnd:true};\n  exactOptUserSelected=true;\n  const btn=document.querySelector('.eo-sel-btn-ae');\n  if(btn){btn.textContent='\u2713 F\u00fcr Anfrage ausgew\u00e4hlt \u2014 klicken zum Abw\u00e4hlen';btn.style.background='#27500A';btn.style.color='#fff';btn.style.border='none';}\n  updateQuoteSummary();\n  const qs=document.getElementById('quote-section');\n  if(qs)setTimeout(()=>qs.scrollIntoView({behavior:'smooth',block:'start'}),100);\n}\n\nfunction addToQuoteAndAnother(){\n  addToQuote();\n  \/\/ Only reset the calculator inputs \u2014 keep the cart intact\n  _lastCalc=null;\n  exactOptUserSelected=false;bestExactOpt=null;_exactOpts=[];\n  sel='T';selV=0;\n  ['T','S','D'].forEach(x=>document.getElementById('sb-'+x).classList.toggle('active',x==='T'));\n  sections=[{id:secNextId++,len:0}];activeSec=0;\n  document.getElementById('f-cin').value=0;\n  document.getElementById('f-cout').value=0;\n  document.getElementById('f-el').value=0;\n  document.getElementById('f-er').value=0;\n  document.getElementById('f-wl').value=0;\n  document.getElementById('f-wr').value=0;\n  coutType='modules';\n  \/\/ Clear map drawings so they don't carry over to the next configuration\n  if(ewMap){\n    mapCurrentPoints=[];\n    mapCurrentMarkers.forEach(m=>ewMap.removeLayer(m));mapCurrentMarkers=[];\n    if(mapCurrentPolyline){ewMap.removeLayer(mapCurrentPolyline);mapCurrentPolyline=null;}\n    if(mapCurrentPreview){ewMap.removeLayer(mapCurrentPreview);mapCurrentPreview=null;}\n    mapShapes.forEach(s=>s.layers.forEach(l=>ewMap.removeLayer(l)));mapShapes=[];\n    const cp=document.getElementById('map-close-popup');if(cp)cp.style.display='none';\n    const db=document.getElementById('map-drawing-btns');if(db)db.style.display='none';\n    const ib=document.getElementById('map-import-bar');if(ib)ib.classList.add('hidden');\n    mapSetMode('draw'); \/\/ reset to draw mode ready for next run\n  }\n  document.getElementById('map-imported-note').style.display='none';\n  const msi=document.getElementById('map-search-input');if(msi)msi.value='';\n  \/\/ Collapse map panel so user starts fresh from the top\n  const mp=document.getElementById('map-panel');if(mp)mp.classList.remove('open');\n  const mb=document.getElementById('map-mode-map');if(mb)mb.classList.remove('active');\n  const mm=document.getElementById('map-mode-manual');if(mm)mm.classList.add('active');\n  renderH();renderSections();updateAvail();\n  calc();\n  window.scrollTo({top:0,behavior:'smooth'});\n}\n\nfunction addToQuoteAndFinish(){\n  addToQuote();\n  scrollToQuote();\n}\n\nfunction getEasyWallEmailBody(){\n  if(!_lastCalc&&!cart.length)return'[Noch keine Konfiguration berechnet]';\n  const today=new Date().toLocaleDateString('en-GB',{day:'2-digit',month:'2-digit',year:'numeric'});\n  const userNotizen=(document.getElementById('q-notes')||{}).value||'';\n  const addrVal=((document.getElementById('q-address')||{}).value||'').trim()||siteAddress;\n  const urgLabels={asap:'URGENT \u2014 as soon as possible',weeks:'Innerhalb weniger Wochen',exploring:'Exploring options \u2014 no fixed date'};\n  const lines=[];\n  lines.push('EasyWall Calculator \u00b7 '+today,'');\n  if(urgency)lines.push('TIMELINE: '+(urgLabels[urgency]||urgency),'');\n  if(addrVal)lines.push('SITE LOCATION: '+addrVal,'');\n\n  if(cart.length>0){\n    lines.push('CONFIGURATIONS ('+cart.length+' total)');\n    cart.forEach((c,i)=>{\n      lines.push('');\n      lines.push((i+1)+'. '+c.label);\n      lines.push('  Model: '+c.model);\n      lines.push('  Ben\u00f6tigte L\u00e4nge: '+c.target+' m');\n      if(c.sections&&c.sections.length>1)lines.push('  Sections ('+c.sections.length+'): '+c.sections.map((s,j)=>'S'+(j+1)+': '+s.len+'m').join(', '));\n      if(c.exactOpt&&c.exactOpt.modules){\n        \/\/ Saved with exact fit \u2014 list exact modules\n        lines.push('  Configuration: exact fit \u2014 '+c.exactOpt.label);\n        lines.push('  MODULES (EXACT FIT)');\n        c.exactOpt.modules.forEach(m=>{\n          const codeClean=m.code?m.code.replace(\/<[^>]+>\/g,''):'';\n          const noteClean=m.note?m.note.replace(\/<[^>]+>\/g,''):'';\n          lines.push('    '+m.qty+'\u00d7 '+m.name+(codeClean?' ('+codeClean+')':'')+(noteClean?' \u2014 '+noteClean:''));\n        });\n        const termPcs=c.exactOpt.modules.reduce((s,m)=>s+(m.qty||0),0);\n        lines.push('  Grand total: '+(termPcs+c.accPcs)+' pcs \u00b7 '+c.totalKg+' kg');\n      } else {\n        \/\/ Standardpassung\n        lines.push('  Total modules: '+c.total+' pcs \u00b7 '+c.totalKg+' kg');\n        lines.push('  Product codes: '+c.codes.join(' \u00b7 '));\n      }\n    });\n    const totalPcs=cart.reduce((s,c)=>s+c.total,0);\n    const totalKg=Math.round(cart.reduce((s,c)=>s+c.totalKg,0)*10)\/10;\n    lines.push('','GRAND TOTAL: '+totalPcs+' pcs \u00b7 '+totalKg+' kg');\n  } else if(_lastCalc){\n    const lc=_lastCalc;\n    const v=lc.v;\n    lines.push('MODEL');\n    lines.push('  '+MODELS[sel].label+' \u00b7 '+v.name+' \u00b7 '+v.prot+' cm protection','');\n    lines.push('LENGTHS');\n    lines.push('  Ben\u00f6tigt: '+lc.target+' m');\n    if(lc.sections&&lc.sections.length>1)lines.push('  Sections ('+lc.sections.length+'): '+lc.sections.map((s,i)=>'S'+(i+1)+': '+s.len+'m').join(', '));\n\n    if(exactOptUserSelected&&bestExactOpt&&bestExactOpt.modules){\n      \/\/ Exakte Passung selected \u2014 list modules from the recommendation\n      lines.push('  Exakte Passung configuration: '+bestExactOpt.label,'');\n      lines.push('MODULES (EXACT FIT)');\n      bestExactOpt.modules.forEach(m=>{\n        const codeClean=m.code?m.code.replace(\/<[^>]+>\/g,''):'';\n        const noteClean=m.note?m.note.replace(\/<[^>]+>\/g,''):'';\n        lines.push('  '+m.qty+'\u00d7 '+m.name+(codeClean?' ('+codeClean+')':'')+(noteClean?' \u2014 '+noteClean:''));\n      });\n      if(lc.cin>0)lines.push('  Innenecke: '+lc.inPcs+' pcs ('+v.c.ci+')');\n      if(lc.cout>0)lines.push('  Au\u00dfenecke: '+lc.outPcs+' pcs ('+v.c.co+')');\n      const termPcs=bestExactOpt.modules.reduce((s,m)=>s+(m.qty||0),0);\n      lines.push('  Grand total: '+(termPcs+lc.accPcs)+' pcs');\n    } else {\n      lines.push('  Gerade Abdeckung: '+lc.actualLen+' m');\n      if(lc.accLen&&lc.accLen>0)lines.push('  Gesamt inkl. Zubeh\u00f6r: '+lc.totalLen+' m');\n      lines.push('');\n      lines.push('MODULES');\n      lines.push('  Gerade: '+lc.nStd+' pcs ('+v.c.st+')');\n      if(lc.cin>0)lines.push('  Innenecke: '+lc.inPcs+' pcs ('+v.c.ci+')');\n      if(lc.cout>0)lines.push('  Au\u00dfenecke: '+lc.outPcs+' pcs ('+v.c.co+')');\n      if(lc.el>0)lines.push('  End \u2013 left: '+lc.el+' pcs ('+v.c.el+')');\n      if(lc.er>0)lines.push('  End \u2013 right: '+lc.er+' pcs ('+v.c.er+')');\n      if(lc.ael>0&&v.adjEnd)lines.push('  End \u2013 adj. left: '+lc.ael+' pcs ('+v.adjEnd.cL+')');\n      if(lc.aer>0&&v.adjEnd)lines.push('  End \u2013 adj. right: '+lc.aer+' pcs ('+v.adjEnd.cR+')');\n      if(lc.wl>0&&v.c.wl)lines.push('  Wandanschluss \u2013 links: '+lc.wl+' pcs ('+v.c.wl+')');\n      if(lc.wr>0&&v.c.wr)lines.push('  Wandanschluss \u2013 rechts: '+lc.wr+' pcs ('+v.c.wr+')');\n      lines.push('  Grand total: '+lc.total+' pcs');\n      lines.push('');\n      lines.push('Product codes: '+lc.codes.join(' \u00b7 '));\n    }\n  }\n  lines.push('');\n  return lines.join('\\n');\n}\n\nfunction sendEasyWallEmail(){\n   if(!_lastCalc&&!cart.length)\n\treturn'[Noch keine Konfiguration berechnet]';\n\t\n\t\n\t       \n\t  const summary = getEasyWallEmailBody();\n\t  if (!summary) return;\n\t\n\t\n\t  const formField = document.getElementById('calc_summary_1');     \/\/ hidden field inside Elementor form\n\t  const formStrecke = document.getElementById('send-to-nofloods'); \/\/ Elementor form wrapper section\n\n\n\n\t  if (formField) formField.value = summary;\n\n\t \n\t  if (formSection) {\n\t\tformSection.style.display = 'block';\n\t\trequestAnimationFrame(() => {\n\t\t  formSection.style.opacity = '1';\n\t\t  formSection.style.transition = 'opacity 0.4s ease';\n\t\t});\n\t  }\n\n\t \n\t  if (formSection) {\n\t\tformSection.scrollIntoView({ behavior: 'smooth', block: 'start' });\n\t  }\n\t  \n}\n\nfunction copyEasyWallQuote(){\n  const text=getEasyWallEmailBody();\n  const btn=document.getElementById('copy-quote-btn');\n  const reset=()=>{if(btn){btn.innerHTML='<svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"none\"><rect x=\"5\" y=\"5\" width=\"10\" height=\"10\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.3\"\/><path d=\"M3 11H2a1 1 0 01-1-1V2a1 1 0 011-1h8a1 1 0 011 1v1\" stroke=\"currentColor\" stroke-width=\"1.3\"\/><\/svg> Text kopieren (Ersatzfunktion)';btn.classList.remove('copied');}};\n  const done=()=>{if(btn){btn.textContent='\u2713 In Zwischenablage kopiert';btn.classList.add('copied');setTimeout(reset,2500);}};\n  navigator.clipboard?navigator.clipboard.writeText(text).then(done).catch(()=>{const ta=document.createElement('textarea');ta.value=text;document.body.appendChild(ta);ta.select();document.execCommand('copy');document.body.removeChild(ta);done();}):(() =>{const ta=document.createElement('textarea');ta.value=text;document.body.appendChild(ta);ta.select();document.execCommand('copy');document.body.removeChild(ta);done();})();\n}\n\n\/\/ \u2500\u2500 INIT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nsetSeries('T');document.getElementById('sb-T').classList.add('active');renderSections();setLang('de');\n<\/script>\n<\/body>\n<\/html>\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<\/div>\n\t\t<div class=\"elementor-element elementor-element-d7fb48f elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile e-flex e-con-boxed e-con e-parent\" data-id=\"d7fb48f\" data-element_type=\"container\" data-e-type=\"container\" id=\"send-to-nofloods\" 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-62cf258 elementor-widget__width-inherit elementor-widget elementor-widget-heading\" data-id=\"62cf258\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Haben Sie Ihre Berechnung abgeschlossen? Fordern Sie jetzt Ihr sofortiges Angebot f\u00fcr HOCHWASSERSCHUTZ an <\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e3f9a2d elementor-widget elementor-widget-text-editor\" data-id=\"e3f9a2d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tGeben Sie unten die Ergebnisse Ihres Rechners ein, und unser Team wird Ihnen ein individuelles Angebot zukommen lassen.\nSollten Sie standortspezifische Anliegen haben, f\u00fcgen Sie bitte Fotos, Karten oder anderes relevantes Material bei \u2013 unser Team wird alles pr\u00fcfen und sich so schnell wie m\u00f6glich mit Ihrem individuellen Angebot und unseren Empfehlungen bei Ihnen melden.\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-c0a1ce3 elementor-widget elementor-widget-shortcode\" data-id=\"c0a1ce3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">\n<div class=\"wpcf7 no-js\" id=\"wpcf7-f42013-o3\" lang=\"de-DE\" dir=\"ltr\" data-wpcf7-id=\"42013\">\n<div class=\"screen-reader-response\"><p role=\"status\" aria-live=\"polite\" aria-atomic=\"true\"><\/p> <ul><\/ul><\/div>\n<form action=\"\/de\/wp-json\/wp\/v2\/pages\/42006#wpcf7-f42013-o3\" method=\"post\" class=\"wpcf7-form init\" aria-label=\"Kontaktformular\" novalidate=\"novalidate\" data-status=\"init\">\n<fieldset class=\"hidden-fields-container\"><input type=\"hidden\" name=\"_wpcf7\" value=\"42013\" \/><input type=\"hidden\" name=\"_wpcf7_version\" value=\"6.2.3\" \/><input type=\"hidden\" name=\"_wpcf7_locale\" value=\"de_DE\" \/><input type=\"hidden\" name=\"_wpcf7_unit_tag\" value=\"wpcf7-f42013-o3\" \/><input type=\"hidden\" name=\"_wpcf7_container_post\" value=\"0\" \/><input type=\"hidden\" name=\"_wpcf7_posted_data_hash\" value=\"\" \/><input type=\"hidden\" name=\"_wpcf7cf_hidden_group_fields\" value=\"[]\" \/><input type=\"hidden\" name=\"_wpcf7cf_hidden_groups\" value=\"[]\" \/><input type=\"hidden\" name=\"_wpcf7cf_visible_groups\" value=\"[]\" \/><input type=\"hidden\" name=\"_wpcf7cf_repeaters\" value=\"[]\" \/><input type=\"hidden\" name=\"_wpcf7cf_steps\" value=\"{}\" \/><input type=\"hidden\" name=\"_wpcf7cf_options\" value=\"{&quot;form_id&quot;:42013,&quot;conditions&quot;:[],&quot;settings&quot;:{&quot;animation&quot;:&quot;yes&quot;,&quot;animation_intime&quot;:&quot;200&quot;,&quot;animation_outtime&quot;:&quot;200&quot;,&quot;conditions_ui&quot;:&quot;normal&quot;,&quot;notice_dismissed&quot;:&quot;&quot;,&quot;repeater_remove_button&quot;:&quot;bottom&quot;,&quot;notice_dismissed_rollback-cf7-6.1.7&quot;:true}}\" \/><input type=\"hidden\" name=\"_wpcf7_recaptcha_response\" value=\"\" \/>\n<\/fieldset>\n<div class=\"uacf7-form-wrapper-container uacf7-form-42013  \"><label>Berechnete Konfiguration\n    <span class=\"wpcf7-form-control-wrap\" data-name=\"calc_summary\"><textarea cols=\"40\" rows=\"10\" maxlength=\"2000\" class=\"wpcf7-form-control wpcf7-textarea wpcf7-validates-as-required\" id=\"calc_summary_1\" readonly=\"readonly\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Bitte f\u00fcllen Sie das Feld zun\u00e4chst mithilfe des Rechners aus\" name=\"calc_summary\"><\/textarea><\/span> <\/label>\n\n\n<div class=\"uacf7-row\"><div class=\"uacf7-col-6\"> <label>  Ihr Name*\n    <span class=\"wpcf7-form-control-wrap\" data-name=\"your-name\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" autocomplete=\"name\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"your-name\" \/><\/span> <\/label> <\/div><div class=\"uacf7-col-6\"> <label> Ihre E-Mail-Adresse\n    <span class=\"wpcf7-form-control-wrap\" data-name=\"your-email\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-email wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-email\" autocomplete=\"email\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"email\" name=\"your-email\" \/><\/span> <\/label> <\/div><\/div>\n\n<div class=\"uacf7-row\"><div class=\"uacf7-col-6\"> <label>  Telefon*\n    <span class=\"wpcf7-form-control-wrap\" data-name=\"your-phone\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-tel wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-tel\" autocomplete=\"tel\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"tel\" name=\"your-phone\" \/><\/span> <\/label> <\/div><div class=\"uacf7-col-6\"> <label>  Bevorzugte Sprache  <span class=\"wpcf7-form-control-wrap\" data-name=\"select-383\"><select class=\"wpcf7-form-control wpcf7-select\" aria-invalid=\"false\" name=\"select-383\"><option value=\"Englisch\">Englisch<\/option><option value=\"Franz\u00f6sisch\">Franz\u00f6sisch<\/option><option value=\"Deutsch\">Deutsch<\/option><option value=\"Spanisch\">Spanisch<\/option><option value=\"D\u00e4nisch\">D\u00e4nisch<\/option><option value=\"Italienisch\">Italienisch<\/option><\/select><\/span>\n<\/div><\/div>\n\n <label> Fotos der Baustelle hochladen [ <\/label><span class=\"wpcf7-form-control-wrap\" data-name=\"mfile-274\"><input size=\"40\" class=\"wpcf7-form-control wpcf7-drag-n-drop-file d-none\" aria-invalid=\"false\" type=\"file\" multiple=\"multiple\" data-name=\"mfile-274\" data-type=\"jpeg|png|jpg|pdf|docx|xlxs\" data-limit=\"10485760\" data-id=\"42013\" data-version=\"free version 1.4.0\" accept=\".jpeg, .png, .jpg, .pdf, .docx, .xlxs\" data-black-list=\"js|php|phtml|php3|php4|php5|php7|phps|phar|mjs|cjs|exe|bat|cmd|sh|bash|pl|py|rb|msi|vbs|vbe|jse|wsf|wsh|ps1|psm1|psd1|hta|scr|cpl|com|gadget|jar|html|htm|xhtml|svg|xml|swf|htaccess|htpasswd|user.ini|web.config|lng|reg|inf|chm|hlp|ws|bat|inc|asp|aspx|axd|asx|asmx|ashx|cgi|jsp|jspx|do|cfm|cfc|dll|sys|drv|ocx|so|elf|bin\" \/><\/span>\n\n<label> Erl\u00e4uterung\/Kommentar\n    <span class=\"wpcf7-form-control-wrap\" data-name=\"your-message\"><textarea cols=\"40\" rows=\"3\" maxlength=\"2000\" class=\"wpcf7-form-control wpcf7-textarea\" aria-invalid=\"false\" name=\"your-message\"><\/textarea><\/span> <\/label>\n\n<input class=\"wpcf7-form-control wpcf7-submit has-spinner\" type=\"submit\" value=\"Senden\" \/><\/div><input type=\"text\" class=\"wpcf7_hp_field\" name=\"wpcf7_hp_field\" value=\"\" tabindex=\"-1\" autocomplete=\"off\" \/><div class=\"wpcf7-response-output\" aria-hidden=\"true\"><\/div>\n<\/form>\n<\/div>\n<\/div>\n\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>EasyWall-Hochwasserschutzbarrieren \u2013 Modulrechner Startseite &gt; Page Planen Sie Ihre EasyWall-Absperrung ganz einfach Mit unserem Rechner k\u00f6nnen Sie ganz einfach die [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"_acf_changed":false,"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-42006","page","type-page","status-publish","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>EasyWall-Rechner - NoFloods<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/nofloods.com\/de\/easywall-products-2\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"EasyWall-Rechner - NoFloods\" \/>\n<meta property=\"og:description\" content=\"EasyWall-Hochwasserschutzbarrieren \u2013 Modulrechner Startseite &gt; Page Planen Sie Ihre EasyWall-Absperrung ganz einfach Mit unserem Rechner k\u00f6nnen Sie ganz einfach die [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nofloods.com\/de\/easywall-products-2\/\" \/>\n<meta property=\"og:site_name\" content=\"NoFloods\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/environmentsolutions\/\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-15T18:33:46+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@NoFloodsBarrier\" \/>\n<meta name=\"twitter:label1\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data1\" content=\"8\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/nofloods.com\\\/de\\\/easywall-products-2\\\/\",\"url\":\"https:\\\/\\\/nofloods.com\\\/de\\\/easywall-products-2\\\/\",\"name\":\"EasyWall-Rechner - NoFloods\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/nofloods.com\\\/de\\\/#website\"},\"datePublished\":\"2026-03-30T16:00:09+00:00\",\"dateModified\":\"2026-10-15T18:33:46+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/nofloods.com\\\/de\\\/easywall-products-2\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/nofloods.com\\\/de\\\/easywall-products-2\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/nofloods.com\\\/de\\\/easywall-products-2\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/nofloods.com\\\/de\\\/home\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"EasyWall-Rechner\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/nofloods.com\\\/de\\\/#website\",\"url\":\"https:\\\/\\\/nofloods.com\\\/de\\\/\",\"name\":\"NoFloods\",\"description\":\"By Environment Solutions\",\"publisher\":{\"@id\":\"https:\\\/\\\/nofloods.com\\\/de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/nofloods.com\\\/de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/nofloods.com\\\/de\\\/#organization\",\"name\":\"NoFloods\",\"url\":\"https:\\\/\\\/nofloods.com\\\/de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/nofloods.com\\\/de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/nofloods.com\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/NoFloods-EasyWall-Logo.webp?wsr\",\"contentUrl\":\"https:\\\/\\\/nofloods.com\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/NoFloods-EasyWall-Logo.webp?wsr\",\"width\":340,\"height\":70,\"caption\":\"NoFloods\"},\"image\":{\"@id\":\"https:\\\/\\\/nofloods.com\\\/de\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/environmentsolutions\\\/\",\"https:\\\/\\\/x.com\\\/NoFloodsBarrier\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/environment-solutions-aps\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"EasyWall-Rechner - NoFloods","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/nofloods.com\/de\/easywall-products-2\/","og_locale":"de_DE","og_type":"article","og_title":"EasyWall-Rechner - NoFloods","og_description":"EasyWall-Hochwasserschutzbarrieren \u2013 Modulrechner Startseite &gt; Page Planen Sie Ihre EasyWall-Absperrung ganz einfach Mit unserem Rechner k\u00f6nnen Sie ganz einfach die [&hellip;]","og_url":"https:\/\/nofloods.com\/de\/easywall-products-2\/","og_site_name":"NoFloods","article_publisher":"https:\/\/www.facebook.com\/environmentsolutions\/","article_modified_time":"2026-10-15T18:33:46+00:00","twitter_card":"summary_large_image","twitter_site":"@NoFloodsBarrier","twitter_misc":{"Gesch\u00e4tzte Lesezeit":"8\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/nofloods.com\/de\/easywall-products-2\/","url":"https:\/\/nofloods.com\/de\/easywall-products-2\/","name":"EasyWall-Rechner - NoFloods","isPartOf":{"@id":"https:\/\/nofloods.com\/de\/#website"},"datePublished":"2026-03-30T16:00:09+00:00","dateModified":"2026-10-15T18:33:46+00:00","breadcrumb":{"@id":"https:\/\/nofloods.com\/de\/easywall-products-2\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nofloods.com\/de\/easywall-products-2\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/nofloods.com\/de\/easywall-products-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/nofloods.com\/de\/home\/"},{"@type":"ListItem","position":2,"name":"EasyWall-Rechner"}]},{"@type":"WebSite","@id":"https:\/\/nofloods.com\/de\/#website","url":"https:\/\/nofloods.com\/de\/","name":"NoFloods","description":"By Environment Solutions","publisher":{"@id":"https:\/\/nofloods.com\/de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/nofloods.com\/de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/nofloods.com\/de\/#organization","name":"NoFloods","url":"https:\/\/nofloods.com\/de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/nofloods.com\/de\/#\/schema\/logo\/image\/","url":"https:\/\/nofloods.com\/wp-content\/uploads\/2025\/05\/NoFloods-EasyWall-Logo.webp?wsr","contentUrl":"https:\/\/nofloods.com\/wp-content\/uploads\/2025\/05\/NoFloods-EasyWall-Logo.webp?wsr","width":340,"height":70,"caption":"NoFloods"},"image":{"@id":"https:\/\/nofloods.com\/de\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/environmentsolutions\/","https:\/\/x.com\/NoFloodsBarrier","https:\/\/www.linkedin.com\/company\/environment-solutions-aps"]}]}},"rttpg_featured_image_url":null,"rttpg_author":{"display_name":"nofloods_admin","author_link":"https:\/\/nofloods.com\/de\/author\/nofloods_admin\/"},"rttpg_comment":0,"rttpg_category":" <a href=\"https:\/\/nofloods.com\/de\/?taxonomy=translation_priority&#038;term=optional-de\" rel=\"tag\">Optional<\/a>","rttpg_excerpt":"EasyWall-Hochwasserschutzbarrieren \u2013 Modulrechner Startseite &gt; Page Planen Sie Ihre EasyWall-Absperrung ganz einfach Mit unserem Rechner k\u00f6nnen Sie ganz einfach die [&hellip;]","_links":{"self":[{"href":"https:\/\/nofloods.com\/de\/wp-json\/wp\/v2\/pages\/42006","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nofloods.com\/de\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/nofloods.com\/de\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/nofloods.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nofloods.com\/de\/wp-json\/wp\/v2\/comments?post=42006"}],"version-history":[{"count":17,"href":"https:\/\/nofloods.com\/de\/wp-json\/wp\/v2\/pages\/42006\/revisions"}],"predecessor-version":[{"id":43831,"href":"https:\/\/nofloods.com\/de\/wp-json\/wp\/v2\/pages\/42006\/revisions\/43831"}],"wp:attachment":[{"href":"https:\/\/nofloods.com\/de\/wp-json\/wp\/v2\/media?parent=42006"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}