1import{a as g,t as G}from"./vendor-lit-reactive-element-Cjcwuima.js";import{b as C,x as l,E as h,e as v}from"./vendor-lit-html-nFsY_NSA.js";import{r as A}from"./vendor-lit-element-CtcYdrtK.js";import"./ds-Bp-orcBC.js";import{p as S,s as $,f as k,r as P}from"./main-BNay8OD8.js";import{t as o}from"./translations-CBNc1gDz.js";import{c as w}from"./combinedSelectLabels.utils-C0keL9fF.js";import{f as T,b as V,i as y,a as R}from"./fetchGiftCollectionProducts-ETwy0cyl.js";import"./vendor-lit-context-BDzdL6mz.js";import"./vendor-vue-runtime-dom-Dqgu9pQP.js";import"./vendor-vue-runtime-core-DAnRjgOf.js";import"./vendor-vue-reactivity-Df4oAq-x.js";import"./vendor-vue-shared-D3_Apz_L.js";import"./client-CYgaPOyd.js";const _={color:[],size:["color"],length:["color","size"]};function L(e,t,i){return!e||!t?!0:_[i].every(n=>{const s=w(e,n),c=w(t,n);return s===null||c===null?!0:s===c})}const z={tiers:[],restrictedTiers:[],nextTier:null,maxThreshold:0,currentValue:0};function O(e){const t=new Map;for(const i of[...e.claimed,...e.available,...e.next])t.has(i.code)||t.set(i.code,i);return[...t.values()].sort((i,n)=>i.threshold-n.threshold)}function E(e,t=0){var x;if(!(e!=null&&e.campaignActive))return z;const i=O(e);if(i.length===0)return z;const n=i.filter(a=>a.hasIncludes!==!0),s=i.filter(a=>a.hasIncludes===!0);if(n.length===0)return{...z,restrictedTiers:s.map(a=>({tier:a,isUnlocked:a.reached,isNext:!a.reached})),nextTier:s.find(a=>!a.reached)??null};const c=n.find(a=>!a.reached),d=n.map(a=>({tier:a,isUnlocked:a.reached,isNext:a===c})),u=n[n.length-1].threshold,p=c?c.currentValue:u,r=Math.max(0,p+t),m=t===0?d:d.map(a=>({...a,tier:{...a.tier,remaining:Math.max(0,a.tier.threshold-r)}}));return{tiers:m,restrictedTiers:s.map(a=>({tier:a,isUnlocked:a.reached,isNext:!a.reached})),nextTier:(c?((x=m.find(a=>a.isNext))==null?void 0:x.tier)??c:null)??s.find(a=>!a.reached)??null,maxThreshold:u,currentValue:r}}const I={offers:[],chosenCount:0,choosableCount:0,unlockedCount:0,lockedCount:0,nextLockedThreshold:null};function D(e){if(!(e!=null&&e.campaignActive))return I;const t=new Map(e.claimed.map(r=>[r.code,r])),i=O(e).filter(r=>r.type==="free_gift").map(r=>{const m=t.get(r.code),x=(m==null?void 0:m.claimedQuantity)??0,a=(m==null?void 0:m.remainingQuantity)??r.remainingQuantity??(x>0?0:1);return{tier:r,isUnlocked:r.reached,claimedCount:x,openCount:a,isActionable:r.reached&&a>0}});if(i.length===0)return I;const n=(r,m)=>r.reduce((x,a)=>x+m(a),0),s=i.filter(r=>r.isUnlocked),c=i.filter(r=>!r.isUnlocked),d=n(i,r=>r.claimedCount),u=n(s,r=>r.openCount),p=c.map(r=>r.tier.threshold);return{offers:i,chosenCount:d,choosableCount:u,unlockedCount:d+u,lockedCount:n(c,r=>r.openCount),nextLockedThreshold:p.length>0?Math.min(...p):null}}var F=Object.defineProperty,K=Object.getOwnPropertyDescriptor,b=(e,t,i,n)=>{for(var s=n>1?void 0:n?K(t,i):t,c=e.length-1,d;c>=0;c--)(d=e[c])&&(s=(n?d(t,i,s):d(s))||s);return n&&s&&F(t,i,s),s};function M(e){const t=e==null?void 0:e.items;return Array.isArray(t)?t.reduce((n,s)=>{const c=s==null?void 0:s.final_line_price;return n+(typeof c=="number"?c:0)},0)/100:null}const B=8e3;let f=class extends A{constructor(){super(...arguments),this.promotionState=null,this.isExpanded=!1,this._isSheetOpen=!1,this.pickerKey=null,this.pickerProducts=null,this.activeProduct=null,this.pickerFailed=!1,this.isLoadingVariant=!1,this.pendingProductId=null,this.variantRequestId=0,this.productCache=new Map,this.cartBasis=null,this.basisAtState=null,this.unsubscribe=null,this.unsubscribeCart=null,this.unsubscribeSlotPick=null,this.unsubscribeGiftChange=null,this.unsubscribeGiftAdded=null,this.addTimeoutId=null,this.replaceKey=null,this.isAddingGift=!1}get isSheetOpen(){return this._isSheetOpen}set isSheetOpen(e){this._isSheetOpen!==e&&(this._isSheetOpen=e,S("promotionSheetOpen",e))}get optimisticDelta(){return this.cartBasis===null||this.basisAtState===null?0:this.cartBasis-this.basisAtState}get model(){return E(this.promotionState,this.optimisticDelta)}get offers(){return D(this.promotionState)}connectedCallback(){super.connectedCallback(),this.unsubscribe=$("freeGiftStateUpdate",t=>{this.promotionState=t,this.basisAtState=this.cartBasis}),this.unsubscribeCart=$("cartUpdate",t=>{this.cartBasis=M(t)}),this.unsubscribeGiftAdded=$("promotionGiftAdded",()=>{this.finishAddingGift()}),this.unsubscribeGiftChange=$("promotionGiftChange",t=>{this.handleGiftChange(t??{})}),this.unsubscribeSlotPick=$("promotionSlotPick",t=>{this.handleSlotPick(t??{})});const e=window.freeGiftState;e&&(this.promotionState=e),this._isSheetOpen&&S("promotionSheetOpen",!0)}disconnectedCallback(){var e,t,i,n,s;super.disconnectedCallback(),(e=this.unsubscribe)==null||e.call(this),this.unsubscribe=null,(t=this.unsubscribeCart)==null||t.call(this),this.unsubscribeCart=null,(i=this.unsubscribeSlotPick)==null||i.call(this),this.unsubscribeSlotPick=null,(n=this.unsubscribeGiftChange)==null||n.call(this),this.unsubscribeGiftChange=null,(s=this.unsubscribeGiftAdded)==null||s.call(this),this.unsubscribeGiftAdded=null,this.addTimeoutId&&(clearTimeout(this.addTimeoutId),this.addTimeoutId=null),this._isSheetOpen&&S("promotionSheetOpen",!1)}createRenderRoot(){return this}handleToggle(){this.isExpanded=!this.isExpanded}handleOpenSheet(){this.isSheetOpen=!0}handleCloseSheet(){this.isSheetOpen=!1,this.closePicker()}handleChoose(e){const t=e.currentTarget,i=t.dataset.tierCode;if(!i)return;const n=t.dataset.collectionId;this.openPicker(i,n?()=>T(n):null)}handleGiftChange(e){const{tierCode:t,collectionId:i}=e;t&&(this.replaceKey=e.replaceKey??null,this.isSheetOpen=!0,this.openPicker(t,i?()=>T(i):null))}handleSlotPick(e){const{setCode:t,slotIndex:i,productIds:n}=e;!t||i===void 0||(this.isSheetOpen=!0,this.openPicker(`set:${t}:${i}`,n&&n.length>0?()=>V(n):null))}iconFor(e){return e.type==="free_shipping"?"free-shipping":"gift"}get headerIcon(){const{nextTier:e,tiers:t}=this.model;return e?this.iconFor(e):t.some(n=>n.tier.type==="free_gift")?"gift":"free-shipping"}tierLabel(e){return e.label?e.label:e.type==="free_shipping"?o("promotion.shipping.freeShippingFallback"):e.name}renderHeadline(){const{nextTier:e}=this.model;return e?C(o("promotion.timeline.headline",[k(e.remaining),this.tierLabel(e)])):C(o("promotion.timeline.headlineAll"))}renderStep(e){const{tier:t,isUnlocked:i,isNext:n}=e,s=i?o("promotion.timeline.unlocked"):o(n?"promotion.timeline.remaining":"promotion.timeline.from",[k(n?t.remaining:t.threshold)]);return l` 2 <hz-timeline-step 3 threshold=${t.threshold} 4 ?unlocked=${i} 5 ?next=${n} 6 icon=${this.iconFor(t)} 7 > 8 ${this.tierLabel(t)}
9 <span slot="note">${s}</span> 10 <span slot="threshold"> 11 ${k(t.threshold)} 12 </span> 13 </hz-timeline-step> 14 `}async openPicker(e,t){if(this.pickerKey=e,this.pickerProducts=null,this.activeProduct=null,this.pickerFailed=!1,!t){this.pickerFailed=!0;return}try{const i=await t();if(!this.isConnected||this.pickerKey!==e)return;const n=i.filter(y);this.pickerProducts=n;const s=n.length===1?n[0]:null;s&&await this.switchProduct(s.id)}catch(i){if(!this.isConnected)return;this.pickerFailed=!0,this.pickerProducts=[],P(new Error("Gift catalogue could not be loaded"),{tags:{cart_promotions:"gift_catalog_failed"},extra:{picker:e,cause:i}})}}closePicker(){this.pickerKey=null,this.pickerProducts=null,this.activeProduct=null,this.pickerFailed=!1,this.abandonVariantRequest()}abandonVariantRequest(){this.variantRequestId+=1,this.isLoadingVariant=!1,this.pendingProductId=null}async switchProduct(e){const t=++this.variantRequestId,i=this.productCache.get(e);if(i){this.isLoadingVariant=!1,this.pendingProductId=null,this.activeProduct=i;return}this.isLoadingVariant=!0,this.pendingProductId=e;try{const n=await R(e);if(!this.isConnected||(n&&this.productCache.set(e,n),t!==this.variantRequestId)||!n)return;this.activeProduct=n}catch(n){if(!this.isConnected)return;t===this.variantRequestId&&(this.pickerFailed=!0),P(new Error("Gift variant could not be loaded"),{tags:{cart_promotions:"gift_variant_failed"},extra:{productId:e,cause:n}})}finally{this.isConnected&&t===this.variantRequestId&&(this.isLoadingVariant=!1,this.pendingProductId=null)}}handleChooseProduct(e){const t=e.currentTarget.dataset.productId;t&&this.switchProduct(t)}handleVariantChange(e){var i;const t=(i=e.detail)==null?void 0:i.value;t&&this.switchProduct(t)}handleBackToList(){this.activeProduct=null,this.abandonVariantRequest()}get isSlotPick(){var e;return((e=this.pickerKey)==null?void 0:e.startsWith("set:"))===!0}handleConfirm(){var t;const e=(t=this.activeProduct)==null?void 0:t.variantId;!e||!this.pickerKey||(this.isAddingGift=!0,this.addTimeoutId&&clearTimeout(this.addTimeoutId),this.addTimeoutId=window.setTimeout(()=>{this.finishAddingGift()},B),this.dispatchEvent(new CustomEvent("giftadd",{bubbles:!0,composed:!0,detail:{productId:e,quantity:1,source:this.pickerKey,replaceKey:this.replaceKey}})))}finishAddingGift(){this.addTimeoutId&&(clearTimeout(this.addTimeoutId),this.addTimeoutId=null),this._isSheetOpen&&S("promotionSheetOpen",!1),this.isAddingGift=!1,this.replaceKey=null,this.closePicker(),this.isSheetOpen=!1}offerSummary(){const{chosenCount:e,choosableCount:t,unlockedCount:i,lockedCount:n,nextLockedThreshold:s}=this.offers,c=[];return i>0&&c.push(o("promotion.offers.summary",[e,i])),t>0&&c.push(o("promotion.offers.choosable",[t])),n>0&&s!==null&&c.push(o("promotion.offers.locked",[n,k(s)])),c.length===0?o("promotion.offers.openNone"):c.join(" · ")}renderOfferRow(){const{offers:e,choosableCount:t}=this.offers;if(e.length===0)return h;if(t===0)return h;const i=this.offerSummary();return l` 15 <div class="border-border border-b px-5 py-3"> 16 <button 17 type="button" 18 class=${v({"flex w-full cursor-pointer items-center gap-2.5 p-2.5 text-left transition-colors":!0,"bg-brand-100":t>0,"bg-surface-50":t===0})} 19 @click=${this.handleOpenSheet} 20 > 21 <hz-badge 22 tone="promo" 23 size="small" 24 > 25 ${o("promotion.offers.badge")} 26 </hz-badge> 27 28 <span 29 class="flex min-w-0 flex-1 flex-col gap-0.5" 30 > 31 <span 32 class="text-13 tracking-1 font-bold uppercase" 33 > 34 ${o("promotion.offers.title")} 35 </span> 36 <span class="text-12 text-surface-800"> 37 ${i} 38 </span> 39 </span> 40 41 <hz-icon 42 type="chevron-right" 43 size="small" 44 ></hz-icon> 45 </button> 46 </div> 47 `}renderOfferTile(e){const{tier:t,isUnlocked:i,claimedCount:n,isActionable:s}=e,c=i?o("promotion.timeline.from",[k(t.threshold)]):o("promotion.gift.availableFrom",[k(t.threshold)]),d=n>0?o("promotion.offers.inCart"):o("promotion.gift.free"),u=l`
48 <span class="w-13 flex-none"> 49 <hz-media-tile 50 placeholder="gift" 51 tone=${i?"promo":"neutral"} 52 ></hz-media-tile> 53 </span> 54 55 <span class="flex min-w-0 flex-1 flex-col gap-1"> 56 <span 57 class=${v({"text-10 tracking-2 font-bold uppercase":!0,"text-campaign-primary":i,"text-surface-800":!i})} 58 > 59 ${c} 60 </span> 61 <span class="text-14 leading-13 font-bold"> 62 ${this.tierLabel(t)} 63 </span> 64 <span class="text-12 text-surface-800"> 65 ${s?o("promotion.offers.choosable",[e.openCount]):o("promotion.offers.locked",[e.openCount,k(t.threshold)])} 66 </span> 67 </span> 68 69 <span 70 class="flex flex-none flex-col items-end gap-1.5 whitespace-nowrap" 71 > 72 <span 73 class=${v({"text-14 font-bold":!0,"text-success-100":n>0,"text-campaign-primary":n===0&&i,"text-surface-800":!i})} 74 > 75 ${d} 76 </span> 77 78 ${s?l` 79 <span 80 class="text-11 tracking-1 text-campaign-primary font-bold uppercase underline underline-offset-2" 81 > 82 ${o("promotion.select.chooseProduct")} 83 </span> 84 `:l` 85 <span class="text-12 text-surface-800"> 86 ${o("promotion.timeline.remaining",[k(t.remaining)])} 87 </span> 88 `} 89 </span> 90 `,p=["flex w-full gap-3 border p-3 text-left",n>0?"border-campaign-primary":"border-border"].join(" ");return s?l` 91 <li> 92 <button 93 type="button" 94 class="${p} hover:border-campaign-primary cursor-pointer transition-colors" 95 data-tier-code=${t.code} 96 data-collection-id=${t.collectionId??h} 97 @click=${this.handleChoose} 98 > 99 ${u} 100 </button> 101 </li> 102 `:l`<li class=${p}>${u}</li>`}renderOptionGroup(e,t){var u,p;if(e.length<2)return h;const i=o(`promotion.attributes.${t}`),s=e.some(r=>r.id===this.pendingProductId)?this.pendingProductId:(u=this.activeProduct)==null?void 0:u.id,c=((p=this.activeProduct)==null?void 0:p.combinedSelectLabels)??null,d=r=>r.active&&L(c,r.combinedSelectLabels,t);return l` 103 <hz-variant-picker 104 value=${s??h} 105 @change=${this.handleVariantChange} 106 > 107 <span slot="label">${i}</span> 108 ${e.map(r=>t==="color"?l` 109 <hz-swatch 110 value=${r.id} 111 color=${r.colorHexCode??h} 112 label=${w(r.combinedSelectLabels,"color")??""} 113 ?disabled=${!d(r)} 114 ></hz-swatch> 115 `:l` 116 <hz-option 117 value=${r.id} 118 ?disabled=${!d(r)} 119 > 120 ${w(r.combinedSelectLabels,t)??""} 121 </hz-option> 122 `)} 123 </hz-variant-picker> 124 `}renderProductImage(e){return l` 125 <hz-media-tile 126 placeholder="gift" 127 tone="promo" 128 > 129 ${e.featuredImage?l`<img 130 src=${e.featuredImage.url} 131 alt=${e.featuredImage.altText??""} 132 width=${e.featuredImage.width} 133 height=${e.featuredImage.height} 134 loading="lazy" 135 decoding="async" 136 />`:h} 137 </hz-media-tile> 138 `}renderProductStep(e){return l` 139 <div 140 class="promo-fade-in bg-surface-100 flex flex-col gap-2.5 p-3" 141 >
142 <span 143 class="text-11 tracking-2 text-surface-800 uppercase" 144 > 145 ${o("promotion.select.chooseProduct")} 146 </span> 147 148 <ul class="flex flex-col gap-2"> 149 ${e.map(t=>l` 150 <li> 151 <button 152 type="button" 153 class="border-border bg-surface-50 flex w-full cursor-pointer items-center gap-2.5 border p-0 pr-2.5 text-left" 154 data-product-id=${t.id} 155 @click=${this.handleChooseProduct} 156 > 157 <span class="w-12 flex-none"> 158 ${this.renderProductImage(t)} 159 </span> 160 <span 161 class="text-13 min-w-0 flex-1 leading-13 font-bold" 162 > 163 ${t.productTitle??t.title} 164 </span> 165 <hz-icon 166 type="chevron-right" 167 size="small" 168 ></hz-icon> 169 </button> 170 </li> 171 `)} 172 </ul> 173 </div> 174 `}renderVariantStep(e,t){return l` 175 <div 176 class="promo-fade-in flex flex-col gap-3.5" 177 aria-busy=${this.isLoadingVariant?"true":h} 178 > 179 <div 180 class="flex items-center justify-between gap-2.5" 181 > 182 <span 183 class="text-11 tracking-2 text-surface-800 uppercase" 184 > 185 ${o("promotion.select.chooseVariant")} 186 </span> 187 ${t?l` 188 <hz-button 189 variant="link" 190 tone="promo" 191 size="small" 192 @click=${this.handleBackToList} 193 > 194 ${o("promotion.select.showAll")} 195 </hz-button> 196 `:h} 197 </div> 198 199 <div class="flex items-center gap-2.5"> 200 <span class="w-12 flex-none"> 201 ${this.renderProductImage(e)} 202 </span> 203 <span 204 class="flex min-w-0 flex-1 flex-col gap-0.5" 205 > 206 ${e.vendor?l`<span 207 class="text-10 tracking-2 text-surface-800 uppercase" 208 > 209 ${e.vendor} 210 </span>`:h} 211 <span 212 class="text-13 leading-13 font-bold" 213 > 214 ${e.productTitle??e.title} 215 </span> 216 </span> 217 </div> 218 219 ${this.renderOptionGroup(e.selectColor,"color")} 220 ${this.renderOptionGroup(e.selectSize,"size")} 221 ${this.renderOptionGroup(e.sizeLength,"length")} 222 223 <hz-button 224 variant="primary" 225 tone="auto" 226 full-width 227 ?loading=${this.isLoadingVariant||this.isAddingGift} 228 ?disabled=${!e.variantId||!y(e)||this.isAddingGift} 229 @click=${this.handleConfirm} 230 > 231 ${y(e)?o("promotion.select.addToCart"):o("promotion.select.soldOut")} 232 </hz-button> 233 </div> 234 `}renderPicker(){if(this.pickerFailed)return l` 235 <div 236 class="bg-surface-100 text-13 text-surface-800 p-3.5" 237 role="alert" 238 > 239 ${o("cartAddModal.error")} 240 </div> 241 `;const e=this.pickerProducts;return e===null?this.renderProductStepSkeleton():e.length===0?h:this.activeProduct?this.renderVariantStep(this.activeProduct,e.length>1):this.isLoadingVariant?this.renderVariantStepSkeleton(e.length>1):this.renderProductStep(e)}renderProductStepSkeleton(){return l` 242 <div 243 class="bg-surface-100 flex flex-col gap-2.5 p-3" 244 aria-busy="true"
245 aria-live="polite" 246 aria-label=${o("promotion.app.selectGift")} 247 > 248 <span 249 class="text-11 tracking-2 text-surface-800 uppercase" 250 > 251 ${o("promotion.select.chooseProduct")} 252 </span> 253 254 <ul class="flex flex-col gap-2"> 255 ${[0,1,2].map(()=>l` 256 <li 257 class="border-border bg-surface-50 flex w-full items-center gap-2.5 border pr-2.5" 258 > 259 <span class="w-12 flex-none"> 260 <span 261 class="skeleton block aspect-[4/5] w-full" 262 ></span> 263 </span> 264 <span 265 class="skeleton h-3.5 min-w-0 flex-1" 266 ></span> 267 <span 268 class="skeleton size-3.5 flex-none" 269 ></span> 270 </li> 271 `)} 272 </ul> 273 </div> 274 `}renderVariantStepSkeleton(e){const t=i=>l` 275 <div class="flex flex-col gap-2"> 276 <span class="skeleton h-3 w-16"></span> 277 <div class="flex flex-wrap gap-2"> 278 ${[0,1,2,3,4].map(()=>i)} 279 </div> 280 </div> 281 `;return l` 282 <div 283 class="bg-surface-100 flex flex-col gap-3.5 p-3.5" 284 aria-busy="true" 285 aria-live="polite" 286 aria-label=${o("promotion.app.selectGift")} 287 > 288 <div 289 class="flex items-center justify-between gap-2.5" 290 > 291 <span 292 class="text-11 tracking-2 text-surface-800 uppercase" 293 > 294 ${o("promotion.select.chooseVariant")} 295 </span> 296 ${e?l`<span 297 class="skeleton h-3 w-20" 298 ></span>`:h} 299 </div> 300 301 <div class="flex items-center gap-2.5"> 302 <span 303 class="skeleton aspect-[4/5] w-12 flex-none" 304 ></span> 305 <span 306 class="flex min-w-0 flex-1 flex-col gap-1" 307 > 308 <span class="skeleton h-2.5 w-16"></span> 309 <span class="skeleton h-3.5 w-36"></span> 310 </span> 311 </div> 312 313 ${t(l`<span 314 class="flex size-11 flex-none items-center justify-center" 315 > 316 <span 317 class="skeleton size-6 !rounded-full" 318 ></span> 319 </span>`)} 320 ${t(l`<span 321 class="skeleton h-9.5 w-11 flex-none" 322 ></span>`)} 323 324 <span class="skeleton block h-11 w-full"></span> 325 </div> 326 `}renderSheet(){const{offers:e}=this.offers;return e.length===0?h:l` 327 <!-- 328 Abdunkeln und Weichzeichnen dahinter, damit die Flaeche nicht 329 im Warenkorb zu schweben scheint. Gleiche Sprache wie der 330 Drawer und das Wunschlisten-Modal, nur schwaecher: deren 331 10px-Unschaerfe liegt hinter einem GANZEN Drawer, diese liegt 332 mitten im Warenkorb und soll ihn zuruecksetzen, nicht 333 unkenntlich machen. 334 335 Verankert an der Buehne, dem naechsten positionierten
336 Vorfahren, deckt also alles unter der Drawer-Kopfzeile ab. Die 337 Kopfzeile steht ausserhalb dieses Kastens und bleibt dadurch 338 scharf und bedienbar, ohne dass jemand ihre Hoehe kennen muss. 339 340 z-30 und nicht z-10: die Warenkorbzeilen tragen sticky 341 positionierte Titelzeilen auf z-10. Bei gleichem z-index 342 entscheidet die DOM-Reihenfolge, und die Vue-Insel steht im 343 Liquid nach diesem Element â die Titel lagen damit VOR dem 344 Backdrop. Das Sheet darueber auf z-40. Die Insel traegt 345 zusaetzlich isolate, damit ihre z-index-Werte gar nicht erst 346 hier heraufreichen. 347 348 Geschlossen ist die Flaeche durchsichtig UND 349 pointer-events-none â sonst laege ein unsichtbarer Klickfaenger 350 ueber dem gesamten Warenkorb. 351 352 Die Klassen stehen als Ausdruck im Attribut und NICHT in einem 353 classMap: dessen Schluessel landen ab dem zweiten Render in 354 classList.add/remove, und die werfen bei einem Token mit 355 Leerzeichen. Ein Schluessel wie 'pointer-events-none opacity-0', 356 der beim Oeffnen umschlaegt, bricht damit den Render ab â das 357 Sheet ging nicht mehr auf. Mehrwortige classMap-Schluessel sind 358 nur solange harmlos, wie ihr Wert sich nie aendert. 359 --> 360 <div 361 class="${this.isSheetOpen?"opacity-100":"pointer-events-none opacity-0"} absolute inset-0 z-30 bg-black/30 backdrop-blur-[3px] transition-opacity duration-200" 362 aria-hidden="true" 363 @click=${this.handleCloseSheet} 364 ></div> 365 366 <div 367 class="pointer-events-none absolute inset-0 z-40 flex flex-col justify-end" 368 > 369 <hz-bottom-sheet 370 class="pointer-events-auto" 371 full-height 372 tone=${this.isSlotPick?"neutral":"promo"} 373 ?open=${this.isSheetOpen} 374 close-label=${o("promotion.app.close")} 375 @close=${this.handleCloseSheet} 376 > 377 <!-- 378 Set und Geschenk tragen dieselben Farben wie ihre 379 Gruppen im Warenkorb: Rust fuer die Aktion, Schwarz 380 fuer das Set. Der Grundton des Badges IST schon 381 schwarz auf weiss â 'promo' ueberschreibt ihn nur. 382 --> 383 <hz-badge 384 slot="mark" 385 tone=${this.isSlotPick?"auto":"promo"} 386 size="small" 387 > 388 ${o(this.isSlotPick?"promotion.offers.bundleBadge":"promotion.offers.badge")} 389 </hz-badge> 390 <span slot="heading"> 391 ${o(this.isSlotPick?"promotion.offers.bundleTitle":"promotion.offers.title")} 392 </span> 393 394 <!-- 395 Keine Mindesthoehe mehr: die Flaeche nimmt die Buehne 396 ganz (full-height) und reicht damit bis zur 397 Drawer-Kopfzeile. Das loest nebenbei das Springen beim 398 Wechsel von der Angebotsliste in die Auswahl â beide 399 Zustaende sind jetzt gleich hoch. 400 --> 401 <div class="px-5 py-3.5"> 402 ${this.pickerKey?this.renderPicker():l`<ul 403 class="flex flex-col gap-2.5" 404 > 405 ${e.map(t=>this.renderOfferTile(t))} 406 </ul>`} 407 </div> 408 </hz-bottom-sheet> 409 </div> 410 `}renderDisclosureIcon(){return l` 411 <span 412 class=${v({"flex transition-transform duration-300":!0,"rotate-180":!this.isExpanded})} 413 > 414 <hz-icon 415 type="chevron-up" 416 size="small" 417 ></hz-icon> 418 </span> 419 `}renderHeaderContent(e){const{nextTier:t}=this.model;return l`
420 <span 421 class="bg-campaign-primary text-campaign-primary-foreground grid size-8 flex-none place-items-center rounded-full" 422 > 423 <hz-icon 424 type=${this.headerIcon} 425 size="small" 426 ></hz-icon> 427 </span> 428 429 <span class="flex min-w-0 flex-1 flex-col gap-0.5"> 430 <span 431 class="text-10 tracking-2 text-surface-800 uppercase" 432 > 433 ${o(t?"promotion.timeline.eyebrow":"promotion.timeline.allDone")} 434 </span> 435 <span class="text-14 leading-13"> 436 ${this.renderHeadline()} 437 </span> 438 </span> 439 440 ${e} 441 `}renderRestriction(e){const t=e.includeCollections??[],[i,...n]=t;if(!i)return l`<span 442 class="text-12 text-surface-800 leading-13" 443 >${o("promotion.timeline.restrictedFallback")}</span 444 >`;const s=l`<a 445 class="text-campaign-primary underline underline-offset-2" 446 href="/collections/${i.handle}" 447 >${i.title}</a 448 >`;return l`<span 449 class="text-12 text-surface-800 leading-13" 450 >${o("promotion.timeline.restrictedOnly")} 451 ${s}${n.length>0?o("promotion.timeline.restrictedMore",[n.length]):""}</span 452 >`}renderRestrictedStep(e){const{tier:t,isUnlocked:i}=e;return l` 453 <hz-timeline-step 454 detached 455 ?unlocked=${i} 456 threshold=${t.threshold} 457 icon=${this.iconFor(t)} 458 > 459 ${this.tierLabel(t)} 460 <span slot="note"> 461 ${i?o("promotion.timeline.unlocked"):o("promotion.timeline.remaining",[k(t.remaining)])} 462 </span> 463 <span slot="note"> 464 ${this.renderRestriction(t)} 465 </span> 466 <span slot="threshold" 467 >${k(t.threshold)}</span 468 > 469 </hz-timeline-step> 470 `}renderHeaderRestriction(){const{nextTier:e}=this.model;return!e||e.hasIncludes!==!0?h:l` 471 <p class="px-5 pb-3 pl-16"> 472 ${this.renderRestriction(e)} 473 </p> 474 `}render(){const{tiers:e,restrictedTiers:t,maxThreshold:i,currentValue:n}=this.model,s=[...e,...t];if(s.length===0)return h;const c=s.length>1,d=c&&this.isExpanded,u=s.filter(a=>a.isUnlocked).length,p=c?l` 475 <span 476 class="text-surface-800 flex h-8 items-center gap-3" 477 > 478 <span class="text-15 tracking-1 uppercase"> 479 ${o("promotion.timeline.unlockedCount",[u,s.length])} 480 </span> 481 ${this.renderDisclosureIcon()} 482 </span> 483 `:h,{nextTier:r}=this.model,x=`flex w-full items-start gap-3 px-5 pt-3.5 text-left ${(r==null?void 0:r.hasIncludes)===!0?"pb-1":"pb-3"}`;return l` 484 <div class="border-border bg-surface-100 border-b"> 485 ${c?l` 486 <button 487 type="button" 488 class="${x} cursor-pointer" 489 aria-expanded=${d} 490 aria-label=${o(d?"promotion.timeline.collapse":"promotion.timeline.expand")} 491 @click=${this.handleToggle} 492 > 493 ${this.renderHeaderContent(p)} 494 </button> 495 `:l` 496 <div class=${x}> 497 ${this.renderHeaderContent(p)} 498 </div> 499 `} 500 ${this.renderHeaderRestriction()} 501 <!-- 502 Auf- und Zuklappen ueber grid-template-rows: 0fr -> 1fr. 503 height animiert nicht von auto, und Messen waere hier 504 unnoetig â das Raster kann es von sich aus. 505 506 Zugeklappt bleibt der Inhalt im DOM, damit es ueberhaupt 507 etwas zu bewegen gibt. Er ist dann inert: kein Tabstopp, 508 nichts fuer den Screenreader. Ohne das laege eine 509 unsichtbare Liste im Fokuspfad. 510 511 Die Timeline ist weiterhin dauerhaft aufgeklappt â die 512 kollabierte Darstellung der Komponente (Punkte auf einem 513 Fortschrittsbalken) wird hier nicht mehr benutzt, der 514 Entwurf kennt keinen mehr. 515 --> 516 <div 517 class="${d?"grid-rows-[1fr]":"grid-rows-[0fr]"} grid transition-[grid-template-rows] duration-300 ease-in-out motion-reduce:transition-none" 518 > 519 <div 520 class="overflow-hidden" 521 ?inert=${!d} 522 > 523 <div class="px-5 pb-3.5"> 524 <hz-timeline 525 expanded 526 value=${n} 527 max=${i} 528 accessibility-label=${o("promotion.timeline.progressLabel")} 529 > 530 ${e.map(a=>this.renderStep(a))} 531 ${t.map(a=>this.renderRestrictedStep(a))} 532 </hz-timeline> 533 </div> 534 </div> 535 </div> 536 </div> 537 538 ${this.renderOfferRow()} ${this.renderSheet()} 539 `}};b([g()],f.prototype,"promotionState",2);b([g()],f.prototype,"isExpanded",2);b([g()],f.prototype,"_isSheetOpen",2);b([g()],f.prototype,"pickerKey",2);b([g()],f.prototype,"pickerProducts",2);b([g()],f.prototype,"activeProduct",2);b([g()],f.prototype,"pickerFailed",2);b([g()],f.prototype,"isLoadingVariant",2);b([g()],f.prototype,"pendingProductId",2);b([g()],f.prototype,"cartBasis",2);b([g()],f.prototype,"isAddingGift",2);f=b([G("cart-promotions")],f);export{f as CartPromotions};
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.