{"id":1284,"date":"2026-09-13T05:25:06","date_gmt":"2026-09-13T05:25:06","guid":{"rendered":"https:\/\/spiritual-activity.org\/?page_id=1284"},"modified":"2026-09-18T18:00:10","modified_gmt":"2026-09-18T18:00:10","slug":"gruppen-anmeldung","status":"publish","type":"page","link":"https:\/\/spiritual-activity.org\/zh\/gruppen-anmeldung\/","title":{"rendered":"Gruppen Anmeldung"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"1284\" class=\"elementor elementor-1284\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d0eca86 e-flex e-con-boxed e-con e-parent\" data-id=\"d0eca86\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-cd1cd89 elementor-widget elementor-widget-shortcode\" data-id=\"cd1cd89\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"536\" class=\"elementor elementor-536\">\n\t\t\t\t<div class=\"elementor-element elementor-element-cbf2c00 e-flex e-con-boxed e-con e-parent\" data-id=\"cbf2c00\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-97ba22c elementor-widget elementor-widget-html\" data-id=\"97ba22c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<style>\n\/* ============================================================\n   ISA \u2013 HEADER WIDGET\n   ============================================================ *\/\n\n#be-nav {\n  position: fixed;\n  top: 0; left: 0; right: 0;\n  z-index: 9999;\n  padding: 12px 2.5rem;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  background: rgba(255,255,255,0.95);\n  backdrop-filter: blur(12px);\n  -webkit-backdrop-filter: blur(12px);\n  border-bottom: 1px solid rgba(33,117,155,0.15);\n  font-family: 'DM Sans', system-ui, sans-serif;\n  box-sizing: border-box;\n}\n\n#be-nav * { box-sizing: border-box; }\n\n\/* Logo *\/\n#be-nav-logo {\n  display: flex;\n  align-items: center;\n  flex-shrink: 0;\n}\n\n#be-nav-logo img {\n  height: 38px;\n  width: auto;\n  display: block;\n}\n\n\/* Rechte Seite: Nav *\/\n#be-nav-right {\n  display: flex;\n  align-items: center;\n  gap: 1.5rem;\n}\n\n\/* Link-Liste *\/\n#be-nav ul {\n  display: flex;\n  gap: 2rem;\n  list-style: none;\n  align-items: center;\n  margin: 0; padding: 0;\n}\n\n#be-nav ul li a {\n  font-size: 15px;\n  font-weight: 400;\n  letter-spacing: 0.10em;\n  text-transform: uppercase;\n  text-decoration: none;\n  color: #1a4a5e;\n  transition: color 0.2s;\n}\n\n#be-nav ul li a:hover { color: #21759b; }\n\n\/* CTA-Button *\/\n#be-nav ul li a.be-cta {\n  background: #21759b;\n  color: #ffffff !important;\n  padding: 0.65rem 1.5rem;\n  border-radius: 3px;\n  font-size: 15px;\n  letter-spacing: 0.09em;\n  transition: background 0.2s;\n}\n\n#be-nav ul li a.be-cta:hover {\n  background: #1a5d7a;\n  color: #ffffff !important;\n}\n\n\/* Sprachumschalter *\/\n#be-nav .be-lang {\n  display: flex;\n  align-items: center;\n  font-size: 14px;\n}\n\n\/* Hamburger *\/\n#be-hamburger {\n  display: none;\n  flex-direction: column;\n  gap: 5px;\n  cursor: pointer;\n  padding: 4px;\n  background: none;\n  border: none;\n  position: relative;\n  z-index: 99999;\n}\n\n#be-hamburger span {\n  display: block;\n  width: 22px;\n  height: 1.5px;\n  background: #21759b;\n  transition: transform 0.25s, opacity 0.2s;\n}\n\n\/* Mobile Menu *\/\n#be-mobile-menu {\n  display: none;\n  position: fixed;\n  top: 0; left: 0; right: 0; bottom: 0;\n  z-index: 9998;\n  background: rgba(255,255,255,0.98);\n  flex-direction: column;\n  justify-content: flex-start;\n  align-items: center;\n  gap: 1.5rem;\n  padding-top: 5.5rem;\n  padding-bottom: 3rem;\n  overflow-y: auto;\n  -webkit-overflow-scrolling: touch;\n  font-family: 'DM Sans', system-ui, sans-serif;\n}\n\n#be-mobile-menu.be-open { display: flex; }\n\n#be-mobile-menu a {\n  font-size: 1.1rem;\n  font-weight: 400;\n  letter-spacing: 0.12em;\n  text-transform: uppercase;\n  text-decoration: none;\n  color: #1a4a5e;\n}\n\n#be-mobile-menu a.be-cta-mobile {\n  background: #21759b;\n  color: #ffffff !important;\n  padding: 0.8rem 2.2rem;\n  border-radius: 3px;\n  margin-top: 0.5rem;\n}\n\n\/* Sprachumschalter im Mobile-Men\u00fc *\/\n#be-mobile-menu .be-lang-mobile {\n  margin-top: 0.5rem;\n  width: 100%;\n  display: flex;\n  justify-content: center;\n  position: relative;\n  overflow: visible !important;\n  max-height: none !important;\n}\n\n\/* Hamburger bleibt sichtbar wenn Men\u00fc offen \u2013 fungiert als X *\/\n#be-nav.be-menu-open {\n  z-index: 99999;\n  background: transparent;\n  border-bottom: none;\n  backdrop-filter: none;\n  -webkit-backdrop-filter: none;\n}\n\n#be-nav.be-menu-open #be-hamburger {\n  position: fixed;\n  top: 1rem;\n  right: 1.5rem;\n}\n#be-nav.be-menu-open #be-hamburger span:nth-child(1) {\n  transform: translateY(6.5px) rotate(45deg);\n}\n#be-nav.be-menu-open #be-hamburger span:nth-child(2) {\n  opacity: 0;\n}\n#be-nav.be-menu-open #be-hamburger span:nth-child(3) {\n  transform: translateY(-6.5px) rotate(-45deg);\n}\n\n\/* Responsive *\/\n@media (max-width: 768px) {\n  #be-nav { padding: 1rem 1.5rem; }\n  #be-nav ul { display: none; }\n  #be-nav .be-lang { display: none; }\n  #be-hamburger { display: flex; }\n  #be-mobile-menu { padding-top: 4.5rem; gap: 1.1rem; }\n  #be-mobile-menu > a { font-size: 1.8rem !important; }\n  #be-mobile-menu a.be-cta-mobile { font-size: 1.8rem !important; padding: 0.8rem 2.4rem; }\n}\n\n@media (min-width: 769px) {\n  #be-nav { padding: 20px 2.5rem; }\n  #be-nav-logo img { height: 42px; }\n}\n<\/style>\n\n<nav id=\"be-nav\">\n\n  <!-- Logo links -->\n  <a id=\"be-nav-logo\" href=\"https:\/\/spiritual-activity.org\" aria-label=\"ISA \u2013 Startseite\">\n    <img decoding=\"async\" src=\"https:\/\/spiritual-activity.org\/wp-content\/uploads\/2026\/06\/ISA_Logo-scaled.png\"\n         alt=\"ISA Logo\"\n         loading=\"eager\">\n  <\/a>\n\n  <!-- Rechte Seite: Links + Hamburger -->\n  <div id=\"be-nav-right\">\n    <ul>\n      <li><a href=\"https:\/\/spiritual-activity.org\/\">Start<\/a><\/li>\n      <!-- Entwicklung: noch nicht anzeigen -->\n      <!-- <li><a href=\"https:\/\/spiritual-activity.org\/entwicklung\/\">Entwicklung<\/a><\/li> -->\n      <li><a href=\"https:\/\/spiritual-activity.org\/verein\/\"><span dir=\"ltr\" style=\"display:inline-block;\">Leben im Denken e.V.<\/span><\/a><\/li>\n      <li><a href=\"https:\/\/spiritual-activity.org\/ueber-uns\/\">\u00dcber uns<\/a><\/li>\n      <li><a href=\"https:\/\/spiritual-activity.org\/kontakt\/\">Kontakt<\/a><\/li>\n      <!-- Shop: noch nicht anzeigen -->\n      <!-- <li><a href=\"https:\/\/spiritual-activity.org\/store\/\">Shop<\/a><\/li> -->\n      <li class=\"be-lang\"><\/li>\n    <\/ul>\n\n    <button id=\"be-hamburger\" aria-label=\"Men\u00fc \u00f6ffnen\">\n      <span><\/span><span><\/span><span><\/span>\n    <\/button>\n  <\/div>\n\n<\/nav>\n\n<!-- Mobile Vollbild-Men\u00fc -->\n<div id=\"be-mobile-menu\">\n  <a href=\"https:\/\/spiritual-activity.org\/\">Start<\/a>\n  <!-- Entwicklung: noch nicht anzeigen -->\n  <!-- <a href=\"https:\/\/spiritual-activity.org\/entwicklung\/\" onclick=\"beCloseMenu()\">Entwicklung<\/a> -->\n  <a href=\"https:\/\/spiritual-activity.org\/verein\/\" onclick=\"beCloseMenu()\"><span dir=\"ltr\" style=\"display:inline-block;\">Leben im Denken e.V.<\/span><\/a>\n  <a href=\"https:\/\/spiritual-activity.org\/ueber-uns\/\" onclick=\"beCloseMenu()\">\u00dcber uns<\/a>\n  <a href=\"https:\/\/spiritual-activity.org\/kontakt\/\" onclick=\"beCloseMenu()\">Kontakt<\/a>\n  <!-- Shop: noch nicht anzeigen -->\n  <!-- <a href=\"https:\/\/spiritual-activity.org\/store\/\" onclick=\"beCloseMenu()\">Shop<\/a> -->\n  <div class=\"be-lang-mobile\"><\/div>\n<\/div>\n\n\n<script>\nfunction beOpenMenu() {\n  document.getElementById('be-mobile-menu').classList.add('be-open');\n  document.getElementById('be-nav').classList.add('be-menu-open');\n  document.body.style.overflow = 'hidden';\n}\n\nfunction beCloseMenu() {\n  document.getElementById('be-mobile-menu').classList.remove('be-open');\n  document.getElementById('be-nav').classList.remove('be-menu-open');\n  document.body.style.overflow = '';\n}\n\n\/* ============================================================\n   Automatische Sprach-Weiterleitung f\u00fcr Nav-Links\n   ============================================================ *\/\nfunction beLocalizeNavLinks() {\n  \/\/ Sprachcodes, die TranslatePress als Subdirectory-Prefix nutzt\n  \/\/ (Deutsch = Default, daher kein Prefix)\n  var LANGS = ['en', 'es', 'it', 'ru', 'he'];\n\n  var pathMatch = window.location.pathname.match(\/^\\\/([a-z]{2})(\\\/|$)\/);\n  var currentLang = (pathMatch && LANGS.indexOf(pathMatch[1]) !== -1) ? pathMatch[1] : null;\n\n  \/\/ Wenn wir auf Deutsch (Default) sind, nichts tun \u2013 Links sind bereits korrekt\n  if (!currentLang) return;\n\n  var navLinks = document.querySelectorAll(\n    '#be-nav a[href^=\"https:\/\/spiritual-activity.org\"], #be-mobile-menu a[href^=\"https:\/\/spiritual-activity.org\"]'\n  );\n\n  navLinks.forEach(function (link) {\n    \/\/ Sprachumschalter-Links (xyz-ips) NICHT anfassen \u2013\n    \/\/ sonst wird der R\u00fcckweg zu Deutsch mit dem aktuellen Sprach-Prefix \u00fcberschrieben\n    \/\/ und man kommt aus der englischen\/etc. Version nicht mehr zur\u00fcck nach Deutsch.\n    if (link.closest('.be-lang') || link.closest('.be-lang-mobile')) return;\n\n    try {\n      var url = new URL(link.getAttribute('href'));\n      var alreadyPrefixed = new RegExp('^\/(' + LANGS.join('|') + ')(\/|$)').test(url.pathname);\n      if (!alreadyPrefixed) {\n        \/\/ z.B. \"\/verein\/\" -> \"\/en\/verein\/\"\n        url.pathname = '\/' + currentLang + url.pathname;\n        link.setAttribute('href', url.toString());\n      }\n    } catch (e) {\n      \/\/ ung\u00fcltige URL \u00fcberspringen\n    }\n  });\n}\n\ndocument.addEventListener('DOMContentLoaded', function() {\n  var burger = document.getElementById('be-hamburger');\n  var menu   = document.getElementById('be-mobile-menu');\n\n  if (burger) burger.addEventListener('click', function() {\n    if (menu.classList.contains('be-open')) {\n      beCloseMenu();\n    } else {\n      beOpenMenu();\n    }\n  });\n\n  if (menu) menu.addEventListener('click', function(e) {\n    if (e.target === menu) beCloseMenu();\n  });\n\n  beLocalizeNavLinks();\n});\n<\/script>\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<\/div>\n\t\t\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-fc178c9 e-flex e-con-boxed e-con e-parent\" data-id=\"fc178c9\" 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-a79e33c e-con-full e-flex e-con e-child\" data-id=\"a79e33c\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-700a45e elementor-widget elementor-widget-html\" data-id=\"700a45e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<div style=\"font-size:14px; font-weight:500; letter-spacing:0.22em; text-transform:uppercase; color:#27703F; display:flex; align-items:center; gap:0.8rem;\">\n  <div style=\"width:24px; height:1px; background:#27703F; flex-shrink:0;\"><\/div>\n  Gruppenanmeldung\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a5c0245 elementor-widget elementor-widget-html\" data-id=\"a5c0245\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<style>\n@import url('https:\/\/fonts.googleapis.com\/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;1,300;1,400&display=swap');\n<\/style>\n<div style=\"font-family:'Cormorant Garamond',Georgia,serif; font-size:clamp(32px,4vw,52px); font-weight:300; line-height:1.15; color:#0C1E14;\">\n  Gemeinschaft <br><em style=\"font-style:italic; color:#27703F;\">st\u00e4rken<\/em>\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-4690755 e-con-full e-flex e-con e-child\" data-id=\"4690755\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-0aa43a2 elementor-widget elementor-widget-text-editor\" data-id=\"0aa43a2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p><em>\u201eDer Einzelne hilft nicht, sondern wer sich mit vielen <br \/>zur rechten Stunde vereinigt.\u201c<\/em><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-13f07c7 e-flex e-con-boxed e-con e-parent\" data-id=\"13f07c7\" 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-455a17e e-con-full e-flex e-con e-child\" data-id=\"455a17e\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6a38e05 elementor-widget elementor-widget-text-editor\" data-id=\"6a38e05\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Wir freuen uns, dass Ihr Euch als Gruppe anmelden wollt. Sei es als ein freier Arbeitskreis oder als Gemeinschaft innerhalb einer Institution. Gerade f\u00fcr Mitarbeitende in einer Institution, wie zum Beispiel in einem Waldorfkollegium, einer Hofgemeinschaft oder einem Unternehmen, kann ein solcher gemeinsamer innerer Schulungsweg eine sch\u00f6ne R\u00fcckwirkung auf das Arbeitsumfeld haben. Durch regelm\u00e4\u00dfige Treffen, das \u00dcben, das Teilen der Erfahrungen und das sich-gegenseitig-St\u00fctzen auf dem seelisch-geistigen Weg kann auch das Miteinander in der Gemeinschaft eine innere Entwicklung durchmachen und die Verbundenheit wachsen.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-e2fd9b7 e-flex e-con-boxed e-con e-parent\" data-id=\"e2fd9b7\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3ec1be7 elementor-widget elementor-widget-html\" data-id=\"3ec1be7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Tinos:ital,wght@0,400;0,700;1,400&display=swap\" rel=\"stylesheet\">\n\n<style>\n  .ecwid-ProductBrowser,\n  .ecwid-productbrowser,\n  div[id^=\"my-store\"],\n  .ecwid:not(#gw-host-de) {\n    visibility: hidden !important;\n    height: 0 !important;\n    max-height: 0 !important;\n    overflow: hidden !important;\n    padding: 0 !important;\n    margin: 0 !important;\n    position: absolute !important;\n    pointer-events: none !important;\n  }\n<\/style>\n\n<div id=\"gw-overlay-de\" style=\"display:none; position:fixed; inset:0; background:rgba(245,250,246,0.92); z-index:99999; flex-direction:column; align-items:center; justify-content:center; gap:20px;\">\n  <div style=\"width:52px; height:52px; border:4px solid #B8DEC4; border-top-color:#0C1E14; border-radius:50%; animation:gw-spin-de 0.8s linear infinite;\"><\/div>\n  <div style=\"font-family:'Tinos',Georgia,serif; font-size:22px; color:#27703F;\">Checkout wird geladen\u2026<\/div>\n<\/div>\n<style>\n  @keyframes gw-spin-de { to { transform: rotate(360deg); } }\n<\/style>\n\n<div id=\"gw-host-de\"><\/div>\n\n<script>\n(function () {\n\n  \/\/ \u2500\u2500 Sprach-Guard: Skript bricht sofort ab, wenn die URL nicht zu DE passt \u2500\u2500\n  const _pathMatch = window.location.pathname.match(\/^\\\/([a-z]{2})(\\\/|$)\/);\n  const _pageLang = _pathMatch ? _pathMatch[1] : \"de\";\n  if (_pageLang !== \"de\") return;\n\n  const OVERLAY_ID      = \"gw-overlay-de\";\n  const SHOP_CART_URL   = \"https:\/\/spiritual-activity.org\/store\/cart\";\n  const N8N_WEBHOOK_URL = \"https:\/\/n8n.spiritual-activity.org\/webhook\/registration-gruppe\";\n\n  const MAX_TEILNEHMER = 100;\n  const MIN_TEILNEHMER = 4;\n\n  \/\/ Eigene Ecwid-Produkte fuer Gruppen-Anmeldungen (eigener Preis, Mindestpreis 0).\n  \/\/ Mit Versand des Kartensets bzw. versandfrei bei rein digitaler Teilnahme.\n  const GRUPPEN_PRODUCT_ID         = 864374018;\n  const GRUPPEN_PRODUCT_ID_APPONLY = 864914962;\n\n  \/\/ Regulaere Einzelpreise \u2013 dienen in der Uebersicht als Vergleichswert.\n  const NORMALPREIS = {\n    cat1: { reduced: 160, base: 360, support: 580 },\n    cat2: { reduced: 105, base: 240, support: 460 },\n    cat3: { reduced:  75, base: 160, support: 340 },\n    cat4: { reduced:  45, base: 105, support: 220 }\n  };\n\n  \/\/ Gruppenpreise \u2013 gelten fuer diese Anmeldung.\n  const ORIENTIERUNG = {\n    cat1: { reduced: 140, base: 280, support: 460 },\n    cat2: { reduced:  80, base: 160, support: 380 },\n    cat3: { reduced:  25, base:  80, support: 220 },\n    cat4: { reduced:   8, base:  45, support: 120 }\n  };\n\n  \/\/ Pauschale, die bei einer Einzelanmeldung fuer die rein digitale Teilnahme\n  \/\/ abgezogen wird \u2013 hier nur als Vergleichswert in der Preisuebersicht.\n  const DIGITAL_ABZUG = 35;\n\n  const RANGES = {\n    cat1: { min: 140, max: 800 },\n    cat2: { min:  80, max: 700 },\n    cat3: { min:  25, max: 600 },\n    cat4: { min:   8, max: 500 }\n  };\n  \/\/ Versandpauschale ausserhalb EU+CH \u2013 bei Sammelversand genau einmal.\n  const SHIPPING_COST = 15;\n\n  const APP_ONLY_LANGS = new Set([\"Arabisch\",\"Farsi\",\"Ukrainisch\",\"Bulgarisch\",\"Franz\u00f6sisch\",\"Vietnamesisch\"]);\n\n  const EU_PLUS_CH = new Set([\n    \"AT\",\"BE\",\"BG\",\"CY\",\"CZ\",\"DE\",\"DK\",\"EE\",\"ES\",\"FI\",\"FR\",\"GR\",\"HR\",\n    \"HU\",\"IE\",\"IT\",\"LT\",\"LU\",\"LV\",\"MT\",\"NL\",\"PL\",\"PT\",\"RO\",\"SE\",\"SI\",\"SK\",\"CH\"\n  ]);\n  function needsShipping(countryCode) {\n    return countryCode && !EU_PLUS_CH.has(countryCode);\n  }\n\n  const COUNTRY_NAME_OVERRIDES = {\n    \"HK\":\"Hongkong\",\"MO\":\"Macau\",\"TW\":\"Taiwan\",\"AE\":\"Vereinigte Arabische Emirate\",\n    \"US\":\"USA\",\"GB\":\"Vereinigtes K\u00f6nigreich\",\"GB-SCT\":\"Schottland\",\n    \"KR\":\"S\u00fcdkorea\",\"SA\":\"Saudi-Arabien\",\n    \"MD\":\"Moldau\",\"PS\":\"Pal\u00e4stina\",\"CD\":\"Kongo (Kinshasa)\",\"CG\":\"Kongo (Brazzaville)\",\n    \"ST\":\"S\u00e3o Tom\u00e9 und Pr\u00edncipe\",\"CI\":\"C\u00f4te d'Ivoire\",\"TL\":\"Timor-Leste\",\n    \"CV\":\"Cabo Verde\",\"SZ\":\"Eswatini\",\"FM\":\"Mikronesien\",\"MH\":\"Marshallinseln\",\n    \"VC\":\"St. Vincent und Grenadinen\",\"LC\":\"St. Lucia\",\"KN\":\"St. Kitts und Nevis\",\n    \"AG\":\"Antigua und Barbuda\",\"TT\":\"Trinidad und Tobago\",\"BA\":\"Bosnien und Herzegowina\",\n    \"MK\":\"Nordmazedonien\",\"GQ\":\"\u00c4quatorialguinea\",\"GW\":\"Guinea-Bissau\",\n    \"CF\":\"Zentralafrikanische Republik\",\"SB\":\"Salomonen\",\"PG\":\"Papua-Neuguinea\",\n    \"DO\":\"Dominikanische Republik\",\"XK\":\"Kosovo\"\n  };\n\n  const COUNTRY_SEARCH_ALIASES = {\n      \"US\": [\"vereinigte staaten\", \"vereinigte staaten von amerika\", \"usa\", \"amerika\", \"united states\", \"united states of america\", \"america\"],\n      \"GB\": [\"vereinigtes k\u00f6nigreich\", \"grossbritannien\", \"gro\u00dfbritannien\", \"england\", \"uk\", \"united kingdom\", \"britannien\", \"great britain\", \"britain\"],\n      \"GB-SCT\": [\"schottland\", \"scotland\"],\n      \"AE\": [\"vereinigte arabische emirate\", \"emirate\", \"uae\", \"vae\", \"united arab emirates\", \"emirates\", \"dubai\"],\n      \"KR\": [\"s\u00fcdkorea\", \"suedkorea\", \"korea\", \"south korea\"],\n      \"NL\": [\"niederlande\", \"holland\", \"netherlands\"],\n      \"CH\": [\"schweiz\", \"switzerland\", \"suisse\"],\n      \"DE\": [\"deutschland\", \"germany\", \"brd\"],\n      \"AT\": [\"\u00f6sterreich\", \"oesterreich\", \"austria\"],\n      \"CZ\": [\"tschechien\", \"tschechische republik\", \"czechia\", \"czech republic\"],\n      \"TR\": [\"t\u00fcrkei\", \"tuerkei\", \"turkey\", \"t\u00fcrkiye\", \"turkiye\"],\n      \"CI\": [\"elfenbeink\u00fcste\", \"elfenbeinkueste\", \"ivory coast\", \"cote d'ivoire\"],\n      \"CV\": [\"kapverden\", \"cabo verde\", \"cape verde\"],\n      \"MM\": [\"myanmar\", \"birma\", \"burma\"],\n      \"TL\": [\"osttimor\", \"timor-leste\", \"east timor\"],\n      \"SZ\": [\"eswatini\", \"swasiland\", \"swaziland\"],\n      \"MK\": [\"nordmazedonien\", \"mazedonien\", \"macedonia\", \"north macedonia\"],\n      \"BY\": [\"belarus\", \"weissrussland\", \"wei\u00dfrussland\"],\n      \"MD\": [\"moldau\", \"moldawien\", \"moldova\"],\n      \"MA\": [\"marokko\", \"morocco\"],\n      \"EG\": [\"\u00e4gypten\", \"aegypten\", \"egypt\"],\n      \"GR\": [\"griechenland\", \"greece\"],\n      \"IT\": [\"italien\", \"italy\"],\n      \"ES\": [\"spanien\", \"spain\"],\n      \"FR\": [\"frankreich\", \"france\"],\n      \"PL\": [\"polen\", \"poland\"],\n      \"RU\": [\"russland\", \"russia\", \"russische f\u00f6deration\", \"russian federation\"],\n      \"CN\": [\"china\", \"volksrepublik china\"],\n      \"JP\": [\"japan\"],\n      \"IN\": [\"indien\", \"india\"],\n      \"BR\": [\"brasilien\", \"brazil\"],\n      \"MX\": [\"mexiko\", \"mexico\"],\n      \"CA\": [\"kanada\", \"canada\"],\n      \"AU\": [\"australien\", \"australia\"],\n      \"NZ\": [\"neuseeland\", \"new zealand\"],\n      \"ZA\": [\"s\u00fcdafrika\", \"suedafrika\", \"south africa\"],\n      \"KP\": [\"north korea\"],\n      \"CD\": [\"dr congo\", \"drc\", \"congo kinshasa\"],\n      \"CG\": [\"congo brazzaville\"],\n      \"VA\": [\"vatican\", \"holy see\"],\n      \"LA\": [\"laos\"],\n      \"VN\": [\"vietnam\", \"viet nam\"],\n      \"IR\": [\"iran\", \"persia\"],\n      \"MO\": [\"macau\", \"macao\"],\n      \"HK\": [\"hong kong\"],\n      \"TW\": [\"taiwan\"],\n      \"GE\": [\"georgia\"]\n  };\n\n  const COUNTRIES = {\n    cat1: [\"CY\",\"CA\",\"FR\",\"FI\",\"BH\",\"AU\",\"AD\",\"SE\",\"DE\",\"SA\",\"AT\",\"BE\",\"HK\",\"MT\",\"IS\",\"SM\",\"NL\",\"DK\",\"TW\",\"AE\",\"US\",\"BN\",\"CH\",\"NO\",\"GY\",\"QA\",\"MO\",\"IE\",\"LU\",\"SG\",\"LI\",\"GB\",\"GB-SCT\"],\n    cat2: [\"KR\",\"ME\",\"CL\",\"TT\",\"MV\",\"UY\",\"BS\",\"OM\",\"SC\",\"MY\",\"PA\",\"TR\",\"LV\",\"GR\",\"KZ\",\"SK\",\"HU\",\"RU\",\"RO\",\"EE\",\"AW\",\"PT\",\"PR\",\"HR\",\"KW\",\"JP\",\"NZ\",\"PL\",\"IL\",\"ES\",\"LT\",\"SI\",\"CZ\",\"IT\"],\n    cat3: [\"BZ\",\"TN\",\"GT\",\"IQ\",\"ZA\",\"FJ\",\"EC\",\"LY\",\"ID\",\"VN\",\"BT\",\"DZ\",\"PE\",\"PW\",\"BW\",\"DM\",\"PY\",\"MD\",\"GQ\",\"MN\",\"VC\",\"IR\",\"GD\",\"EG\",\"CO\",\"SR\",\"TM\",\"BA\",\"BB\",\"BR\",\"AL\",\"AM\",\"GA\",\"MX\",\"AZ\",\"TH\",\"LC\",\"CN\",\"MK\",\"DO\",\"AG\",\"AR\",\"GE\",\"CR\",\"MU\",\"RS\",\"BY\",\"KN\",\"XK\",\"BG\"],\n    cat4: [\"UA\",\"BI\",\"SS\",\"CF\",\"YE\",\"MZ\",\"MW\",\"SO\",\"CD\",\"LR\",\"MG\",\"NE\",\"AF\",\"SD\",\"SB\",\"ML\",\"HT\",\"VU\",\"BF\",\"LS\",\"TD\",\"GW\",\"TG\",\"GM\",\"KI\",\"SL\",\"PG\",\"UG\",\"KM\",\"PS\",\"RW\",\"TZ\",\"ET\",\"ZM\",\"FM\",\"BJ\",\"GN\",\"TL\",\"MM\",\"SN\",\"CM\",\"TJ\",\"TV\",\"NP\",\"CG\",\"ST\",\"PK\",\"KE\",\"ZW\",\"MH\",\"HN\",\"TO\",\"CI\",\"WS\",\"GH\",\"VE\",\"KH\",\"MR\",\"KG\",\"NI\",\"NG\",\"DJ\",\"AO\",\"LA\",\"BD\",\"BO\",\"MA\",\"JO\",\"LB\",\"NR\",\"IN\",\"NA\",\"CV\",\"UZ\",\"PH\",\"SZ\",\"JM\",\"SV\",\"LK\"]\n  };\n\n  \/\/ Exakter Wortlaut aus dem Ecwid-Produkt \u2013 Abweichungen werden still verworfen.\n  const OPT_COMM_LANG = \"In welcher Sprache nimmst Du teil?\";\n  const OPT_ORG       = \"Name der Gruppe\/ Organisation\";\n\n  \/\/ \u2500\u2500 Shadow DOM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  const host = document.getElementById(\"gw-host-de\");\n  const shadow = host.attachShadow({ mode: \"open\" });\n\n  const styleEl = document.createElement(\"style\");\n  styleEl.textContent = `\n    :host {\n      display: block;\n      --bg:           #F5FAF6;\n      --card:         #FFFFFF;\n      --ink:          #0C1E14;\n      --ink-muted:    #27703F;\n      --accent:       #0C1E14;\n      --accent-light: #E6F2E8;\n      --border:       #C8E0CE;\n      --radius:       16px;\n      --radius-sm:    10px;\n    }\n    @keyframes wiz-spin { to { transform: rotate(360deg); } }\n\n    .gw-root {\n      font-family: 'Tinos', Georgia, serif;\n      font-size: 20px; font-weight: 400; color: var(--ink);\n      background: var(--bg); padding: 32px 20px;\n      display: flex; align-items: flex-start; justify-content: center;\n    }\n    .gw-card {\n      background: var(--card); border: 1px solid var(--border);\n      border-radius: 24px; padding: 36px 32px;\n      width: 100%; max-width: 860px;\n      box-shadow: 0 4px 24px rgba(12,30,20,0.08); box-sizing: border-box;\n    }\n    @media (max-width: 480px) {\n      .gw-root { padding: 16px 10px; }\n      .gw-card { padding: 24px 16px; border-radius: 16px; }\n    }\n\n    .gw-org-banner {\n      display: none; margin-bottom: 22px; padding: 12px 16px;\n      background: var(--accent-light); border: 1px solid rgba(12,30,20,0.15);\n      border-radius: var(--radius-sm); font-size: 18px; color: var(--accent);\n    }\n\n    .gw-progress { display: flex; gap: 8px; margin-bottom: 32px; }\n    .gw-progress-step { flex: 1; height: 4px; background: var(--border); border-radius: 999px; transition: background 0.35s; }\n    .gw-progress-step.active { background: var(--accent); }\n    .gw-progress-step.done   { background: var(--accent); opacity: 0.4; }\n\n    .gw-step-label { font-size: 12px; font-weight: 400; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-muted); margin-bottom: 10px; }\n    .gw-heading { font-size: 26px; font-weight: 500; line-height: 1.2; margin: 0 0 6px; color: var(--accent); letter-spacing: 0.01em; }\n    .gw-subtext { font-size: 18px; font-weight: 400; color: var(--ink-muted); margin: 0 0 28px; line-height: 1.6; }\n    .gw-label { display: block; font-size: 18px; font-weight: 700; margin-bottom: 6px; color: var(--ink); }\n    .gw-hint { font-size: 15px; color: var(--ink-muted); line-height: 1.5; margin: -4px 0 14px; }\n\n    .gw-select, .gw-text-input {\n      width: 100%; padding: 13px 15px;\n      border: 1px solid var(--border); border-radius: var(--radius-sm);\n      background: var(--bg);\n      font-family: 'Tinos', Georgia, serif; font-size: 18px; font-weight: 400; color: var(--ink);\n      transition: border-color 0.2s; box-sizing: border-box;\n    }\n    .gw-select {\n      appearance: none;\n      background-image: url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%2327703F' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'\/%3E%3C\/svg%3E\");\n      background-repeat: no-repeat; background-position: right 15px center;\n      cursor: pointer;\n    }\n    .gw-select:focus, .gw-text-input:focus {\n      outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(12,30,20,0.1);\n    }\n    .gw-text-input { margin-bottom: 14px; }\n\n    .gw-field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }\n    @media (max-width: 480px) { .gw-field-grid { grid-template-columns: 1fr; } }\n\n    .gw-redirect { display: none; margin-top: 12px; padding: 18px 20px; border-radius: var(--radius-sm); background: #FFF8F0; border: 1px solid rgba(180,80,0,0.2); font-size: 17px; line-height: 1.8; color: var(--ink); }\n    .gw-redirect strong { display: block; margin-bottom: 8px; font-size: 17px; color: #7A3500; }\n    .gw-redirect a { color: #27703F; text-decoration: underline; }\n\n    .gw-infobox {\n      margin-top: 12px; padding: 15px 17px; border-radius: var(--radius-sm);\n      background: var(--accent-light); border: 1px solid rgba(12,30,20,0.15);\n      font-size: 18px; font-weight: 400; line-height: 1.5;\n    }\n    .gw-infobox-title {\n      font-weight: 700; font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase;\n      color: var(--accent); margin-bottom: 3px;\n    }\n\n    .gw-pricetable { width: 100%; border-collapse: collapse; margin-top: 14px; font-size: 17px; }\n    .gw-pricetable th, .gw-pricetable td { text-align: left; padding: 9px 10px; border-bottom: 1px solid var(--border); }\n    .gw-pricetable th { font-weight: 700; font-size: 15px; color: var(--ink-muted); }\n    .gw-pricetable td:not(:first-child), .gw-pricetable th:not(:first-child) { text-align: right; }\n    .gw-pricetable .gw-price-old { color: var(--ink-muted); font-weight: 400; text-decoration: line-through; }\n    .gw-pricetable th.gw-price-old { text-decoration: none; }\n    .gw-pricetable .gw-price-new { font-weight: 700; color: var(--accent); }\n    .gw-pricetable tr:last-child td { border-bottom: 0; }\n\n    .gw-divider { border: 0; border-top: 1px solid var(--border); margin: 30px 0 24px; }\n\n    .gw-choice-row { display: flex; gap: 10px; flex-wrap: wrap; }\n    .gw-choice-card {\n      flex: 1; min-width: 180px; padding: 16px 14px;\n      border: 1px solid var(--border); border-radius: var(--radius-sm);\n      text-align: center; cursor: pointer; font-size: 17px; line-height: 1.35;\n      transition: all 0.15s; background: var(--bg); box-sizing: border-box;\n    }\n    .gw-choice-card:hover { border-color: var(--accent); }\n    .gw-choice-card.active { background: var(--accent-light); border-color: var(--accent); font-weight: 700; color: var(--accent); }\n    @media (max-width: 480px) { .gw-choice-card { min-width: 100%; } }\n\n    \/* \u2500\u2500 Teilnehmerliste \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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    .gw-p-head {\n      display: grid; grid-template-columns: 34px 1fr 1fr 1.4fr 120px 34px;\n      gap: 8px; padding: 0 2px 8px; font-size: 14px; font-weight: 700; color: var(--ink-muted);\n    }\n    .gw-p-row {\n      display: grid; grid-template-columns: 34px 1fr 1fr 1.4fr 120px 34px;\n      gap: 8px; align-items: center; margin-bottom: 8px;\n    }\n    .gw-p-num { font-size: 16px; color: var(--ink-muted); text-align: center; }\n    .gw-p-row input {\n      width: 100%; padding: 10px 11px; box-sizing: border-box;\n      border: 1px solid var(--border); border-radius: var(--radius-sm);\n      background: var(--bg); font-family: 'Tinos', Georgia, serif; font-size: 17px; color: var(--ink);\n      margin: 0;\n    }\n    .gw-p-row input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(12,30,20,0.1); }\n    .gw-p-row input.gw-invalid { border-color: #C46A6A; background: #FFF7F7; }\n    .gw-p-amount { text-align: right; font-weight: 700; }\n    .gw-p-remove {\n      border: 1px solid var(--border); background: var(--bg); color: var(--ink-muted);\n      border-radius: var(--radius-sm); width: 34px; height: 40px; cursor: pointer;\n      font-family: 'Tinos', Georgia, serif; font-size: 18px; line-height: 1; padding: 0;\n    }\n    .gw-p-remove:hover { border-color: #C46A6A; color: #8A1F1F; }\n    @media (max-width: 700px) {\n      .gw-p-head { display: none; }\n      .gw-p-row {\n        grid-template-columns: 1fr 1fr; gap: 8px;\n        padding: 14px; margin-bottom: 14px;\n        border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg);\n      }\n      .gw-p-num { grid-column: 1 \/ 2; text-align: left; font-weight: 700; color: var(--accent); }\n      .gw-p-remove { grid-column: 2 \/ 3; justify-self: end; }\n      .gw-p-row input { grid-column: 1 \/ 3; }\n      .gw-p-row input.gw-p-amount { grid-column: 1 \/ 3; text-align: left; }\n    }\n\n    .gw-bulk { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 22px; }\n    .gw-bulk > div { flex: 1; min-width: 180px; }\n    .gw-btn-ghost {\n      padding: 12px 18px; border-radius: var(--radius-sm); border: 1px solid var(--border);\n      background: var(--bg); font-family: 'Tinos', Georgia, serif; font-size: 17px;\n      color: var(--ink); cursor: pointer; transition: all 0.15s;\n    }\n    .gw-btn-ghost:hover { border-color: var(--accent); background: var(--accent-light); }\n\n    .gw-add-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; align-items: center; }\n    .gw-count { font-size: 16px; color: var(--ink-muted); margin-left: auto; }\n\n    .gw-summary-box { padding: 18px 20px; background: var(--accent-light); border: 1px solid rgba(12,30,20,0.2); border-radius: var(--radius-sm); margin-top: 20px; }\n    .gw-summary-row { display: flex; justify-content: space-between; align-items: center; padding: 5px 0; font-size: 17px; color: var(--ink); gap: 12px; }\n    .gw-summary-row.gw-summary-discount { color: #8A1F1F; }\n    .gw-summary-row.gw-summary-total { border-top: 1px solid rgba(12,30,20,0.25); margin-top: 8px; padding-top: 12px; font-weight: 700; font-size: 22px; color: var(--accent); }\n\n    .gw-list-preview { max-height: 260px; overflow-y: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); margin-top: 14px; }\n    .gw-list-preview-item { display: flex; justify-content: space-between; gap: 12px; padding: 9px 14px; border-bottom: 1px solid var(--border); font-size: 16px; }\n    .gw-list-preview-item:last-child { border-bottom: 0; }\n    .gw-list-preview-item span:last-child { font-weight: 700; white-space: nowrap; }\n\n    .gw-btn-row { display: flex; gap: 10px; margin-top: 24px; flex-wrap: wrap; }\n    .gw-btn { flex: 1; min-width: 140px; padding: 15px 17px; border-radius: var(--radius-sm); font-family: 'Tinos', Georgia, serif; font-size: 18px; font-weight: 700; cursor: pointer; transition: all 0.2s; border: 0; }\n    .gw-btn-primary { background: var(--accent); color: #fff; }\n    .gw-btn-primary:hover { background: #27703F; transform: translateY(-1px); }\n    .gw-btn-primary:disabled { opacity: 0.4; cursor: not-allowed; transform: none; }\n    .gw-btn-secondary { background: transparent; color: var(--ink); border: 1px solid var(--border); }\n    .gw-btn-secondary:hover { background: var(--bg); }\n\n    .gw-error { display: none; margin-top: 15px; padding: 13px 15px; border-radius: var(--radius-sm); background: #FFF3F3; border: 1px solid rgba(220,30,30,0.2); color: #8A1F1F; font-size: 18px; font-weight: 400; line-height: 1.5; white-space: pre-wrap; }\n    .wiz-spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid rgba(255,255,255,0.4); border-top-color: #fff; border-radius: 50%; animation: wiz-spin 0.7s linear infinite; vertical-align: middle; margin-right: 8px; }\n\n    .gw-country-search-wrap { position: relative; margin-bottom: 10px; }\n    .gw-country-search-icon { position: absolute; left: 18px; top: 50%; transform: translateY(-50%); color: var(--ink-muted); pointer-events: none; opacity: 0.5; }\n    .gw-country-search {\n      width: 100%; padding: 13px 15px 13px 54px;\n      border: 1px solid var(--border); border-radius: var(--radius-sm);\n      background: var(--bg); font-family: 'Tinos', Georgia, serif;\n      font-size: 18px; font-weight: 400; color: var(--ink);\n      transition: border-color 0.2s; box-sizing: border-box;\n    }\n    .gw-country-search:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(12,30,20,0.1); }\n    .gw-country-list { max-height: 240px; overflow-y: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); }\n    .gw-country-item { padding: 11px 15px; cursor: pointer; font-family: 'Tinos', Georgia, serif; font-size: 18px; font-weight: 400; display: flex; justify-content: space-between; align-items: center; transition: background 0.15s; border-bottom: 1px solid var(--border); }\n    .gw-country-item:last-child { border-bottom: 0; }\n    .gw-country-item:hover { background: var(--accent-light); }\n    .gw-country-item.selected { background: var(--accent-light); font-weight: 700; }\n    .gw-country-item-cat { font-size: 12px; color: var(--ink-muted); background: var(--border); padding: 2px 8px; border-radius: 999px; }\n    .gw-country-empty { padding: 15px; font-size: 18px; color: var(--ink-muted); text-align: center; }\n\n    .gw-final-list { margin: 0 0 28px; padding: 0; list-style: none; }\n    .gw-final-list li {\n      position: relative; padding: 0 0 0 30px; margin-bottom: 15px;\n      font-size: 18px; line-height: 1.6; color: var(--ink);\n    }\n    .gw-final-list li::before {\n      content: \"\"; position: absolute; left: 6px; top: 11px;\n      width: 7px; height: 7px; border-radius: 50%; background: var(--ink-muted);\n    }\n    .gw-final-list ul { list-style: none; margin: 10px 0 0; padding: 0; }\n    .gw-final-list ul li { font-size: 17px; margin-bottom: 8px; padding-left: 26px; }\n    .gw-final-list ul li::before {\n      top: 10px; left: 4px; width: 10px; height: 2px; border-radius: 0; background: var(--border);\n    }\n    .gw-final-list .gw-final-note { font-size: 16px; color: var(--ink-muted); }\n\n    .gw-coordinator {\n      display: flex; gap: 18px; align-items: center;\n      padding: 18px 20px; border-radius: var(--radius-sm);\n      background: var(--accent-light); border: 1px solid rgba(12,30,20,0.15);\n      font-size: 17px; line-height: 1.6;\n    }\n    .gw-coordinator-photo {\n      width: 84px; height: 84px; flex: 0 0 84px;\n      border-radius: 50%; overflow: hidden;\n      border: 2px solid #fff; background: var(--card);\n      box-shadow: 0 2px 8px rgba(12,30,20,0.12);\n    }\n    .gw-coordinator-photo img {\n      width: 100%; height: 100%; display: block;\n      object-fit: cover; object-position: center 22%;\n    }\n    \/* Feiner Zoom, damit die Gesichter den Kreis gut fuellen *\/\n    .gw-photo-susanne img { transform: scale(1.09); }\n    .gw-photo-andreas img { transform: scale(1.18); }\n    .gw-coordinator a { color: var(--ink-muted); text-decoration: underline; }\n    .gw-coordinator-photos { display: flex; gap: 14px; flex-shrink: 0; }\n    @media (max-width: 480px) {\n      .gw-coordinator { flex-direction: column; text-align: center; }\n    }\n\n    .gw-step { display: none; }\n    .gw-step.active { display: block; }\n  `;\n  shadow.appendChild(styleEl);\n\n  const wrapper = document.createElement(\"div\");\n  wrapper.innerHTML = `\n    <div class=\"gw-root\">\n      <div class=\"gw-card\">\n\n        <div class=\"gw-org-banner\" id=\"gw-org-banner\"><\/div>\n\n        <div class=\"gw-progress\">\n          <div class=\"gw-progress-step\" id=\"gw-prog-1\"><\/div>\n          <div class=\"gw-progress-step\" id=\"gw-prog-2\"><\/div>\n          <div class=\"gw-progress-step\" id=\"gw-prog-3\"><\/div>\n          <div class=\"gw-progress-step\" id=\"gw-prog-4\"><\/div>\n          <div class=\"gw-progress-step\" id=\"gw-prog-5\"><\/div>\n          <div class=\"gw-progress-step\" id=\"gw-prog-6\"><\/div>\n          <div class=\"gw-progress-step\" id=\"gw-prog-7\"><\/div>\n        <\/div>\n\n        <!-- STEP 1: WILLKOMMEN -->\n        <div class=\"gw-step active\" id=\"gw-step-welcome\">\n          <div class=\"gw-step-label\">Schritt 1 von 7<\/div>\n          <h2 class=\"gw-heading\">Sch\u00f6n, dass Ihr gemeinsam dabei seid<\/h2>\n          <p class=\"gw-subtext\">\n            Hier meldet Ihr Eure ganze Gruppe in einem Zug an \u2013 eine Person tr\u00e4gt alle\n            Teilnehmenden ein, und Ihr bezahlt zusammen.<br><br>\n            Ihr braucht daf\u00fcr nur: den Namen Eurer Organisation, Euer Land, und die Namen\n            und E-Mail-Adressen der Teilnehmenden. Den Beitrag legt Ihr f\u00fcr jede Person\n            selbst fest. Das dauert etwa f\u00fcnf Minuten.\n          <\/p>\n          <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-welcome-next\" style=\"width:100%;\">Gruppen-Anmeldung beginnen<\/button>\n        <\/div>\n\n        <!-- STEP 2: ORGANISATION -->\n        <div class=\"gw-step\" id=\"gw-step-org\">\n          <div class=\"gw-step-label\">Schritt 2 von 7<\/div>\n          <h2 class=\"gw-heading\">Wer meldet sich an?<\/h2>\n          <p class=\"gw-subtext\">Der Name Eurer Gruppe begleitet Euch durch die ganze Anmeldung und steht sp\u00e4ter auch auf der Best\u00e4tigung.<\/p>\n\n          <label class=\"gw-label\">Name der Organisation oder Gruppe<\/label>\n          <input class=\"gw-text-input\" type=\"text\" id=\"gw-org-name\" placeholder=\"z. B. Freie Waldorfschule T\u00fcbingen\">\n\n          <hr class=\"gw-divider\">\n\n          <div class=\"gw-label\" style=\"margin-bottom:14px;\">Ansprechperson<\/div>\n          <div class=\"gw-field-grid\">\n            <div><label class=\"gw-label\">Vorname<\/label><input class=\"gw-text-input\" type=\"text\" id=\"gw-kontakt-vorname\"><\/div>\n            <div><label class=\"gw-label\">Nachname<\/label><input class=\"gw-text-input\" type=\"text\" id=\"gw-kontakt-nachname\"><\/div>\n          <\/div>\n          <label class=\"gw-label\">E-Mail<\/label>\n          <p class=\"gw-hint\">An diese Adresse gehen Best\u00e4tigung und Rechnung.<\/p>\n          <input class=\"gw-text-input\" type=\"email\" id=\"gw-kontakt-email\">\n\n          <label class=\"gw-label\">Telefon <span style=\"font-weight:400; color:var(--ink-muted);\">(freiwillig)<\/span><\/label>\n          <input class=\"gw-text-input\" type=\"tel\" id=\"gw-kontakt-telefon\">\n\n          <div class=\"gw-error\" id=\"gw-error-org\"><\/div>\n\n          <div class=\"gw-btn-row\">\n            <button class=\"gw-btn gw-btn-secondary\" id=\"gw-btn-org-back\">Zur\u00fcck<\/button>\n            <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-org-next\" disabled>Weiter<\/button>\n          <\/div>\n        <\/div>\n\n        <!-- STEP 3: LAND + PREISE -->\n        <div class=\"gw-step\" id=\"gw-step-country\">\n          <div class=\"gw-step-label\">Schritt 3 von 7<\/div>\n          <h2 class=\"gw-heading\">Wo seid Ihr zu Hause?<\/h2>\n          <p class=\"gw-subtext\">Unsere Beitr\u00e4ge richten sich nach den Lebenshaltungskosten im jeweiligen Land. Sobald Ihr Euer Land gew\u00e4hlt habt, seht Ihr Eure Preisspanne.<\/p>\n\n          <label class=\"gw-label\">Land<\/label>\n          <div class=\"gw-country-search-wrap\">\n            <svg class=\"gw-country-search-icon\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"11\" cy=\"11\" r=\"8\"\/><path d=\"m21 21-4.35-4.35\"\/><\/svg>\n            <input type=\"text\" class=\"gw-country-search\" id=\"gw-country-search\" placeholder=\"Land suchen\u2026\" autocomplete=\"off\">\n          <\/div>\n          <div class=\"gw-country-list\" id=\"gw-country-list\"><\/div>\n          <input type=\"hidden\" id=\"gw-country\">\n\n          <div class=\"gw-infobox\" id=\"gw-catInfo\">\n            <div class=\"gw-infobox-title\">Preiskategorie<\/div>\n            <div id=\"gw-catText\">Bitte zuerst ein Land w\u00e4hlen.<\/div>\n            <div id=\"gw-priceTableWrap\"><\/div>\n          <\/div>\n\n          <div class=\"gw-redirect\" id=\"gw-redirect-russia\">\n            <strong>F\u00fcr Gruppen aus Russland gibt es einen eigenen Weg.<\/strong>\n            Unser Bezahlsystem ist in Russland nicht verf\u00fcgbar. Schreibt uns bitte direkt an\n            <a href=\"mailto:info@basic-exercises.com\">info@basic-exercises.com<\/a> \u2013 wir melden uns schnell bei Euch.\n          <\/div>\n\n          <div class=\"gw-btn-row\">\n            <button class=\"gw-btn gw-btn-secondary\" id=\"gw-btn-country-back\">Zur\u00fcck<\/button>\n            <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-country-next\" disabled>Weiter<\/button>\n          <\/div>\n        <\/div>\n\n        <!-- STEP 4: SPRACHE + VERSAND -->\n        <div class=\"gw-step\" id=\"gw-step-langship\">\n          <div class=\"gw-step-label\">Schritt 4 von 7<\/div>\n          <h2 class=\"gw-heading\">In welcher Sprache nehmt Ihr teil?<\/h2>\n\n          <label class=\"gw-label\" for=\"gw-commLang\">In welcher Sprache nehmt Ihr teil?<\/label>\n          <p class=\"gw-hint\">Alle Teilnehmenden der Gruppe erhalten die Materialien in dieser Sprache.<\/p>\n          <select class=\"gw-select\" id=\"gw-commLang\">\n            <option value=\"\" selected disabled>Bitte w\u00e4hlen\u2026<\/option>\n            <option>Deutsch<\/option>\n            <option>Vietnamesisch<\/option>\n            <option>Englisch<\/option>\n            <option>Spanisch<\/option>\n            <option>Franz\u00f6sisch<\/option>\n            <option>Italienisch<\/option>\n            <option>Portugiesisch<\/option>\n            <option>Arabisch<\/option>\n            <option>Hebr\u00e4isch<\/option>\n            <option>Farsi<\/option>\n            <option>Georgisch<\/option>\n            <option>Russisch<\/option>\n            <option>Chinesisch<\/option>\n            <option>Japanisch<\/option>\n            <option>Koreanisch<\/option>\n            <option>Ukrainisch<\/option>\n            <option>Niederl\u00e4ndisch<\/option>\n            <option>T\u00fcrkisch<\/option>\n            <option>Bulgarisch<\/option>\n          <\/select>\n\n          <div class=\"gw-infobox\" id=\"gw-apponly-note\" style=\"display:none; margin-top:14px;\">\n            <div class=\"gw-infobox-title\">Digitale Teilnahme<\/div>\n            <div id=\"gw-apponly-note-text\"><\/div>\n          <\/div>\n\n          <div id=\"gw-shipping-block\" class=\"gw-infobox\" style=\"margin-top:26px;\">\n            <div class=\"gw-infobox-title\">Versand<\/div>\n            <div>Die Kartensets gehen als ein Paket an eine Adresse \u2013 Ihr verteilt sie dann vor Ort. Die Lieferadresse tragt Ihr am Ende im Checkout ein.<\/div>\n          <\/div>\n\n          <div class=\"gw-error\" id=\"gw-error-langship\"><\/div>\n\n          <div class=\"gw-btn-row\">\n            <button class=\"gw-btn gw-btn-secondary\" id=\"gw-btn-langship-back\">Zur\u00fcck<\/button>\n            <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-langship-next\" disabled>Weiter<\/button>\n          <\/div>\n        <\/div>\n\n        <!-- STEP 5: TEILNEHMENDE -->\n        <div class=\"gw-step\" id=\"gw-step-people\">\n          <div class=\"gw-step-label\">Schritt 5 von 7<\/div>\n          <h2 class=\"gw-heading\">Wer nimmt teil?<\/h2>\n          <p class=\"gw-subtext\" id=\"gw-people-intro\">\n            Tragt hier alle Teilnehmenden ein. Jede Person bekommt ihren eigenen Zugang an die\n            angegebene E-Mail-Adresse. Den Beitrag k\u00f6nnt Ihr f\u00fcr jede Person einzeln festlegen \u2013\n            so l\u00e4sst sich innerhalb der Gruppe ausgleichen, was der oder die Einzelne tragen kann.\n          <\/p>\n\n          <div class=\"gw-infobox\" id=\"gw-range-note\" style=\"margin-bottom:22px;\"><\/div>\n\n          <div class=\"gw-bulk\">\n            <div>\n              <label class=\"gw-label\">Gleicher Betrag f\u00fcr alle<\/label>\n              <input class=\"gw-text-input\" type=\"number\" id=\"gw-bulk-amount\" style=\"margin-bottom:0;\">\n            <\/div>\n            <button class=\"gw-btn-ghost\" id=\"gw-bulk-apply\">F\u00fcr alle \u00fcbernehmen<\/button>\n          <\/div>\n\n          <div class=\"gw-p-head\">\n            <div><\/div><div>Vorname<\/div><div>Nachname<\/div><div>E-Mail<\/div><div style=\"text-align:right;\">Beitrag \u20ac<\/div><div><\/div>\n          <\/div>\n          <div id=\"gw-people-list\"><\/div>\n\n          <div class=\"gw-add-row\">\n            <button class=\"gw-btn-ghost\" id=\"gw-add-1\">+ Person<\/button>\n            <button class=\"gw-btn-ghost\" id=\"gw-add-5\">+ 5 Personen<\/button>\n            <button class=\"gw-btn-ghost\" id=\"gw-add-10\">+ 10 Personen<\/button>\n            <div class=\"gw-count\" id=\"gw-people-count\"><\/div>\n          <\/div>\n\n          <div class=\"gw-error\" id=\"gw-error-people\"><\/div>\n\n          <div class=\"gw-btn-row\">\n            <button class=\"gw-btn gw-btn-secondary\" id=\"gw-btn-people-back\">Zur\u00fcck<\/button>\n            <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-people-next\">Weiter<\/button>\n          <\/div>\n        <\/div>\n\n        <!-- STEP 6: ZUSAMMENFASSUNG -->\n        <div class=\"gw-step\" id=\"gw-step-summary\">\n          <div class=\"gw-step-label\">Schritt 6 von 7<\/div>\n          <h2 class=\"gw-heading\">Alles auf einen Blick<\/h2>\n          <p class=\"gw-subtext\">Schaut noch einmal in Ruhe dr\u00fcber. Danach geht es zur Bezahlung \u2013 die Adresse f\u00fcr den Versand tragt Ihr dort ein.<\/p>\n\n          <div class=\"gw-list-preview\" id=\"gw-summary-people\"><\/div>\n\n          <div class=\"gw-summary-box\">\n            <div class=\"gw-summary-row\"><span>Teilnehmende<\/span><span id=\"gw-sum-count\">0<\/span><\/div>\n            <div class=\"gw-summary-row\"><span>Summe der Beitr\u00e4ge<\/span><span id=\"gw-sum-gross\">0\u20ac<\/span><\/div>\n            <div class=\"gw-summary-row\" id=\"gw-sum-ship-row\" style=\"display:none;\"><span>Versand<\/span><span>15\u20ac<\/span><\/div>\n            <div class=\"gw-summary-row gw-summary-total\"><span>Gesamt<\/span><span><span id=\"gw-sum-total\">0<\/span>\u20ac<\/span><\/div>\n          <\/div>\n\n          <div class=\"gw-error\" id=\"gw-error-summary\"><\/div>\n\n          <div class=\"gw-btn-row\">\n            <button class=\"gw-btn gw-btn-secondary\" id=\"gw-btn-summary-back\">Zur\u00fcck<\/button>\n            <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-summary-next\">Weiter<\/button>\n          <\/div>\n        <\/div>\n\n        <!-- STEP 7: ABSCHLUSS -->\n        <div class=\"gw-step\" id=\"gw-step-final\">\n          <div class=\"gw-step-label\">Schritt 7 von 7<\/div>\n          <h2 class=\"gw-heading\">Der letzte Schritt<\/h2>\n          <p class=\"gw-subtext\" id=\"gw-final-intro\"><\/p>\n\n          <div class=\"gw-final-list\" id=\"gw-final-list\"><\/div>\n\n          <div class=\"gw-coordinator\">\n            <div class=\"gw-coordinator-photos\">\n              <div class=\"gw-coordinator-photo gw-photo-susanne\">\n                <img decoding=\"async\" src=\"https:\/\/spiritual-activity.org\/wp-content\/uploads\/2026\/07\/Susanne_Schwaier.jpg\" alt=\"Susanne\">\n              <\/div>\n              <div class=\"gw-coordinator-photo gw-photo-andreas\">\n                <img decoding=\"async\" src=\"https:\/\/spiritual-activity.org\/wp-content\/uploads\/2026\/07\/Andreas-scaled.jpg\" alt=\"Andreas\">\n              <\/div>\n            <\/div>\n            <div class=\"gw-coordinator-text\">\n              <p style=\"margin:0 0 8px;\">Wir freuen uns auf die gemeinsame Zeit mit Euch.<\/p>\n              <p style=\"margin:0;\">Wenn unterwegs Fragen auftauchen, sind Susanne und Andreas f\u00fcr Euch da:<br>\n                <a href=\"mailto:susanne@spiritual-activity.org\">susanne@spiritual-activity.org<\/a>\n              <\/p>\n            <\/div>\n          <\/div>\n\n          <div class=\"gw-error\" id=\"gw-error-final\"><\/div>\n\n          <div class=\"gw-btn-row\">\n            <button class=\"gw-btn gw-btn-secondary\" id=\"gw-btn-final-back\">Zur\u00fcck<\/button>\n            <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-checkout\">Anmeldung abschlie\u00dfen<\/button>\n          <\/div>\n        <\/div>\n\n      <\/div>\n    <\/div>\n  `;\n  shadow.appendChild(wrapper);\n\n  const $ = (id) => shadow.getElementById(id);\n\n  const COUNTRY_TO_CAT = {};\n  Object.keys(COUNTRIES).forEach(cat => COUNTRIES[cat].forEach(code => COUNTRY_TO_CAT[code] = cat));\n\n  function getCountryName(code) {\n    if (COUNTRY_NAME_OVERRIDES[code]) return COUNTRY_NAME_OVERRIDES[code];\n    try { return new Intl.DisplayNames([\"de\"], { type: \"region\" }).of(code) || code; }\n    catch { return code; }\n  }\n\n  function getCountryAliases(code) {\n    const list = [];\n    if (COUNTRY_NAME_OVERRIDES[code]) {\n      try {\n        const intlName = new Intl.DisplayNames([\"de\"], { type: \"region\" }).of(code);\n        if (intlName) list.push(intlName.toLowerCase());\n      } catch {}\n    }\n    (COUNTRY_SEARCH_ALIASES[code] || []).forEach(a => list.push(a.toLowerCase()));\n    return list;\n  }\n\n  function getAllCountriesSorted() {\n    const all = [];\n    [\"cat1\",\"cat2\",\"cat3\",\"cat4\"].forEach(cat => {\n      COUNTRIES[cat]\n        .map(code => ({ code, name: getCountryName(code), cat, aliases: getCountryAliases(code) }))\n        .sort((a, b) => a.name.localeCompare(b.name, \"de\"))\n        .forEach(c => all.push(c));\n    });\n    return all;\n  }\n\n  function emptyPerson(amount) {\n    return { vorname: \"\", nachname: \"\", email: \"\", amount: amount || 0 };\n  }\n\n  const state = {\n    org: \"\", kontakt: { vorname: \"\", nachname: \"\", email: \"\", telefon: \"\" },\n    country: \"\", category: \"cat1\",\n    commLang: \"\",\n    people: [],\n    kontaktEingefuegt: false\n  };\n\n\n  const APP_ONLY_CATEGORY_EXCEPTION_LANG = { CN: \"Chinesisch\" };\n\n  function isAppOnly() {\n    const { category: cat, commLang: lang, country } = state;\n    if (cat === \"cat3\" || cat === \"cat4\") {\n      const exceptionLang = APP_ONLY_CATEGORY_EXCEPTION_LANG[country];\n      if (!exceptionLang || lang !== exceptionLang) return true;\n    }\n    if (APP_ONLY_LANGS.has(lang)) return true;\n    if (lang === \"Russisch\" && country && country !== \"RU\") return true;\n    return false;\n  }\n\n  function hasPhysicalShipment() { return !isAppOnly(); }\n\n  \/\/ Kauf auf Rechnung bieten wir nur Gruppen aus Deutschland an.\n  function rechnungMoeglich() { return state.country === \"DE\"; }\n\n  function getParticipationProductId() {\n    return hasPhysicalShipment() ? GRUPPEN_PRODUCT_ID : GRUPPEN_PRODUCT_ID_APPONLY;\n  }\n\n  \/\/ \u2500\u2500 Banner & Schritte \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function updateOrgBanner() {\n    const b = $(\"gw-org-banner\");\n    if (state.org.trim()) {\n      b.style.display = \"block\";\n      b.textContent = \"Gruppen-Anmeldung f\u00fcr \" + state.org.trim();\n    } else {\n      b.style.display = \"none\";\n    }\n  }\n\n  const STEP_CONTAINER = {\n    1: \"gw-step-welcome\",\n    2: \"gw-step-org\",\n    3: \"gw-step-country\",\n    4: \"gw-step-langship\",\n    5: \"gw-step-people\",\n    6: \"gw-step-summary\",\n    7: \"gw-step-final\"\n  };\n\n  function showStep(n) {\n    shadow.querySelectorAll(\".gw-step\").forEach(el => el.classList.remove(\"active\"));\n    $(STEP_CONTAINER[n]).classList.add(\"active\");\n    for (let i = 1; i <= 7; i++) {\n      const prog = $(\"gw-prog-\" + i);\n      if (!prog) continue;\n      if (i < n) prog.className = \"gw-progress-step done\";\n      else if (i === n) prog.className = \"gw-progress-step active\";\n      else prog.className = \"gw-progress-step\";\n    }\n    if (n === 5) { ensureInitialPeople(); renderRangeNote(); renderPeople(); }\n    if (n === 6) renderSummary();\n    if (n === 7) renderFinal();\n    const root = shadow.querySelector(\".gw-root\");\n    if (root && root.scrollIntoView) root.scrollIntoView({ block: \"start\", behavior: \"smooth\" });\n  }\n\n  function setNextEnabled(id, enabled) {\n    const b = $(id);\n    if (!b) return;\n    b.disabled = !enabled;\n    b.style.opacity = enabled ? \"1\" : \".4\";\n    b.style.cursor  = enabled ? \"pointer\" : \"not-allowed\";\n  }\n\n  function showErrorIn(id, msg) { const el=$(id); el.style.display=\"block\"; el.textContent=msg; }\n  function clearErrorIn(id)     { const el=$(id); el.style.display=\"none\";  el.textContent=\"\"; }\n\n  function setCheckoutLoading(loading) {\n    const btn = $(\"gw-btn-checkout\");\n    const overlay = document.getElementById(OVERLAY_ID);\n    if (!btn.dataset.defaultLabel) btn.dataset.defaultLabel = btn.textContent;\n    if (loading) {\n      btn.disabled = true;\n      btn.innerHTML = '<span class=\"wiz-spinner\"><\/span> Wird vorbereitet\u2026';\n      btn.style.opacity = \".8\";\n      if (overlay) overlay.style.display = \"flex\";\n    } else {\n      btn.disabled = false;\n      btn.textContent = btn.dataset.defaultLabel;\n      btn.style.opacity = \"1\";\n      if (overlay) overlay.style.display = \"none\";\n    }\n  }\n\n  function showThankYou() {\n    const card = shadow.querySelector(\".gw-card\");\n    if (!card) return;\n    card.innerHTML = `\n      <div style=\"text-align:center; padding:20px 0;\">\n        <div style=\"font-size:56px; margin-bottom:16px; color:#27703F;\">\u2713<\/div>\n        <h2 style=\"font-family:'Tinos',Georgia,serif; font-size:26px; font-weight:500; margin:0 0 12px; color:#0C1E14;\">Vielen Dank!<\/h2>\n        <p style=\"font-family:'Tinos',Georgia,serif; font-size:18px; color:#27703F; line-height:1.6; margin:0 0 24px;\">Wir haben Eure Anmeldung erhalten.<br>Ihr werdet gleich zum Checkout weitergeleitet\u2026<\/p>\n        <div style=\"display:flex; justify-content:center;\">\n          <div style=\"width:36px; height:36px; border:4px solid #B8DEC4; border-top-color:#0C1E14; border-radius:50%; animation:wiz-spin 0.8s linear infinite;\"><\/div>\n        <\/div>\n      <\/div>`;\n  }\n\n  \/\/ \u2500\u2500 Schritt 2: Organisation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function validateOrg() {\n    const emailOk = \/\\S+@\\S+\\.\\S+\/.test(state.kontakt.email || \"\");\n    const ok = !!state.org.trim() && !!state.kontakt.vorname.trim() &&\n               !!state.kontakt.nachname.trim() && emailOk;\n    setNextEnabled(\"gw-btn-org-next\", ok);\n    return ok;\n  }\n\n  $(\"gw-org-name\").addEventListener(\"input\", e => {\n    state.org = e.target.value;\n    updateOrgBanner();\n    validateOrg();\n  });\n  [[\"vorname\",\"gw-kontakt-vorname\"],[\"nachname\",\"gw-kontakt-nachname\"],\n   [\"email\",\"gw-kontakt-email\"],[\"telefon\",\"gw-kontakt-telefon\"]].forEach(([key, id]) => {\n    $(id).addEventListener(\"input\", e => { state.kontakt[key] = e.target.value; validateOrg(); });\n  });\n\n  \/\/ \u2500\u2500 Schritt 3: Land \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function renderCountryList(filter) {\n    const list = $(\"gw-country-list\");\n    const q = (filter || \"\").toLowerCase().trim();\n    const filtered = q\n      ? getAllCountriesSorted().filter(c =>\n          c.name.toLowerCase().includes(q) ||\n          (c.aliases || []).some(a => a.includes(q))\n        )\n      : getAllCountriesSorted();\n    list.innerHTML = \"\";\n    if (!filtered.length) { list.innerHTML = '<div class=\"gw-country-empty\">Kein Land gefunden<\/div>'; return; }\n    filtered.forEach(c => {\n      const div = document.createElement(\"div\");\n      div.className = \"gw-country-item\" + (state.country === c.code ? \" selected\" : \"\");\n      div.dataset.code = c.code;\n      div.innerHTML = `<span>${c.name}<\/span><span class=\"gw-country-item-cat\">Kat. ${c.cat.replace(\"cat\",\"\")}<\/span>`;\n      div.addEventListener(\"click\", () => selectCountry(c.code, c.cat, c.name));\n      list.appendChild(div);\n    });\n  }\n\n  function renderPriceTable(cat) {\n    const g = ORIENTIERUNG[cat];\n    \/\/ Bei rein digitaler Teilnahme wird vom Einzelpreis regulaer die App-Pauschale\n    \/\/ abgezogen \u2013 nur so ist der Vergleich mit dem Gruppenpreis ehrlich.\n    const digital = isAppOnly();\n    const roh = NORMALPREIS[cat];\n    const n = digital\n      ? { reduced: roh.reduced - DIGITAL_ABZUG, base: roh.base - DIGITAL_ABZUG, support: roh.support - DIGITAL_ABZUG }\n      : roh;\n    const zeile = (label, normal, gruppe) => `\n        <tr>\n          <td>${label}<\/td>\n          <td class=\"gw-price-old\">${normal} \u20ac<\/td>\n          <td class=\"gw-price-new\">${gruppe} \u20ac<\/td>\n        <\/tr>`;\n    return `\n      <table class=\"gw-pricetable\">\n        <tr><th>Beitrag pro Person<\/th><th class=\"gw-price-old\">Einzeln${digital ? \" (digital)\" : \"\"}<\/th><th class=\"gw-price-new\">Als Gruppe<\/th><\/tr>\n        ${zeile(\"Reduzierter Beitrag\", n.reduced, g.reduced)}\n        ${zeile(\"Grundbeitrag\",        n.base,    g.base)}\n        ${zeile(\"F\u00f6rderbeitrag\",       n.support, g.support)}\n      <\/table>\n      <div style=\"font-size:15px; line-height:1.6; margin-top:12px; color:var(--ink-muted);\">\n        Bitte w\u00e4hlt individuell aus, was jede und jeder Einzelne zahlen m\u00f6chte.\n        Kommt gerne auf uns zu, wenn die Beitr\u00e4ge noch zu hoch sind \u2013 dann finden wir\n        gemeinsam eine L\u00f6sung, die f\u00fcr Euch passt.\n      <\/div>`;\n  }\n\n  function selectCountry(code, cat, name) {\n    state.country  = code;\n    state.category = cat;\n    $(\"gw-country\").value = code;\n    $(\"gw-country-search\").value = name;\n    $(\"gw-country-list\").innerHTML = \"\";\n\n    const catLabels = { cat1:\"Preiskategorie 1\", cat2:\"Preiskategorie 2\", cat3:\"Preiskategorie 3\", cat4:\"Preiskategorie 4\" };\n    const exceptionLang = APP_ONLY_CATEGORY_EXCEPTION_LANG[code];\n    let suffix = \"\";\n    if (cat === \"cat3\" || cat === \"cat4\") {\n      suffix = exceptionLang\n        ? ` \u2013 Versand nur bei Teilnahmesprache ${exceptionLang} m\u00f6glich, sonst digitale Teilnahme`\n        : \" \u2013 in dieser Region ist nur die digitale Teilnahme m\u00f6glich\";\n    }\n    $(\"gw-catText\").textContent = (catLabels[cat] || cat) + suffix;\n    $(\"gw-priceTableWrap\").innerHTML = renderPriceTable(cat);\n\n    const nachRussland = (code === \"RU\");\n    $(\"gw-redirect-russia\").style.display = nachRussland ? \"block\" : \"none\";\n    $(\"gw-catInfo\").style.display         = nachRussland ? \"none\"  : \"block\";\n    setNextEnabled(\"gw-btn-country-next\", !nachRussland);\n\n    \/\/ Betr\u00e4ge auf den neuen Grundbeitrag setzen, solange noch nichts angepasst wurde\n    const base = ORIENTIERUNG[cat].base;\n    state.people.forEach(p => { if (!p._touched) p.amount = base; });\n    $(\"gw-bulk-amount\").value = base;\n    updateAppOnlyUI();\n  }\n\n  $(\"gw-country-search\").addEventListener(\"input\", e => renderCountryList(e.target.value));\n  $(\"gw-country-search\").addEventListener(\"focus\", () => renderCountryList($(\"gw-country-search\").value));\n  shadow.addEventListener(\"click\", e => {\n    if (!e.target.closest(\"#gw-country-list\") && !e.target.closest(\"#gw-country-search\")) {\n      $(\"gw-country-list\").innerHTML = \"\";\n    }\n  });\n\n  \/\/ \u2500\u2500 Schritt 4: Sprache & Versand \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function updateAppOnlyUI() {\n    const appOnly = state.commLang ? isAppOnly() : false;\n    let reason = \"\";\n    if (appOnly) {\n      const exceptionLang = APP_ONLY_CATEGORY_EXCEPTION_LANG[state.country];\n      if ((state.category === \"cat3\" || state.category === \"cat4\") && exceptionLang) {\n        reason = `In Eure Region k\u00f6nnen wir nur bei der Teilnahmesprache ${exceptionLang} versenden. Ihr nehmt deshalb digital teil \u2013 das ist in den Gruppen-Beitr\u00e4gen bereits ber\u00fccksichtigt.`;\n      } else if (state.category === \"cat3\" || state.category === \"cat4\") {\n        reason = \"In Eure Region k\u00f6nnen wir leider nicht versenden. Ihr nehmt deshalb digital teil \u2013 das ist in den Gruppen-Beitr\u00e4gen bereits ber\u00fccksichtigt.\";\n      } else if (state.commLang === \"Russisch\") {\n        reason = \"F\u00fcr Russischsprachige au\u00dferhalb Russlands gibt es die Materialien nur digital \u2013 das ist in den Gruppen-Beitr\u00e4gen bereits ber\u00fccksichtigt.\";\n      } else {\n        reason = \"In dieser Sprache gibt es die Materialien nur digital \u2013 das ist in den Gruppen-Beitr\u00e4gen bereits ber\u00fccksichtigt.\";\n      }\n    }\n    const note = $(\"gw-apponly-note\");\n    note.style.display = appOnly ? \"block\" : \"none\";\n    $(\"gw-apponly-note-text\").textContent = reason;\n    $(\"gw-shipping-block\").style.display = appOnly ? \"none\" : \"block\";\n  }\n\n  $(\"gw-commLang\").addEventListener(\"change\", e => {\n    state.commLang = e.target.value;\n    updateAppOnlyUI();\n    setNextEnabled(\"gw-btn-langship-next\", !!state.commLang);\n  });\n\n  \/\/ \u2500\u2500 Schritt 5: Teilnehmende \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function ensureInitialPeople() {\n    const base = ORIENTIERUNG[state.category].base;\n    \/\/ Die Ansprechperson steht automatisch als erste Teilnehmerin in der Liste.\n    \/\/ Sie laesst sich wie jede andere Zeile wieder entfernen \u2013 dann kommt sie\n    \/\/ auch nicht zurueck.\n    if (!state.kontaktEingefuegt) {\n      const k = emptyPerson(base);\n      k.vorname  = state.kontakt.vorname.trim();\n      k.nachname = state.kontakt.nachname.trim();\n      k.email    = state.kontakt.email.trim();\n      state.people.unshift(k);\n      state.kontaktEingefuegt = true;\n    }\n    while (state.people.length < MIN_TEILNEHMER) state.people.push(emptyPerson(base));\n    if (!$(\"gw-bulk-amount\").value) $(\"gw-bulk-amount\").value = base;\n  }\n\n  function renderRangeNote() {\n    const g = ORIENTIERUNG[state.category], r = RANGES[state.category];\n    $(\"gw-range-note\").innerHTML = `\n      <div class=\"gw-infobox-title\">Eure Gruppenpreise<\/div>\n      <div>Grundbeitrag ${g.base} \u20ac \u00b7 reduziert ${g.reduced} \u20ac \u00b7 F\u00f6rderbeitrag ${g.support} \u20ac.\n      M\u00f6glich ist alles zwischen ${r.min} \u20ac und ${r.max} \u20ac pro Person. Wenn die Beitr\u00e4ge\n      noch zu hoch sind, meldet Euch gerne bei uns \u2013 wir finden eine L\u00f6sung, die f\u00fcr Euch passt.<\/div>`;\n  }\n\n  function clampAmount(v) {\n    const r = RANGES[state.category];\n    let n = Number(v);\n    if (isNaN(n)) n = r.min;\n    return Math.min(r.max, Math.max(r.min, Math.round(n)));\n  }\n\n  function renderPeople() {\n    const list = $(\"gw-people-list\");\n    list.innerHTML = \"\";\n    state.people.forEach((p, i) => {\n      const row = document.createElement(\"div\");\n      row.className = \"gw-p-row\";\n      row.innerHTML = `\n        <div class=\"gw-p-num\">${i + 1}<\/div>\n        <input type=\"text\"   data-f=\"vorname\"  placeholder=\"Vorname\"  value=\"${escapeAttr(p.vorname)}\">\n        <input type=\"text\"   data-f=\"nachname\" placeholder=\"Nachname\" value=\"${escapeAttr(p.nachname)}\">\n        <input type=\"email\"  data-f=\"email\"    placeholder=\"E-Mail\"   value=\"${escapeAttr(p.email)}\">\n        <input type=\"number\" data-f=\"amount\" class=\"gw-p-amount\" value=\"${p.amount}\">\n        <button class=\"gw-p-remove\" title=\"Zeile entfernen\">\u00d7<\/button>\n      `;\n      row.querySelectorAll(\"input\").forEach(inp => {\n        const f = inp.dataset.f;\n        inp.addEventListener(\"input\", e => {\n          if (f === \"amount\") { p.amount = Number(e.target.value); p._touched = true; }\n          else p[f] = e.target.value;\n          inp.classList.remove(\"gw-invalid\");\n          updatePeopleCount();\n        });\n        if (f === \"amount\") {\n          inp.addEventListener(\"change\", e => {\n            p.amount = clampAmount(e.target.value);\n            e.target.value = p.amount;\n            updatePeopleCount();\n          });\n        }\n      });\n      row.querySelector(\".gw-p-remove\").addEventListener(\"click\", () => {\n        if (state.people.length <= 1) return;\n        state.people.splice(i, 1);\n        renderPeople();\n      });\n      list.appendChild(row);\n    });\n    updatePeopleCount();\n  }\n\n  function escapeAttr(s) { return String(s || \"\").replace(\/\"\/g, \"&quot;\"); }\n\n  function updatePeopleCount() {\n    const n = state.people.length;\n    const sum = state.people.reduce((a, p) => a + (Number(p.amount) || 0), 0);\n    const fehlend = MIN_TEILNEHMER - n;\n    $(\"gw-people-count\").textContent = fehlend > 0\n      ? `${n} Personen \u00b7 noch ${fehlend} bis zur Mindestgr\u00f6\u00dfe von ${MIN_TEILNEHMER}`\n      : `${n} von max. ${MAX_TEILNEHMER} Personen \u00b7 Summe ${sum} \u20ac`;\n  }\n\n  function addPeople(n) {\n    const base = ORIENTIERUNG[state.category].base;\n    const bulk = Number($(\"gw-bulk-amount\").value);\n    const amount = clampAmount(isNaN(bulk) || !bulk ? base : bulk);\n    let added = 0;\n    for (let i = 0; i < n && state.people.length < MAX_TEILNEHMER; i++) {\n      state.people.push(emptyPerson(amount));\n      added++;\n    }\n    renderPeople();\n    if (added < n) showErrorIn(\"gw-error-people\", `Mehr als ${MAX_TEILNEHMER} Personen k\u00f6nnen wir hier nicht aufnehmen. F\u00fcr gr\u00f6\u00dfere Gruppen schreibt uns bitte an info@basic-exercises.com.`);\n    else clearErrorIn(\"gw-error-people\");\n  }\n\n  $(\"gw-add-1\").addEventListener(\"click\",  () => addPeople(1));\n  $(\"gw-add-5\").addEventListener(\"click\",  () => addPeople(5));\n  $(\"gw-add-10\").addEventListener(\"click\", () => addPeople(10));\n\n  $(\"gw-bulk-apply\").addEventListener(\"click\", () => {\n    const v = clampAmount($(\"gw-bulk-amount\").value);\n    $(\"gw-bulk-amount\").value = v;\n    state.people.forEach(p => { p.amount = v; p._touched = true; });\n    renderPeople();\n  });\n\n  function validatePeople() {\n    const emailOk = s => \/\\S+@\\S+\\.\\S+\/.test(s || \"\");\n    const r = RANGES[state.category];\n    let firstBad = -1;\n    state.people.forEach((p, i) => {\n      const bad = !p.vorname.trim() || !p.nachname.trim() || !emailOk(p.email) ||\n                  !(p.amount >= r.min && p.amount <= r.max);\n      if (bad && firstBad < 0) firstBad = i;\n    });\n    \/\/ doppelte E-Mails\n    const seen = new Set(); let dupe = \"\";\n    state.people.forEach(p => {\n      const e = (p.email || \"\").trim().toLowerCase();\n      if (e && seen.has(e)) dupe = e;\n      seen.add(e);\n    });\n    if (firstBad >= 0) {\n      markInvalid(firstBad);\n      return { ok: false, msg: `Bitte pr\u00fcft Zeile ${firstBad + 1}: Vorname, Nachname, eine g\u00fcltige E-Mail-Adresse und ein Beitrag zwischen ${r.min} \u20ac und ${r.max} \u20ac.` };\n    }\n    if (dupe) return { ok: false, msg: `Die E-Mail-Adresse ${dupe} kommt doppelt vor. Jede Person braucht eine eigene Adresse f\u00fcr ihren Zugang.` };\n    if (state.people.length < MIN_TEILNEHMER) {\n      return { ok: false, msg: `F\u00fcr eine Gruppen-Anmeldung braucht es mindestens ${MIN_TEILNEHMER} Personen. F\u00fcr kleinere Gruppen nutzt bitte die Einzel-Anmeldung.` };\n    }\n    return { ok: true };\n  }\n\n  function markInvalid(index) {\n    const rows = shadow.querySelectorAll(\"#gw-people-list .gw-p-row\");\n    const row = rows[index];\n    if (!row) return;\n    const emailOk = s => \/\\S+@\\S+\\.\\S+\/.test(s || \"\");\n    const p = state.people[index];\n    const r = RANGES[state.category];\n    row.querySelectorAll(\"input\").forEach(inp => {\n      const f = inp.dataset.f;\n      let bad = false;\n      if (f === \"vorname\")  bad = !p.vorname.trim();\n      if (f === \"nachname\") bad = !p.nachname.trim();\n      if (f === \"email\")    bad = !emailOk(p.email);\n      if (f === \"amount\")   bad = !(p.amount >= r.min && p.amount <= r.max);\n      inp.classList.toggle(\"gw-invalid\", bad);\n    });\n    row.scrollIntoView({ block: \"center\", behavior: \"smooth\" });\n  }\n\n  $(\"gw-btn-people-next\").addEventListener(\"click\", () => {\n    const v = validatePeople();\n    if (!v.ok) return showErrorIn(\"gw-error-people\", v.msg);\n    clearErrorIn(\"gw-error-people\");\n    showStep(6);\n  });\n\n  \/\/ \u2500\u2500 Schritt 6: Zusammenfassung \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function computeTotals() {\n    const appOnly = isAppOnly();\n    const n = state.people.length;\n    const gross = state.people.reduce((a, p) => a + (Number(p.amount) || 0), 0);\n    const shipping = (hasPhysicalShipment() && needsShipping(state.country)) ? SHIPPING_COST : 0;\n    const total = gross + shipping;\n    return { n, gross, shipping, total, appOnly };\n  }\n\n  function renderSummary() {\n    const t = computeTotals();\n    const listEl = $(\"gw-summary-people\");\n    listEl.innerHTML = \"\";\n    state.people.forEach((p, i) => {\n      const div = document.createElement(\"div\");\n      div.className = \"gw-list-preview-item\";\n      div.innerHTML = `<span>${i + 1}. ${escapeHtml(p.vorname)} ${escapeHtml(p.nachname)} \u00b7 ${escapeHtml(p.email)}<\/span><span>${p.amount} \u20ac<\/span>`;\n      listEl.appendChild(div);\n    });\n\n    $(\"gw-sum-count\").textContent = t.n;\n    $(\"gw-sum-gross\").textContent = t.gross + \"\u20ac\";\n    $(\"gw-sum-ship-row\").style.display = t.shipping ? \"flex\" : \"none\";\n    $(\"gw-sum-total\").textContent = t.total;\n  }\n\n  \/\/ \u2500\u2500 Schritt 7: Abschluss \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function renderFinal() {\n    const t = computeTotals();\n    const vorname = state.kontakt.vorname.trim();\n\n    $(\"gw-final-intro\").textContent = vorname\n      ? `${vorname}, Ihr seid fast fertig. Hier steht kurz, was jetzt passiert.`\n      : \"Ihr seid fast fertig. Hier steht kurz, was jetzt passiert.\";\n\n    const zugangZeile = \"Sobald wir Eure Gruppen-Anmeldung gepr\u00fcft haben, erh\u00e4lt jede und jeder Teilnehmende alles \u00fcber die eigene E-Mail-Adresse: die Einladung zur Konferenz, die w\u00f6chentlichen Briefe und den Zugang zur App.\";\n    const versandZeile = t.appOnly\n      ? zugangZeile\n      : zugangZeile + \" Die Kartensets gehen als ein Paket an die Lieferadresse, die Du im Shop eintr\u00e4gst.\";\n\n    $(\"gw-final-list\").innerHTML = `\n      <li>Mit dem Klick auf <strong>\u201eAnmeldung abschlie\u00dfen\"<\/strong> \u00fcbermittelst Du uns die Daten aller ${t.n} Teilnehmenden. Danach \u00f6ffnet sich der Shop.<\/li>\n      <li>Im Shop tr\u00e4gst Du die Rechnungs- und Lieferadresse ein. Bitte erg\u00e4nze in der Rechnungsadresse den Namen Eurer Organisation bzw. Gruppe \u2013 so ordnen wir Zahlung und Anmeldung sicher einander zu.<\/li>\n      <li>${versandZeile}<\/li>\n      <li>Bezahlen k\u00f6nnt Ihr per ${rechnungMoeglich() ? \"Kreditkarte, PayPal oder Rechnung\" : \"Kreditkarte oder PayPal\"}.<\/li>\n      <li>Die Rechnung liegt der Best\u00e4tigung als Anhang bei.<\/li>\n      <li class=\"gw-final-note\">Gesamtbetrag: <strong>${t.total} \u20ac<\/strong> f\u00fcr ${t.n} Teilnehmende${t.shipping ? \" (inkl. Versand)\" : \"\"}.<\/li>\n    `;\n  }\n\n  function escapeHtml(s) {\n    return String(s || \"\").replace(\/[&<>\"']\/g, c => ({ \"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#39;\" }[c]));\n  }\n\n  \/\/ \u2500\u2500 Ecwid & n8n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function ensureEcwidReady(timeoutMs = 12000) {\n    return new Promise((resolve, reject) => {\n      function isReady() {\n        return window.Ecwid && window.Ecwid.Cart &&\n               typeof window.Ecwid.Cart.addProduct === \"function\" &&\n               typeof window.Ecwid.Cart.clear === \"function\";\n      }\n      if (isReady()) return resolve(true);\n      let resolved = false;\n      function done() { if (!resolved) { resolved = true; setTimeout(() => resolve(true), 200); } }\n      if (window.Ecwid) { try { window.Ecwid.OnAPILoaded.add(done); } catch(e) {} }\n      const start = Date.now();\n      const t = setInterval(() => {\n        if (isReady()) { clearInterval(t); done(); }\n        else if (Date.now() - start > timeoutMs) {\n          clearInterval(t);\n          if (!resolved) { resolved = true; reject(new Error(\"Ecwid Cart API nicht verf\u00fcgbar nach \" + (timeoutMs\/1000) + \"s.\")); }\n        }\n      }, 200);\n    });\n  }\n\n  function clearCartAsync() { return new Promise(r => Ecwid.Cart.clear(() => r(true))); }\n\n  function addProductAsync(payload, timeoutMs = 4000) {\n    return new Promise((resolve, reject) => {\n      let done = false;\n      const t = setTimeout(() => { if (!done) { done = true; resolve({ product:null, cart:null, timedOut:true }); } }, timeoutMs);\n      Ecwid.Cart.addProduct(payload, function(success, product, cart, error) {\n        if (done) return;\n        done = true; clearTimeout(t);\n        if (success) resolve({ product, cart, timedOut:false });\n        else reject(new Error((error || \"Produkt konnte nicht hinzugef\u00fcgt werden\") + \" | Payload: \" + JSON.stringify(payload)));\n      });\n    });\n  }\n\n  function goToCart() { window.location.href = SHOP_CART_URL; }\n\n  function buildN8nPayload() {\n    const t = computeTotals();\n    return {\n      typ: \"gruppe\",\n      organisation: state.org.trim(),\n      ansprechperson: { ...state.kontakt },\n      land: state.country,\n      kategorie: state.category,\n      sprache: state.commLang,\n      appOnly: t.appOnly,\n      versandAn: t.appOnly ? \"kein_versand\" : \"sammel\",\n      anzahl: t.n,\n      rechnungMoeglich: rechnungMoeglich(),\n      teilnehmer: state.people.map(p => ({\n        vorname: p.vorname.trim(),\n        nachname: p.nachname.trim(),\n        email: p.email.trim(),\n        gewaehlt: Number(p.amount) || 0,\n        endbetrag: Number(p.amount) || 0\n      })),\n      summen: {\n        beitraege: t.gross,\n        versand: t.shipping,\n        gesamt: t.total\n      },\n      timestamp: new Date().toISOString()\n    };\n  }\n\n  async function sendToN8n(payload) {\n    if (!N8N_WEBHOOK_URL || N8N_WEBHOOK_URL.indexOf(\"HIER_\") === 0) {\n      throw new Error(\"Die n8n-Webhook-URL ist im Code noch nicht eingetragen.\");\n    }\n    let res;\n    try {\n      res = await fetch(N8N_WEBHOOK_URL, { method:\"POST\", headers:{\"Content-Type\":\"application\/json\"}, body:JSON.stringify(payload) });\n    } catch (e) {\n      throw new Error(\"Die Daten konnten nicht \u00fcbermittelt werden. Bitte pr\u00fcft Eure Internetverbindung und versucht es noch einmal.\");\n    }\n    if (!res.ok) throw new Error(\"Die \u00dcbermittlung ist fehlgeschlagen (Fehler \" + res.status + \"). Bitte versucht es noch einmal.\");\n    return true;\n  }\n\n  async function goCheckout() {\n    clearErrorIn(\"gw-error-final\");\n    if (!state.country)  return showErrorIn(\"gw-error-final\", \"Bitte w\u00e4hlt zuerst Euer Land aus.\");\n    if (!state.commLang) return showErrorIn(\"gw-error-final\", \"Bitte w\u00e4hlt zuerst die Teilnahmesprache aus.\");\n    const v = validatePeople();\n    if (!v.ok) return showErrorIn(\"gw-error-final\", v.msg);\n\n    const t = computeTotals();\n    const productId = getParticipationProductId();\n\n    setCheckoutLoading(true);\n    try {\n      await sendToN8n(buildN8nPayload());\n      await ensureEcwidReady();\n      await clearCartAsync();\n      await new Promise(r => setTimeout(r, 1500));\n\n      const options = {\n        [OPT_COMM_LANG]: state.commLang,\n        [OPT_ORG]: state.org.trim()\n      };\n\n      const priceWithoutShipping = t.gross;\n      const result = await addProductAsync({\n        id: productId, quantity: 1, selectedPrice: priceWithoutShipping, options\n      });\n      if (result.timedOut) console.warn(\"[Gruppen-Wizard] addProduct timed out \u2013 proceeding to cart anyway\");\n      showThankYou();\n      setTimeout(goToCart, 2500);\n    } catch (e) {\n      showErrorIn(\"gw-error-final\", e.message || String(e));\n    } finally {\n      setCheckoutLoading(false);\n    }\n  }\n\n  \/\/ \u2500\u2500 Navigation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  $(\"gw-btn-welcome-next\").addEventListener(\"click\", () => showStep(2));\n  $(\"gw-btn-org-back\").addEventListener(\"click\",     () => showStep(1));\n  $(\"gw-btn-org-next\").addEventListener(\"click\",     () => { if (validateOrg()) showStep(3); });\n  $(\"gw-btn-country-back\").addEventListener(\"click\", () => showStep(2));\n  $(\"gw-btn-country-next\").addEventListener(\"click\", () => showStep(4));\n  $(\"gw-btn-langship-back\").addEventListener(\"click\",() => showStep(3));\n  $(\"gw-btn-langship-next\").addEventListener(\"click\",() => showStep(5));\n  $(\"gw-btn-people-back\").addEventListener(\"click\",  () => showStep(4));\n  $(\"gw-btn-summary-back\").addEventListener(\"click\", () => showStep(5));\n  $(\"gw-btn-summary-next\").addEventListener(\"click\", () => showStep(7));\n  $(\"gw-btn-final-back\").addEventListener(\"click\",   () => showStep(6));\n  $(\"gw-btn-checkout\").addEventListener(\"click\", goCheckout);\n\n  showStep(1);\n\n})();\n<\/script>\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-5d21717 e-flex e-con-boxed e-con e-parent\" data-id=\"5d21717\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c16b1d8 elementor-widget elementor-widget-html\" data-id=\"c16b1d8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Tinos:ital,wght@0,400;0,700;1,400&display=swap\" rel=\"stylesheet\">\n\n<style>\n  .ecwid-ProductBrowser,\n  .ecwid-productbrowser,\n  div[id^=\"my-store\"],\n  .ecwid:not(#gw-host-en) {\n    visibility: hidden !important;\n    height: 0 !important;\n    max-height: 0 !important;\n    overflow: hidden !important;\n    padding: 0 !important;\n    margin: 0 !important;\n    position: absolute !important;\n    pointer-events: none !important;\n  }\n<\/style>\n\n<div id=\"gw-overlay-en\" style=\"display:none; position:fixed; inset:0; background:rgba(245,250,246,0.92); z-index:99999; flex-direction:column; align-items:center; justify-content:center; gap:20px;\">\n  <div style=\"width:52px; height:52px; border:4px solid #B8DEC4; border-top-color:#0C1E14; border-radius:50%; animation:gw-spin-en 0.8s linear infinite;\"><\/div>\n  <div style=\"font-family:'Tinos',Georgia,serif; font-size:22px; color:#27703F;\">Loading checkout\u2026<\/div>\n<\/div>\n<style>\n  @keyframes gw-spin-en { to { transform: rotate(360deg); } }\n<\/style>\n\n<div id=\"gw-host-en\"><\/div>\n\n<script>\n(function () {\n\n  \/\/ \u2500\u2500 Sprach-Guard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  \/\/ Der englische Wizard laeuft auf ALLEN Seiten ausser der deutschen.\n  \/\/ Deutsch ist die Standardsprache ohne Praefix im Pfad.\n  const _pathMatch = window.location.pathname.match(\/^\\\/([a-z]{2})(\\\/|$)\/);\n  const _pageLang = _pathMatch ? _pathMatch[1] : \"de\";\n  if (_pageLang === \"de\") {\n    document.getElementById(\"gw-host-en\")?.remove();\n    document.getElementById(\"gw-overlay-en\")?.remove();\n    return;\n  }\n\n  const OVERLAY_ID      = \"gw-overlay-en\";\n  \/\/ Warenkorb der jeweiligen Sprachversion. Fuer Sprachen ohne eigenen Shop\n  \/\/ faellt der Link auf die englische Fassung zurueck.\n  const SHOP_FALLBACK_LANGS = new Set([\"he\",\"iw\",\"ar\",\"fa\"]);\n  const _cartLang = SHOP_FALLBACK_LANGS.has(_pageLang) ? \"en\" : _pageLang;\n  const SHOP_CART_URL   = \"https:\/\/spiritual-activity.org\/\" + _cartLang + \"\/store\/cart\";\n  const N8N_WEBHOOK_URL = \"https:\/\/n8n.spiritual-activity.org\/webhook\/registration-gruppe\";\n\n  const MAX_TEILNEHMER = 100;\n  const MIN_TEILNEHMER = 4;\n\n  \/\/ Eigene Ecwid-Produkte fuer Gruppen-Anmeldungen (eigener Preis, Mindestpreis 0).\n  \/\/ Mit Versand des Kartensets bzw. versandfrei bei rein digitaler Teilnahme.\n  const GRUPPEN_PRODUCT_ID         = 864374018;\n  const GRUPPEN_PRODUCT_ID_APPONLY = 864914962;\n\n  \/\/ Regulaere Einzelpreise \u2013 dienen in der Uebersicht als Vergleichswert.\n  const NORMALPREIS = {\n    cat1: { reduced: 160, base: 360, support: 580 },\n    cat2: { reduced: 105, base: 240, support: 460 },\n    cat3: { reduced:  75, base: 160, support: 340 },\n    cat4: { reduced:  45, base: 105, support: 220 }\n  };\n\n  \/\/ Gruppenpreise \u2013 gelten fuer diese Anmeldung.\n  const ORIENTIERUNG = {\n    cat1: { reduced: 140, base: 280, support: 460 },\n    cat2: { reduced:  80, base: 160, support: 380 },\n    cat3: { reduced:  25, base:  80, support: 220 },\n    cat4: { reduced:   8, base:  45, support: 120 }\n  };\n\n  \/\/ Pauschale, die bei einer Einzelanmeldung fuer die rein digitale Teilnahme\n  \/\/ abgezogen wird \u2013 hier nur als Vergleichswert in der Preisuebersicht.\n  const DIGITAL_ABZUG = 35;\n\n  const RANGES = {\n    cat1: { min: 140, max: 800 },\n    cat2: { min:  80, max: 700 },\n    cat3: { min:  25, max: 600 },\n    cat4: { min:   8, max: 500 }\n  };\n\n  \/\/ Versandpauschale ausserhalb EU+CH \u2013 bei Sammelversand genau einmal.\n  const SHIPPING_COST = 15;\n\n  \/\/ Interne Werte bleiben deutsch, weil Ecwid und n8n sie so erwarten.\n  const APP_ONLY_LANGS = new Set([\"Arabisch\",\"Farsi\",\"Ukrainisch\",\"Bulgarisch\",\"Franz\u00f6sisch\",\"Vietnamesisch\"]);\n  const APP_ONLY_CATEGORY_EXCEPTION_LANG = { CN: \"Chinesisch\" };\n\n  \/\/ \u2500\u2500 Anzeigenamen der Teilnahmesprachen \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  \/\/ Der interne Wert bleibt deutsch, nur die Anzeige wird uebersetzt.\n  const LANG_DISPLAY = {\n      \"Deutsch\": \"German\",\n      \"Englisch\": \"English\",\n      \"Spanisch\": \"Spanish\",\n      \"Franz\u00f6sisch\": \"French\",\n      \"Italienisch\": \"Italian\",\n      \"Portugiesisch\": \"Portuguese\",\n      \"Arabisch\": \"Arabic\",\n      \"Hebr\u00e4isch\": \"Hebrew\",\n      \"Farsi\": \"Farsi (Persian)\",\n      \"Georgisch\": \"Georgian\",\n      \"Russisch\": \"Russian\",\n      \"Chinesisch\": \"Chinese\",\n      \"Japanisch\": \"Japanese\",\n      \"Koreanisch\": \"Korean\",\n      \"Ukrainisch\": \"Ukrainian\",\n      \"Niederl\u00e4ndisch\": \"Dutch\",\n      \"T\u00fcrkisch\": \"Turkish\",\n      \"Bulgarisch\": \"Bulgarian\",\n      \"Vietnamesisch\": \"Vietnamese\"\n  };\n\n  const EU_PLUS_CH = new Set([\n    \"AT\",\"BE\",\"BG\",\"CY\",\"CZ\",\"DE\",\"DK\",\"EE\",\"ES\",\"FI\",\"FR\",\"GR\",\"HR\",\n    \"HU\",\"IE\",\"IT\",\"LT\",\"LU\",\"LV\",\"MT\",\"NL\",\"PL\",\"PT\",\"RO\",\"SE\",\"SI\",\"SK\",\"CH\"\n  ]);\n  function needsShipping(countryCode) {\n    return countryCode && !EU_PLUS_CH.has(countryCode);\n  }\n\n  const COUNTRY_NAME_OVERRIDES = {\n    \"HK\":\"Hong Kong\",\"MO\":\"Macau\",\"TW\":\"Taiwan\",\"AE\":\"United Arab Emirates\",\n    \"US\":\"USA\",\"GB\":\"United Kingdom\",\"GB-SCT\":\"Scotland\",\n    \"KR\":\"South Korea\",\"SA\":\"Saudi Arabia\",\n    \"MD\":\"Moldova\",\"PS\":\"Palestine\",\"CD\":\"Congo (Kinshasa)\",\"CG\":\"Congo (Brazzaville)\",\n    \"ST\":\"S\u00e3o Tom\u00e9 and Pr\u00edncipe\",\"CI\":\"C\u00f4te d'Ivoire\",\"TL\":\"Timor-Leste\",\n    \"CV\":\"Cabo Verde\",\"SZ\":\"Eswatini\",\"FM\":\"Micronesia\",\"MH\":\"Marshall Islands\",\n    \"VC\":\"St. Vincent and the Grenadines\",\"LC\":\"St. Lucia\",\"KN\":\"St. Kitts and Nevis\",\n    \"AG\":\"Antigua and Barbuda\",\"TT\":\"Trinidad and Tobago\",\"BA\":\"Bosnia and Herzegovina\",\n    \"MK\":\"North Macedonia\",\"GQ\":\"Equatorial Guinea\",\"GW\":\"Guinea-Bissau\",\n    \"CF\":\"Central African Republic\",\"SB\":\"Solomon Islands\",\"PG\":\"Papua New Guinea\",\n    \"DO\":\"Dominican Republic\",\"XK\":\"Kosovo\"\n  };\n\n  \/\/ \u2500\u2500 Zusaetzliche Suchbegriffe (Aliasse) je Land \u2500\u2500\u2500\u2500\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  \/\/ Beeinflusst NUR die Suche, nicht den angezeigten Namen. Alles klein schreiben.\n  const COUNTRY_SEARCH_ALIASES = {\n      \"US\": [\"united states\", \"united states of america\", \"usa\", \"u.s.\", \"u.s.a.\", \"america\"],\n      \"GB\": [\"united kingdom\", \"uk\", \"great britain\", \"britain\", \"england\"],\n      \"GB-SCT\": [\"scotland\"],\n      \"AE\": [\"uae\", \"united arab emirates\", \"emirates\", \"dubai\"],\n      \"KR\": [\"south korea\", \"korea\", \"republic of korea\"],\n      \"NL\": [\"netherlands\", \"holland\"],\n      \"CH\": [\"switzerland\", \"swiss\"],\n      \"DE\": [\"germany\", \"deutschland\"],\n      \"AT\": [\"austria\"],\n      \"CZ\": [\"czechia\", \"czech republic\"],\n      \"TR\": [\"turkey\", \"t\u00fcrkiye\", \"turkiye\"],\n      \"CI\": [\"ivory coast\", \"cote d'ivoire\"],\n      \"CV\": [\"cape verde\", \"cabo verde\"],\n      \"MM\": [\"myanmar\", \"burma\"],\n      \"TL\": [\"east timor\", \"timor-leste\"],\n      \"SZ\": [\"eswatini\", \"swaziland\"],\n      \"MK\": [\"north macedonia\", \"macedonia\"],\n      \"KP\": [\"north korea\"],\n      \"RU\": [\"russia\", \"russian federation\"],\n      \"CD\": [\"dr congo\", \"drc\", \"congo kinshasa\"],\n      \"CG\": [\"congo brazzaville\"],\n      \"VA\": [\"vatican\", \"holy see\"],\n      \"LA\": [\"laos\"],\n      \"VN\": [\"vietnam\", \"viet nam\"],\n      \"IR\": [\"iran\", \"persia\"],\n      \"MO\": [\"macau\", \"macao\"],\n      \"HK\": [\"hong kong\"],\n      \"TW\": [\"taiwan\"],\n      \"GE\": [\"georgia\"],\n      \"MD\": [\"moldova\"],\n      \"BY\": [\"belarus\"]\n  };\n\n  const COUNTRIES = {\n    cat1: [\"CY\",\"CA\",\"FR\",\"FI\",\"BH\",\"AU\",\"AD\",\"SE\",\"DE\",\"SA\",\"AT\",\"BE\",\"HK\",\"MT\",\"IS\",\"SM\",\"NL\",\"DK\",\"TW\",\"AE\",\"US\",\"BN\",\"CH\",\"NO\",\"GY\",\"QA\",\"MO\",\"IE\",\"LU\",\"SG\",\"LI\",\"GB\",\"GB-SCT\"],\n    cat2: [\"KR\",\"ME\",\"CL\",\"TT\",\"MV\",\"UY\",\"BS\",\"OM\",\"SC\",\"MY\",\"PA\",\"TR\",\"LV\",\"GR\",\"KZ\",\"SK\",\"HU\",\"RU\",\"RO\",\"EE\",\"AW\",\"PT\",\"PR\",\"HR\",\"KW\",\"JP\",\"NZ\",\"PL\",\"IL\",\"ES\",\"LT\",\"SI\",\"CZ\",\"IT\"],\n    cat3: [\"BZ\",\"TN\",\"GT\",\"IQ\",\"ZA\",\"FJ\",\"EC\",\"LY\",\"ID\",\"VN\",\"BT\",\"DZ\",\"PE\",\"PW\",\"BW\",\"DM\",\"PY\",\"MD\",\"GQ\",\"MN\",\"VC\",\"IR\",\"GD\",\"EG\",\"CO\",\"SR\",\"TM\",\"BA\",\"BB\",\"BR\",\"AL\",\"AM\",\"GA\",\"MX\",\"AZ\",\"TH\",\"LC\",\"CN\",\"MK\",\"DO\",\"AG\",\"AR\",\"GE\",\"CR\",\"MU\",\"RS\",\"BY\",\"KN\",\"XK\",\"BG\"],\n    cat4: [\"UA\",\"BI\",\"SS\",\"CF\",\"YE\",\"MZ\",\"MW\",\"SO\",\"CD\",\"LR\",\"MG\",\"NE\",\"AF\",\"SD\",\"SB\",\"ML\",\"HT\",\"VU\",\"BF\",\"LS\",\"TD\",\"GW\",\"TG\",\"GM\",\"KI\",\"SL\",\"PG\",\"UG\",\"KM\",\"PS\",\"RW\",\"TZ\",\"ET\",\"ZM\",\"FM\",\"BJ\",\"GN\",\"TL\",\"MM\",\"SN\",\"CM\",\"TJ\",\"TV\",\"NP\",\"CG\",\"ST\",\"PK\",\"KE\",\"ZW\",\"MH\",\"HN\",\"TO\",\"CI\",\"WS\",\"GH\",\"VE\",\"KH\",\"MR\",\"KG\",\"NI\",\"NG\",\"DJ\",\"AO\",\"LA\",\"BD\",\"BO\",\"MA\",\"JO\",\"LB\",\"NR\",\"IN\",\"NA\",\"CV\",\"UZ\",\"PH\",\"SZ\",\"JM\",\"SV\",\"LK\"]\n  };\n\n  \/\/ Exakter Wortlaut aus dem Ecwid-Produkt \u2013 Abweichungen werden still verworfen.\n  const OPT_COMM_LANG = \"In welcher Sprache nimmst Du teil?\";\n  const OPT_ORG       = \"Name der Gruppe\/ Organisation\";\n\n  \/\/ \u2500\u2500 Shadow DOM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  const host = document.getElementById(\"gw-host-en\");\n  const shadow = host.attachShadow({ mode: \"open\" });\n\n  const styleEl = document.createElement(\"style\");\n  styleEl.textContent = `\n    :host {\n      display: block;\n      --bg:           #F5FAF6;\n      --card:         #FFFFFF;\n      --ink:          #0C1E14;\n      --ink-muted:    #27703F;\n      --accent:       #0C1E14;\n      --accent-light: #E6F2E8;\n      --border:       #C8E0CE;\n      --radius:       16px;\n      --radius-sm:    10px;\n    }\n    @keyframes wiz-spin { to { transform: rotate(360deg); } }\n\n    .gw-root {\n      font-family: 'Tinos', Georgia, serif;\n      font-size: 20px; font-weight: 400; color: var(--ink);\n      background: var(--bg); padding: 32px 20px;\n      display: flex; align-items: flex-start; justify-content: center;\n    }\n    .gw-card {\n      background: var(--card); border: 1px solid var(--border);\n      border-radius: 24px; padding: 36px 32px;\n      width: 100%; max-width: 860px;\n      box-shadow: 0 4px 24px rgba(12,30,20,0.08); box-sizing: border-box;\n    }\n    @media (max-width: 480px) {\n      .gw-root { padding: 16px 10px; }\n      .gw-card { padding: 24px 16px; border-radius: 16px; }\n    }\n\n    .gw-org-banner {\n      display: none; margin-bottom: 22px; padding: 12px 16px;\n      background: var(--accent-light); border: 1px solid rgba(12,30,20,0.15);\n      border-radius: var(--radius-sm); font-size: 18px; color: var(--accent);\n    }\n\n    .gw-progress { display: flex; gap: 8px; margin-bottom: 32px; }\n    .gw-progress-step { flex: 1; height: 4px; background: var(--border); border-radius: 999px; transition: background 0.35s; }\n    .gw-progress-step.active { background: var(--accent); }\n    .gw-progress-step.done   { background: var(--accent); opacity: 0.4; }\n\n    .gw-step-label { font-size: 12px; font-weight: 400; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-muted); margin-bottom: 10px; }\n    .gw-heading { font-size: 26px; font-weight: 500; line-height: 1.2; margin: 0 0 6px; color: var(--accent); letter-spacing: 0.01em; }\n    .gw-subtext { font-size: 18px; font-weight: 400; color: var(--ink-muted); margin: 0 0 28px; line-height: 1.6; }\n    .gw-label { display: block; font-size: 18px; font-weight: 700; margin-bottom: 6px; color: var(--ink); }\n    .gw-hint { font-size: 15px; color: var(--ink-muted); line-height: 1.5; margin: -4px 0 14px; }\n\n    .gw-select, .gw-text-input {\n      width: 100%; padding: 13px 15px;\n      border: 1px solid var(--border); border-radius: var(--radius-sm);\n      background: var(--bg);\n      font-family: 'Tinos', Georgia, serif; font-size: 18px; font-weight: 400; color: var(--ink);\n      transition: border-color 0.2s; box-sizing: border-box;\n    }\n    .gw-select {\n      appearance: none;\n      background-image: url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%2327703F' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'\/%3E%3C\/svg%3E\");\n      background-repeat: no-repeat; background-position: right 15px center;\n      cursor: pointer;\n    }\n    .gw-select:focus, .gw-text-input:focus {\n      outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(12,30,20,0.1);\n    }\n    .gw-text-input { margin-bottom: 14px; }\n\n    .gw-field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }\n    @media (max-width: 480px) { .gw-field-grid { grid-template-columns: 1fr; } }\n\n    .gw-redirect { display: none; margin-top: 12px; padding: 18px 20px; border-radius: var(--radius-sm); background: #FFF8F0; border: 1px solid rgba(180,80,0,0.2); font-size: 17px; line-height: 1.8; color: var(--ink); }\n    .gw-redirect strong { display: block; margin-bottom: 8px; font-size: 17px; color: #7A3500; }\n    .gw-redirect a { color: #27703F; text-decoration: underline; }\n\n    .gw-infobox {\n      margin-top: 12px; padding: 15px 17px; border-radius: var(--radius-sm);\n      background: var(--accent-light); border: 1px solid rgba(12,30,20,0.15);\n      font-size: 18px; font-weight: 400; line-height: 1.5;\n    }\n    .gw-infobox-title {\n      font-weight: 700; font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase;\n      color: var(--accent); margin-bottom: 3px;\n    }\n\n    .gw-pricetable { width: 100%; border-collapse: collapse; margin-top: 14px; font-size: 17px; }\n    .gw-pricetable th, .gw-pricetable td { text-align: left; padding: 9px 10px; border-bottom: 1px solid var(--border); }\n    .gw-pricetable th { font-weight: 700; font-size: 15px; color: var(--ink-muted); }\n    .gw-pricetable td:not(:first-child), .gw-pricetable th:not(:first-child) { text-align: right; }\n    .gw-pricetable .gw-price-old { color: var(--ink-muted); font-weight: 400; text-decoration: line-through; }\n    .gw-pricetable th.gw-price-old { text-decoration: none; }\n    .gw-pricetable .gw-price-new { font-weight: 700; color: var(--accent); }\n    .gw-pricetable tr:last-child td { border-bottom: 0; }\n\n    .gw-divider { border: 0; border-top: 1px solid var(--border); margin: 30px 0 24px; }\n\n    \/* \u2500\u2500 Teilnehmerliste \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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    .gw-p-head {\n      display: grid; grid-template-columns: 34px 1fr 1fr 1.4fr 120px 34px;\n      gap: 8px; padding: 0 2px 8px; font-size: 14px; font-weight: 700; color: var(--ink-muted);\n    }\n    .gw-p-row {\n      display: grid; grid-template-columns: 34px 1fr 1fr 1.4fr 120px 34px;\n      gap: 8px; align-items: center; margin-bottom: 8px;\n    }\n    .gw-p-num { font-size: 16px; color: var(--ink-muted); text-align: center; }\n    .gw-p-row input {\n      width: 100%; padding: 10px 11px; box-sizing: border-box;\n      border: 1px solid var(--border); border-radius: var(--radius-sm);\n      background: var(--bg); font-family: 'Tinos', Georgia, serif; font-size: 17px; color: var(--ink);\n      margin: 0;\n    }\n    .gw-p-row input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(12,30,20,0.1); }\n    .gw-p-row input.gw-invalid { border-color: #C46A6A; background: #FFF7F7; }\n    .gw-p-amount { text-align: right; font-weight: 700; }\n    .gw-p-remove {\n      border: 1px solid var(--border); background: var(--bg); color: var(--ink-muted);\n      border-radius: var(--radius-sm); width: 34px; height: 40px; cursor: pointer;\n      font-family: 'Tinos', Georgia, serif; font-size: 18px; line-height: 1; padding: 0;\n    }\n    .gw-p-remove:hover { border-color: #C46A6A; color: #8A1F1F; }\n    @media (max-width: 700px) {\n      .gw-p-head { display: none; }\n      .gw-p-row {\n        grid-template-columns: 1fr 1fr; gap: 8px;\n        padding: 14px; margin-bottom: 14px;\n        border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg);\n      }\n      .gw-p-num { grid-column: 1 \/ 2; text-align: left; font-weight: 700; color: var(--accent); }\n      .gw-p-remove { grid-column: 2 \/ 3; justify-self: end; }\n      .gw-p-row input { grid-column: 1 \/ 3; }\n      .gw-p-row input.gw-p-amount { grid-column: 1 \/ 3; text-align: left; }\n    }\n\n    .gw-bulk { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 22px; }\n    .gw-bulk > div { flex: 1; min-width: 180px; }\n    .gw-btn-ghost {\n      padding: 12px 18px; border-radius: var(--radius-sm); border: 1px solid var(--border);\n      background: var(--bg); font-family: 'Tinos', Georgia, serif; font-size: 17px;\n      color: var(--ink); cursor: pointer; transition: all 0.15s;\n    }\n    .gw-btn-ghost:hover { border-color: var(--accent); background: var(--accent-light); }\n\n    .gw-add-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; align-items: center; }\n    .gw-count { font-size: 16px; color: var(--ink-muted); margin-left: auto; }\n\n    .gw-summary-box { padding: 18px 20px; background: var(--accent-light); border: 1px solid rgba(12,30,20,0.2); border-radius: var(--radius-sm); margin-top: 20px; }\n    .gw-summary-row { display: flex; justify-content: space-between; align-items: center; padding: 5px 0; font-size: 17px; color: var(--ink); gap: 12px; }\n    .gw-summary-row.gw-summary-total { border-top: 1px solid rgba(12,30,20,0.25); margin-top: 8px; padding-top: 12px; font-weight: 700; font-size: 22px; color: var(--accent); }\n\n    .gw-list-preview { max-height: 260px; overflow-y: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); margin-top: 14px; }\n    .gw-list-preview-item { display: flex; justify-content: space-between; gap: 12px; padding: 9px 14px; border-bottom: 1px solid var(--border); font-size: 16px; }\n    .gw-list-preview-item:last-child { border-bottom: 0; }\n    .gw-list-preview-item span:last-child { font-weight: 700; white-space: nowrap; }\n\n    .gw-btn-row { display: flex; gap: 10px; margin-top: 24px; flex-wrap: wrap; }\n    .gw-btn { flex: 1; min-width: 140px; padding: 15px 17px; border-radius: var(--radius-sm); font-family: 'Tinos', Georgia, serif; font-size: 18px; font-weight: 700; cursor: pointer; transition: all 0.2s; border: 0; }\n    .gw-btn-primary { background: var(--accent); color: #fff; }\n    .gw-btn-primary:hover { background: #27703F; transform: translateY(-1px); }\n    .gw-btn-primary:disabled { opacity: 0.4; cursor: not-allowed; transform: none; }\n    .gw-btn-secondary { background: transparent; color: var(--ink); border: 1px solid var(--border); }\n    .gw-btn-secondary:hover { background: var(--bg); }\n\n    .gw-error { display: none; margin-top: 15px; padding: 13px 15px; border-radius: var(--radius-sm); background: #FFF3F3; border: 1px solid rgba(220,30,30,0.2); color: #8A1F1F; font-size: 18px; font-weight: 400; line-height: 1.5; white-space: pre-wrap; }\n    .wiz-spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid rgba(255,255,255,0.4); border-top-color: #fff; border-radius: 50%; animation: wiz-spin 0.7s linear infinite; vertical-align: middle; margin-right: 8px; }\n\n    .gw-country-search-wrap { position: relative; margin-bottom: 10px; }\n    .gw-country-search-icon { position: absolute; left: 18px; top: 50%; transform: translateY(-50%); color: var(--ink-muted); pointer-events: none; opacity: 0.5; }\n    .gw-country-search {\n      width: 100%; padding: 13px 15px 13px 54px;\n      border: 1px solid var(--border); border-radius: var(--radius-sm);\n      background: var(--bg); font-family: 'Tinos', Georgia, serif;\n      font-size: 18px; font-weight: 400; color: var(--ink);\n      transition: border-color 0.2s; box-sizing: border-box;\n    }\n    .gw-country-search:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(12,30,20,0.1); }\n    .gw-country-list { max-height: 240px; overflow-y: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); }\n    .gw-country-item { padding: 11px 15px; cursor: pointer; font-family: 'Tinos', Georgia, serif; font-size: 18px; font-weight: 400; display: flex; justify-content: space-between; align-items: center; transition: background 0.15s; border-bottom: 1px solid var(--border); }\n    .gw-country-item:last-child { border-bottom: 0; }\n    .gw-country-item:hover { background: var(--accent-light); }\n    .gw-country-item.selected { background: var(--accent-light); font-weight: 700; }\n    .gw-country-item-cat { font-size: 12px; color: var(--ink-muted); background: var(--border); padding: 2px 8px; border-radius: 999px; }\n    .gw-country-empty { padding: 15px; font-size: 18px; color: var(--ink-muted); text-align: center; }\n\n    .gw-final-list { margin: 0 0 28px; padding: 0; list-style: none; }\n    .gw-final-list li {\n      position: relative; padding: 0 0 0 30px; margin-bottom: 15px;\n      font-size: 18px; line-height: 1.6; color: var(--ink);\n    }\n    .gw-final-list li::before {\n      content: \"\"; position: absolute; left: 6px; top: 11px;\n      width: 7px; height: 7px; border-radius: 50%; background: var(--ink-muted);\n    }\n    .gw-final-list .gw-final-note { font-size: 16px; color: var(--ink-muted); }\n\n    .gw-coordinator {\n      display: flex; gap: 18px; align-items: center;\n      padding: 18px 20px; border-radius: var(--radius-sm);\n      background: var(--accent-light); border: 1px solid rgba(12,30,20,0.15);\n      font-size: 17px; line-height: 1.6;\n    }\n    .gw-coordinator-photo {\n      width: 84px; height: 84px; flex: 0 0 84px;\n      border-radius: 50%; overflow: hidden;\n      border: 2px solid #fff; background: var(--card);\n      box-shadow: 0 2px 8px rgba(12,30,20,0.12);\n    }\n    .gw-coordinator-photo img {\n      width: 100%; height: 100%; display: block;\n      object-fit: cover; object-position: center 22%;\n    }\n    \/* Feiner Zoom, damit die Gesichter den Kreis gut fuellen *\/\n    .gw-photo-susanne img { transform: scale(1.09); }\n    .gw-photo-andreas img { transform: scale(1.18); }\n    .gw-coordinator a { color: var(--ink-muted); text-decoration: underline; }\n    .gw-coordinator-photos { display: flex; gap: 14px; flex-shrink: 0; }\n    @media (max-width: 480px) {\n      .gw-coordinator { flex-direction: column; text-align: center; }\n    }\n\n    .gw-step { display: none; }\n    .gw-step.active { display: block; }\n  `;\n  shadow.appendChild(styleEl);\n\n  const wrapper = document.createElement(\"div\");\n  wrapper.innerHTML = `\n    <div class=\"gw-root\">\n      <div class=\"gw-card\">\n\n        <div class=\"gw-org-banner\" id=\"gw-org-banner\"><\/div>\n\n        <div class=\"gw-progress\">\n          <div class=\"gw-progress-step\" id=\"gw-prog-1\"><\/div>\n          <div class=\"gw-progress-step\" id=\"gw-prog-2\"><\/div>\n          <div class=\"gw-progress-step\" id=\"gw-prog-3\"><\/div>\n          <div class=\"gw-progress-step\" id=\"gw-prog-4\"><\/div>\n          <div class=\"gw-progress-step\" id=\"gw-prog-5\"><\/div>\n          <div class=\"gw-progress-step\" id=\"gw-prog-6\"><\/div>\n          <div class=\"gw-progress-step\" id=\"gw-prog-7\"><\/div>\n        <\/div>\n\n        <!-- STEP 1: WELCOME -->\n        <div class=\"gw-step active\" id=\"gw-step-welcome\">\n          <div class=\"gw-step-label\">Step 1 of 7<\/div>\n          <h2 class=\"gw-heading\">How lovely that you are joining as a group<\/h2>\n          <p class=\"gw-subtext\">\n            Here you can register your whole group in one go \u2013 one person enters everyone,\n            and you pay together.<br><br>\n            All you need is: the name of your organisation, your country, and the names and\n            e-mail addresses of the participants. You decide the contribution for each person\n            yourselves. This takes about five minutes.\n          <\/p>\n          <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-welcome-next\" style=\"width:100%;\">Start group registration<\/button>\n        <\/div>\n\n        <!-- STEP 2: ORGANISATION -->\n        <div class=\"gw-step\" id=\"gw-step-org\">\n          <div class=\"gw-step-label\">Step 2 of 7<\/div>\n          <h2 class=\"gw-heading\">Who is registering?<\/h2>\n          <p class=\"gw-subtext\">The name of your group will accompany you through the whole registration and will also appear on your confirmation.<\/p>\n\n          <label class=\"gw-label\">Name of the organisation or group<\/label>\n          <input class=\"gw-text-input\" type=\"text\" id=\"gw-org-name\" placeholder=\"e.g. Rudolf Steiner School Edinburgh\">\n\n          <hr class=\"gw-divider\">\n\n          <div class=\"gw-label\" style=\"margin-bottom:14px;\">Contact person<\/div>\n          <div class=\"gw-field-grid\">\n            <div><label class=\"gw-label\">First name<\/label><input class=\"gw-text-input\" type=\"text\" id=\"gw-kontakt-vorname\"><\/div>\n            <div><label class=\"gw-label\">Last name<\/label><input class=\"gw-text-input\" type=\"text\" id=\"gw-kontakt-nachname\"><\/div>\n          <\/div>\n          <label class=\"gw-label\">E-mail<\/label>\n          <p class=\"gw-hint\">Confirmation and invoice will be sent to this address.<\/p>\n          <input class=\"gw-text-input\" type=\"email\" id=\"gw-kontakt-email\">\n\n          <label class=\"gw-label\">Phone <span style=\"font-weight:400; color:var(--ink-muted);\">(optional)<\/span><\/label>\n          <input class=\"gw-text-input\" type=\"tel\" id=\"gw-kontakt-telefon\">\n\n          <div class=\"gw-error\" id=\"gw-error-org\"><\/div>\n\n          <div class=\"gw-btn-row\">\n            <button class=\"gw-btn gw-btn-secondary\" id=\"gw-btn-org-back\">Back<\/button>\n            <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-org-next\" disabled>Next<\/button>\n          <\/div>\n        <\/div>\n\n        <!-- STEP 3: COUNTRY + PRICES -->\n        <div class=\"gw-step\" id=\"gw-step-country\">\n          <div class=\"gw-step-label\">Step 3 of 7<\/div>\n          <h2 class=\"gw-heading\">Where are you based?<\/h2>\n          <p class=\"gw-subtext\">Our contributions are based on the cost of living in each country. Once you have selected your country, you will see your price range.<\/p>\n\n          <label class=\"gw-label\">Country<\/label>\n          <div class=\"gw-country-search-wrap\">\n            <svg class=\"gw-country-search-icon\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"11\" cy=\"11\" r=\"8\"\/><path d=\"m21 21-4.35-4.35\"\/><\/svg>\n            <input type=\"text\" class=\"gw-country-search\" id=\"gw-country-search\" placeholder=\"Search for country\u2026\" autocomplete=\"off\">\n          <\/div>\n          <div class=\"gw-country-list\" id=\"gw-country-list\"><\/div>\n          <input type=\"hidden\" id=\"gw-country\">\n\n          <div class=\"gw-infobox\" id=\"gw-catInfo\">\n            <div class=\"gw-infobox-title\">Price category<\/div>\n            <div id=\"gw-catText\">Please select a country first.<\/div>\n            <div id=\"gw-priceTableWrap\"><\/div>\n          <\/div>\n\n          <div class=\"gw-redirect\" id=\"gw-redirect-russia\">\n            <strong>For groups from Russia there is a separate way.<\/strong>\n            Our payment system is not available in Russia. Please write to us directly at\n            <a href=\"mailto:info@basic-exercises.com\">info@basic-exercises.com<\/a> \u2013 we will get back to you quickly.\n          <\/div>\n\n          <div class=\"gw-btn-row\">\n            <button class=\"gw-btn gw-btn-secondary\" id=\"gw-btn-country-back\">Back<\/button>\n            <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-country-next\" disabled>Next<\/button>\n          <\/div>\n        <\/div>\n\n        <!-- STEP 4: LANGUAGE + SHIPPING -->\n        <div class=\"gw-step\" id=\"gw-step-langship\">\n          <div class=\"gw-step-label\">Step 4 of 7<\/div>\n          <h2 class=\"gw-heading\">In which language are you participating?<\/h2>\n\n          <label class=\"gw-label\" for=\"gw-commLang\">In which language are you participating?<\/label>\n          <p class=\"gw-hint\">All participants in the group receive the materials in this language.<\/p>\n          <select class=\"gw-select\" id=\"gw-commLang\">\n            <option value=\"\" selected disabled>Please select\u2026<\/option>\n            <option value=\"Deutsch\">German<\/option>\n            <option value=\"Englisch\">English<\/option>\n            <option value=\"Spanisch\">Spanish<\/option>\n            <option value=\"Franz\u00f6sisch\">French<\/option>\n            <option value=\"Italienisch\">Italian<\/option>\n            <option value=\"Portugiesisch\">Portuguese<\/option>\n            <option value=\"Arabisch\">Arabic<\/option>\n            <option value=\"Hebr\u00e4isch\">Hebrew<\/option>\n            <option value=\"Farsi\">Farsi (Persian)<\/option>\n            <option value=\"Georgisch\">Georgian<\/option>\n            <option value=\"Russisch\">Russian<\/option>\n            <option value=\"Chinesisch\">Chinese<\/option>\n            <option value=\"Japanisch\">Japanese<\/option>\n            <option value=\"Koreanisch\">Korean<\/option>\n            <option value=\"Ukrainisch\">Ukrainian<\/option>\n            <option value=\"Niederl\u00e4ndisch\">Dutch<\/option>\n            <option value=\"T\u00fcrkisch\">Turkish<\/option>\n            <option value=\"Bulgarisch\">Bulgarian<\/option>\n            <option value=\"Vietnamesisch\">Vietnamese<\/option>\n          <\/select>\n\n          <div class=\"gw-infobox\" id=\"gw-apponly-note\" style=\"display:none; margin-top:14px;\">\n            <div class=\"gw-infobox-title\">Digital participation<\/div>\n            <div id=\"gw-apponly-note-text\"><\/div>\n          <\/div>\n\n          <div id=\"gw-shipping-block\" class=\"gw-infobox\" style=\"margin-top:26px;\">\n            <div class=\"gw-infobox-title\">Shipping<\/div>\n            <div>The card sets are sent as one parcel to a single address \u2013 you then hand them out locally. You will enter the delivery address at checkout.<\/div>\n          <\/div>\n\n          <div class=\"gw-error\" id=\"gw-error-langship\"><\/div>\n\n          <div class=\"gw-btn-row\">\n            <button class=\"gw-btn gw-btn-secondary\" id=\"gw-btn-langship-back\">Back<\/button>\n            <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-langship-next\" disabled>Next<\/button>\n          <\/div>\n        <\/div>\n\n        <!-- STEP 5: PARTICIPANTS -->\n        <div class=\"gw-step\" id=\"gw-step-people\">\n          <div class=\"gw-step-label\">Step 5 of 7<\/div>\n          <h2 class=\"gw-heading\">Who is taking part?<\/h2>\n          <p class=\"gw-subtext\" id=\"gw-people-intro\">\n            Please enter all participants here. Each person receives their own access at the\n            e-mail address given. You can set the contribution individually for each person \u2013\n            that way the group can balance out what each person is able to carry.\n          <\/p>\n\n          <div class=\"gw-infobox\" id=\"gw-range-note\" style=\"margin-bottom:22px;\"><\/div>\n\n          <div class=\"gw-bulk\">\n            <div>\n              <label class=\"gw-label\">Same amount for everyone<\/label>\n              <input class=\"gw-text-input\" type=\"number\" id=\"gw-bulk-amount\" style=\"margin-bottom:0;\">\n            <\/div>\n            <button class=\"gw-btn-ghost\" id=\"gw-bulk-apply\">Apply to all<\/button>\n          <\/div>\n\n          <div class=\"gw-p-head\">\n            <div><\/div><div>First name<\/div><div>Last name<\/div><div>E-mail<\/div><div style=\"text-align:right;\">Amount \u20ac<\/div><div><\/div>\n          <\/div>\n          <div id=\"gw-people-list\"><\/div>\n\n          <div class=\"gw-add-row\">\n            <button class=\"gw-btn-ghost\" id=\"gw-add-1\">+ Person<\/button>\n            <button class=\"gw-btn-ghost\" id=\"gw-add-5\">+ 5 people<\/button>\n            <button class=\"gw-btn-ghost\" id=\"gw-add-10\">+ 10 people<\/button>\n            <div class=\"gw-count\" id=\"gw-people-count\"><\/div>\n          <\/div>\n\n          <div class=\"gw-error\" id=\"gw-error-people\"><\/div>\n\n          <div class=\"gw-btn-row\">\n            <button class=\"gw-btn gw-btn-secondary\" id=\"gw-btn-people-back\">Back<\/button>\n            <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-people-next\">Next<\/button>\n          <\/div>\n        <\/div>\n\n        <!-- STEP 6: SUMMARY -->\n        <div class=\"gw-step\" id=\"gw-step-summary\">\n          <div class=\"gw-step-label\">Step 6 of 7<\/div>\n          <h2 class=\"gw-heading\">Everything at a glance<\/h2>\n          <p class=\"gw-subtext\">Please take a moment to look through it all. After that you will go to payment \u2013 you will enter the delivery address there.<\/p>\n\n          <div class=\"gw-list-preview\" id=\"gw-summary-people\"><\/div>\n\n          <div class=\"gw-summary-box\">\n            <div class=\"gw-summary-row\"><span>Participants<\/span><span id=\"gw-sum-count\">0<\/span><\/div>\n            <div class=\"gw-summary-row\"><span>Sum of contributions<\/span><span id=\"gw-sum-gross\">0\u20ac<\/span><\/div>\n            <div class=\"gw-summary-row\" id=\"gw-sum-ship-row\" style=\"display:none;\"><span>Shipping<\/span><span>15\u20ac<\/span><\/div>\n            <div class=\"gw-summary-row gw-summary-total\"><span>Total<\/span><span><span id=\"gw-sum-total\">0<\/span>\u20ac<\/span><\/div>\n          <\/div>\n\n          <div class=\"gw-error\" id=\"gw-error-summary\"><\/div>\n\n          <div class=\"gw-btn-row\">\n            <button class=\"gw-btn gw-btn-secondary\" id=\"gw-btn-summary-back\">Back<\/button>\n            <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-summary-next\">Next<\/button>\n          <\/div>\n        <\/div>\n\n        <!-- STEP 7: FINAL -->\n        <div class=\"gw-step\" id=\"gw-step-final\">\n          <div class=\"gw-step-label\">Step 7 of 7<\/div>\n          <h2 class=\"gw-heading\">The last step<\/h2>\n          <p class=\"gw-subtext\" id=\"gw-final-intro\"><\/p>\n\n          <div class=\"gw-final-list\" id=\"gw-final-list\"><\/div>\n\n          <div class=\"gw-coordinator\">\n            <div class=\"gw-coordinator-photos\">\n              <div class=\"gw-coordinator-photo gw-photo-susanne\">\n                <img decoding=\"async\" src=\"https:\/\/spiritual-activity.org\/wp-content\/uploads\/2026\/07\/Susanne_Schwaier.jpg\" alt=\"Susanne\">\n              <\/div>\n              <div class=\"gw-coordinator-photo gw-photo-andreas\">\n                <img decoding=\"async\" src=\"https:\/\/spiritual-activity.org\/wp-content\/uploads\/2026\/07\/Andreas-scaled.jpg\" alt=\"Andreas\">\n              <\/div>\n            <\/div>\n            <div class=\"gw-coordinator-text\">\n              <p style=\"margin:0 0 8px;\">We are looking forward to the time together with you.<\/p>\n              <p style=\"margin:0;\">If any questions come up along the way, Susanne and Andreas are here for you:<br>\n                <a href=\"mailto:susanne@spiritual-activity.org\">susanne@spiritual-activity.org<\/a>\n              <\/p>\n            <\/div>\n          <\/div>\n\n          <div class=\"gw-error\" id=\"gw-error-final\"><\/div>\n\n          <div class=\"gw-btn-row\">\n            <button class=\"gw-btn gw-btn-secondary\" id=\"gw-btn-final-back\">Back<\/button>\n            <button class=\"gw-btn gw-btn-primary\" id=\"gw-btn-checkout\">Complete registration<\/button>\n          <\/div>\n        <\/div>\n\n      <\/div>\n    <\/div>\n  `;\n  shadow.appendChild(wrapper);\n\n  const $ = (id) => shadow.getElementById(id);\n\n  const COUNTRY_TO_CAT = {};\n  Object.keys(COUNTRIES).forEach(cat => COUNTRIES[cat].forEach(code => COUNTRY_TO_CAT[code] = cat));\n\n  function getCountryName(code) {\n    if (COUNTRY_NAME_OVERRIDES[code]) return COUNTRY_NAME_OVERRIDES[code];\n    try { return new Intl.DisplayNames([\"en\"], { type: \"region\" }).of(code) || code; }\n    catch { return code; }\n  }\n\n  function getCountryAliases(code) {\n    const list = [];\n    if (COUNTRY_NAME_OVERRIDES[code]) {\n      try {\n        const intlName = new Intl.DisplayNames([\"en\"], { type: \"region\" }).of(code);\n        if (intlName) list.push(intlName.toLowerCase());\n      } catch {}\n    }\n    (COUNTRY_SEARCH_ALIASES[code] || []).forEach(a => list.push(a.toLowerCase()));\n    return list;\n  }\n\n  function getAllCountriesSorted() {\n    const all = [];\n    [\"cat1\",\"cat2\",\"cat3\",\"cat4\"].forEach(cat => {\n      COUNTRIES[cat]\n        .map(code => ({ code, name: getCountryName(code), cat, aliases: getCountryAliases(code) }))\n        .sort((a, b) => a.name.localeCompare(b.name, \"en\"))\n        .forEach(c => all.push(c));\n    });\n    return all;\n  }\n\n  function emptyPerson(amount) {\n    return { vorname: \"\", nachname: \"\", email: \"\", amount: amount || 0 };\n  }\n\n  const state = {\n    org: \"\", kontakt: { vorname: \"\", nachname: \"\", email: \"\", telefon: \"\" },\n    country: \"\", category: \"cat1\",\n    commLang: \"\",\n    people: [],\n    kontaktEingefuegt: false\n  };\n\n  function isAppOnly() {\n    const { category: cat, commLang: lang, country } = state;\n    if (cat === \"cat3\" || cat === \"cat4\") {\n      const exceptionLang = APP_ONLY_CATEGORY_EXCEPTION_LANG[country];\n      if (!exceptionLang || lang !== exceptionLang) return true;\n    }\n    if (APP_ONLY_LANGS.has(lang)) return true;\n    if (lang === \"Russisch\" && country && country !== \"RU\") return true;\n    return false;\n  }\n\n  function hasPhysicalShipment() { return !isAppOnly(); }\n\n  \/\/ Kauf auf Rechnung bieten wir nur Gruppen aus Deutschland an.\n  function rechnungMoeglich() { return state.country === \"DE\"; }\n\n  function getParticipationProductId() {\n    return hasPhysicalShipment() ? GRUPPEN_PRODUCT_ID : GRUPPEN_PRODUCT_ID_APPONLY;\n  }\n\n  \/\/ \u2500\u2500 Banner & Schritte \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function updateOrgBanner() {\n    const b = $(\"gw-org-banner\");\n    if (state.org.trim()) {\n      b.style.display = \"block\";\n      b.textContent = \"Group registration for \" + state.org.trim();\n    } else {\n      b.style.display = \"none\";\n    }\n  }\n\n  const STEP_CONTAINER = {\n    1: \"gw-step-welcome\",\n    2: \"gw-step-org\",\n    3: \"gw-step-country\",\n    4: \"gw-step-langship\",\n    5: \"gw-step-people\",\n    6: \"gw-step-summary\",\n    7: \"gw-step-final\"\n  };\n\n  function showStep(n) {\n    shadow.querySelectorAll(\".gw-step\").forEach(el => el.classList.remove(\"active\"));\n    $(STEP_CONTAINER[n]).classList.add(\"active\");\n    for (let i = 1; i <= 7; i++) {\n      const prog = $(\"gw-prog-\" + i);\n      if (!prog) continue;\n      if (i < n) prog.className = \"gw-progress-step done\";\n      else if (i === n) prog.className = \"gw-progress-step active\";\n      else prog.className = \"gw-progress-step\";\n    }\n    if (n === 5) { ensureInitialPeople(); renderRangeNote(); renderPeople(); }\n    if (n === 6) renderSummary();\n    if (n === 7) renderFinal();\n    const root = shadow.querySelector(\".gw-root\");\n    if (root && root.scrollIntoView) root.scrollIntoView({ block: \"start\", behavior: \"smooth\" });\n  }\n\n  function setNextEnabled(id, enabled) {\n    const b = $(id);\n    if (!b) return;\n    b.disabled = !enabled;\n    b.style.opacity = enabled ? \"1\" : \".4\";\n    b.style.cursor  = enabled ? \"pointer\" : \"not-allowed\";\n  }\n\n  function showErrorIn(id, msg) { const el=$(id); el.style.display=\"block\"; el.textContent=msg; }\n  function clearErrorIn(id)     { const el=$(id); el.style.display=\"none\";  el.textContent=\"\"; }\n\n  function setCheckoutLoading(loading) {\n    const btn = $(\"gw-btn-checkout\");\n    const overlay = document.getElementById(OVERLAY_ID);\n    if (!btn.dataset.defaultLabel) btn.dataset.defaultLabel = btn.textContent;\n    if (loading) {\n      btn.disabled = true;\n      btn.innerHTML = '<span class=\"wiz-spinner\"><\/span> Preparing\u2026';\n      btn.style.opacity = \".8\";\n      if (overlay) overlay.style.display = \"flex\";\n    } else {\n      btn.disabled = false;\n      btn.textContent = btn.dataset.defaultLabel;\n      btn.style.opacity = \"1\";\n      if (overlay) overlay.style.display = \"none\";\n    }\n  }\n\n  function showThankYou() {\n    const card = shadow.querySelector(\".gw-card\");\n    if (!card) return;\n    card.innerHTML = `\n      <div style=\"text-align:center; padding:20px 0;\">\n        <div style=\"font-size:56px; margin-bottom:16px; color:#27703F;\">\u2713<\/div>\n        <h2 style=\"font-family:'Tinos',Georgia,serif; font-size:26px; font-weight:500; margin:0 0 12px; color:#0C1E14;\">Thank you!<\/h2>\n        <p style=\"font-family:'Tinos',Georgia,serif; font-size:18px; color:#27703F; line-height:1.6; margin:0 0 24px;\">We have received your registration.<br>You will be redirected to the checkout shortly\u2026<\/p>\n        <div style=\"display:flex; justify-content:center;\">\n          <div style=\"width:36px; height:36px; border:4px solid #B8DEC4; border-top-color:#0C1E14; border-radius:50%; animation:wiz-spin 0.8s linear infinite;\"><\/div>\n        <\/div>\n      <\/div>`;\n  }\n\n  \/\/ \u2500\u2500 Schritt 2: Organisation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function validateOrg() {\n    const emailOk = \/\\S+@\\S+\\.\\S+\/.test(state.kontakt.email || \"\");\n    const ok = !!state.org.trim() && !!state.kontakt.vorname.trim() &&\n               !!state.kontakt.nachname.trim() && emailOk;\n    setNextEnabled(\"gw-btn-org-next\", ok);\n    return ok;\n  }\n\n  $(\"gw-org-name\").addEventListener(\"input\", e => {\n    state.org = e.target.value;\n    updateOrgBanner();\n    validateOrg();\n  });\n  [[\"vorname\",\"gw-kontakt-vorname\"],[\"nachname\",\"gw-kontakt-nachname\"],\n   [\"email\",\"gw-kontakt-email\"],[\"telefon\",\"gw-kontakt-telefon\"]].forEach(([key, id]) => {\n    $(id).addEventListener(\"input\", e => { state.kontakt[key] = e.target.value; validateOrg(); });\n  });\n\n  \/\/ \u2500\u2500 Schritt 3: Land \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function renderCountryList(filter) {\n    const list = $(\"gw-country-list\");\n    const q = (filter || \"\").toLowerCase().trim();\n    const filtered = q\n      ? getAllCountriesSorted().filter(c =>\n          c.name.toLowerCase().includes(q) ||\n          (c.aliases || []).some(a => a.includes(q))\n        )\n      : getAllCountriesSorted();\n    list.innerHTML = \"\";\n    if (!filtered.length) { list.innerHTML = '<div class=\"gw-country-empty\">No country found<\/div>'; return; }\n    filtered.forEach(c => {\n      const div = document.createElement(\"div\");\n      div.className = \"gw-country-item\" + (state.country === c.code ? \" selected\" : \"\");\n      div.dataset.code = c.code;\n      div.innerHTML = `<span>${c.name}<\/span><span class=\"gw-country-item-cat\">Cat. ${c.cat.replace(\"cat\",\"\")}<\/span>`;\n      div.addEventListener(\"click\", () => selectCountry(c.code, c.cat, c.name));\n      list.appendChild(div);\n    });\n  }\n\n  function renderPriceTable(cat) {\n    const g = ORIENTIERUNG[cat];\n    \/\/ Bei rein digitaler Teilnahme wird vom Einzelpreis regulaer die App-Pauschale\n    \/\/ abgezogen \u2013 nur so ist der Vergleich mit dem Gruppenpreis ehrlich.\n    const digital = isAppOnly();\n    const roh = NORMALPREIS[cat];\n    const n = digital\n      ? { reduced: roh.reduced - DIGITAL_ABZUG, base: roh.base - DIGITAL_ABZUG, support: roh.support - DIGITAL_ABZUG }\n      : roh;\n    const zeile = (label, normal, gruppe) => `\n        <tr>\n          <td>${label}<\/td>\n          <td class=\"gw-price-old\">${normal} \u20ac<\/td>\n          <td class=\"gw-price-new\">${gruppe} \u20ac<\/td>\n        <\/tr>`;\n    return `\n      <table class=\"gw-pricetable\">\n        <tr><th>Contribution per person<\/th><th class=\"gw-price-old\">Individually${digital ? \" (digital)\" : \"\"}<\/th><th class=\"gw-price-new\">As a group<\/th><\/tr>\n        ${zeile(\"Reduced contribution\",  n.reduced, g.reduced)}\n        ${zeile(\"Standard contribution\", n.base,    g.base)}\n        ${zeile(\"Support contribution\",  n.support, g.support)}\n      <\/table>\n      <div style=\"font-size:15px; line-height:1.6; margin-top:12px; color:var(--ink-muted);\">\n        Please choose individually what each single person would like to pay.\n        Do get in touch with us if the contributions are still too high \u2013 we will find\n        a solution together that works for you.\n      <\/div>`;\n  }\n\n  function selectCountry(code, cat, name) {\n    state.country  = code;\n    state.category = cat;\n    $(\"gw-country\").value = code;\n    $(\"gw-country-search\").value = name;\n    $(\"gw-country-list\").innerHTML = \"\";\n\n    const catLabels = { cat1:\"Price category 1\", cat2:\"Price category 2\", cat3:\"Price category 3\", cat4:\"Price category 4\" };\n    const exceptionLang = APP_ONLY_CATEGORY_EXCEPTION_LANG[code];\n    let suffix = \"\";\n    if (cat === \"cat3\" || cat === \"cat4\") {\n      suffix = exceptionLang\n        ? ` \u2013 shipping only possible for the participation language ${LANG_DISPLAY[exceptionLang] || exceptionLang}, otherwise digital participation`\n        : \" \u2013 in this region only digital participation is possible\";\n    }\n    $(\"gw-catText\").textContent = (catLabels[cat] || cat) + suffix;\n    $(\"gw-priceTableWrap\").innerHTML = renderPriceTable(cat);\n\n    const nachRussland = (code === \"RU\");\n    $(\"gw-redirect-russia\").style.display = nachRussland ? \"block\" : \"none\";\n    $(\"gw-catInfo\").style.display         = nachRussland ? \"none\"  : \"block\";\n    setNextEnabled(\"gw-btn-country-next\", !nachRussland);\n\n    \/\/ Betr\u00e4ge auf den neuen Grundbeitrag setzen, solange noch nichts angepasst wurde\n    const base = ORIENTIERUNG[cat].base;\n    state.people.forEach(p => { if (!p._touched) p.amount = base; });\n    $(\"gw-bulk-amount\").value = base;\n    updateAppOnlyUI();\n  }\n\n  $(\"gw-country-search\").addEventListener(\"input\", e => renderCountryList(e.target.value));\n  $(\"gw-country-search\").addEventListener(\"focus\", () => renderCountryList($(\"gw-country-search\").value));\n  shadow.addEventListener(\"click\", e => {\n    if (!e.target.closest(\"#gw-country-list\") && !e.target.closest(\"#gw-country-search\")) {\n      $(\"gw-country-list\").innerHTML = \"\";\n    }\n  });\n\n  \/\/ \u2500\u2500 Schritt 4: Sprache & Versand \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function updateAppOnlyUI() {\n    const appOnly = state.commLang ? isAppOnly() : false;\n    let reason = \"\";\n    if (appOnly) {\n      const exceptionLang = APP_ONLY_CATEGORY_EXCEPTION_LANG[state.country];\n      if ((state.category === \"cat3\" || state.category === \"cat4\") && exceptionLang) {\n        reason = `We can only ship to your region for the participation language ${LANG_DISPLAY[exceptionLang] || exceptionLang}. You therefore take part digitally \u2013 this is already reflected in the group contributions.`;\n      } else if (state.category === \"cat3\" || state.category === \"cat4\") {\n        reason = \"Unfortunately we cannot ship to your region. You therefore take part digitally \u2013 this is already reflected in the group contributions.\";\n      } else if (state.commLang === \"Russisch\") {\n        reason = \"For Russian speakers outside Russia the materials are only available digitally \u2013 this is already reflected in the group contributions.\";\n      } else {\n        reason = \"In this language the materials are only available digitally \u2013 this is already reflected in the group contributions.\";\n      }\n    }\n    const note = $(\"gw-apponly-note\");\n    note.style.display = appOnly ? \"block\" : \"none\";\n    $(\"gw-apponly-note-text\").textContent = reason;\n    $(\"gw-shipping-block\").style.display = appOnly ? \"none\" : \"block\";\n  }\n\n  $(\"gw-commLang\").addEventListener(\"change\", e => {\n    state.commLang = e.target.value;\n    updateAppOnlyUI();\n    setNextEnabled(\"gw-btn-langship-next\", !!state.commLang);\n  });\n\n  \/\/ \u2500\u2500 Schritt 5: Teilnehmende \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function ensureInitialPeople() {\n    const base = ORIENTIERUNG[state.category].base;\n    \/\/ Die Ansprechperson steht automatisch als erste Teilnehmerin in der Liste.\n    \/\/ Sie laesst sich wie jede andere Zeile wieder entfernen \u2013 dann kommt sie\n    \/\/ auch nicht zurueck.\n    if (!state.kontaktEingefuegt) {\n      const k = emptyPerson(base);\n      k.vorname  = state.kontakt.vorname.trim();\n      k.nachname = state.kontakt.nachname.trim();\n      k.email    = state.kontakt.email.trim();\n      state.people.unshift(k);\n      state.kontaktEingefuegt = true;\n    }\n    while (state.people.length < MIN_TEILNEHMER) state.people.push(emptyPerson(base));\n    if (!$(\"gw-bulk-amount\").value) $(\"gw-bulk-amount\").value = base;\n  }\n\n  function renderRangeNote() {\n    const g = ORIENTIERUNG[state.category], r = RANGES[state.category];\n    $(\"gw-range-note\").innerHTML = `\n      <div class=\"gw-infobox-title\">Your group prices<\/div>\n      <div>Standard contribution ${g.base} \u20ac \u00b7 reduced ${g.reduced} \u20ac \u00b7 support contribution ${g.support} \u20ac.\n      Anything between ${r.min} \u20ac and ${r.max} \u20ac per person is possible. If the contributions\n      are still too high, do get in touch with us \u2013 we will find a solution that works for you.<\/div>`;\n  }\n\n  function clampAmount(v) {\n    const r = RANGES[state.category];\n    let n = Number(v);\n    if (isNaN(n)) n = r.min;\n    return Math.min(r.max, Math.max(r.min, Math.round(n)));\n  }\n\n  function renderPeople() {\n    const list = $(\"gw-people-list\");\n    list.innerHTML = \"\";\n    state.people.forEach((p, i) => {\n      const row = document.createElement(\"div\");\n      row.className = \"gw-p-row\";\n      row.innerHTML = `\n        <div class=\"gw-p-num\">${i + 1}<\/div>\n        <input type=\"text\"   data-f=\"vorname\"  placeholder=\"First name\" value=\"${escapeAttr(p.vorname)}\">\n        <input type=\"text\"   data-f=\"nachname\" placeholder=\"Last name\"  value=\"${escapeAttr(p.nachname)}\">\n        <input type=\"email\"  data-f=\"email\"    placeholder=\"E-mail\"     value=\"${escapeAttr(p.email)}\">\n        <input type=\"number\" data-f=\"amount\" class=\"gw-p-amount\" value=\"${p.amount}\">\n        <button class=\"gw-p-remove\" title=\"Remove row\">\u00d7<\/button>\n      `;\n      row.querySelectorAll(\"input\").forEach(inp => {\n        const f = inp.dataset.f;\n        inp.addEventListener(\"input\", e => {\n          if (f === \"amount\") { p.amount = Number(e.target.value); p._touched = true; }\n          else p[f] = e.target.value;\n          inp.classList.remove(\"gw-invalid\");\n          updatePeopleCount();\n        });\n        if (f === \"amount\") {\n          inp.addEventListener(\"change\", e => {\n            p.amount = clampAmount(e.target.value);\n            e.target.value = p.amount;\n            updatePeopleCount();\n          });\n        }\n      });\n      row.querySelector(\".gw-p-remove\").addEventListener(\"click\", () => {\n        if (state.people.length <= 1) return;\n        state.people.splice(i, 1);\n        renderPeople();\n      });\n      list.appendChild(row);\n    });\n    updatePeopleCount();\n  }\n\n  function escapeAttr(s) { return String(s || \"\").replace(\/\"\/g, \"&quot;\"); }\n\n  function updatePeopleCount() {\n    const n = state.people.length;\n    const sum = state.people.reduce((a, p) => a + (Number(p.amount) || 0), 0);\n    const fehlend = MIN_TEILNEHMER - n;\n    $(\"gw-people-count\").textContent = fehlend > 0\n      ? `${n} people \u00b7 ${fehlend} more to reach the minimum of ${MIN_TEILNEHMER}`\n      : `${n} of max. ${MAX_TEILNEHMER} people \u00b7 total ${sum} \u20ac`;\n  }\n\n  function addPeople(n) {\n    const base = ORIENTIERUNG[state.category].base;\n    const bulk = Number($(\"gw-bulk-amount\").value);\n    const amount = clampAmount(isNaN(bulk) || !bulk ? base : bulk);\n    let added = 0;\n    for (let i = 0; i < n && state.people.length < MAX_TEILNEHMER; i++) {\n      state.people.push(emptyPerson(amount));\n      added++;\n    }\n    renderPeople();\n    if (added < n) showErrorIn(\"gw-error-people\", `We cannot take more than ${MAX_TEILNEHMER} people here. For larger groups please write to us at info@basic-exercises.com.`);\n    else clearErrorIn(\"gw-error-people\");\n  }\n\n  $(\"gw-add-1\").addEventListener(\"click\",  () => addPeople(1));\n  $(\"gw-add-5\").addEventListener(\"click\",  () => addPeople(5));\n  $(\"gw-add-10\").addEventListener(\"click\", () => addPeople(10));\n\n  $(\"gw-bulk-apply\").addEventListener(\"click\", () => {\n    const v = clampAmount($(\"gw-bulk-amount\").value);\n    $(\"gw-bulk-amount\").value = v;\n    state.people.forEach(p => { p.amount = v; p._touched = true; });\n    renderPeople();\n  });\n\n  function validatePeople() {\n    const emailOk = s => \/\\S+@\\S+\\.\\S+\/.test(s || \"\");\n    const r = RANGES[state.category];\n    let firstBad = -1;\n    state.people.forEach((p, i) => {\n      const bad = !p.vorname.trim() || !p.nachname.trim() || !emailOk(p.email) ||\n                  !(p.amount >= r.min && p.amount <= r.max);\n      if (bad && firstBad < 0) firstBad = i;\n    });\n    \/\/ doppelte E-Mails\n    const seen = new Set(); let dupe = \"\";\n    state.people.forEach(p => {\n      const e = (p.email || \"\").trim().toLowerCase();\n      if (e && seen.has(e)) dupe = e;\n      seen.add(e);\n    });\n    if (firstBad >= 0) {\n      markInvalid(firstBad);\n      return { ok: false, msg: `Please check row ${firstBad + 1}: first name, last name, a valid e-mail address and an amount between ${r.min} \u20ac and ${r.max} \u20ac.` };\n    }\n    if (dupe) return { ok: false, msg: `The e-mail address ${dupe} appears twice. Each person needs their own address for their access.` };\n    if (state.people.length < MIN_TEILNEHMER) {\n      return { ok: false, msg: `A group registration requires at least ${MIN_TEILNEHMER} people. For smaller groups please use the individual registration.` };\n    }\n    return { ok: true };\n  }\n\n  function markInvalid(index) {\n    const rows = shadow.querySelectorAll(\"#gw-people-list .gw-p-row\");\n    const row = rows[index];\n    if (!row) return;\n    const emailOk = s => \/\\S+@\\S+\\.\\S+\/.test(s || \"\");\n    const p = state.people[index];\n    const r = RANGES[state.category];\n    row.querySelectorAll(\"input\").forEach(inp => {\n      const f = inp.dataset.f;\n      let bad = false;\n      if (f === \"vorname\")  bad = !p.vorname.trim();\n      if (f === \"nachname\") bad = !p.nachname.trim();\n      if (f === \"email\")    bad = !emailOk(p.email);\n      if (f === \"amount\")   bad = !(p.amount >= r.min && p.amount <= r.max);\n      inp.classList.toggle(\"gw-invalid\", bad);\n    });\n    row.scrollIntoView({ block: \"center\", behavior: \"smooth\" });\n  }\n\n  $(\"gw-btn-people-next\").addEventListener(\"click\", () => {\n    const v = validatePeople();\n    if (!v.ok) return showErrorIn(\"gw-error-people\", v.msg);\n    clearErrorIn(\"gw-error-people\");\n    showStep(6);\n  });\n\n  \/\/ \u2500\u2500 Schritt 6: Zusammenfassung \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function computeTotals() {\n    const appOnly = isAppOnly();\n    const n = state.people.length;\n    const gross = state.people.reduce((a, p) => a + (Number(p.amount) || 0), 0);\n    const shipping = (hasPhysicalShipment() && needsShipping(state.country)) ? SHIPPING_COST : 0;\n    const total = gross + shipping;\n    return { n, gross, shipping, total, appOnly };\n  }\n\n  function renderSummary() {\n    const t = computeTotals();\n    const listEl = $(\"gw-summary-people\");\n    listEl.innerHTML = \"\";\n    state.people.forEach((p, i) => {\n      const div = document.createElement(\"div\");\n      div.className = \"gw-list-preview-item\";\n      div.innerHTML = `<span>${i + 1}. ${escapeHtml(p.vorname)} ${escapeHtml(p.nachname)} \u00b7 ${escapeHtml(p.email)}<\/span><span>${p.amount} \u20ac<\/span>`;\n      listEl.appendChild(div);\n    });\n\n    $(\"gw-sum-count\").textContent = t.n;\n    $(\"gw-sum-gross\").textContent = t.gross + \"\u20ac\";\n    $(\"gw-sum-ship-row\").style.display = t.shipping ? \"flex\" : \"none\";\n    $(\"gw-sum-total\").textContent = t.total;\n  }\n\n  \/\/ \u2500\u2500 Schritt 7: Abschluss \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function renderFinal() {\n    const t = computeTotals();\n    const vorname = state.kontakt.vorname.trim();\n\n    $(\"gw-final-intro\").textContent = vorname\n      ? `${vorname}, you are almost done. Here is a short overview of what happens next.`\n      : \"You are almost done. Here is a short overview of what happens next.\";\n\n    const zugangZeile = \"Once we have reviewed your group registration, every participant will receive everything at their own e-mail address: the invitation to the conference, the weekly letters and access to the app.\";\n    const versandZeile = t.appOnly\n      ? zugangZeile\n      : zugangZeile + \" The card sets will be sent as one parcel to the delivery address you enter in the shop.\";\n\n    $(\"gw-final-list\").innerHTML = `\n      <li>By clicking <strong>\u201cComplete registration\u201d<\/strong> you send us the details of all ${t.n} participants. The shop will then open.<\/li>\n      <li>In the shop you enter the billing and delivery address. Please add the name of your organisation or group to the billing address \u2013 that way we can match payment and registration reliably.<\/li>\n      <li>${versandZeile}<\/li>\n      <li>You can pay by ${rechnungMoeglich() ? \"credit card, PayPal or invoice\" : \"credit card or PayPal\"}.<\/li>\n      <li>The invoice is attached to the confirmation.<\/li>\n      <li class=\"gw-final-note\">Total amount: <strong>${t.total} \u20ac<\/strong> for ${t.n} participants${t.shipping ? \" (incl. shipping)\" : \"\"}.<\/li>\n    `;\n  }\n\n  function escapeHtml(s) {\n    return String(s || \"\").replace(\/[&<>\"']\/g, c => ({ \"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#39;\" }[c]));\n  }\n\n  \/\/ \u2500\u2500 Ecwid & n8n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  function ensureEcwidReady(timeoutMs = 12000) {\n    return new Promise((resolve, reject) => {\n      function isReady() {\n        return window.Ecwid && window.Ecwid.Cart &&\n               typeof window.Ecwid.Cart.addProduct === \"function\" &&\n               typeof window.Ecwid.Cart.clear === \"function\";\n      }\n      if (isReady()) return resolve(true);\n      let resolved = false;\n      function done() { if (!resolved) { resolved = true; setTimeout(() => resolve(true), 200); } }\n      if (window.Ecwid) { try { window.Ecwid.OnAPILoaded.add(done); } catch(e) {} }\n      const start = Date.now();\n      const t = setInterval(() => {\n        if (isReady()) { clearInterval(t); done(); }\n        else if (Date.now() - start > timeoutMs) {\n          clearInterval(t);\n          if (!resolved) { resolved = true; reject(new Error(\"Ecwid Cart API not available after \" + (timeoutMs\/1000) + \"s.\")); }\n        }\n      }, 200);\n    });\n  }\n\n  function clearCartAsync() { return new Promise(r => Ecwid.Cart.clear(() => r(true))); }\n\n  function addProductAsync(payload, timeoutMs = 4000) {\n    return new Promise((resolve, reject) => {\n      let done = false;\n      const t = setTimeout(() => { if (!done) { done = true; resolve({ product:null, cart:null, timedOut:true }); } }, timeoutMs);\n      Ecwid.Cart.addProduct(payload, function(success, product, cart, error) {\n        if (done) return;\n        done = true; clearTimeout(t);\n        if (success) resolve({ product, cart, timedOut:false });\n        else reject(new Error((error || \"Product could not be added\") + \" | Payload: \" + JSON.stringify(payload)));\n      });\n    });\n  }\n\n  function goToCart() { window.location.href = SHOP_CART_URL; }\n\n  function buildN8nPayload() {\n    const t = computeTotals();\n    return {\n      typ: \"gruppe\",\n      seite: _pageLang,\n      organisation: state.org.trim(),\n      ansprechperson: { ...state.kontakt },\n      land: state.country,\n      kategorie: state.category,\n      sprache: state.commLang,\n      appOnly: t.appOnly,\n      versandAn: t.appOnly ? \"kein_versand\" : \"sammel\",\n      anzahl: t.n,\n      rechnungMoeglich: rechnungMoeglich(),\n      teilnehmer: state.people.map(p => ({\n        vorname: p.vorname.trim(),\n        nachname: p.nachname.trim(),\n        email: p.email.trim(),\n        gewaehlt: Number(p.amount) || 0,\n        endbetrag: Number(p.amount) || 0\n      })),\n      summen: {\n        beitraege: t.gross,\n        versand: t.shipping,\n        gesamt: t.total\n      },\n      timestamp: new Date().toISOString()\n    };\n  }\n\n  async function sendToN8n(payload) {\n    if (!N8N_WEBHOOK_URL || N8N_WEBHOOK_URL.indexOf(\"HIER_\") === 0) {\n      throw new Error(\"The n8n webhook URL has not been configured in the code.\");\n    }\n    let res;\n    try {\n      res = await fetch(N8N_WEBHOOK_URL, { method:\"POST\", headers:{\"Content-Type\":\"application\/json\"}, body:JSON.stringify(payload) });\n    } catch (e) {\n      throw new Error(\"The data could not be submitted. Please check your internet connection and try again.\");\n    }\n    if (!res.ok) throw new Error(\"Submission failed (error \" + res.status + \"). Please try again.\");\n    return true;\n  }\n\n  async function goCheckout() {\n    clearErrorIn(\"gw-error-final\");\n    if (!state.country)  return showErrorIn(\"gw-error-final\", \"Please select your country first.\");\n    if (!state.commLang) return showErrorIn(\"gw-error-final\", \"Please select your participation language first.\");\n    const v = validatePeople();\n    if (!v.ok) return showErrorIn(\"gw-error-final\", v.msg);\n\n    const t = computeTotals();\n    const productId = getParticipationProductId();\n\n    setCheckoutLoading(true);\n    try {\n      await sendToN8n(buildN8nPayload());\n      await ensureEcwidReady();\n      await clearCartAsync();\n      await new Promise(r => setTimeout(r, 1500));\n\n      const options = {\n        [OPT_COMM_LANG]: state.commLang,\n        [OPT_ORG]: state.org.trim()\n      };\n\n      const priceWithoutShipping = t.gross;\n      const result = await addProductAsync({\n        id: productId, quantity: 1, selectedPrice: priceWithoutShipping, options\n      });\n      if (result.timedOut) console.warn(\"[Group wizard] addProduct timed out \u2013 proceeding to cart anyway\");\n      showThankYou();\n      setTimeout(goToCart, 2500);\n    } catch (e) {\n      showErrorIn(\"gw-error-final\", e.message || String(e));\n    } finally {\n      setCheckoutLoading(false);\n    }\n  }\n\n  \/\/ \u2500\u2500 Navigation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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  $(\"gw-btn-welcome-next\").addEventListener(\"click\", () => showStep(2));\n  $(\"gw-btn-org-back\").addEventListener(\"click\",     () => showStep(1));\n  $(\"gw-btn-org-next\").addEventListener(\"click\",     () => { if (validateOrg()) showStep(3); });\n  $(\"gw-btn-country-back\").addEventListener(\"click\", () => showStep(2));\n  $(\"gw-btn-country-next\").addEventListener(\"click\", () => showStep(4));\n  $(\"gw-btn-langship-back\").addEventListener(\"click\",() => showStep(3));\n  $(\"gw-btn-langship-next\").addEventListener(\"click\",() => showStep(5));\n  $(\"gw-btn-people-back\").addEventListener(\"click\",  () => showStep(4));\n  $(\"gw-btn-summary-back\").addEventListener(\"click\", () => showStep(5));\n  $(\"gw-btn-summary-next\").addEventListener(\"click\", () => showStep(7));\n  $(\"gw-btn-final-back\").addEventListener(\"click\",   () => showStep(6));\n  $(\"gw-btn-checkout\").addEventListener(\"click\", goCheckout);\n\n  showStep(1);\n\n})();\n<\/script>\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-a729569 e-flex e-con-boxed e-con e-parent\" data-id=\"a729569\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-aa6fd05 elementor-widget elementor-widget-shortcode\" data-id=\"aa6fd05\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><div id=\"dynamic-ec-store-container\" class=\"\"><!-- Ecwid shopping cart plugin v 7.0.9 --><!--noptimize--><script data-cfasync=\"false\" data-no-optimize=\"1\" src=\"https:\/\/app.ecwid.com\/script.js?89632828&data_platform=wporg&lang=zh\"><\/script><script data-cfasync=\"false\" data-no-optimize=\"1\">if (typeof jQuery !== undefined && jQuery.mobile) { jQuery.mobile.hashListeningEnabled = false; jQuery.mobile.pushStateEnabled=false; }<\/script><!--\/noptimize--><div id=\"ecwid-store-89632828\" class=\"ecwid-shopping-cart-product-browser\" data-ecwid-default-category-id=\"0\"><\/div><script data-cfasync=\"false\" data-no-optimize=\"1\" type=\"text\/javascript\">xProductBrowser(\"id=ecwid-store-89632828\",\"views=grid(20,3) list(60) table(60)\",\"default_page=\");<\/script><!-- END Ecwid Shopping Cart v 7.0.9 --><\/div>\n<\/div>\n\t\t\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-fdbddec e-con-full e-flex e-con e-parent\" data-id=\"fdbddec\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t<div class=\"elementor-element elementor-element-83ab53f e-con-full e-flex e-con e-child\" data-id=\"83ab53f\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2a1b8c3 elementor-widget elementor-widget-text-editor\" data-id=\"2a1b8c3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Institute for Spiritual Activity<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-bb96aaf e-con-full e-flex e-con e-child\" data-id=\"bb96aaf\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-8b23361 e-con-full e-flex e-con e-child\" data-id=\"8b23361\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6225ac5 elementor-widget elementor-widget-text-editor\" data-id=\"6225ac5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Datenschutz <span>\u00b7 Impressum \u00b7 AGB<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Gruppenanmeldung Gemeinschaft st\u00e4rken \u201eDer Einzelne hilft nicht, sondern wer sich mit vielen zur rechten Stunde vereinigt.\u201c Wir freuen uns, dass Ihr Euch als Gruppe anmelden wollt. Sei es als ein freier Arbeitskreis oder als Gemeinschaft innerhalb einer Institution. Gerade f\u00fcr Mitarbeitende in einer Institution, wie zum Beispiel in einem Waldorfkollegium, einer Hofgemeinschaft oder einem Unternehmen, [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-1284","page","type-page","status-publish","hentry","entry"],"_links":{"self":[{"href":"https:\/\/spiritual-activity.org\/zh\/wp-json\/wp\/v2\/pages\/1284","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spiritual-activity.org\/zh\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/spiritual-activity.org\/zh\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/spiritual-activity.org\/zh\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/spiritual-activity.org\/zh\/wp-json\/wp\/v2\/comments?post=1284"}],"version-history":[{"count":40,"href":"https:\/\/spiritual-activity.org\/zh\/wp-json\/wp\/v2\/pages\/1284\/revisions"}],"predecessor-version":[{"id":1345,"href":"https:\/\/spiritual-activity.org\/zh\/wp-json\/wp\/v2\/pages\/1284\/revisions\/1345"}],"wp:attachment":[{"href":"https:\/\/spiritual-activity.org\/zh\/wp-json\/wp\/v2\/media?parent=1284"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}