PageSourceSearch

https://www.alphadi.org/en/cart

html alphadi.org collected 2026-10-09 22:41:37 UTC 111,733 bytes, 2,201 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4
5    <meta charset="utf-8" />
6    <meta name="color-scheme" content="dark light">
7    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8    <title>Cart  |  Alphadi</title>
9    <meta name="description" content="Lean Six Sigma, Operational Excellence und Qualit&#xE4;tsmanagement: Alphadi bietet Weiterbildung, Zertifizierung, Coaching, Beratung und AlphadiTab Software f&#xFC;r Verbesserungsprojekte." />
10    <meta name="og:title" content="Cart  |  Alphadi" />
11    <meta name="og:description" content="Lean Six Sigma, Operational Excellence und Qualit&#xE4;tsmanagement: Alphadi bietet Weiterbildung, Zertifizierung, Coaching, Beratung und AlphadiTab Software f&#xFC;r Verbesserungsprojekte." />
12    <meta name="og:type" content="website" />
13    <meta name="og:locale" content="en" />
14
15    <link rel="icon" href="/img/favicon.ico" sizes="any">
16    <link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png">
17    
18    <link rel="preconnect" href="https://fonts.googleapis.com">
19    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
20    <link rel="stylesheet" href="/bundles/hp-styles.css?v=_0Jinmn5XM4Jg2spIz_GA6SmJGHyq_C09ckEcirX2Nk" />
21    <link rel="stylesheet" href="/lib/katex/katex.min.css?v=7NQzvryVCIQkViOS3GPdLDyHtm1nHMrm7xzxO09F158" />
22    <style>
23        /* Mobile nav sheet: ALL top-level items look identical, whether or not they have sub-levels.
24           The plain links (Home, Events, …) are adjusted to match the dropdown group-triggers
25           (Akademie, Consulting, …) — uppercase section-header style. Inline so it always wins
26           over the prebuilt hp-styles bundle (which the browser may cache). */
27        .nav__sheet-link,
28        .nav__sheet-group-trigger {
29            font-family: var(--f-ui);
30            font-size: 0.72rem;
31            font-weight: 700;
32            letter-spacing: 0.5px; /* matches desktop, reduced from the old 0.12em */
33            text-transform: uppercase;
34            color: var(--c-subtle);
35        }
36        .nav__sheet-link { border-left: none; }
37        .nav__sheet-link:hover,
38        .nav__sheet-link.is-active { color: var(--c-dark); background: none; }
39        /* "Request a date" inquiry link (training/event booking box). It's a bare <button>, so with
40           color-scheme:dark light the browser paints its text white in OS dark mode and it vanishes.
41           Force it orange in every mode/device. Inline so it wins over the cached hp-styles bundle. */
42        .btn-link-inline {
43            background: none;
44            border: none;
45            padding: 0;
46            font: inherit;
47            color: var(--c-orange) !important;
48            font-weight: 600;
49            text-decoration: underline;
50            cursor: pointer;
51        }
52        .btn-link-inline:hover { color: var(--c-orange) !important; opacity: 0.8; }
53        /* Per-date "By invoice" inquiry toggle in the training/event booking box. Clicking
54           "By invoice" expands an inline note whose "Inquire here" link opens the request
55           modal. Inline so it wins over the cached hp-styles bundle (which dotnet build
56           does not regenerate). */
57        .date-item--two-row { flex-direction: column; align-items: stretch; gap: 0; }
58        .date-item--two-row .date-item__top {
59            display: flex; align-items: center; justify-content: space-between;
60            gap: 1rem; flex-wrap: wrap; width: 100%;
61        }
62        .date-item__actions { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
63        .date-invoice-body {
64            flex-basis: 100%;
65            display: grid; grid-template-rows: 0fr;
66            transition: grid-template-rows 0.25s ease;
67        }
68        .date-item.is-open .date-invoice-body { grid-template-rows: 1fr; }
69        .date-invoice-content { overflow: hidden; }
70        .date-invoice-content p {
71            font-family: var(--f-ui); font-size: 0.8rem; color: var(--c-dark); line-height: 1.6;
72            margin: 0.75rem 0 0; padding-top: 0.75rem; border-top: 1px solid var(--c-border);
73        }
74        .link-btn {
75            background: none; border: none; padding: 0; margin: 0; font: inherit;
76            color: var(--c-orange) !important; text-decoration: underline; cursor: pointer;
77        }
78        .link-btn:hover { opacity: 0.8; }
79        /* Two-row date item: date + action buttons on top, location on its own row below, so the
80           buttons always have room even with a long location. Inline so it wins over the cached
81           hp-styles bundle (which dotnet build does not regenerate). */
82        .date-item--two-row { flex-direction: column; align-items: stretch; gap: 0; }
83        .date-item--two-row .date-item__top { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; width: 100%; }
84        .date-item--two-row .date-item__loc { margin-top: 0.25rem; }
85        :root {
86    color-scheme: dark light;
87}
88        /* Logo strip is dark so the WHITE logo stays visible in light AND force-dark mode.
89           The white logo has a declared filter (filter:none) so browser force-dark won't re-invert it. */
90        .account-menu { position: relative; display: flex; align-items: center; }
91        .account-menu__chevron { flex-shrink: 0; transition: transform var(--t-base); }
92        .account-menu.is-open .account-menu__chevron { transform: rotate(180deg); }
93        .account-menu__dropdown {
94            position: absolute; top: calc(100% + 0.75rem); right: 0;
95            background: var(--c-white); border: 1px solid var(--c-border);
96            border-radius: 6px; padding: 0.5rem; width: 300px;
97            box-shadow: 0 8px 24px rgba(0,0,0,.12);
98            opacity: 0; pointer-events: none; transform: translateY(-4px);
99            transition: opacity 0.18s ease, transform 0.18s ease; z-index: 1100;
100        }
101        .account-menu__dropdown::before {
102            content: ''; position: absolute; top: -5px; right: 13px;
103            width: 9px; height: 9px; background: #fff;
104            border-top: 1px solid var(--c-border); border-left: 1px solid var(--c-border);
105            border-radius: 2px 0 0 0; transform: rotate(45deg);
106        }
107        .account-menu.is-open .account-menu__dropdown { opacity: 1; pointer-events: all; transform: translateY(0); }
108        .account-menu__body { display: flex; flex-direction: column; gap: 1rem; padding: 0.5rem 0.5rem 0.75rem; }
109        .account-menu__lead { display: flex; align-items: center; gap: 0.75rem; font-family: var(--f-ui), sans-serif; font-size: 1rem; line-height: 1.5; color: var(--c-dark); margin: 0; }
110        .account-menu__lead-icon { color: var(--c-orange); flex: 1 1 25%; min-width: 0; display: flex; justify-content: center; }
111        .account-menu__lead-text { flex: 3 3 75%; min-width: 0; }
112        .account-menu__actions { display: flex; flex-direction: column; gap: 0.5rem; }
113        .account-menu__actions .btn { width: 100%; justify-content: center; }
114        .nav__sheet-account { display: flex; flex-direction: column; gap: 0.5rem; padding: 0.5rem 0 0.375rem; }
115        .nav__sheet-account-lead { font-family: var(--f-ui), sans-serif; font-size: 0.9rem; line-height: 1.5; color: var(--c-subtle); margin: 0 0 0.25rem; }
116        .nav__sheet-account .btn { width: 100%; justify-content: center; }
117    </style>
118    
118<script src="/bundles/hp-plugins.min.js"></script>
118
119
120    
121
122        <style>#training-modules {
123background-color: #efefef;
124}
125
126section[class*="hero-padded"] {
127  padding-top: 114px;
128}
129.hero {
130  position: relative; background: var(--c-bg-warm); overflow: hidden;
131  padding-bottom: 4rem;
132}
133
134section[class*="sa-hero"] {
135  padding-top: 190px;
136}
137
138
139:root {
140  color-scheme: light only;
141}
142
143@media (prefers-color-scheme: dark) {
144  :root {
145    color-scheme: light only;
146  }
147}
148
149.sa-freetext-wrap textarea {
150
151    color: #555555 !important;
152
153}
154#cartPageContent::after {
155  content: "";
156  display: block;
157  width: 100%;
158  max-width: 420px;
159  aspect-ratio: 3 / 4;
160  margin: 3rem auto 0;
161  background: url("https://www.alphadi.org/image/1705") center / contain no-repeat;
162}
163
164html[lang="en"] #cartPageContent::after { background-image: url("https://www.alphadi.org/image/1706"); }
165html[lang="es"] #cartPageContent::after { background-image: url("https://www.alphadi.org/image/1707"); }
166html[lang="fr"] #cartPageContent::after { background-image: url("https://www.alphadi.org/image/1708"); }
167html[lang="it"] #cartPageContent::after { background-image: url("https://www.alphadi.org/image/1709"); }
168html[lang="pl"] #cartPageContent::after { background-image: url("https://www.alphadi.org/image/1710"); }
169html[lang="pt"] #cartPageContent::after { background-image: url("https://www.alphadi.org/image/1711"); }</style>
170</head>
171
172<body class="">
173    <!-- Floating alerts -->
174
175    <!-- ═══════ NAVIGATION ═══════ -->
176    <nav class="nav nav--white nav--two-row" id="mainNav">
177        <!-- Row 1: topbar (desktop only) -->
178        <div class="nav__row--top-wrap">
179            <div class="nav__row--top">
180                <div class="nav__row--top-right">
181                        <div class="lang-switch" id="topbarLangSwitch">
182                            <button class="lang-switch__btn" type="button" aria-haspopup="true">
183                                EN
184                                <svg viewBox="0 0 10 6" fill="none" stroke="currentColor">
185                                    <path d="M1 1L5 5L9 1" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
186                                </svg>
187                            </button>
188                            <div class="lang-switch__dropdown">
189                                    <form method="post" style="margin:0;padding:0;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
190                                        <button type="submit" name="culture" value="de-DE"
191                                                class="lang-switch__opt ">
192                                            DE — German
193                                        </button>
194                                    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
195                                    <form method="post" style="margin:0;padding:0;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
196                                        <button type="submit" name="culture" value="en-US"
197                                                class="lang-switch__opt is-active">
198                                            EN — English
199                                        </button>
200                                    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
201                                    <form method="post" style="margin:0;padding:0;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
202                                        <button type="submit" name="culture" value="es-ES"
203                                                class="lang-switch__opt ">
204                                            ES — Spanish
205                                        </button>
206                                    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
207                                    <form method="post" style="margin:0;padding:0;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
208                                        <button type="submit" name="culture" value="it-IT"
209                                                class="lang-switch__opt ">
210                                            IT — Italian
211                                        </button>
212                                    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
213                                    <form method="post" style="margin:0;padding:0;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
214                                        <button type="submit" name="culture" value="fr-FR"
215                                                class="lang-switch__opt ">
216                                            FR — French
217                                        </button>
218                                    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
219                                    <form method="post" style="margin:0;padding:0;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
220                                        <button type="submit" name="culture" value="pl-PL"
221                                                class="lang-switch__opt ">
222                                            PL — Polish
223                                        </button>
224                                    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
225                                    <form method="post" style="margin:0;padding:0;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
226                                        <button type="submit" name="culture" value="pt-PT"
227                                                class="lang-switch__opt ">
228                                            PT — Portuguese
229                                        </button>
230                                    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
231                            </div>
232                        </div>
233
234                        <div class="account-menu" id="accountMenu">
235                            <button class="nav__login-btn" id="accountMenuBtn" type="button" aria-haspopup="true" aria-expanded="false" aria-label="Account">
236                                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/></svg>
237                                Account
238                                <svg class="account-menu__chevron" width="10" height="10" viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
239                            </button>
240                            <div class="account-menu__dropdown">
241                                <div class="account-menu__body">
242                                    <div class="account-menu__lead">
243                                        <div class="account-menu__lead-icon">
244                                            <svg width="42" height="42" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/></svg>
245                                        </div>
246                                        <div class="account-menu__lead-text">Log in into your shop account or create a new one.</div>
247                                    </div>
248                                    <div class="account-menu__actions">
249                                        <a class="btn btn--primary" href="/Internal/Account/Login?returnUrl=~%2Fen%2Fcart">
250                                            Login
251                                        </a>
252                                        <a class="btn btn--outline" href="/Internal/Account/Register?returnUrl=~%2Fen%2Fcart">
253                                            Create account
254                                        </a>
255                                    </div>
256                                </div>
257                            </div>
258                        </div>
259                    
260                    <button class="cart-btn" id="cartNavBtn" aria-label="Cart">
261                        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 2L3 6v14a2 2 0 002 2h14a2 2 0 002-2V6l-3-4z" /><line x1="3" y1="6" x2="21" y2="6" /><path d="M16 10a4 4 0 01-8 0" /></svg>
262                        <span class="cart-badge">0</span>
263                    </button>
264                </div>
265            </div>
266        </div>
267
268        <!-- Row 2: main nav bar -->
269        <div class="nav__inner">
270            <a class="nav__logo" style="flex-shrink:0;" href="/en">
271                    <img src="/img/logo_f.svg" alt="Alphadi" />
272            </a>
273
274            <button class="nav__toggle" id="sheetToggle" aria-label="Menu">
275                <svg class="menu-icon" viewBox="0 0 32 32" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" width="22" height="22">
276                    <path class="menu-icon__morph" d="M27 10 13 10C10.8 10 9 8.2 9 6 9 3.5 10.8 2 13 2 15.2 2 17 3.8 17 6L17 26C17 28.2 18.8 30 21 30 23.2 30 25 28.2 25 26 25 23.8 23.2 22 21 22L7 22"/>
277                    <path d="M7 16 27 16"/>
278                </svg>
279            </button>
280
281            <div class="nav__menu">
282                        <div class="nav__item nav__link ">
283                            <button class="nav__dropdown-trigger">
284                                Academy
285                                <svg viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
286                            </button>
287
288                            <div class="nav__dropdown">
289                                    <a href="/en/workshops" class="nav__dropdown-item ">
290                                        <div class="nav__dropdown-icon">
291                                                <img src="/image/1164" alt="" width="25" height="25" style="object-fit:contain;">
292                                        </div>
293                                        <div>
294                                            <div class="nav__dropdown-text-title">Further training &amp; seminars</div>
295                                                <div class="nav__dropdown-text-desc"><p>Internationally certified &ndash; with access to the Excellence Program.</p>
296</div>
297                                        </div>
298                                    </a>
299                                    <a href="/en/excellence-program" class="nav__dropdown-item ">
300                                        <div class="nav__dropdown-icon">
301                                                <img src="/image/1180" alt="" width="25" height="25" style="object-fit:contain;">
302                                        </div>
303                                        <div>
304                                            <div class="nav__dropdown-text-title">Excellence Program</div>
305                                                <div class="nav__dropdown-text-desc"><p>Internationally recognized certifications for professionals and executives</p>
306</div>
307                                        </div>
308                                    </a>
309                                    <a href="/en/coaching" class="nav__dropdown-item ">
310                                        <div class="nav__dropdown-icon">
311                                                <img src="/image/1167" alt="" width="25" height="25" style="object-fit:contain;">
312                                        </div>
313                                        <div>
314                                            <div class="nav__dropdown-text-title">Coaching &amp; Consulting</div>
315                                                <div class="nav__dropdown-text-desc"><p>Individual support for companies and executives &ndash; on demand</p>
316</div>
317                                        </div>
318                                    </a>
319                                    <a href="/en/shingo-model" class="nav__dropdown-item ">
320                                        <div class="nav__dropdown-icon">
321                                                <img src="/image/1178" alt="" width="25" height="25" style="object-fit:contain;">
322                                        </div>
323                                        <div>
324                                            <div class="nav__dropdown-text-title">Shingo Model&#x2122;</div>
325                                                <div class="nav__dropdown-text-desc"><p>Systemically develop operational excellence &mdash; with culture, behavior, and leadership as the foundation.</p>
326</div>
327                                        </div>
328                                    </a>
329                            </div>
330                        </div>
331                        <a href="/en/events" class="nav__link ">Events</a>
332                        <div class="nav__item nav__link ">
333                            <button class="nav__dropdown-trigger">
334                                Consulting
335                                <svg viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
336                            </button>
337
338                            <div class="nav__dropdown">
339                                    <a href="/en/benchmarking" class="nav__dropdown-item ">
340                                        <div class="nav__dropdown-icon">
341                                                <img src="/image/1165" alt="" width="25" height="25" style="object-fit:contain;">
342                                        </div>
343                                        <div>
344                                            <div class="nav__dropdown-text-title">Benchmarking</div>
345                                                <div class="nav__dropdown-text-desc"><p>Identify potential improvements in processes, structures, and collaboration.</p>
346</div>
347                                        </div>
348                                    </a>
349                                    <a href="/en/culture-development-system-explained" class="nav__dropdown-item ">
350                                        <div class="nav__dropdown-icon">
351                                                <img src="/image/1713" alt="" width="25" height="25" style="object-fit:contain;">
352                                        </div>
353                                        <div>
354                                            <div class="nav__dropdown-text-title">What is the Culture Development System?</div>
355                                                <div class="nav__dropdown-text-desc"><p>Develop culture purposefully</p>
356</div>
357                                        </div>
358                                    </a>
359                                    <a href="/en/excellence-community" class="nav__dropdown-item ">
360                                        <div class="nav__dropdown-icon">
361                                                <img src="/image/1181" alt="" width="25" height="25" style="object-fit:contain;">
362                                        </div>
363                                        <div>
364                                            <div class="nav__dropdown-text-title">Excellence Community</div>
365                                                <div class="nav__dropdown-text-desc"><p>Network, refresh knowledge, and exchange best practices.</p>
366</div>
367                                        </div>
368                                    </a>
369                                    <a href="/en/talent-development" class="nav__dropdown-item ">
370                                        <div class="nav__dropdown-icon">
371                                                <img src="/image/1173" alt="" width="25" height="25" style="object-fit:contain;">
372                                        </div>
373                                        <div>
374                                            <div class="nav__dropdown-text-title">Talent development</div>
375                                                <div class="nav__dropdown-text-desc"><p>Strengthen employees in a targeted manner &ndash; for performance, change, and competitiveness.</p>
376</div>
377                                        </div>
378                                    </a>
379                                    <a href="/en/opex-roll-out" class="nav__dropdown-item ">
380                                        <div class="nav__dropdown-icon">
381                                                <img src="/image/1170" alt="" width="25" height="25" style="object-fit:contain;">
382                                        </div>
383                                        <div>
384                                            <div class="nav__dropdown-text-title">OPEX Roll-out</div>
385                                                <div class="nav__dropdown-text-desc"><p>Effectively roll out OPEX &ndash; for less waste and more sustainable impact.</p>
386</div>
387                                        </div>
388                                    </a>
389                            </div>
390                        </div>
391                        <div class="nav__item nav__link ">
392                            <button class="nav__dropdown-trigger">
393                                Products
394                                <svg viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
395                            </button>
396
397                            <div class="nav__dropdown">
398                                    <a href="/en/products/books" class="nav__dropdown-item ">
399                                        <div class="nav__dropdown-icon">
400                                                <img src="/image/1166" alt="" width="25" height="25" style="object-fit:contain;">
401                                        </div>
402                                        <div>
403                                            <div class="nav__dropdown-text-title">Publications</div>
404                                                <div class="nav__dropdown-text-desc"><p>Books, case studies, and booklets for process managers and organizations.</p>
405</div>
406                                        </div>
407                                    </a>
408                                    <a href="/en/products/tools-templates" class="nav__dropdown-item ">
409                                        <div class="nav__dropdown-icon">
410                                                <img src="/image/1184" alt="" width="25" height="25" style="object-fit:contain;">
411                                        </div>
412                                        <div>
413                                            <div class="nav__dropdown-text-title">Tools</div>
414                                                <div class="nav__dropdown-text-desc"><p>Handouts, plots, and presentations for Lean &amp; LSS &mdash; ready to use.</p>
415</div>
416                                        </div>
417                                    </a>
418                                    <a href="/en/products/workshops" class="nav__dropdown-item ">
419                                        <div class="nav__dropdown-icon">
420                                                <img src="/image/1293" alt="" width="25" height="25" style="object-fit:contain;">
421                                        </div>
422                                        <div>
423                                            <div class="nav__dropdown-text-title">Workshops</div>
424                                                <div class="nav__dropdown-text-desc"><p>Interactive formats for targeted awareness and knowledge transfer &ndash; compact and practical.</p>
425</div>
426                                        </div>
427                                    </a>
428                            </div>
429                        </div>
430                        <div class="nav__item nav__link ">
431                            <button class="nav__dropdown-trigger">
432                                Software
433                                <svg viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
434                            </button>
435
436                            <div class="nav__dropdown">
437                                    <a href="/en/support" class="nav__dropdown-item ">
438                                        <div class="nav__dropdown-icon">
439                                                <img src="/image/1172" alt="" width="25" height="25" style="object-fit:contain;">
440                                        </div>
441                                        <div>
442                                            <div class="nav__dropdown-text-title">Support</div>
443                                                <div class="nav__dropdown-text-desc"><p>Everything about documentation, help, and support for our software solutions</p>
444</div>
445                                        </div>
446                                    </a>
447                                    <a href="/en/alphadi-tab" class="nav__dropdown-item ">
448                                        <div class="nav__dropdown-icon">
449                                                <img src="/image/1169" alt="" width="25" height="25" style="object-fit:contain;">
450                                        </div>
451                                        <div>
452                                            <div class="nav__dropdown-text-title">AlphadiTab</div>
453                                                <div class="nav__dropdown-text-desc"><p>Project management software for problem solving</p>
454</div>
455                                        </div>
456                                    </a>
457                            </div>
458                        </div>
459                        <div class="nav__item nav__link ">
460                            <button class="nav__dropdown-trigger">
461                                About us
462                                <svg viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
463                            </button>
464
465                            <div class="nav__dropdown">
466                                    <a href="/en/career" class="nav__dropdown-item ">
467                                        <div class="nav__dropdown-icon">
468                                                <img src="/image/1416" alt="" width="25" height="25" style="object-fit:contain;">
469                                        </div>
470                                        <div>
471                                            <div class="nav__dropdown-text-title">Career </div>
472                                                <div class="nav__dropdown-text-desc"><p>Open positions at Alphadi &ndash; flat hierarchies, real responsibility, and room for professional development.</p>
473</div>
474                                        </div>
475                                    </a>
476                                    <a href="/en/ueber-uns" class="nav__dropdown-item ">
477                                        <div class="nav__dropdown-icon">
478                                                <img src="/image/1182" alt="" width="25" height="25" style="object-fit:contain;">
479                                        </div>
480                                        <div>
481                                            <div class="nav__dropdown-text-title">Meet the Team</div>
482                                                <div class="nav__dropdown-text-desc"><p>Get to know the people who shape Alphadi with heart and experience.</p>
483</div>
484                                        </div>
485                                    </a>
486                                    <a href="/en/glossary" class="nav__dropdown-item ">
487                                        <div class="nav__dropdown-icon">
488                                                <img src="/image/216" alt="" width="25" height="25" style="object-fit:contain;">
489                                        </div>
490                                        <div>
491                                            <div class="nav__dropdown-text-title">Glossary</div>
492                                                <div class="nav__dropdown-text-desc"><p>Terms, definitions and important technical terms explained at a glance.</p>
493</div>
494                                        </div>
495                                    </a>
496                            </div>
497                        </div>
498
499
500            </div>
501
502                <a href="/en/contact" class="nav__cta nav__cta--desktop">Contact</a>
503        </div>
504    </nav>
505
506    <!-- Backdrop -->
507    <div class="nav__sheet-overlay" id="sheetOverlay"></div>
508
509    <!-- Right-side nav sheet -->
510    <div class="nav__sheet" id="navSheet">
511        <div class="nav__sheet-header">
512            <div class="nav__sheet-logo">
513                <a href="/en">
514                        <img src="/img/logo_f.svg" alt="Alphadi" style="height:35px;width:auto;" />
515                </a>
516            </div>
517            <button class="nav__sheet-close" id="sheetClose" aria-label="Close menu">
518                <svg viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
519                    <path d="M1 1l12 12M13 1L1 13"/>
520                </svg>
521            </button>
522        </div>
523
524        <div class="nav__sheet-body">
525
526            <a class="nav__sheet-link " href="/en">Home</a>
527
528                    <button class="nav__sheet-group-trigger" type="button">
529                        <span>Academy</span>
530                        <svg viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
531                    </button>
532                    <div class="nav__sheet-sub">
533                            <a href="/en/workshops" class="nav__sheet-sub-item">
534                                <div class="nav__sheet-sub-icon">
535                                        <img src="/image/1164" alt="" width="20" height="20" style="object-fit:contain;">
536                                </div>
537                                Further training &amp; seminars
538                            </a>
539                            <a href="/en/excellence-program" class="nav__sheet-sub-item">
540                                <div class="nav__sheet-sub-icon">
541                                        <img src="/image/1180" alt="" width="20" height="20" style="object-fit:contain;">
542                                </div>
543                                Excellence Program
544                            </a>
545                            <a href="/en/coaching" class="nav__sheet-sub-item">
546                                <div class="nav__sheet-sub-icon">
547                                        <img src="/image/1167" alt="" width="20" height="20" style="object-fit:contain;">
548                                </div>
549                                Coaching &amp; Consulting
550                            </a>
551                            <a href="/en/shingo-model" class="nav__sheet-sub-item">
552                                <div class="nav__sheet-sub-icon">
553                                        <img src="/image/1178" alt="" width="20" height="20" style="object-fit:contain;">
554                                </div>
555                                Shingo Model&#x2122;
556                            </a>
557                    </div>
558                    <a href="/en/events" class="nav__sheet-link ">Events</a>
559                    <button class="nav__sheet-group-trigger" type="button">
560                        <span>Consulting</span>
561                        <svg viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
562                    </button>
563                    <div class="nav__sheet-sub">
564                            <a href="/en/benchmarking" class="nav__sheet-sub-item">
565                                <div class="nav__sheet-sub-icon">
566                                        <img src="/image/1165" alt="" width="20" height="20" style="object-fit:contain;">
567                                </div>
568                                Benchmarking
569                            </a>
570                            <a href="/en/culture-development-system-explained" class="nav__sheet-sub-item">
571                                <div class="nav__sheet-sub-icon">
572                                        <img src="/image/1713" alt="" width="20" height="20" style="object-fit:contain;">
573                                </div>
574                                What is the Culture Development System?
575                            </a>
576                            <a href="/en/excellence-community" class="nav__sheet-sub-item">
577                                <div class="nav__sheet-sub-icon">
578                                        <img src="/image/1181" alt="" width="20" height="20" style="object-fit:contain;">
579                                </div>
580                                Excellence Community
581                            </a>
582                            <a href="/en/talent-development" class="nav__sheet-sub-item">
583                                <div class="nav__sheet-sub-icon">
584                                        <img src="/image/1173" alt="" width="20" height="20" style="object-fit:contain;">
585                                </div>
586                                Talent development
587                            </a>
588                            <a href="/en/opex-roll-out" class="nav__sheet-sub-item">
589                                <div class="nav__sheet-sub-icon">
590                                        <img src="/image/1170" alt="" width="20" height="20" style="object-fit:contain;">
591                                </div>
592                                OPEX Roll-out
593                            </a>
594                    </div>
595                    <button class="nav__sheet-group-trigger" type="button">
596                        <span>Products</span>
597                        <svg viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
598                    </button>
599                    <div class="nav__sheet-sub">
600                            <a href="/en/products/books" class="nav__sheet-sub-item">
601                                <div class="nav__sheet-sub-icon">
602                                        <img src="/image/1166" alt="" width="20" height="20" style="object-fit:contain;">
603                                </div>
604                                Publications
605                            </a>
606                            <a href="/en/products/tools-templates" class="nav__sheet-sub-item">
607                                <div class="nav__sheet-sub-icon">
608                                        <img src="/image/1184" alt="" width="20" height="20" style="object-fit:contain;">
609                                </div>
610                                Tools
611                            </a>
612                            <a href="/en/products/workshops" class="nav__sheet-sub-item">
613                                <div class="nav__sheet-sub-icon">
614                                        <img src="/image/1293" alt="" width="20" height="20" style="object-fit:contain;">
615                                </div>
616                                Workshops
617                            </a>
618                    </div>
619                    <button class="nav__sheet-group-trigger" type="button">
620                        <span>Software</span>
621                        <svg viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
622                    </button>
623                    <div class="nav__sheet-sub">
624                            <a href="/en/support" class="nav__sheet-sub-item">
625                                <div class="nav__sheet-sub-icon">
626                                        <img src="/image/1172" alt="" width="20" height="20" style="object-fit:contain;">
627                                </div>
628                                Support
629                            </a>
630                            <a href="/en/alphadi-tab" class="nav__sheet-sub-item">
631                                <div class="nav__sheet-sub-icon">
632                                        <img src="/image/1169" alt="" width="20" height="20" style="object-fit:contain;">
633                                </div>
634                                AlphadiTab
635                            </a>
636                    </div>
637                    <button class="nav__sheet-group-trigger" type="button">
638                        <span>About us</span>
639                        <svg viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
640                    </button>
641                    <div class="nav__sheet-sub">
642                            <a href="/en/career" class="nav__sheet-sub-item">
643                                <div class="nav__sheet-sub-icon">
644                                        <img src="/image/1416" alt="" width="20" height="20" style="object-fit:contain;">
645                                </div>
646                                Career 
647                            </a>
648                            <a href="/en/ueber-uns" class="nav__sheet-sub-item">
649                                <div class="nav__sheet-sub-icon">
650                                        <img src="/image/1182" alt="" width="20" height="20" style="object-fit:contain;">
651                                </div>
652                                Meet the Team
653                            </a>
654                            <a href="/en/glossary" class="nav__sheet-sub-item">
655                                <div class="nav__sheet-sub-icon">
656                                        <img src="/image/216" alt="" width="20" height="20" style="object-fit:contain;">
657                                </div>
658                                Glossary
659                            </a>
660                    </div>
661
662
663
664                <div class="nav__sheet-divider"></div>
665                <button class="nav__sheet-group-trigger" type="button" aria-haspopup="true" aria-expanded="false">
666                    <span>
667                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:.35rem;"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/></svg>
668                        Account
669                    </span>
670                    <svg viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
671                </button>
672                <div class="nav__sheet-sub">
673                    <div class="nav__sheet-account">
674                        <p class="nav__sheet-account-lead">Log in into your shop account or create a new one.</p>
675                        <a class="btn btn--primary" href="/Internal/Account/Login?returnUrl=~%2Fen%2Fcart">Login</a>
676                        <a class="btn btn--outline" href="/Internal/Account/Register?returnUrl=~%2Fen%2Fcart">Create account</a>
677                    </div>
678                </div>
679
680                <div class="nav__sheet-divider"></div>
681                <button class="nav__sheet-group-trigger" id="sheetLangTrigger" type="button">
682                    <span>
683                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:.35rem;"><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
684                        Language
685                    </span>
686                    <svg viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
687                </button>
688                <div class="nav__sheet-sub" id="sheetLangSub">
689                        <form method="post" style="margin:0;padding:0;display:contents;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
690                            <button type="submit" name="culture" value="de-DE"
691                                    class="nav__sheet-sub-item ">
692                                DE — German
693                            </button>
694                        <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
695                        <form method="post" style="margin:0;padding:0;display:contents;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
696                            <button type="submit" name="culture" value="en-US"
697                                    class="nav__sheet-sub-item is-active">
698                                EN — English
699                            </button>
700                        <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
701                        <form method="post" style="margin:0;padding:0;display:contents;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
702                            <button type="submit" name="culture" value="es-ES"
703                                    class="nav__sheet-sub-item ">
704                                ES — Spanish
705                            </button>
706                        <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
707                        <form method="post" style="margin:0;padding:0;display:contents;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
708                            <button type="submit" name="culture" value="it-IT"
709                                    class="nav__sheet-sub-item ">
710                                IT — Italian
711                            </button>
712                        <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
713                        <form method="post" style="margin:0;padding:0;display:contents;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
714                            <button type="submit" name="culture" value="fr-FR"
715                                    class="nav__sheet-sub-item ">
716                                FR — French
717                            </button>
718                        <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
719                        <form method="post" style="margin:0;padding:0;display:contents;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
720                            <button type="submit" name="culture" value="pl-PL"
721                                    class="nav__sheet-sub-item ">
722                                PL — Polish
723                            </button>
724                        <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
725                        <form method="post" style="margin:0;padding:0;display:contents;" action="/Home/SetLanguage?returnUrl=~%2Fen%2Fcart">
726                            <button type="submit" name="culture" value="pt-PT"
727                                    class="nav__sheet-sub-item ">
728                                PT — Portuguese
729                            </button>
730                        <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BIMwQTuEtBBtnnpT6fmYEKb6v25N11wuRzX0I64UnyPw-C7gZWLT11sxHWNTmQhtTiInNS7UPupdXQdYVRE6gQ_4u1wV71CUdofocXJdktLpstz1i59LCQiVkSbBohFHDcEK07xWddynYgIWADfKi8" /></form>
731                </div>
732        </div>
733
734            <div class="nav__sheet-footer">
735                <a href="/en/contact">Contact</a>
736            </div>
737    </div>
738
739    <!-- ═══════ MAIN ═══════ -->
740    
741<div class="page-hero">
742    <div class="container">
743        <nav class="breadcrumb">
744            <a href="/en">Home</a>
745            <span>/</span>
746            <span style="color:rgba(0,0,0,.45);">Cart</span>
747        </nav>
748        <h1 class="page-hero__title">Cart</h1>
749    </div>
750</div>
751
752<section class="section bg-white">
753    <div class="container">
754
755        <div id="cartPageNotice" style="display:none;max-width:640px;margin:0 auto 1.5rem;"
756             data-msg-title="Your cart was updated"
757             data-msg-removed="{name} is no longer available and was removed."
758             data-msg-repriced="Price of {name} changed to {price}."></div>
759
760        <div id="cartPageEmpty" style="display:none;text-align:center;padding:4rem 1rem;">
761            <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="var(--c-border)" stroke-width="1.5" style="margin-bottom:1.5rem;"><path d="M6 2L3 6v14a2 2 0 002 2h14a2 2 0 002-2V6l-3-4z"/><line x1="3" y1="6" x2="21" y2="6"/><path d="M16 10a4 4 0 01-8 0"/></svg>
762            <p style="font-family:var(--f-ui);font-size:1.1rem;color:var(--c-mid);margin-bottom:2rem;">Your cart is empty.</p>
763            <a href="/en" class="btn btn--primary">Continue shopping</a>
764        </div>
765
766        <div id="cartPageContent" style="display:none;">
767            <div class="cart-page-layout">
768
769                <!-- Items table -->
770                <div class="cart-page-items">
771                    <div class="cart-page-table-head">
772                        <span>Product</span>
773                        <span style="text-align:center;">Quantity</span>
774                        <span style="text-align:right;">Price</span>
775                    </div>
776                    <div id="cartPageRows"></div>
777                </div>
778
779                <!-- Order summary -->
780                <div class="cart-page-summary">
781                    <h2 class="cart-page-summary__title">Order summary</h2>
782                    <div class="cart-page-summary__rows" id="cartPageSummaryRows"></div>
783                    <div class="cart-page-summary__total">
784                        <span>Total</span>
785                        <span id="cartPageTotal">0,00 €</span>
786                    </div>
787                    <a href="/en/checkout" class="btn btn--primary btn--lg" style="width:100%;justify-content:center;margin-top:1.5rem;">
788                        Proceed to checkout →
789                    </a>
790                    <a href="/en" class="btn btn--ghost" style="width:100%;justify-content:center;margin-top:0.75rem;">
791                        ← Continue shopping
792                    </a>
793                </div>
794
795            </div>
796        </div>
797
798    </div>
799</section>
800
801
802
803
804    <!-- ═══════ FOOTER ═══════ -->
805<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
806<title></title>
807<link href="https://api.fontshare.com" rel="preconnect" />
808<link href="https://fonts.googleapis.com" rel="preconnect" />
809<link href="https://api.fontshare.com/v2/css?f[]=satoshi@300,400,500,600,700,900&amp;display=swap" rel="stylesheet" />
810<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@300;400;500;600;700&amp;display=swap" rel="stylesheet" />
811<style type="text/css">*, *::before, *::after {
812  box-sizing: border-box;
813  margin: 0;
814  padding: 0;
815  }
816  html {
817    font-size: 16px;
818  }
819  body {
820    font-family: 'Satoshi', system-ui, sans-serif;
821    -webkit-font-smoothing: antialiased;
822  }
823  a {
824    color: inherit;
825    text-decoration: none;
826  }
827  img {
828    max-width: 100%;
829    display: block;
830  }
831  .footer-v2 {
832    background: #111111;
833    position: relative;
834    overflow: hidden;
835  }
836  .footer-v2::before {
837    content: '';
838    position: absolute;
839    top: 0;
840    left: 0;
841    right: 0;
842    height: 3px;
843    background: linear-gradient(90deg, #111111, #EC841F, #1a0a00);
844  }
845  .footer-v2::after {
846    content: '';
847    position: absolute;
848    top: -120px;
849    left: -80px;
850    width: 500px;
851    height: 500px;
852    border-radius: 50%;
853    background: radial-gradient(circle, rgba(236,132,31,.07) 0%, transparent 65%);
854    pointer-events: none;
855  }
856  .footer-v2__inner {
857    max-width: 1280px;
858    margin: 0 auto;
859    padding: 4rem 3rem 0;
860  }
861  @media (max-width: 767px) {
862    .footer-v2__inner {
863      padding: 3rem 1.5rem 0;
864    }
865  }
866  .footer-v2__top {
867    display: grid;
868    grid-template-columns: 1.6fr 2.4fr;
869    gap: 4rem;
870    padding-bottom: 3rem;
871    border-bottom: 1px solid rgba(255,255,255,.08);
872  }
873  @media (max-width: 767px) {
874    .footer-v2__top {
875      grid-template-columns: 1fr;
876      gap: 2.5rem;
877    }
878  }
879  .footer-v2__brand img {
880    height: 56px;
881    width: auto;
882    margin-bottom: 2rem;
883    filter: none !important;
884    /* Prevents browser dark mode from inverting the white logo to black */
885    forced-color-adjust: none;
886    /* Exclude logo from automatic color adjustment (Dark Mode/High Contrast) */
887  }
888  .footer-v2__claim {
889    font-family: 'Satoshi', system-ui, sans-serif;
890    font-size: clamp(1.15rem, 1.8vw, 1.45rem);
891    font-weight: 700;
892    color: #ffffff;
893    line-height: 1.35;
894    letter-spacing: -0.02em;
895    margin-bottom: 1.5rem;
896    max-width: 280px;
897  }
898  .footer-v2__claim em {
899    font-style: normal;
900    color: #EC841F;
901  }
902  .footer-v2__contact {
903    display: flex;
904    flex-direction: column;
905    gap: 0.4rem;
906  }
907  .footer-v2__contact a {
908    display: flex;
909    align-items: center;
910    gap: 0.5rem;
911    font-family: 'Satoshi', system-ui, sans-serif;
912    font-size: 0.78rem;
913    color: rgba(255,255,255,.88);
914    text-decoration: none;
915    transition: color 0.15s;
916    font-weight: 400;
917    letter-spacing: 0.8px;
918  }
919  .footer-v2__contact a:hover {
920    color: #EC841F;
921  }
922  .footer-v2__contact svg {
923    flex-shrink: 0;
924    opacity: .6;
925  }
926  .footer-v2__links {
927    display: grid;
928    grid-template-columns: repeat(3, 1fr);
929    gap: 2rem;
930    padding-top: 0.25rem;
931  }
932  @media (max-width: 479px) {
933    .footer-v2__links {
934      grid-template-columns: repeat(2, 1fr);
935    }
936  }
937  .footer-v2__col h4 {
938    font-family: 'Satoshi', system-ui, sans-serif;
939    font-size: 0.65rem;
940    font-weight: 700;
941    letter-spacing: 0.14em;
942    text-transform: uppercase;
943    color: #ffffff;
944    margin-bottom: 1rem;
945  }
946  .footer-v2__col a {
947    display: block;
948    font-family: 'Satoshi', system-ui, sans-serif;
949    font-size: 0.78rem;
950    color: rgba(255,255,255,.88);
951    margin-bottom: 0.5rem;
952    text-decoration: none;
953    transition: color 0.15s, padding-left 0.15s;
954    font-weight: 300;
955    letter-spacing: 0.8px;
956  }
957  .footer-v2__col a:hover {
958    color: #fff;
959    padding-left: 3px;
960  }
961  .footer-v2__bottom {
962    max-width: 1280px;
963    margin: 0 auto;
964    padding: 1.25rem 3rem;
965    border-top: 1px solid rgba(255,255,255,.14);
966    display: flex;
967    flex-wrap: wrap;
968    justify-content: space-between;
969    align-items: center;
970    gap: 0.75rem;
971  }
972  @media (max-width: 767px) {
973    .footer-v2__bottom {
974      padding: 1.25rem 1.5rem;
975      flex-direction: column;
976      align-items: flex-start;
977    }
978  }
979  .footer-v2__copy {
980    font-family: 'Satoshi', system-ui, sans-serif;
981    font-size: 0.75rem;
982    color: rgba(255,255,255,.88);
983  }
984  .footer-v2__socials {
985    display: flex;
986    align-items: center;
987    gap: 0.5rem;
988  }
989  .footer-v2__social {
990    width: 36px;
991    height: 36px;
992    display: flex;
993    align-items: center;
994    justify-content: center;
995    border: 1px solid rgba(255,255,255,.5);
996    border-radius: 8px;
997    color: rgba(255,255,255,.9);
998    text-decoration: none;
999    transition: border-color 0.15s, color 0.15s, background 0.15s;
1000  }
1001  .footer-v2__social:hover {
1002    border-color: #EC841F;
1003    color: #EC841F;
1004    background: rgba(236,132,31,.08);
1005  }
1006  .footer-v2__social svg {
1007    width: 14px;
1008    height: 14px;
1009  }
1010</style>
1011<footer class="footer-v2">
1012<div class="footer-v2__inner">
1013<div class="footer-v2__top">
1014<div class="footer-v2__brand">
1015<a href="/"><img alt="Alphadi" src="/image/222" /></a>
1016
1017<p class="footer-v2__claim">We focus on<br />
1018<em>people</em>.</p>
1019
1020<div class="footer-v2__contact">
1021<a href="tel:+4956194918900"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1022              <path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.68 12a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.59 1.23h3a2 2 0 0 1 2 1.72c.128.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 8.87a16 16 0 0 0 6 6l.87-.87a2 2 0 0 1 2.11-.45c.907.339 1.85.572 2.81.7A2 2 0 0 1 22 16.92z"/>
1023            </svg>+49 561 949 189 0</a>
1024
1025<a href="mailto:[email protected]"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1026              <path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/>
1027              <polyline points="22,6 12,13 2,6"/>
1028            </svg>[email protected]</a>
1029</div>
1030</div>
1031
1032<div class="footer-v2__links">
1033<div class="footer-v2__col">
1034<h4>Programs</h4>
1035
1036<a href="/en/workshops">Workshops &amp; Seminars</a>
1037
1038<a href="/en/events">Events</a>
1039
1040<a href="/en/assessments">Assessments</a>
1041
1042<a href="/en/support">Software Support &amp; Help</a>
1043</div>
1044
1045<div class="footer-v2__col">
1046<h4>Company</h4>
1047
1048<a href="/en/ueber-uns">About us</a>
1049
1050<a href="/en/contact">Contact</a>
1051
1052<a href="/en/career">Career</a>
1053</div>
1054
1055<div class="footer-v2__col">
1056<h4>Legal</h4>
1057
1058<a href="/en/privacy-policy">Privacy Policy</a>
1059
1060<a href="/en/t&amp;c">Terms and Conditions</a>
1061
1062<a href="/en/imprint">Imprint</a>
1063
1064<a href="/en/cancellation-policy">Revoke Contract Here</a>
1065
1066<a href="/en/shipping-payment-terms">Shipping &amp; Payment</a>
1067</div>
1068</div>
1069</div>
1070
1071<div class="footer-v2__bottom"><span class="footer-v2__copy">&copy; 2026 Alphadi Deutschland GmbH. All rights reserved.</span>
1072
1073<div class="footer-v2__socials">
1074<a aria-label="YouTube" class="footer-v2__social" href="#"><svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16">
1075            <path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/>
1076          </svg></a>
1077
1078<a aria-label="LinkedIn" class="footer-v2__social" href="#"><svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16">
1079            <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
1080          </svg></a>
1081</div>
1082</div>
1083</div>
1084</footer>
1085
1086    
1086<script>
1087        // Shared price formatter — mirrors DecimalUtils.PriceDisplay (German format, e.g. "6.600,00 €").
1088        // Used by every client-side price render (cart drawer, cart page, checkout, product options).
1089        window.formatPrice = function (value, symbol) {
1090            var n = Number(value);
1091            if (!isFinite(n)) { n = 0; }
1092            var number = n.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
1093            return number + ' ' + (symbol || '€');
1094        };
1095    </script>
1095
1096    
1096<script src="/bundles/hp-scripts.min.js?v=ZHApbpWBMcSvjokQcwPZYptpuVDzcPqCftH9nsYyTTE"></script>
1096
1097    
1097<script src="/js/cart-sync.js?v=9IsathfVPUw6nubjgrQKNjXkyoTVZ-DBaj0qJNKNn8w"></script>
1097
1098
1099    <!-- KaTeX: render LaTeX math anywhere in the page content (delimiters \( \), \[ \], $$ $$) -->
1100    
1100<script src="/lib/katex/katex.min.js?v=3ISyluw-iE3gkxWPdg_Z1Ftser5YtTgVV_ThOPRqWK4"></script>
1100
1101    
1101<script src="/lib/katex/contrib/auto-render.min.js?v=nLjaz8CGwpZsnsS6VPSi3EO3y-KzPOwaJ0PYhsf7R6c"></script>
1101
1102    
1102<script>
1103
1104
1105    (function () {
1106        function renderMath() {
1107            if (typeof renderMathInElement !== 'function') { return; }
1108            renderMathInElement(document.body, {
1109                delimiters: [
1110                    { left: '$$', right: '$$', display: true },
1111                    { left: '\\[', right: '\\]', display: true },
1112                    { left: '\\(', right: '\\)', display: false }
1113                ],
1114                throwOnError: false,
1115                ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
1116            });
1117        }
1118
1119        if (document.readyState === 'loading') {
1120            document.addEventListener('DOMContentLoaded', renderMath);
1121        } else {
1122            renderMath();
1123        }
1124    })();
1125    </script>
1125
1126
1127    <!-- Topbar user menu toggle -->
1128    
1128<script>
1129    (function () {
1130        var userMenu = document.getElementById('userMenu');
1131        var userMenuBtn = document.getElementById('userMenuBtn');
1132        if (userMenu && userMenuBtn) {
1133            userMenuBtn.addEventListener('click', function (e) {
1134                e.stopPropagation();
1135                userMenu.classList.toggle('is-open');
1136            });
1137            document.addEventListener('click', function () {
1138                userMenu.classList.remove('is-open');
1139            });
1140            userMenu.addEventListener('click', function (e) { e.stopPropagation(); });
1141        }
1142        // Note: lang-switch toggles are already handled globally by hp-scripts.js
1143    })();
1144    </script>
1144
1145
1146    <!-- Topbar account (signed out) dropdown toggle -->
1147    
1147<script>
1148    (function () {
1149        var accountMenu = document.getElementById('accountMenu');
1150        var accountMenuBtn = document.getElementById('accountMenuBtn');
1151        if (accountMenu && accountMenuBtn) {
1152            accountMenuBtn.addEventListener('click', function (e) {
1153                e.stopPropagation();
1154                var open = accountMenu.classList.toggle('is-open');
1155                accountMenuBtn.setAttribute('aria-expanded', open ? 'true' : 'false');
1156            });
1157            document.addEventListener('click', function () {
1158                if (accountMenu.classList.contains('is-open')) {
1159                    accountMenu.classList.remove('is-open');
1160                    accountMenuBtn.setAttribute('aria-expanded', 'false');
1161                }
1162            });
1163            accountMenu.addEventListener('click', function (e) { e.stopPropagation(); });
1164        }
1165    })();
1166    </script>
1166
1167
1168    
1169<script>
1170(function () {
1171  let state = {};
1172  try { state = JSON.parse(localStorage.getItem('alphadi-cart') || '{}'); } catch (e) { state = {}; }
1173
1174  const entries = Object.entries(state).filter(([, v]) => v.qty > 0);
1175  const emptyEl = document.getElementById('cartPageEmpty');
1176  const contentEl = document.getElementById('cartPageContent');
1177  const rowsEl = document.getElementById('cartPageRows');
1178  const summaryEl = document.getElementById('cartPageSummaryRows');
1179  const totalEl = document.getElementById('cartPageTotal');
1180
1181  const save = () => localStorage.setItem('alphadi-cart', JSON.stringify(state));
1182
1183  const updateBadges = () => {
1184    const n = Object.values(state).reduce((s, v) => s + v.qty, 0);
1185    document.querySelectorAll('.cart-badge').forEach(b => {
1186      b.textContent = n;
1187      b.classList.toggle('has-items', n > 0);
1188    });
1189  };
1190
1191  const render = () => {
1192    const live = Object.entries(state).filter(([, v]) => v.qty > 0);
1193    if (!live.length) {
1194      contentEl.style.display = 'none';
1195      emptyEl.style.display = '';
1196      return;
1197    }
1198    emptyEl.style.display = 'none';
1199    contentEl.style.display = '';
1200
1201    let grandTotal = 0;
1202
1203    rowsEl.innerHTML = live.map(([id, v]) => {
1204      const lineTotal = v.price * v.qty;
1205      grandTotal += lineTotal;
1206      const unitHtml = v.price < 0
1207        ? `<span style="color:#28a745;">${window.formatPrice(v.price)}</span>`
1208        : `${window.formatPrice(v.price)}`;
1209      const coverHtml = v.image
1210        ? `<img src="${v.image}" alt="${v.name}" style="width:100%;height:100%;object-fit:cover;display:block;">`
1211        : `<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="rgba(255,255,255,.4)" stroke-width="1.5"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>`;
1212      const isBooking = v.type === 'training' || v.type === 'event';
1213      const qtyHtml = isBooking
1214        ? `<div style="text-align:center;font-size:.85rem;color:var(--c-mid);">1 seat</div>`
1215        : `<div class="cart-item__qty">
1216              <button data-action="dec" data-id="${id}">&#8722;</button>
1217              <span class="cart-item__qty-num">${v.qty}</span>
1218              <button data-action="inc" data-id="${id}">+</button>
1219            </div>`;
1220      const participantHtml = isBooking && v.participant && v.participant.name
1221        ? `<div class="cart-page-row__format" style="margin-top:.25rem;">
1222             <strong>Participant:</strong> ${v.participant.name}${v.participant.company ? ' · ' + v.participant.company : ''}${v.participant.email ? ' · ' + v.participant.email : ''}
1223           </div>`
1224        : '';
1225      return `
1226        <div class="cart-page-row" data-row-id="${id}">
1227          <div class="cart-page-row__cover" style="overflow:hidden;">
1228            ${coverHtml}
1229          </div>
1230          <div class="cart-page-row__info">
1231            <div class="cart-page-row__name">${v.name}</div>
1232            ${v.format ? `<div class="cart-page-row__format">${v.format}</div>` : ''}
1233            ${participantHtml}
1234            <div class="cart-page-row__unit">${unitHtml} / unit</div>
1235          </div>
1236          <div class="cart-page-row__qty">
1237            ${qtyHtml}
1238            <button class="cart-page-row__remove" data-action="remove" data-id="${id}">Remove</button>
1239          </div>
1240          <div class="cart-page-row__total">${window.formatPrice(lineTotal)}</div>
1241        </div>`;
1242    }).join('');
1243
1244    summaryEl.innerHTML = live.map(([, v]) =>
1245      `<div class="cart-page-summary__row">
1246        <span>${v.name}${v.format ? ` <small>(${v.format})</small>` : ''} × ${v.qty}</span>
1247        <span>${window.formatPrice(v.price * v.qty)}</span>
1248      </div>`
1249    ).join('');
1250
1251    if (totalEl) { totalEl.textContent = window.formatPrice(grandTotal); }
1252    updateBadges();
1253  };
1254
1255  // Qty / remove actions
1256  rowsEl?.addEventListener('click', e => {
1257    const btn = e.target.closest('[data-action]');
1258    if (!btn) { return; }
1259    const { action, id } = btn.dataset;
1260    if (action === 'inc') {
1261      if (state[id]) { state[id].qty += 1; }
1262    } else if (action === 'dec') {
1263      if (state[id]) {
1264        state[id].qty = Math.max(0, state[id].qty - 1);
1265        if (state[id].qty === 0) { delete state[id]; }
1266      }
1267    } else if (action === 'remove') {
1268      delete state[id];
1269    }
1270    save();
1271    render();
1272  });
1273
1274  // Re-sync stale cart data (price / availability may have changed) before showing it,
1275  // then surface a notice about anything that changed / was removed.
1276  if (window.AlphadiCartSync) {
1277    window.AlphadiCartSync.applyTo(state).then(function (r) {
1278      render();
1279      window.AlphadiCartSync.showNotice(r, document.getElementById('cartPageNotice'));
1280    });
1281  } else {
1282    render();
1283  }
1284})();
1285</script>
1285
1286
1287
1288
1289    <!-- Cart FAB (mobile) -->
1290    <button class="cart-fab cart-btn" id="cartFab" aria-label="Cart">
1291        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 2L3 6v14a2 2 0 002 2h14a2 2 0 002-2V6l-3-4z"/><line x1="3" y1="6" x2="21" y2="6"/><path d="M16 10a4 4 0 01-8 0"/></svg>
1292        <span class="cart-fab__badge cart-badge">0</span>
1293    </button>
1294
1295    <!-- Cart Overlay + Drawer -->
1296    <div class="cart-overlay" id="cartOverlay"></div>
1297    <div class="cart-drawer" id="cartDrawer"
1298         data-label-empty="Your cart is empty."
1299         data-label-remove="Remove"
1300         data-label-order="Order now"
1301         data-label-continue="Continue shopping"
1302         data-label-unit="unit"
1303         data-label-required="This option is required.">
1304        <div class="cart-drawer__head">
1305            <span class="cart-drawer__title">Cart</span>
1306            <button class="cart-drawer__close" id="cartClose">&#x2715;</button>
1307        </div>
1308        <div class="cart-drawer__notice" id="cartNotice" style="display:none;padding:0.9rem 1.1rem 0;"
1309             data-msg-title="Your cart was updated"
1310             data-msg-removed="{name} is no longer available and was removed."
1311             data-msg-repriced="Price of {name} changed to {price}."></div>
1312        <div class="cart-drawer__body" id="cartBody"></div>
1313        <div class="cart-drawer__foot" id="cartFoot" style="display:none;">
1314            <div class="cart-subtotal">
1315                <span class="cart-subtotal__label">Total</span>
1316                <span class="cart-subtotal__amount" id="cartTotal">0,00 &#8364;</span>
1317            </div>
1318            <a href="/en/cart" class="btn btn--primary btn--lg" style="width:100%;justify-content:center;">View cart</a>
1319            <button class="cart-continue" id="cartContinue">Continue shopping</button>
1320        </div>
1321    </div>
1322
1323    
1324<div class="modal-overlay" id="bookingRequestModal">
1325    <div class="modal" role="dialog" aria-modal="true" aria-labelledby="bookingRequestModalTitle">
1326        <button type="button" class="modal__close" data-booking-request-close aria-label="Close">&times;</button>
1327        <div class="modal__title" id="bookingRequestModalTitle">Reserve a seat</div>
1328        <p style="font-family:var(--f-ui);font-size:0.875rem;color:var(--c-mid);margin-bottom:1.5rem;">
1329            <strong id="bookingRequestProduct"></strong>
1330            <span id="bookingRequestFormat"></span>
1331        </p>
1332        <form id="bookingRequestForm" novalidate>
1333            <div class="form-group">
1334                <label class="form-label">First name *</label>
1335                <input type="text" class="form-input" name="firstName" required />
1336                <div class="field-error"></div>
1337            </div>
1338            <div class="form-group">
1339                <label class="form-label">Last name *</label>
1340                <input type="text" class="form-input" name="lastName" required />
1341                <div class="field-error"></div>
1342            </div>
1343            <div class="form-group">
1344                <label class="form-label">Company *</label>
1345                <input type="text" class="form-input" name="company" required />
1346                <div class="field-error"></div>
1347            </div>
1348            <div class="form-group">
1349                <label class="form-label">Email *</label>
1350                <input type="email" class="form-input" name="email" required />
1351                <div class="field-error"></div>
1352            </div>
1353            <div class="form-group">
1354                <label class="form-label">Phone *</label>
1355                <input type="tel" class="form-input" name="phone" required />
1356                <div class="field-error"></div>
1357            </div>
1358            <div class="form-group">
1359                <label class="form-label">Notes / special requirements</label>
1360                <textarea class="form-textarea" name="notes" rows="3"></textarea>
1361            </div>
1362                <div class="checkout-check-field">
1363                    <label class="checkout-check-label">
1364                        <input type="checkbox" id="br-terms" name="terms" />
1365                        <span>
1366                            I have read the
1367                            <a href="/en/t&amp;c" target="_blank" rel="noopener">Terms &amp; Conditions</a>
1368                            and agree to them. <span class="req">*</span>
1369                        </span>
1370                    </label>
1371                    <span class="field-error fw-bold text-danger" id="brTermsError"></span>
1372                </div>
1373            <div class="checkout-check-field">
1374                <label class="checkout-check-label">
1375                    <input type="checkbox" id="br-privacy" name="privacy" />
1376                    <span>
1377                        I have read the
1378                        <a href="/en/privacy-policy" target="_blank" rel="noopener">Privacy Policy</a>
1379                        and agree that my data will be processed. <span class="req">*</span>
1380                    </span>
1381                </label>
1382                <span class="field-error fw-bold text-danger" id="brPrivacyError"></span>
1383            </div>
1384
1385            <div class="field-error" id="bookingRequestFormError" style="margin-bottom:.75rem;"></div>
1386            <button type="submit" class="btn btn--primary" style="width:100%;justify-content:center;">
1387                Send booking request
1388            </button>
1389        </form>
1390    </div>
1391</div>
1392
1393<script>
1394(function () {
1395    'use strict';
1396
1397    var overlay = document.getElementById('bookingRequestModal');
1398    var form    = document.getElementById('bookingRequestForm');
1399    if (!overlay || !form) { return; }
1400
1401    var productEl = document.getElementById('bookingRequestProduct');
1402    var formatEl  = document.getElementById('bookingRequestFormat');
1403    var formError = document.getElementById('bookingRequestFormError');
1404    var pending   = null;
1405    var submitting = false;
1406
1407    var POST_URL     = '/en/cart/submit-booking-request';
1408    var MSG_REQUIRED = "This field is required.";
1409    var MSG_EMAIL    = "Please enter a valid e-mail address.";
1410    var MSG_ERROR    = "An error occurred. Please try again.";
1411    var MSG_TERMS    = "You must agree to the Terms & Conditions to continue.";
1412    var MSG_PRIVACY  = "You must agree to the Privacy Policy to continue.";
1413
1414    function isEmail(v) { return /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test((v || '').trim()); }
1415
1416    function openModal(data) {
1417        pending = data;
1418        productEl.textContent = data.name || '';
1419        formatEl.innerHTML    = data.format ? (' · ' + data.format) : '';
1420        form.reset();
1421        formError.textContent = '';
1422        form.querySelectorAll('.is-invalid').forEach(function (el) { el.classList.remove('is-invalid'); });
1423        form.querySelectorAll('.field-error').forEach(function (el) { el.textContent = ''; });
1424        overlay.classList.add('is-open');
1425        document.body.style.overflow = 'hidden';
1426        setTimeout(function () { form.querySelector('[name=firstName]')?.focus(); }, 50);
1427    }
1428
1429    function closeModal() {
1430        overlay.classList.remove('is-open');
1431        document.body.style.overflow = '';
1432        pending = null;
1433    }
1434
1435    overlay.addEventListener('click', function (e) {
1436        if (e.target === overlay) { closeModal(); }
1437    });
1438    overlay.querySelectorAll('[data-booking-request-close]').forEach(function (b) {
1439        b.addEventListener('click', closeModal);
1440    });
1441    document.addEventListener('keydown', function (e) {
1442        if (e.key === 'Escape' && overlay.classList.contains('is-open')) { closeModal(); }
1443    });
1444
1445    // Capture-phase interception so we beat both the cart booking modal and the global add-to-cart handler.
1446    document.addEventListener('click', function (e) {
1447        var btn = e.target.closest('[data-add-to-cart][data-cart-type]');
1448        if (!btn) { return; }
1449        if (btn.dataset.onlyBooking !== 'true') { return; }   // not an OnlyBooking appointment — let the cart flow run
1450        var type = btn.dataset.cartType;
1451        if (type !== 'training' && type !== 'event') { return; }
1452        if (btn.disabled) { return; }
1453        e.preventDefault();
1454        e.stopImmediatePropagation();
1455        openModal({
1456            id:     btn.dataset.addToCart,
1457            type:   type,
1458            name:   btn.dataset.cartName   || btn.dataset.addToCart,
1459            format: btn.dataset.cartFormat || '',
1460        });
1461    }, true);
1462
1463    function showErr(field, msg) {
1464        field.classList.add('is-invalid');
1465        var s = field.parentElement.querySelector('.field-error');
1466        if (s) { s.textContent = msg; }
1467    }
1468    function clearErr(field) {
1469        field.classList.remove('is-invalid');
1470        var s = field.parentElement.querySelector('.field-error');
1471        if (s) { s.textContent = ''; }
1472    }
1473    function validate(field) {
1474        var val = (field.value || '').trim();
1475        if (field.hasAttribute('required') && !val) { showErr(field, MSG_REQUIRED); return false; }
1476        if (field.type === 'email' && val && !isEmail(val)) { showErr(field, MSG_EMAIL); return false; }
1477        clearErr(field); return true;
1478    }
1479
1480    form.querySelectorAll('input, textarea').forEach(function (f) {
1481        f.addEventListener('blur',  function () { validate(f); });
1482        f.addEventListener('input', function () { if (f.classList.contains('is-invalid')) { clearErr(f); } });
1483    });
1484
1485    form.addEventListener('submit', function (e) {
1486        e.preventDefault();
1487        if (!pending || submitting) { return; }
1488        formError.textContent = '';
1489        var ok = true;
1490        form.querySelectorAll('input[required], input[type=email]').forEach(function (f) {
1491            if (!validate(f)) { ok = false; }
1492        });
1493
1494        var termsCb  = document.getElementById('br-terms');
1495        var termsErr = document.getElementById('brTermsError');
1496        if (termsCb) {
1497            if (!termsCb.checked) {
1498                termsCb.classList.add('is-invalid');
1499                if (termsErr) { termsErr.textContent = MSG_TERMS; }
1500                ok = false;
1501            } else {
1502                termsCb.classList.remove('is-invalid');
1503                if (termsErr) { termsErr.textContent = ''; }
1504            }
1505        }
1506
1507        var privacyCb  = document.getElementById('br-privacy');
1508        var privacyErr = document.getElementById('brPrivacyError');
1509        if (!privacyCb.checked) {
1510            privacyCb.classList.add('is-invalid');
1511            if (privacyErr) { privacyErr.textContent = MSG_PRIVACY; }
1512            ok = false;
1513        } else {
1514            privacyCb.classList.remove('is-invalid');
1515            if (privacyErr) { privacyErr.textContent = ''; }
1516        }
1517
1518        if (!ok) { return; }
1519
1520        var fd = new FormData(form);
1521        var payload = {
1522            id:        pending.id,
1523            type:      pending.type,
1524            firstName: (fd.get('firstName') || '').trim(),
1525            lastName:  (fd.get('lastName')  || '').trim(),
1526            company:   (fd.get('company')   || '').trim(),
1527            email:     (fd.get('email')     || '').trim(),
1528            phone:     (fd.get('phone')     || '').trim(),
1529            notes:     (fd.get('notes')     || '').trim(),
1530        };
1531
1532        submitting = true;
1533        var submitBtn = form.querySelector('button[type=submit]');
1534        if (submitBtn) { submitBtn.disabled = true; }
1535
1536        fetch(POST_URL, {
1537            method: 'POST',
1538            headers: { 'Content-Type': 'application/json' },
1539            body: JSON.stringify(payload),
1540        }).then(function (res) {
1541            return res.ok ? res.json() : Promise.reject(res);
1542        }).then(function (data) {
1543            if (data && data.redirectUrl) {
1544                window.location = data.redirectUrl;
1545            } else {
1546                window.location.reload();
1547            }
1548        }).catch(function () {
1549            submitting = false;
1550            if (submitBtn) { submitBtn.disabled = false; }
1551            formError.textContent = MSG_ERROR;
1552        });
1553    });
1554})();
1555</script>
1555
1556
1557    
1558<div class="modal-overlay" id="bookingModal">
1559    <div class="modal" role="dialog" aria-modal="true" aria-labelledby="bookingModalTitle">
1560        <button type="button" class="modal__close" data-booking-close aria-label="Close">&times;</button>
1561        <div class="modal__title" id="bookingModalTitle">Reserve a seat</div>
1562        <p style="font-family:var(--f-ui);font-size:0.875rem;color:var(--c-mid);margin-bottom:1.5rem;">
1563            <strong id="bookingModalProduct"></strong>
1564            <span id="bookingModalFormat"></span>
1565        </p>
1566        <form id="bookingForm" novalidate>
1567            <div class="form-group">
1568                <label class="form-label">First name *</label>
1569                <input type="text" class="form-input" name="participantFirstName" required />
1570                <div class="field-error"></div>
1571            </div>
1572            <div class="form-group">
1573                <label class="form-label">Last name *</label>
1574                <input type="text" class="form-input" name="participantLastName" required />
1575                <div class="field-error"></div>
1576            </div>
1577            <div class="form-group">
1578                <label class="form-label">Company *</label>
1579                <input type="text" class="form-input" name="participantCompany" required />
1580                <div class="field-error"></div>
1581            </div>
1582            <div class="form-group">
1583                <label class="form-label">Email *</label>
1584                <input type="email" class="form-input" name="participantEmail" required />
1585                <div class="field-error"></div>
1586            </div>
1587            <div class="form-group">
1588                <label class="form-label">Phone *</label>
1589                <input type="tel" class="form-input" name="participantPhone" required />
1590                <div class="field-error"></div>
1591            </div>
1592            <div class="form-group">
1593                <label class="form-label">Notes / special requirements</label>
1594                <textarea class="form-textarea" name="participantNotes" rows="3"></textarea>
1595            </div>
1596            <button type="submit" class="btn btn--primary" style="width:100%;justify-content:center;">
1597                Add to cart
1598            </button>
1599        </form>
1600    </div>
1601</div>
1602
1603<script>
1604(function () {
1605    'use strict';
1606
1607    var overlay = document.getElementById('bookingModal');
1608    var form    = document.getElementById('bookingForm');
1609    if (!overlay || !form) { return; }
1610
1611    var productEl = document.getElementById('bookingModalProduct');
1612    var formatEl  = document.getElementById('bookingModalFormat');
1613    var pending   = null;
1614
1615    var MSG_REQUIRED = 'This field is required.';
1616    var MSG_EMAIL    = 'Please enter a valid e-mail address.';
1617
1618    function isEmail(v) { return /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test((v || '').trim()); }
1619
1620    function openModal(data) {
1621        pending = data;
1622        productEl.textContent = data.name || '';
1623        formatEl.innerHTML    = data.format ? (' · ' + data.format) : '';
1624        form.reset();
1625        form.querySelectorAll('.is-invalid').forEach(function (el) { el.classList.remove('is-invalid'); });
1626        form.querySelectorAll('.field-error').forEach(function (el) { el.textContent = ''; });
1627        overlay.classList.add('is-open');
1628        document.body.style.overflow = 'hidden';
1629        setTimeout(function () { form.querySelector('[name=participantFirstName]')?.focus(); }, 50);
1630    }
1631
1632    function closeModal() {
1633        overlay.classList.remove('is-open');
1634        document.body.style.overflow = '';
1635        pending = null;
1636    }
1637
1638    overlay.addEventListener('click', function (e) {
1639        if (e.target === overlay) { closeModal(); }
1640    });
1641    overlay.querySelectorAll('[data-booking-close]').forEach(function (b) {
1642        b.addEventListener('click', closeModal);
1643    });
1644    document.addEventListener('keydown', function (e) {
1645        if (e.key === 'Escape' && overlay.classList.contains('is-open')) { closeModal(); }
1646    });
1647
1648    // Intercept add-to-cart clicks for trainings/events so we collect participant info first.
1649    document.addEventListener('click', function (e) {
1650        var btn = e.target.closest('[data-add-to-cart][data-cart-type]');
1651        if (!btn) { return; }
1652        var type = btn.dataset.cartType;
1653        if (type !== 'training' && type !== 'event') { return; }
1654        // OnlyBooking appointments are handled by the separate "Send booking request" modal.
1655        if (btn.dataset.onlyBooking === 'true') { return; }
1656        if (btn.disabled) { return; }
1657        e.preventDefault();
1658        e.stopImmediatePropagation();
1659        openModal({
1660            id:     btn.dataset.addToCart,
1661            name:   btn.dataset.cartName   || btn.dataset.addToCart,
1662            price:  btn.dataset.cartPrice  || '0',
1663            format: btn.dataset.cartFormat || '',
1664            image:  btn.dataset.cartImage  || '',
1665            type:   type,
1666        });
1667    }, true); // capture phase so we beat the global add-to-cart handler
1668
1669    function showErr(field, msg) {
1670        field.classList.add('is-invalid');
1671        var s = field.parentElement.querySelector('.field-error');
1672        if (s) { s.textContent = msg; }
1673    }
1674    function clearErr(field) {
1675        field.classList.remove('is-invalid');
1676        var s = field.parentElement.querySelector('.field-error');
1677        if (s) { s.textContent = ''; }
1678    }
1679    function validate(field) {
1680        var val = (field.value || '').trim();
1681        if (field.hasAttribute('required') && !val) { showErr(field, MSG_REQUIRED); return false; }
1682        if (field.type === 'email' && val && !isEmail(val)) { showErr(field, MSG_EMAIL); return false; }
1683        clearErr(field); return true;
1684    }
1685
1686    form.querySelectorAll('input, textarea').forEach(function (f) {
1687        f.addEventListener('blur',  function () { validate(f); });
1688        f.addEventListener('input', function () { if (f.classList.contains('is-invalid')) { clearErr(f); } });
1689    });
1690
1691    form.addEventListener('submit', function (e) {
1692        e.preventDefault();
1693        if (!pending) { return; }
1694        var ok = true;
1695        form.querySelectorAll('input[required], input[type=email]').forEach(function (f) {
1696            if (!validate(f)) { ok = false; }
1697        });
1698        if (!ok) { return; }
1699
1700        var fd = new FormData(form);
1701        var firstName = (fd.get('participantFirstName') || '').trim();
1702        var lastName  = (fd.get('participantLastName')  || '').trim();
1703        var participant = {
1704            firstName: firstName,
1705            lastName:  lastName,
1706            // Combined name kept for the mini-cart display (and legacy back-compat).
1707            name:    (firstName + ' ' + lastName).trim(),
1708            company: (fd.get('participantCompany') || '').trim(),
1709            email:   (fd.get('participantEmail')   || '').trim(),
1710            phone:   (fd.get('participantPhone')   || '').trim(),
1711            notes:   (fd.get('participantNotes')   || '').trim(),
1712        };
1713
1714        if (typeof window.alphadiAddBookingToCart === 'function') {
1715            window.alphadiAddBookingToCart(pending, participant);
1716        }
1717        closeModal();
1718    });
1719})();
1720</script>
1720
1721
1722    
1723<div class="modal-overlay" id="requestModal">
1724    <div class="modal" role="dialog" aria-modal="true" aria-labelledby="requestModalTitle">
1725        <button type="button" class="modal__close" data-request-close aria-label="Close">&times;</button>
1726        <div class="modal__title" id="requestModalTitle">Request</div>
1727        <p style="font-family:var(--f-ui);font-size:0.875rem;color:var(--c-mid);margin-bottom:1.5rem;">
1728            <strong id="requestModalProduct"></strong>
1729        </p>
1730        <form id="requestForm" novalidate>
1731            <input type="hidden" name="itemName" id="requestItemName" />
1732            <div class="form-group">
1733                <label class="form-label">First name *</label>
1734                <input type="text" class="form-input" name="firstName" required />
1735                <div class="field-error"></div>
1736            </div>
1737            <div class="form-group">
1738                <label class="form-label">Last name *</label>
1739                <input type="text" class="form-input" name="lastName" required />
1740                <div class="field-error"></div>
1741            </div>
1742            <div class="form-group">
1743                <label class="form-label">Company</label>
1744                <input type="text" class="form-input" name="company" />
1745                <div class="field-error"></div>
1746            </div>
1747            <div class="form-group">
1748                <label class="form-label">Email *</label>
1749                <input type="email" class="form-input" name="email" required />
1750                <div class="field-error"></div>
1751            </div>
1752            <div class="form-group">
1753                <label class="form-label">Phone *</label>
1754                <input type="tel" class="form-input" name="phone" required />
1755                <div class="field-error"></div>
1756            </div>
1757            <div class="form-group">
1758                <label class="form-label">Message</label>
1759                <textarea class="form-textarea" name="message" rows="3"></textarea>
1760            </div>
1761            <div id="requestFormStatus" style="display:none;margin-bottom:1rem;font-family:var(--f-ui);font-size:0.875rem;"></div>
1762
1763                <div class="checkout-check-field">
1764                    <label class="checkout-check-label">
1765                        <input type="checkbox" id="req-terms" name="terms" />
1766                        <span>
1767                            I have read the
1768                            <a href="/en/t&amp;c" target="_blank" rel="noopener">Terms &amp; Conditions</a>
1769                            and agree to them. <span class="req">*</span>
1770                        </span>
1771                    </label>
1772                    <span class="field-error fw-bold text-danger" id="reqTermsError"></span>
1773                </div>
1774            <div class="checkout-check-field">
1775                <label class="checkout-check-label">
1776                    <input type="checkbox" id="req-privacy" name="privacy" />
1777                    <span>
1778                        I have read the
1779                        <a href="/en/privacy-policy" target="_blank" rel="noopener">Privacy Policy</a>
1780                        and agree that my data will be processed. <span class="req">*</span>
1781                    </span>
1782                </label>
1783                <span class="field-error fw-bold text-danger" id="reqPrivacyError"></span>
1784            </div>
1785
1786            <button type="submit" class="btn btn--primary" style="width:100%;justify-content:center;">
1787                Send request
1788            </button>
1789        </form>
1790    </div>
1791</div>
1792
1793<script>
1794(function () {
1795    'use strict';
1796
1797    var overlay    = document.getElementById('requestModal');
1798    var form       = document.getElementById('requestForm');
1799    var productEl  = document.getElementById('requestModalProduct');
1800    var itemNameEl = document.getElementById('requestItemName');
1801    var statusEl   = document.getElementById('requestFormStatus');
1802    if (!overlay || !form) { return; }
1803
1804    var MSG_REQUIRED = "This field is required.";
1805    var MSG_EMAIL    = "Please enter a valid e-mail address.";
1806    var MSG_SUCCESS  = "Your request has been sent. We will get back to you shortly.";
1807    var MSG_ERROR    = "Something went wrong. Please try again.";
1808    var MSG_TERMS    = "You must agree to the Terms & Conditions to continue.";
1809    var MSG_PRIVACY  = "You must agree to the Privacy Policy to continue.";
1810
1811    function isEmail(v) { return /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test((v || '').trim()); }
1812
1813    function openModal(name) {
1814        if (productEl) { productEl.textContent = name || ''; }
1815        if (itemNameEl) { itemNameEl.value = name || ''; }
1816        form.reset();
1817        if (itemNameEl) { itemNameEl.value = name || ''; }
1818        form.querySelectorAll('.is-invalid').forEach(function (el) { el.classList.remove('is-invalid'); });
1819        form.querySelectorAll('.field-error').forEach(function (el) { el.textContent = ''; });
1820        statusEl.style.display = 'none';
1821        statusEl.textContent = '';
1822        overlay.classList.add('is-open');
1823        document.body.style.overflow = 'hidden';
1824        setTimeout(function () { form.querySelector('[name=firstName]')?.focus(); }, 50);
1825    }
1826
1827    function closeModal() {
1828        overlay.classList.remove('is-open');
1829        document.body.style.overflow = '';
1830    }
1831
1832    overlay.addEventListener('click', function (e) {
1833        if (e.target === overlay) { closeModal(); }
1834    });
1835    overlay.querySelectorAll('[data-request-close]').forEach(function (b) {
1836        b.addEventListener('click', closeModal);
1837    });
1838    document.addEventListener('keydown', function (e) {
1839        if (e.key === 'Escape' && overlay.classList.contains('is-open')) { closeModal(); }
1840    });
1841
1842    document.addEventListener('click', function (e) {
1843        var btn = e.target.closest('[data-open-request-modal]');
1844        if (!btn) { return; }
1845        e.preventDefault();
1846        openModal(btn.dataset.openRequestModal || '');
1847    });
1848
1849    // Per-date "By invoice" toggle — expands the inline note ("Inquire here …") within the
1850    // booking box; the link inside it opens this modal.
1851    document.addEventListener('click', function (e) {
1852        var toggle = e.target.closest('[data-invoice-toggle]');
1853        if (!toggle) { return; }
1854        var item = toggle.closest('[data-date-item]');
1855        if (item) { item.classList.toggle('is-open'); }
1856    });
1857
1858    function showErr(field, msg) {
1859        field.classList.add('is-invalid');
1860        var s = field.parentElement.querySelector('.field-error');
1861        if (s) { s.textContent = msg; }
1862    }
1863    function clearErr(field) {
1864        field.classList.remove('is-invalid');
1865        var s = field.parentElement.querySelector('.field-error');
1866        if (s) { s.textContent = ''; }
1867    }
1868    function validate(field) {
1869        var val = (field.value || '').trim();
1870        if (field.hasAttribute('required') && !val) { showErr(field, MSG_REQUIRED); return false; }
1871        if (field.type === 'email' && val && !isEmail(val)) { showErr(field, MSG_EMAIL); return false; }
1872        clearErr(field); return true;
1873    }
1874
1875    form.querySelectorAll('input, textarea').forEach(function (f) {
1876        f.addEventListener('blur',  function () { validate(f); });
1877        f.addEventListener('input', function () { if (f.classList.contains('is-invalid')) { clearErr(f); } });
1878    });
1879
1880    form.addEventListener('submit', function (e) {
1881        e.preventDefault();
1882        var ok = true;
1883        form.querySelectorAll('input[required], input[type=email]').forEach(function (f) {
1884            if (!validate(f)) { ok = false; }
1885        });
1886
1887        var termsCb  = document.getElementById('req-terms');
1888        var termsErr = document.getElementById('reqTermsError');
1889        if (termsCb) {
1890            if (!termsCb.checked) {
1891                termsCb.classList.add('is-invalid');
1892                if (termsErr) { termsErr.textContent = MSG_TERMS; }
1893                ok = false;
1894            } else {
1895                termsCb.classList.remove('is-invalid');
1896                if (termsErr) { termsErr.textContent = ''; }
1897            }
1898        }
1899
1900        var privacyCb  = document.getElementById('req-privacy');
1901        var privacyErr = document.getElementById('reqPrivacyError');
1902        if (!privacyCb.checked) {
1903            privacyCb.classList.add('is-invalid');
1904            if (privacyErr) { privacyErr.textContent = MSG_PRIVACY; }
1905            ok = false;
1906        } else {
1907            privacyCb.classList.remove('is-invalid');
1908            if (privacyErr) { privacyErr.textContent = ''; }
1909        }
1910
1911        if (!ok) { return; }
1912
1913        var submitBtn = form.querySelector('[type=submit]');
1914        submitBtn.disabled = true;
1915
1916        var fd = new FormData(form);
1917        var payload = {
1918            itemName:  (fd.get('itemName')  || '').trim(),
1919            firstName: (fd.get('firstName') || '').trim(),
1920            lastName:  (fd.get('lastName')  || '').trim(),
1921            company:   (fd.get('company')   || '').trim(),
1922            email:     (fd.get('email')     || '').trim(),
1923            phone:     (fd.get('phone')     || '').trim(),
1924            message:   (fd.get('message')   || '').trim(),
1925        };
1926
1927        fetch('/Home/SendRequest', {
1928            method: 'POST',
1929            headers: { 'Content-Type': 'application/json' },
1930            body: JSON.stringify(payload),
1931        })
1932        .then(function (r) { return r.json(); })
1933        .then(function (data) {
1934            if (data.success) {
1935                if (data.redirectUrl) {
1936                    window.location.href = data.redirectUrl;
1937                } else {
1938                    statusEl.style.display = 'block';
1939                    statusEl.style.color = 'var(--c-green, green)';
1940                    statusEl.textContent = MSG_SUCCESS;
1941                    form.querySelectorAll('input, textarea, button[type=submit]').forEach(function (el) { el.disabled = true; });
1942                }
1943            } else {
1944                statusEl.style.display = 'block';
1945                statusEl.style.color = 'var(--c-error, red)';
1946                statusEl.textContent = data.message || MSG_ERROR;
1947                submitBtn.disabled = false;
1948            }
1949        })
1950        .catch(function () {
1951            statusEl.style.display = 'block';
1952            statusEl.style.color = 'var(--c-error, red)';
1953            statusEl.textContent = MSG_ERROR;
1954            submitBtn.disabled = false;
1955        });
1956    });
1957})();
1958</script>
1958
1959
1960    
1961<div class="modal-overlay" id="productFeatureModal">
1962    <div class="modal" role="dialog" aria-modal="true" aria-labelledby="productFeatureModalTitle" style="max-width:560px;">
1963        <button type="button" class="modal__close" data-pf-close aria-label="Close">&times;</button>
1964        <div class="modal__title" id="productFeatureModalTitle">Choose options</div>
1965        <p style="font-family:var(--f-ui);font-size:0.875rem;color:var(--c-mid);margin-bottom:1.25rem;">
1966            <strong id="pfModalProduct"></strong>
1967        </p>
1968
1969        <div id="pfModalBody"></div>
1970
1971        <div style="display:flex;align-items:baseline;justify-content:space-between;gap:1rem;margin:1.25rem 0 1rem;padding-top:1rem;border-top:1px solid var(--c-border);">
1972            <span style="font-family:var(--f-ui);font-size:0.8rem;font-weight:600;letter-spacing:0.08em;text-transform:uppercase;color:var(--c-subtle);">Total</span>
1973            <span id="pfModalTotal" style="font-family:var(--f-display);font-size:1.75rem;font-weight:700;color:var(--c-orange);line-height:1;">0,00 &#8364;</span>
1974        </div>
1975
1976        <button type="button" id="pfModalSubmit" class="btn btn--primary" style="width:100%;justify-content:center;">
1977            Add to cart
1978        </button>
1979    </div>
1980</div>
1981
1982<script>
1983(function () {
1984    'use strict';
1985
1986    var overlay = document.getElementById('productFeatureModal');
1987    if (!overlay) { return; }
1988
1989    var productEl = document.getElementById('pfModalProduct');
1990    var bodyEl    = document.getElementById('pfModalBody');
1991    var totalEl   = document.getElementById('pfModalTotal');
1992    var submitBtn = document.getElementById('pfModalSubmit');
1993
1994    var MSG_REQUIRED = 'Please select an option.';
1995
1996    var pending  = null;   // { id, name, basePrice, image, shippableMap }
1997    var features = [];     // [{ name, isRequired, options: [...] }]
1998    var selected = {};     // { [featureIndex]: { name, price, isShippable } }
1999
2000    function fmtPrice(v) {
2001        return window.formatPrice
2002            ? window.formatPrice(v)
2003            : '\u20AC' + (v < 0 ? '-' + Math.abs(v).toFixed(2) : v.toFixed(2));
2004    }
2005
2006    // Build shippability lookup from raw DB JSON (PascalCase, all feature types).
2007    // Returns map[listFeatureIndex][optionIndex] = bool
2008    function buildShippableMap(rawJson) {
2009        var map = {};
2010        try {
2011            var all = JSON.parse(rawJson || '[]');
2012            var listIdx = 0;
2013            all.forEach(function (f) {
2014                if ((f.Type !== undefined ? f.Type : f.type) !== 0) { return; }
2015                var fi = listIdx++;
2016                map[fi] = {};
2017                (f.Options || f.options || []).forEach(function (o, oi) {
2018                    map[fi][oi] = !!(o.IsShippable || o.isShippable);
2019                });
2020            });
2021        } catch (e) {}
2022        return map;
2023    }
2024
2025    function recalcTotal() {
2026        var delta = 0;
2027        Object.keys(selected).forEach(function (k) { delta += selected[k].price; });
2028        var total = Math.max(0, pending.basePrice + delta);
2029        totalEl.textContent = fmtPrice(total);
2030        return total;
2031    }
2032
2033    function renderBody() {
2034        selected = {};
2035        if (!features.length) { bodyEl.innerHTML = ''; return; }
2036        var sm = (pending && pending.shippableMap) || {};
2037
2038        bodyEl.innerHTML = features.map(function (f, fi) {
2039            var opts = (f.options || []).map(function (o, oi) {
2040                var deltaHtml = '';
2041                if (o.price > 0)      { deltaHtml = '<span class="product-fmt-card__delta">+' + fmtPrice(o.price) + '</span>'; }
2042                else if (o.price < 0) { deltaHtml = '<span class="product-fmt-card__delta product-fmt-card__delta--down">' + fmtPrice(o.price) + '</span>'; }
2043
2044                var badgeHtml = o.badgeText
2045                    ? '<span class="product-fmt-card__badge">' + o.badgeText + '</span>'
2046                    : '';
2047
2048                var isShippable = !!(sm[fi] && sm[fi][oi]);
2049                var isDefault = !!o.isDefault;
2050                if (isDefault) {
2051                    selected[fi] = { name: o.name, price: parseFloat(o.price) || 0, isShippable: isShippable };
2052                }
2053
2054                return '<label class="product-fmt-card' + (isDefault ? ' is-selected' : '') + '"' +
2055                       ' data-feature-index="' + fi + '"' +
2056                       ' data-option-index="' + oi + '"' +
2057                       ' data-option-name="' + (o.name || '').replace(/"/g, '&quot;') + '"' +
2058                       ' data-option-price="' + (parseFloat(o.price) || 0) + '"' +
2059                       ' data-option-shippable="' + (isShippable ? 'true' : 'false') + '">' +
2060                            '<input type="radio" name="pf-' + fi + '" ' + (isDefault ? 'checked' : '') + ' style="display:none">' +
2061                            '<div class="product-fmt-card__name">' + (o.name || '') + ' ' + badgeHtml + '</div>' +
2062                            (deltaHtml ? '<div class="product-fmt-card__meta">' + deltaHtml + '</div>' : '') +
2063                       '</label>';
2064            }).join('');
2065
2066            return '<div class="product-fmt-group" data-feature-index="' + fi + '" data-feature-required="' + (f.isRequired ? 'true' : 'false') + '">' +
2067                       '<div class="product-fmt-group__label">' +
2068                            (f.name || '') +
2069                            (f.isRequired ? '<span class="product-fmt-group__req" title="Required">*</span>' : '') +
2070                       '</div>' +
2071                       '<div class="product-fmt-grid">' + opts + '</div>' +
2072                       '<div class="product-fmt-error"></div>' +
2073                   '</div>';
2074        }).join('');
2075    }
2076
2077    function openModal(data, parsedFeatures, shippableMap) {
2078        pending  = data;
2079        pending.shippableMap = shippableMap || {};
2080        features = parsedFeatures || [];
2081        productEl.textContent = data.name || '';
2082        renderBody();
2083        recalcTotal();
2084        overlay.classList.add('is-open');
2085        document.body.style.overflow = 'hidden';
2086    }
2087
2088    function closeModal() {
2089        overlay.classList.remove('is-open');
2090        document.body.style.overflow = '';
2091        pending  = null;
2092        features = [];
2093        selected = {};
2094    }
2095
2096    overlay.addEventListener('click', function (e) {
2097        if (e.target === overlay) { closeModal(); }
2098    });
2099    overlay.querySelectorAll('[data-pf-close]').forEach(function (b) {
2100        b.addEventListener('click', closeModal);
2101    });
2102    document.addEventListener('keydown', function (e) {
2103        if (e.key === 'Escape' && overlay.classList.contains('is-open')) { closeModal(); }
2104    });
2105
2106    bodyEl.addEventListener('click', function (e) {
2107        var card = e.target.closest('.product-fmt-card');
2108        if (!card) { return; }
2109        var fi = card.dataset.featureIndex;
2110        var group = card.closest('.product-fmt-group');
2111        if (group) {
2112            group.querySelectorAll('.product-fmt-card').forEach(function (c) { c.classList.remove('is-selected', 'is-error'); });
2113            var errEl = group.querySelector('.product-fmt-error');
2114            if (errEl) { errEl.textContent = ''; }
2115        }
2116        card.classList.add('is-selected');
2117        var input = card.querySelector('input[type=radio]');
2118        if (input) { input.checked = true; }
2119        selected[fi] = {
2120            name:       card.dataset.optionName,
2121            price:      parseFloat(card.dataset.optionPrice) || 0,
2122            isShippable: card.dataset.optionShippable === 'true',
2123        };
2124        recalcTotal();
2125    });
2126
2127    submitBtn.addEventListener('click', function () {
2128        if (!pending) { return; }
2129
2130        var ok = true;
2131        bodyEl.querySelectorAll('.product-fmt-group[data-feature-required="true"]').forEach(function (group) {
2132            var fi = group.dataset.featureIndex;
2133            var errEl = group.querySelector('.product-fmt-error');
2134            if (!selected[fi]) {
2135                if (errEl) { errEl.textContent = MSG_REQUIRED; }
2136                group.querySelectorAll('.product-fmt-card').forEach(function (c) { c.classList.add('is-error'); });
2137                ok = false;
2138            }
2139        });
2140        if (!ok) { return; }
2141
2142        var finalPrice  = recalcTotal();
2143        var parts       = [];
2144        features.forEach(function (f, fi) { if (selected[fi]) { parts.push(selected[fi].name); } });
2145        var finalFormat = parts.join(', ') || (pending.format || '');
2146        var isShippable = Object.values(selected).some(function (s) { return s.isShippable; });
2147
2148        if (typeof window.alphadiAddProductToCart === 'function') {
2149            window.alphadiAddProductToCart({
2150                id:          pending.id,
2151                name:        pending.name,
2152                price:       finalPrice,
2153                format:      finalFormat,
2154                image:       pending.image,
2155                isShippable: isShippable,
2156            });
2157        }
2158        closeModal();
2159    });
2160
2161    // Intercept add-to-cart clicks for products that ship feature data.
2162    document.addEventListener('click', function (e) {
2163        var btn = e.target.closest('[data-add-to-cart][data-cart-type="product"]');
2164        if (!btn) { return; }
2165        if (btn.disabled) { return; }
2166
2167        var raw = btn.dataset.cartFeatures;
2168        if (!raw) { return; } // no features → fall through to global handler
2169
2170        var parsed = null;
2171        try { parsed = JSON.parse(raw); } catch (_) { parsed = null; }
2172        if (!parsed || !parsed.length) { return; }
2173
2174        e.preventDefault();
2175        e.stopImmediatePropagation();
2176
2177        var shippableMap = buildShippableMap(btn.dataset.featuresRaw || '');
2178
2179        openModal({
2180            id:        btn.dataset.addToCart,
2181            name:      btn.dataset.cartName  || btn.dataset.addToCart,
2182            basePrice: parseFloat(btn.dataset.cartPrice) || 0,
2183            format:    btn.dataset.cartFormat || '',
2184            image:     btn.dataset.cartImage  || '',
2185        }, parsed, shippableMap);
2186    }, true); // capture phase — beat the global add-to-cart handler
2187})();
2188</script>
2188
2189
2190
2191    <div style="display: none !important">
2192            <a href="https://www.alphadi.org/de">Cart German</a>
2193            <a href="https://www.alphadi.org/en">Cart English</a>
2194            <a href="https://www.alphadi.org/es">Cart Spanish</a>
2195            <a href="https://www.alphadi.org/it">Cart Italian</a>
2196            <a href="https://www.alphadi.org/fr">Cart French</a>
2197            <a href="https://www.alphadi.org/pl">Cart Polish</a>
2198            <a href="https://www.alphadi.org/pt">Cart Portuguese</a>
2199    </div>
2200</body>
2201</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.