shopic 0.2.7 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";(()=>{var nt=new Map,T=(t,r)=>{if(nt.has(t))throw new Error(`[shopic] Animation "${t}" is registered twice.`);nt.set(t,r)},ot=(t,r=document)=>{let a=r.querySelectorAll("[data-anim]");for(let n of a){let e=n.dataset.anim;if(!e||n.dataset.animState==="ready")continue;let s=nt.get(e);if(!s){console.warn(`[shopic] No animation registered for data-anim="${e}".`,n);continue}n.dataset.animState="ready",s(n,t)}};var It=2,Ot=150,Rt=4,Ct=1,_t=5e3,Nt=.75,qt="power3.out",Pt=[0,.25,.5,.6,.7,.8,.9,1],rt="shopic:slide-enter";T("carousel",(t,{gsap:r,reducedMotion:a})=>{let n=Array.from(t.querySelectorAll(":scope > [data-slide]"));if(n.length<2)return;let e=t.closest("section")??t.parentElement??document.body,s=Array.from(e.querySelectorAll("[data-tab]")),l=a?0:Nt,o=n.length,i=new Map(n.map((c,y)=>[c,y])),f=new Map;n.forEach((c,y)=>{let x=c.dataset.slide;x&&!f.has(x)&&f.set(x,y)});let d=[],b=()=>{let c=t.getBoundingClientRect().left,y=t.scrollLeft,x=parseFloat(getComputedStyle(t).paddingLeft)||0,I=t.scrollWidth-t.clientWidth;d=n.map(G=>Math.min(G.getBoundingClientRect().left-c+y-x,I))},p=c=>{for(let y of s){let x=y.dataset.tab===c;y.classList.toggle("is-active",x),x?y.setAttribute("aria-current","true"):y.removeAttribute("aria-current")}},h=-1,v=null,L=!1,m=!1,E,A,w=null,O=0,_=0,C=0,R=0,S=!1,N=()=>w!==null,q=()=>v!==null,P=()=>{clearTimeout(E),E=void 0},W=()=>!a&&!document.hidden&&m&&!N()&&!L&&!e.contains(document.activeElement),$=()=>{P(),W()&&(E=setTimeout(()=>{E=void 0,W()&&k((h+1)%o)},_t))},Y=c=>{let y=n[c],x=y.dataset.slide;if(x&&p(x),c!==h){h=c;for(let I of n)I.classList.toggle("is-current",I===y);y.dispatchEvent(new CustomEvent(rt))}},F=c=>{v=null,Y(c),$()},U=()=>{clearTimeout(A),r.killTweensOf(t),v=null};function k(c){if(U(),v=c,l===0){t.scrollLeft=d[c],F(c);return}r.to(t,{scrollLeft:d[c],duration:l,ease:qt,overwrite:"auto",onComplete:()=>F(c),onInterrupt:()=>{v=null}})}let z=()=>{let c=t.scrollLeft,y=0;return d.forEach((x,I)=>{Math.abs(x-c)<Math.abs(d[y]-c)&&(y=I)}),y},D=()=>{let c=z();Math.abs(d[c]-t.scrollLeft)<Ct?F(c):k(c)},tt=()=>{let c=O>0?d[O]-d[O-1]:1/0,y=O<o-1?d[O+1]-d[O]:1/0,x=Math.min(Math.abs(c),Math.abs(y));if(Math.abs(R)<x*.25){D();return}k((O+Math.sign(R)+o)%o)};for(let c of s)c.addEventListener("click",y=>{y.preventDefault();let x=c.dataset.tab??"",I=f.get(x);I!==void 0&&(P(),p(x),k(I))});let K=new Array(o).fill(0),et=new IntersectionObserver(c=>{for(let I of c){let G=i.get(I.target);G!==void 0&&(K[G]=I.isIntersecting?I.intersectionRatio:0)}let y=-1,x=0;K.forEach((I,G)=>{I<=x||(x=I,y=G)}),y!==-1&&(v!==null&&y!==v||Y(y))},{root:t,threshold:Pt});for(let c of n)et.observe(c);b(),t.style.scrollSnapType="none",t.style.touchAction="pan-y",t.addEventListener("dragstart",c=>c.preventDefault());let[u]=d;t.scrollLeft=u;let g=new ResizeObserver(b);g.observe(t);for(let c of n)g.observe(c);"onscrollend"in window?t.addEventListener("scrollend",()=>{!q()&&!N()&&D()}):t.addEventListener("scroll",()=>{q()||N()||(clearTimeout(A),A=setTimeout(D,Ot))}),t.addEventListener("pointerdown",c=>{P(),U(),w=c.pointerId,S=!1,_=c.clientX,C=t.scrollLeft,R=0,O=z()}),t.addEventListener("pointermove",c=>{if(c.pointerId!==w)return;let y=c.clientX-_;if(!S){if(Math.abs(y)<Rt)return;S=!0,t.classList.add("is-dragging"),t.setPointerCapture(c.pointerId)}R=-y*It,t.scrollLeft=C+R,c.pointerType==="mouse"&&c.preventDefault()});let M=c=>{c.pointerId===w&&(w=null,t.hasPointerCapture(c.pointerId)&&t.releasePointerCapture(c.pointerId),S?(t.classList.remove("is-dragging"),tt()):D())};window.addEventListener("pointerup",M),window.addEventListener("pointercancel",M),t.addEventListener("click",c=>{S&&(S=!1,c.preventDefault(),c.stopPropagation())},!0),e.addEventListener("pointerenter",c=>{c.pointerType==="mouse"&&(L=!0,P())}),e.addEventListener("pointerleave",c=>{c.pointerType==="mouse"&&(L=!1,$())}),e.addEventListener("focusin",P),e.addEventListener("focusout",()=>queueMicrotask($)),document.addEventListener("visibilitychange",()=>{document.hidden?P():$()}),new IntersectionObserver(c=>{m=c.some(y=>y.isIntersecting),m?$():P()},{threshold:.2}).observe(t)});var ut="!<>-_\\/[]{}=+*^?#$%01",Z=new WeakMap,V=(t,{duration:r=1050,stagger:a=.75,text:n,reducedMotion:e=!1,relaunchOnHover:s=!1}={})=>{if(e){n!==void 0&&(t.textContent=n);return}if(n!==void 0)t.dataset.scrambleText=n;else if(!t.dataset.scrambleText){let L=t.textContent;if(!L||!L.trim())return;t.dataset.scrambleText=L}let l=t.dataset.scrambleText;if(!l||!l.trim())return;let o=Array.from(l),i=o.length,f=Array.from(t.children),d;f.length===i&&f.every(L=>L.tagName==="SPAN")?d=f:(d=o.map(L=>{let m=document.createElement("span");return m.textContent=L,m}),t.textContent="",t.append(...d));let b=Symbol("scramble");Z.set(t,b);let p=o.map((L,m)=>i<=1?0:m/(i-1)*r*a),h=performance.now(),v=L=>{if(Z.get(t)!==b)return;let m=L-h,E=!0;o.forEach((A,w)=>{if(A===" "){d[w].textContent=" ";return}m>=p[w]?d[w].textContent=A:(E=!1,d[w].textContent=ut[Math.random()*ut.length|0])}),E?Z.delete(t):requestAnimationFrame(v)};requestAnimationFrame(v),s&&$t(t,{duration:r,stagger:a})},$t=(t,r)=>{t.dataset.scrambleHoverBound||(t.dataset.scrambleHoverBound="true",t.addEventListener("pointerenter",()=>{Z.has(t)||V(t,r)}))};var Dt=.5,Ft="power2.out",kt=".status-pill, .evidence_label, .evidence_sku",Gt={duration:630,stagger:.6,relaunchOnHover:!0};T("evidence",(t,{gsap:r,reducedMotion:a})=>{let n=Array.from(t.children);if(!n.length)return;if(a){for(let i of n)i.style.height="auto",i.style.opacity="1";return}let e=()=>{r.killTweensOf(n),r.set(n,{height:0,opacity:0,overflow:"hidden"});let i=r.timeline();for(let f of n)i.call(()=>{for(let d of f.querySelectorAll(kt))V(d,Gt)}),i.to(f,{height:"auto",opacity:1,duration:Dt,ease:Ft,onComplete:()=>r.set(f,{height:"auto"})})},s=!1,l=!1,o=()=>{if(!s||l)return;let i=t.closest("[data-slide]");i&&!i.classList.contains("is-current")||(l=!0,e())};if("IntersectionObserver"in window){let i=new IntersectionObserver(f=>{for(let d of f)d.isIntersecting&&(s=!0,o(),l&&i.disconnect())},{threshold:.2});i.observe(t)}else s=!0,o();t.closest("[data-slide]")?.addEventListener(rt,()=>{l=!1,o()})});var st="is-open",Vt=".faq_answer",Xt=".faq_answer-text",it=".faq_row",at=".faq_toggle",Bt=t=>{let r=Array.from(t.querySelectorAll(`${it}, ${at}, ${Vt}, ${Xt}`)),a=r.map(n=>n.style.transition);for(let n of r)n.style.transition="none";return()=>{r.forEach((n,e)=>{n.style.transition=a[e]})}};T("faq",t=>{let r=t.querySelectorAll(it);if(r.length===0){console.warn(`[shopic] faq found no ${it} to open.`,t);return}let a=[];for(let d of r){let b=d.querySelector(at);if(!b){console.warn(`[shopic] faq row has no ${at} to click.`,d);continue}a.push({row:d,toggle:b})}if(a.length===0)return;let n=d=>{for(let{row:b,toggle:p}of a){let h=b===d;b.classList.toggle(st,h),p.setAttribute("aria-expanded",String(h))}};for(let{row:d,toggle:b}of a)b.addEventListener("click",()=>{n(d.classList.contains(st)?null:d)}),b.addEventListener("keydown",p=>{p.key!=="Enter"&&p.key!==" "||(p.preventDefault(),b.click())}),b.hasAttribute("tabindex")||(b.tabIndex=0);let e=a.find(({toggle:d})=>d.getAttribute("aria-expanded")==="true");n((e??a[0]).row);let s=()=>{let d=a.find(({row:h})=>h.classList.contains(st))?.row??a[0].row,b=Bt(t);t.style.height="";let p=0;for(let{row:h}of a)n(h),p=Math.max(p,t.getBoundingClientRect().height);n(d),t.offsetHeight,Number.isFinite(p)&&p>0&&(t.style.height=`${Math.ceil(p)}px`),b()},l=0,o=t.getBoundingClientRect().width,i=()=>{cancelAnimationFrame(l),l=requestAnimationFrame(()=>{l=0,s()})};s(),new ResizeObserver(([d])=>{let b=d?.contentRect.width??t.getBoundingClientRect().width;Math.abs(b-o)<.5||(o=b,i())}).observe(t),document.fonts.ready.then(i)});var ft=8;T("focus-drift",(t,{reducedMotion:r})=>{let a=t.querySelector(":scope > .camera_focus");!a||r||(t.addEventListener("pointermove",n=>{if(n.pointerType!=="mouse")return;let e=t.getBoundingClientRect(),s=(n.clientX-e.left)/e.width-.5,l=(n.clientY-e.top)/e.height-.5,o=(s*ft*2).toFixed(1),i=(l*ft*2).toFixed(1);a.style.transform=`translate(${o}px, ${i}px)`}),t.addEventListener("pointerleave",()=>{a.style.transform=""}))});var pt=42,mt=96,Wt=2600,Yt="is-scanned",Ut="is-fresh";T("foundation-rail",(t,{gsap:r,reducedMotion:a})=>{let n=t.closest(".camera_photo"),e=Array.from(t.querySelectorAll(":scope > .foundation_slot"),m=>({element:m,parts:Array.from(m.querySelectorAll(".foundation_photo, .foundation_card")),tile:m.querySelector(".foundation_scan"),setX:r.quickSetter(m,"x","px"),home:0,turn:0,state:null}));if(!n||e.length===0){console.warn("[shopic] foundation-rail expects a .camera_photo tile around a track of .foundation_slot items.",t);return}let s=r.quickSetter(t,"x","px"),l=0,o=0,i=m=>m,f=()=>{let[m]=e,E=m.element.offsetWidth,A=E+(parseFloat(getComputedStyle(t).columnGap)||0);l=A*e.length,o=l/pt*(Wt/1e3),i=r.utils.wrap(-l/2,l/2),l<n.offsetWidth+E&&console.warn(`[shopic] foundation-rail: ${e.length} slots span ${l}px but the tile needs ${n.offsetWidth+E}px to loop without a gap.`,t);let w=n.getBoundingClientRect(),O=w.width/n.offsetWidth||1,_=(m.element.getBoundingClientRect().left-w.left)/O+E/2-n.offsetWidth/2-(Number(r.getProperty(t,"x"))||0)-(Number(r.getProperty(m.element,"x"))||0);e.forEach((C,R)=>{C.home=_+R*A,C.setX(C.turn*l)})},d=m=>m>mt?"unseen":m>mt-o?"fresh":"seen",b=(m,E)=>{if(m.state!==E){m.state=E;for(let A of m.parts)A.classList.toggle(Yt,E!=="unseen");m.tile?.classList.toggle(Ut,E==="fresh")}},p=m=>{if(l){s(-m);for(let E of e){let A=i(E.home-m),w=Math.round((A-(E.home-m))/l);w!==E.turn&&(E.turn=w,E.setX(w*l)),b(E,d(A))}}},h={t:0},v=()=>h.t*l,L=a?null:r.to(h,{t:1,duration:pt,ease:"none",repeat:-1,paused:!0,onUpdate:()=>p(v())});new ResizeObserver(()=>{f(),p(v())}).observe(t),L&&new IntersectionObserver(m=>{L.paused(!m.some(E=>E.isIntersecting))}).observe(t)});var gt="split_line",zt="split_word",yt="split_word-inner",Kt=t=>{let r=document.createDocumentFragment(),a=[],n=[],e=document.createElement("span");e.className=gt,r.appendChild(e);let s=(o,i)=>{if(!o)return;let f=document.createElement("span");f.className=zt;let d=document.createElement("span");d.className=i?`${yt} ${i}`:yt,d.textContent=o,f.appendChild(d),e.appendChild(f),a.push(f),n.push(d)},l=(o,i)=>{for(let f of o.split(/(\s+)/))f&&(/^\s+$/.test(f)?e.appendChild(document.createTextNode(" ")):s(f,i))};for(let o of Array.from(t.childNodes))o.nodeType===Node.TEXT_NODE?l(o.textContent??""):o instanceof HTMLBRElement?(e=document.createElement("span"),e.className=gt,r.appendChild(e)):o instanceof HTMLElement&&l(o.textContent??"",o.className||void 0);return t.textContent="",t.appendChild(r),{masks:a,words:n}},ht={yPercent:0,duration:.9,ease:"power4.out",stagger:.035};T("headline",(t,{gsap:r,ScrollTrigger:a,reducedMotion:n})=>{if(n){t.style.visibility="visible";return}let{masks:e,words:s}=Kt(t),l=()=>{for(let o of e)o.style.overflow="visible"};if(r.set(s,{yPercent:110}),t.style.visibility="visible",t.dataset.animTrigger==="load"||!a){r.to(s,{...ht,delay:.3,onComplete:l});return}r.to(s,{...ht,onComplete:l,scrollTrigger:{trigger:t,start:"top 85%"}})});var Zt=26;T("marquee",(t,{gsap:r,reducedMotion:a})=>{if(a)return;let n=Number(t.dataset.animSets??4),e=Number(t.dataset.animDuration??Zt);if(!Number.isFinite(n)||n<2)return;let s=()=>t.scrollWidth/n,l=r.to(t,{x:()=>-s(),duration:e,ease:"none",repeat:-1,modifiers:{x:i=>`${Number.parseFloat(i)%s()}px`}}),o=t.parentElement;o&&(o.addEventListener("pointerenter",()=>l.pause()),o.addEventListener("pointerleave",()=>l.resume()))});var jt=1.15,Et=.18,bt=10,j=8,B=.55,vt="is-visible",Tt="opacity, width, height",Jt=["name","price","packaging","sku"];T("photo-hover",(t,{reducedMotion:r})=>{let a=t.querySelector(":scope > img"),n=t.querySelector(":scope > .detect_layer"),e=t.querySelector(":scope > .camera_focus");if(!a&&!e)return;let s=e?.querySelector(".is-ring")??null,l=e?.querySelector(".is-corners")??null;e&&(!s||!l)&&console.warn("[shopic] photo-hover expects is-ring and is-corners layers inside the reticle.",e);let o=t.querySelector(":scope > .camera_readout"),i=Number(t.dataset.animZoom)||jt,f=Array.from(t.querySelectorAll(".detect_box")),d=t.querySelector('[data-match="card"]'),b=d?.querySelector('[data-match="thumb"]')??null,p=0,h=0,v=0,L=0,m=0,E=0,A=0,w=null,O=u=>u.width/t.offsetWidth||1,_=(u,g)=>{let M=t.getBoundingClientRect(),H=O(M);return{x:(u-M.left)/H,y:(g-M.top)/H,width:t.offsetWidth,height:t.offsetHeight}},C=u=>{let g=t.getBoundingClientRect(),M=u.getBoundingClientRect(),H=O(g);return{x:(M.left-g.left)/H-j,y:(M.top-g.top)/H-j,w:M.width/H+j*2,h:M.height/H+j*2}},R=()=>{let{x:u,y:g,width:M,height:H}=_(E,A),c=(u/M-.5)*M*(i-1),y=(g/H-.5)*H*(i-1),x=`translate(${c.toFixed(2)}px, ${y.toFixed(2)}px) scale(${i})`;a&&(a.style.transform=x),n&&(n.style.transform=x)},S=()=>{if(!o)return;let u=t.getBoundingClientRect();if(!u.width||!u.height)return;let g=(E-u.left)/u.width-.5,M=(A-u.top)/u.height-.5,H=(g*bt*2).toFixed(1),c=(M*bt*2).toFixed(1);o.style.setProperty("translate",`${H}px ${c}px`)},N=()=>{let{x:u,y:g}=_(E,A);return{x:u-(e?.offsetWidth??0)/2,y:g-(e?.offsetHeight??0)/2}},q=(u,g)=>{e&&(e.style.left=`${u.toFixed(2)}px`,e.style.top=`${g.toFixed(2)}px`)},P=()=>{let u=N();q(u.x,u.y),L=u.x,m=u.y,h=0,v=0,l&&(l.style.transform="")},W=()=>{let u=N();q(u.x,u.y),r||(h-=u.x-L,v-=u.y-m),L=u.x,m=u.y},$=u=>{if(!e)return;let g=C(u);q(g.x,g.y),e.style.width=`${g.w.toFixed(2)}px`,e.style.height=`${g.h.toFixed(2)}px`},Y=()=>{if(l){if(h-=h*Et,v-=v*Et,Math.abs(h)>.1||Math.abs(v)>.1){l.style.transform=`translate(${h.toFixed(2)}px, ${v.toFixed(2)}px)`;return}h=0,v=0,l.style.transform=""}},F=()=>{w?$(w):W(),Y(),p=requestAnimationFrame(F)},U=u=>{if(d){for(let g of Jt){let M=u.dataset[g],H=d.querySelector(`[data-match="${g}"]`);H&&M!==void 0&&(H.textContent=M)}if(b){let g=u.dataset.thumb;g&&(b.removeAttribute("srcset"),b.removeAttribute("sizes"),b.src=g),b.style.display=g?"":"none"}d.classList.add(vt)}},k=u=>{if(w=u,U(u),!!e&&(e.style.transitionProperty="",$(u),l&&(l.style.opacity="0"),s)){let g=(1-B)/2*100;s.style.width=`${B*100}%`,s.style.height=`${B*100}%`,s.style.left=`${g}%`,s.style.top=`${g}%`,s.style.right="auto",s.style.bottom="auto"}},z=u=>{if(!s)return;let g=C(u),{x:M,y:H}=_(E,A),c=(M-g.x)/g.w-.5,y=(H-g.y)/g.h-.5,x=c*g.w*(1-B),I=y*g.h*(1-B);s.style.setProperty("translate",`${x.toFixed(2)}px ${I.toFixed(2)}px`)},D=()=>{w=null,d?.classList.remove(vt),e&&(e.style.width="",e.style.height="",e.style.transitionProperty=Tt,l&&(l.style.opacity=""),s&&(s.style.width="",s.style.height="",s.style.left="",s.style.top="",s.style.right="",s.style.bottom="",s.style.removeProperty("translate")))},tt=u=>{u.pointerType==="mouse"&&(E=u.clientX,A=u.clientY,R(),S(),e&&(e.style.transitionProperty=Tt,P(),cancelAnimationFrame(p),p=requestAnimationFrame(F)))},K=u=>{u.pointerType==="mouse"&&(E=u.clientX,A=u.clientY,R(),S())},et=()=>{cancelAnimationFrame(p),p=0,a&&(a.style.transform=""),n&&(n.style.transform=""),o?.style.setProperty("translate","0px 0px"),D(),e&&(e.style.left="",e.style.top="",e.style.transitionProperty="",l&&(l.style.transform=""),h=0,v=0)};t.addEventListener("pointerenter",tt),t.addEventListener("pointermove",K),t.addEventListener("pointerleave",et);for(let u of f)u.addEventListener("pointerenter",g=>{g.pointerType==="mouse"&&k(u)}),u.addEventListener("pointermove",()=>{w===u&&z(u)}),u.addEventListener("pointerleave",()=>{w===u&&(D(),P())})});var Qt="display_none",lt=0,te=".platform-layers_card",ee=(t,{gsap:r,ScrollTrigger:a,reducedMotion:n})=>{if(n||!a)return;for(let p of t.querySelectorAll(te))r.set(p,{autoAlpha:0,y:"1.5rem"}),a.create({trigger:p,start:"top 85%",once:!0,onEnter:()=>{r.to(p,{autoAlpha:1,y:0,duration:.9,ease:"power4.out"})}});let e=t.querySelector(".platform-layers_layout"),s=t.querySelector(".is-layer-top"),l=t.querySelector(".is-layer-middle"),o=t.querySelector(".is-layer-bottom");if(!e||!s||!l||!o)return;let i=()=>(l.offsetTop-s.offsetTop)/2,f=()=>(o.offsetTop-s.offsetTop)/2,d=!1;r.matchMedia().add("(min-width: 992px)",()=>{let p=document.querySelector('[data-anim="scroll-topbar"]'),h=()=>Math.max(p?.offsetHeight??0,(innerHeight-e.offsetHeight)/2);if(e.offsetHeight+(p?.offsetHeight??0)>innerHeight)return;if(d){r.set([l,o],{y:0});return}let v=r.timeline({paused:!0});v.fromTo(l,{y:i},{y:0,duration:1,ease:"none"},0),v.fromTo(o,{y:f},{y:0,duration:1,ease:"none"},0),a.create({trigger:e,start:()=>`top ${h()}px`,end:()=>`+=${innerHeight}`,pin:e,invalidateOnRefresh:!0,onRefresh:()=>{v.invalidate(),d&&v.progress(1)},onUpdate:L=>{L.progress>=1&&(d=!0),v.progress(d?1:L.progress)}})});for(let p of[s,l,o])p instanceof HTMLImageElement&&!p.complete&&p.addEventListener("load",()=>a.refresh(),{once:!0})};T("platform-hotspots",(t,r)=>{ee(t,r);let a=0,n=Array.from(t.querySelectorAll("[data-platform-hotspot-wrap]")).flatMap(o=>{let i=o.querySelector("[data-platform-hotspot]"),f=o.querySelector("[data-platform-tooltip]");return!i||!f?(a+=1,[]):[{wrap:o,trigger:i,tooltip:f}]});if(a>0&&console.warn(`[shopic] platform-hotspots skipped ${a} malformed ${a===1?"group":"groups"} (a trigger and tooltip are required).`,t),n.length===0)return;n.forEach(({trigger:o,tooltip:i})=>{if(!i.id){do lt+=1;while(t.ownerDocument.getElementById(`platform-tooltip-${lt}`));i.id=`platform-tooltip-${lt}`}let f=new Set((o.getAttribute("aria-describedby")??"").split(/\s+/).filter(Boolean));f.add(i.id),o.setAttribute("aria-describedby",[...f].join(" "))});let e=(o,i)=>{o.tooltip.classList.toggle(Qt,!i),o.tooltip.style.visibility=i?"visible":"hidden",o.tooltip.style.pointerEvents=i?"auto":"none",o.trigger.setAttribute("aria-expanded",String(i))},s=()=>n.forEach(o=>e(o,!1)),l=o=>{n.forEach(i=>e(i,i===o))};s(),n.forEach(o=>{let i=null;o.wrap.addEventListener("pointerenter",f=>{f.pointerType==="mouse"&&l(o)}),o.wrap.addEventListener("pointerleave",f=>{f.pointerType==="mouse"&&!o.wrap.contains(t.ownerDocument.activeElement)&&e(o,!1)}),o.wrap.addEventListener("focusout",f=>{(!(f.relatedTarget instanceof Node)||!o.wrap.contains(f.relatedTarget))&&e(o,!1)}),o.trigger.addEventListener("pointerdown",f=>{i=f.pointerType}),o.trigger.addEventListener("focus",()=>{i!=="touch"&&i!=="pen"&&l(o)}),o.trigger.addEventListener("click",f=>{i==="touch"||i==="pen"?o.trigger.getAttribute("aria-expanded")==="true"?e(o,!1):l(o):i===null&&f.detail===0&&l(o),i=null})}),t.ownerDocument.addEventListener("pointerdown",o=>{(!(o.target instanceof Node)||n.every(i=>!i.wrap.contains(o.target)))&&s()}),t.ownerDocument.addEventListener("keydown",o=>{o.key==="Escape"&&s()})});var Lt="is-visible";T("reveal",(t,{reducedMotion:r})=>{let a=Number(t.dataset.animDelay??0);if(a&&(t.style.transitionDelay=`${a}ms`),r||!("IntersectionObserver"in window)){t.classList.add(Lt);return}let n=new IntersectionObserver(e=>{for(let s of e)s.isIntersecting&&(s.target.classList.add(Lt),n.unobserve(s.target))},{threshold:.15});n.observe(t)});T("scramble",(t,{reducedMotion:r})=>{let a={duration:Number(t.dataset.animDuration??1050),stagger:Number(t.dataset.animStagger??.75),reducedMotion:r};if(r||!("IntersectionObserver"in window)){V(t,a);return}let n=new IntersectionObserver(e=>{for(let s of e)s.isIntersecting&&(V(t,{...a,relaunchOnHover:!0}),n.unobserve(s.target))},{threshold:.2});n.observe(t)});T("scroll-topbar",t=>{let r=document.querySelector("[data-topbar-trigger]");if(!r){console.warn("[shopic] Scroll topbar is missing its trigger.");return}let a=0,n=()=>{a=0;let s=r.getBoundingClientRect().top<=t.offsetHeight;t.dataset.topbarVisible=String(s),t.style.visibility=s?"visible":"hidden",t.inert=!s,t.setAttribute("aria-hidden",String(!s))},e=()=>{a||(a=window.requestAnimationFrame(n))};window.addEventListener("scroll",e,{passive:!0}),window.addEventListener("resize",e),window.addEventListener("pageshow",e),new ResizeObserver(e).observe(document.body),n()});var J=({grouped:t=!1,prefix:r="",suffix:a="",value:n})=>{let e=Math.round(n),s=t?e.toLocaleString("en-US"):String(e);return`${r}${s}${a}`};var ne=.5,St="power4.out",oe=.18,re="power2.in",se=.35,ie=1400,ae=.15,le=420,ce=10,X=null,de=t=>{let r=t.querySelector("[data-stat-value]");return r||console.warn("[shopic] stats row is missing [data-stat-value]",t),r},ct=t=>({grouped:(t.dataset.statGrouped??t.closest('[data-anim="stats"]')?.dataset.statGrouped)==="true",prefix:t.dataset.statPrefix??t.closest('[data-anim="stats"]')?.dataset.statPrefix??"",suffix:t.dataset.statSuffix??t.closest('[data-anim="stats"]')?.dataset.statSuffix??""}),xt=(t,r)=>{t.textContent=J({...ct(t),value:r})},Q=(t,r)=>{t.classList.toggle("is-hovered",r);for(let a of t.querySelectorAll("[data-stat-label], [data-stat-hover]"))a.classList.toggle("is-hovered",r)},wt=(t,r,a,n)=>{if(a){xt(t,r);return}let e=performance.now(),s=l=>{if(n!==Number(t.dataset.statsGeneration))return;let o=Math.min((l-e)/ie,1),i=1-(1-o)**3;t.textContent=J({...ct(t),value:r*i}),o<1&&requestAnimationFrame(s)};requestAnimationFrame(s)},ue=(t,{gsap:r,reducedMotion:a})=>{let n=t,e=de(n);if(!e)return;let s=n.dataset.statCount??e.dataset.statCount,l=s===void 0?null:Number(s),o=n.dataset.statTicker??e.dataset.statTicker,i=o===void 0?null:Number(o),f=n.dataset.statTickerInterval??e.dataset.statTickerInterval,d=f===void 0?Number.NaN:Number(f),b=d>0?d:le,p=null,h=0,v=!1,L=()=>{i!==null&&(e.textContent=J({...ct(e),value:i}))},m=()=>{a||i===null||p!==null||(p=setInterval(()=>{i!==null&&(i+=1+Math.floor(Math.random()*3),L())},b))},E=()=>{p!==null&&(clearInterval(p),p=null)},A=()=>{h+=1,e.dataset.statsGeneration=String(h),l!==null?xt(e,l):L(),r.set(e,{clearProps:"transform"})},w=S=>{h+=1,e.dataset.statsGeneration=String(h),r.killTweensOf(e),r.set(e,{yPercent:110}),r.to(e,{duration:ne,ease:St,yPercent:0}),S&&l!==null&&wt(e,l,a,h)};if(a){A();return}L(),r.set(e,{yPercent:110});let O=()=>{v||(v=!0,w(!0))};if("IntersectionObserver"in window){let S=new IntersectionObserver(N=>{N.some(q=>q.isIntersecting)&&(O(),S.disconnect())},{threshold:ae});S.observe(n)}else O();i!==null&&("IntersectionObserver"in window?new IntersectionObserver(N=>{N.some(q=>q.isIntersecting)?m():E()}).observe(n):m());let _=()=>{Q(n,!0),h+=1,e.dataset.statsGeneration=String(h),r.killTweensOf(e),r.timeline().to(e,{duration:oe,ease:re,yPercent:-110}).set(e,{yPercent:110}).to(e,{duration:se,ease:St,onStart:()=>{l!==null&&wt(e,l,a,h)},yPercent:0})};n.addEventListener("pointerenter",S=>{S.pointerType==="mouse"&&_()}),n.addEventListener("pointerleave",S=>{S.pointerType==="mouse"&&Q(n,!1)});let C=0,R=0;n.addEventListener("pointerdown",S=>{S.pointerType!=="mouse"&&(C=S.clientX,R=S.clientY)}),n.addEventListener("pointerup",S=>{if(S.pointerType!=="mouse"&&!(Math.hypot(S.clientX-C,S.clientY-R)>ce)){if(X&&X!==n&&Q(X,!1),X===n){Q(n,!1),X=null;return}X=n,_()}})};T("stats",ue);var dt=t=>String(t).padStart(2,"0");T("timer",t=>{let r=()=>{let a=new Date;t.textContent=`${dt(a.getHours())}:${dt(a.getMinutes())}:${dt(a.getSeconds())}`};r(),setInterval(r,1e3)});var At="is-active",fe="(max-width: 991px)";T("versus-tabs",t=>{let r=Array.from(t.querySelectorAll('[role="tab"]')),a=t.nextElementSibling,n=a?Array.from(a.querySelectorAll(":scope > *")):[];if(r.length===0||r.length!==n.length){console.warn(`[shopic] versus-tabs expects one tab per panel; found ${r.length} tabs and ${n.length} panels.`,t);return}let e=window.matchMedia(fe),s=o=>{r.forEach((i,f)=>{i.classList.toggle(At,f===o),i.setAttribute("aria-selected",String(f===o))}),n.forEach((i,f)=>{i.hidden=e.matches&&f!==o})},l=()=>Math.max(0,r.indexOf(t.querySelector(`.${At}`)));r.forEach((o,i)=>{o.addEventListener("click",()=>s(i)),o.addEventListener("keydown",f=>{(f.key==="Enter"||f.key===" ")&&(f.preventDefault(),s(i))}),o.hasAttribute("tabindex")||(o.tabIndex=0)}),e.addEventListener("change",()=>s(l())),s(l())});var Mt=()=>{let{gsap:t,ScrollTrigger:r}=window;if(!t)throw new Error("[shopic] GSAP is not on the page. Enable it in Webflow \u2192 Site Settings \u2192 Custom Code \u2192 GSAP.");return r&&t.registerPlugin(r),{gsap:t,ScrollTrigger:r}},Ht=()=>window.matchMedia("(prefers-reduced-motion: reduce)").matches;window.Webflow||(window.Webflow=[]);window.Webflow.push(()=>{let{gsap:t,ScrollTrigger:r}=Mt();ot({gsap:t,ScrollTrigger:r,reducedMotion:Ht()})});})();
1
+ "use strict";(()=>{var ot=new Map,v=(t,r)=>{if(ot.has(t))throw new Error(`[shopic] Animation "${t}" is registered twice.`);ot.set(t,r)},rt=(t,r=document)=>{let a=r.querySelectorAll("[data-anim]");for(let n of a){let e=n.dataset.anim;if(!e||n.dataset.animState==="ready")continue;let i=ot.get(e);if(!i){console.warn(`[shopic] No animation registered for data-anim="${e}".`,n);continue}n.dataset.animState="ready",i(n,t)}};var Ct=2,_t=150,Nt=4,qt=1,Pt=5e3,Dt=.75,$t="power3.out",Ft=[0,.25,.5,.6,.7,.8,.9,1],st="shopic:slide-enter";v("carousel",(t,{gsap:r,reducedMotion:a})=>{let n=Array.from(t.querySelectorAll(":scope > [data-slide]"));if(n.length<2)return;let e=t.closest("section")??t.parentElement??document.body,i=Array.from(e.querySelectorAll("[data-tab]")),l=a?0:Dt,o=n.length,s=new Map(n.map((c,E)=>[c,E])),u=new Map;n.forEach((c,E)=>{let x=c.dataset.slide;x&&!u.has(x)&&u.set(x,E)});let d=[],y=()=>{let c=t.getBoundingClientRect().left,E=t.scrollLeft,x=parseFloat(getComputedStyle(t).paddingLeft)||0,I=t.scrollWidth-t.clientWidth;d=n.map(G=>Math.min(G.getBoundingClientRect().left-c+E-x,I))},p=c=>{for(let E of i){let x=E.dataset.tab===c;E.classList.toggle("is-active",x),x?E.setAttribute("aria-current","true"):E.removeAttribute("aria-current")}},h=-1,b=null,L=!1,m=!1,T,A,w=null,R=0,_=0,C=0,O=0,S=!1,N=()=>w!==null,q=()=>b!==null,P=()=>{clearTimeout(T),T=void 0},W=()=>!a&&!document.hidden&&m&&!N()&&!L&&!e.contains(document.activeElement),D=()=>{P(),W()&&(T=setTimeout(()=>{T=void 0,W()&&k((h+1)%o)},Pt))},U=c=>{let E=n[c],x=E.dataset.slide;if(x&&p(x),c!==h){h=c;for(let I of n)I.classList.toggle("is-current",I===E);E.dispatchEvent(new CustomEvent(st))}},F=c=>{b=null,U(c),D()},Y=()=>{clearTimeout(A),r.killTweensOf(t),b=null};function k(c){if(Y(),b=c,l===0){t.scrollLeft=d[c],F(c);return}r.to(t,{scrollLeft:d[c],duration:l,ease:$t,overwrite:"auto",onComplete:()=>F(c),onInterrupt:()=>{b=null}})}let z=()=>{let c=t.scrollLeft,E=0;return d.forEach((x,I)=>{Math.abs(x-c)<Math.abs(d[E]-c)&&(E=I)}),E},$=()=>{let c=z();Math.abs(d[c]-t.scrollLeft)<qt?F(c):k(c)},et=()=>{let c=R>0?d[R]-d[R-1]:1/0,E=R<o-1?d[R+1]-d[R]:1/0,x=Math.min(Math.abs(c),Math.abs(E));if(Math.abs(O)<x*.25){$();return}k((R+Math.sign(O)+o)%o)};for(let c of i)c.addEventListener("click",E=>{E.preventDefault();let x=c.dataset.tab??"",I=u.get(x);I!==void 0&&(P(),p(x),k(I))});let K=new Array(o).fill(0),nt=new IntersectionObserver(c=>{for(let I of c){let G=s.get(I.target);G!==void 0&&(K[G]=I.isIntersecting?I.intersectionRatio:0)}let E=-1,x=0;K.forEach((I,G)=>{I<=x||(x=I,E=G)}),E!==-1&&(b!==null&&E!==b||U(E))},{root:t,threshold:Ft});for(let c of n)nt.observe(c);y(),t.style.scrollSnapType="none",t.style.touchAction="pan-y",t.addEventListener("dragstart",c=>c.preventDefault());let[f]=d;t.scrollLeft=f;let g=new ResizeObserver(y);g.observe(t);for(let c of n)g.observe(c);"onscrollend"in window?t.addEventListener("scrollend",()=>{!q()&&!N()&&$()}):t.addEventListener("scroll",()=>{q()||N()||(clearTimeout(A),A=setTimeout($,_t))}),t.addEventListener("pointerdown",c=>{P(),Y(),w=c.pointerId,S=!1,_=c.clientX,C=t.scrollLeft,O=0,R=z()}),t.addEventListener("pointermove",c=>{if(c.pointerId!==w)return;let E=c.clientX-_;if(!S){if(Math.abs(E)<Nt)return;S=!0,t.classList.add("is-dragging"),t.setPointerCapture(c.pointerId)}O=-E*Ct,t.scrollLeft=C+O,c.pointerType==="mouse"&&c.preventDefault()});let M=c=>{c.pointerId===w&&(w=null,t.hasPointerCapture(c.pointerId)&&t.releasePointerCapture(c.pointerId),S?(t.classList.remove("is-dragging"),et()):$())};window.addEventListener("pointerup",M),window.addEventListener("pointercancel",M),t.addEventListener("click",c=>{S&&(S=!1,c.preventDefault(),c.stopPropagation())},!0),e.addEventListener("pointerenter",c=>{c.pointerType==="mouse"&&(L=!0,P())}),e.addEventListener("pointerleave",c=>{c.pointerType==="mouse"&&(L=!1,D())}),e.addEventListener("focusin",P),e.addEventListener("focusout",()=>queueMicrotask(D)),document.addEventListener("visibilitychange",()=>{document.hidden?P():D()}),new IntersectionObserver(c=>{m=c.some(E=>E.isIntersecting),m?D():P()},{threshold:.2}).observe(t)});var mt="!<>-_\\/[]{}=+*^?#$%01",Z=new WeakMap,V=(t,{duration:r=1050,stagger:a=.75,text:n,reducedMotion:e=!1,relaunchOnHover:i=!1}={})=>{if(e){n!==void 0&&(t.textContent=n);return}if(n!==void 0)t.dataset.scrambleText=n;else if(!t.dataset.scrambleText){let L=t.textContent;if(!L||!L.trim())return;t.dataset.scrambleText=L}let l=t.dataset.scrambleText;if(!l||!l.trim())return;let o=Array.from(l),s=o.length,u=Array.from(t.children),d;u.length===s&&u.every(L=>L.tagName==="SPAN")?d=u:(d=o.map(L=>{let m=document.createElement("span");return m.textContent=L,m}),t.textContent="",t.append(...d));let y=Symbol("scramble");Z.set(t,y);let p=o.map((L,m)=>s<=1?0:m/(s-1)*r*a),h=performance.now(),b=L=>{if(Z.get(t)!==y)return;let m=L-h,T=!0;o.forEach((A,w)=>{if(A===" "){d[w].textContent=" ";return}m>=p[w]?d[w].textContent=A:(T=!1,d[w].textContent=mt[Math.random()*mt.length|0])}),T?Z.delete(t):requestAnimationFrame(b)};requestAnimationFrame(b),i&&kt(t,{duration:r,stagger:a})},kt=(t,r)=>{t.dataset.scrambleHoverBound||(t.dataset.scrambleHoverBound="true",t.addEventListener("pointerenter",()=>{Z.has(t)||V(t,r)}))};var Gt=.5,Vt="power2.out",Xt=".status-pill, .evidence_label, .evidence_sku",Bt={duration:630,stagger:.6,relaunchOnHover:!0};v("evidence",(t,{gsap:r,reducedMotion:a})=>{let n=Array.from(t.children);if(!n.length)return;if(a){for(let s of n)s.style.height="auto",s.style.opacity="1";return}let e=()=>{r.killTweensOf(n),r.set(n,{height:0,opacity:0,overflow:"hidden"});let s=r.timeline();for(let u of n)s.call(()=>{for(let d of u.querySelectorAll(Xt))V(d,Bt)}),s.to(u,{height:"auto",opacity:1,duration:Gt,ease:Vt,onComplete:()=>r.set(u,{height:"auto"})})},i=!1,l=!1,o=()=>{if(!i||l)return;let s=t.closest("[data-slide]");s&&!s.classList.contains("is-current")||(l=!0,e())};if("IntersectionObserver"in window){let s=new IntersectionObserver(u=>{for(let d of u)d.isIntersecting&&(i=!0,o(),l&&s.disconnect())},{threshold:.2});s.observe(t)}else i=!0,o();t.closest("[data-slide]")?.addEventListener(st,()=>{l=!1,o()})});var it="is-open",Wt=".faq_answer",Ut=".faq_answer-text",at=".faq_row",lt=".faq_toggle",Yt=t=>{let r=Array.from(t.querySelectorAll(`${at}, ${lt}, ${Wt}, ${Ut}`)),a=r.map(n=>n.style.transition);for(let n of r)n.style.transition="none";return()=>{r.forEach((n,e)=>{n.style.transition=a[e]})}};v("faq",t=>{let r=t.querySelectorAll(at);if(r.length===0){console.warn(`[shopic] faq found no ${at} to open.`,t);return}let a=[];for(let d of r){let y=d.querySelector(lt);if(!y){console.warn(`[shopic] faq row has no ${lt} to click.`,d);continue}a.push({row:d,toggle:y})}if(a.length===0)return;let n=d=>{for(let{row:y,toggle:p}of a){let h=y===d;y.classList.toggle(it,h),p.setAttribute("aria-expanded",String(h))}};for(let{row:d,toggle:y}of a)y.addEventListener("click",()=>{n(d.classList.contains(it)?null:d)}),y.addEventListener("keydown",p=>{p.key!=="Enter"&&p.key!==" "||(p.preventDefault(),y.click())}),y.hasAttribute("tabindex")||(y.tabIndex=0);let e=a.find(({toggle:d})=>d.getAttribute("aria-expanded")==="true");n((e??a[0]).row);let i=()=>{let d=a.find(({row:h})=>h.classList.contains(it))?.row??a[0].row,y=Yt(t);t.style.height="";let p=0;for(let{row:h}of a)n(h),p=Math.max(p,t.getBoundingClientRect().height);n(d),t.offsetHeight,Number.isFinite(p)&&p>0&&(t.style.height=`${Math.ceil(p)}px`),y()},l=0,o=t.getBoundingClientRect().width,s=()=>{cancelAnimationFrame(l),l=requestAnimationFrame(()=>{l=0,i()})};i(),new ResizeObserver(([d])=>{let y=d?.contentRect.width??t.getBoundingClientRect().width;Math.abs(y-o)<.5||(o=y,s())}).observe(t),document.fonts.ready.then(s)});var gt=8;v("focus-drift",(t,{reducedMotion:r})=>{let a=t.querySelector(":scope > .camera_focus");!a||r||(t.addEventListener("pointermove",n=>{if(n.pointerType!=="mouse")return;let e=t.getBoundingClientRect(),i=(n.clientX-e.left)/e.width-.5,l=(n.clientY-e.top)/e.height-.5,o=(i*gt*2).toFixed(1),s=(l*gt*2).toFixed(1);a.style.transform=`translate(${o}px, ${s}px)`}),t.addEventListener("pointerleave",()=>{a.style.transform=""}))});var yt=42,ht=96,zt=2600,Kt="is-scanned",Zt="is-fresh";v("foundation-rail",(t,{gsap:r,reducedMotion:a})=>{let n=t.closest(".camera_photo"),e=Array.from(t.querySelectorAll(":scope > .foundation_slot"),m=>({element:m,parts:Array.from(m.querySelectorAll(".foundation_photo, .foundation_card")),tile:m.querySelector(".foundation_scan"),setX:r.quickSetter(m,"x","px"),home:0,turn:0,state:null}));if(!n||e.length===0){console.warn("[shopic] foundation-rail expects a .camera_photo tile around a track of .foundation_slot items.",t);return}let i=r.quickSetter(t,"x","px"),l=0,o=0,s=m=>m,u=()=>{let[m]=e,T=m.element.offsetWidth,A=T+(parseFloat(getComputedStyle(t).columnGap)||0);l=A*e.length,o=l/yt*(zt/1e3),s=r.utils.wrap(-l/2,l/2),l<n.offsetWidth+T&&console.warn(`[shopic] foundation-rail: ${e.length} slots span ${l}px but the tile needs ${n.offsetWidth+T}px to loop without a gap.`,t);let w=n.getBoundingClientRect(),R=w.width/n.offsetWidth||1,_=(m.element.getBoundingClientRect().left-w.left)/R+T/2-n.offsetWidth/2-(Number(r.getProperty(t,"x"))||0)-(Number(r.getProperty(m.element,"x"))||0);e.forEach((C,O)=>{C.home=_+O*A,C.setX(C.turn*l)})},d=m=>m>ht?"unseen":m>ht-o?"fresh":"seen",y=(m,T)=>{if(m.state!==T){m.state=T;for(let A of m.parts)A.classList.toggle(Kt,T!=="unseen");m.tile?.classList.toggle(Zt,T==="fresh")}},p=m=>{if(l){i(-m);for(let T of e){let A=s(T.home-m),w=Math.round((A-(T.home-m))/l);w!==T.turn&&(T.turn=w,T.setX(w*l)),y(T,d(A))}}},h={t:0},b=()=>h.t*l,L=a?null:r.to(h,{t:1,duration:yt,ease:"none",repeat:-1,paused:!0,onUpdate:()=>p(b())});new ResizeObserver(()=>{u(),p(b())}).observe(t),L&&new IntersectionObserver(m=>{L.paused(!m.some(T=>T.isIntersecting))}).observe(t)});var Et="split_line",jt="split_word",Tt="split_word-inner",Jt=t=>{let r=document.createDocumentFragment(),a=[],n=[],e=document.createElement("span");e.className=Et,r.appendChild(e);let i=(o,s)=>{if(!o)return;let u=document.createElement("span");u.className=jt;let d=document.createElement("span");d.className=s?`${Tt} ${s}`:Tt,d.textContent=o,u.appendChild(d),e.appendChild(u),a.push(u),n.push(d)},l=(o,s)=>{for(let u of o.split(/(\s+)/))u&&(/^\s+$/.test(u)?e.appendChild(document.createTextNode(" ")):i(u,s))};for(let o of Array.from(t.childNodes))o.nodeType===Node.TEXT_NODE?l(o.textContent??""):o instanceof HTMLBRElement?(e=document.createElement("span"),e.className=Et,r.appendChild(e)):o instanceof HTMLElement&&l(o.textContent??"",o.className||void 0);return t.textContent="",t.appendChild(r),{masks:a,words:n}},vt={yPercent:0,duration:.9,ease:"power4.out",stagger:.035};v("headline",(t,{gsap:r,ScrollTrigger:a,reducedMotion:n})=>{if(n){t.style.visibility="visible";return}let{masks:e,words:i}=Jt(t),l=()=>{for(let o of e)o.style.overflow="visible"};if(r.set(i,{yPercent:110}),t.style.visibility="visible",t.dataset.animTrigger==="load"||!a){r.to(i,{...vt,delay:.3,onComplete:l});return}r.to(i,{...vt,onComplete:l,scrollTrigger:{trigger:t,start:"top 85%"}})});var Qt=26;v("marquee",(t,{gsap:r,reducedMotion:a})=>{if(a)return;let n=Number(t.dataset.animSets??4),e=Number(t.dataset.animDuration??Qt);if(!Number.isFinite(n)||n<2)return;let i=()=>t.scrollWidth/n,l=r.to(t,{x:()=>-i(),duration:e,ease:"none",repeat:-1,modifiers:{x:s=>`${Number.parseFloat(s)%i()}px`}}),o=t.parentElement;o&&(o.addEventListener("pointerenter",()=>l.pause()),o.addEventListener("pointerleave",()=>l.resume()))});var te=1.15,bt=.18,Lt=10,j=8,B=.55,St="is-visible",wt="opacity, width, height",ee=["name","price","packaging","sku"];v("photo-hover",(t,{reducedMotion:r})=>{let a=t.querySelector(":scope > img"),n=t.querySelector(":scope > .detect_layer"),e=t.querySelector(":scope > .camera_focus");if(!a&&!e)return;let i=e?.querySelector(".is-ring")??null,l=e?.querySelector(".is-corners")??null;e&&(!i||!l)&&console.warn("[shopic] photo-hover expects is-ring and is-corners layers inside the reticle.",e);let o=t.querySelector(":scope > .camera_readout"),s=Number(t.dataset.animZoom)||te,u=Array.from(t.querySelectorAll(".detect_box")),d=t.querySelector('[data-match="card"]'),y=d?.querySelector('[data-match="thumb"]')??null,p=0,h=0,b=0,L=0,m=0,T=0,A=0,w=null,R=f=>f.width/t.offsetWidth||1,_=(f,g)=>{let M=t.getBoundingClientRect(),H=R(M);return{x:(f-M.left)/H,y:(g-M.top)/H,width:t.offsetWidth,height:t.offsetHeight}},C=f=>{let g=t.getBoundingClientRect(),M=f.getBoundingClientRect(),H=R(g);return{x:(M.left-g.left)/H-j,y:(M.top-g.top)/H-j,w:M.width/H+j*2,h:M.height/H+j*2}},O=()=>{let{x:f,y:g,width:M,height:H}=_(T,A),c=(f/M-.5)*M*(s-1),E=(g/H-.5)*H*(s-1),x=`translate(${c.toFixed(2)}px, ${E.toFixed(2)}px) scale(${s})`;a&&(a.style.transform=x),n&&(n.style.transform=x)},S=()=>{if(!o)return;let f=t.getBoundingClientRect();if(!f.width||!f.height)return;let g=(T-f.left)/f.width-.5,M=(A-f.top)/f.height-.5,H=(g*Lt*2).toFixed(1),c=(M*Lt*2).toFixed(1);o.style.setProperty("translate",`${H}px ${c}px`)},N=()=>{let{x:f,y:g}=_(T,A);return{x:f-(e?.offsetWidth??0)/2,y:g-(e?.offsetHeight??0)/2}},q=(f,g)=>{e&&(e.style.left=`${f.toFixed(2)}px`,e.style.top=`${g.toFixed(2)}px`)},P=()=>{let f=N();q(f.x,f.y),L=f.x,m=f.y,h=0,b=0,l&&(l.style.transform="")},W=()=>{let f=N();q(f.x,f.y),r||(h-=f.x-L,b-=f.y-m),L=f.x,m=f.y},D=f=>{if(!e)return;let g=C(f);q(g.x,g.y),e.style.width=`${g.w.toFixed(2)}px`,e.style.height=`${g.h.toFixed(2)}px`},U=()=>{if(l){if(h-=h*bt,b-=b*bt,Math.abs(h)>.1||Math.abs(b)>.1){l.style.transform=`translate(${h.toFixed(2)}px, ${b.toFixed(2)}px)`;return}h=0,b=0,l.style.transform=""}},F=()=>{w?D(w):W(),U(),p=requestAnimationFrame(F)},Y=f=>{if(d){for(let g of ee){let M=f.dataset[g],H=d.querySelector(`[data-match="${g}"]`);H&&M!==void 0&&(H.textContent=M)}if(y){let g=f.dataset.thumb;g&&(y.removeAttribute("srcset"),y.removeAttribute("sizes"),y.src=g),y.style.display=g?"":"none"}d.classList.add(St)}},k=f=>{if(w=f,Y(f),!!e&&(e.style.transitionProperty="",D(f),l&&(l.style.opacity="0"),i)){let g=(1-B)/2*100;i.style.width=`${B*100}%`,i.style.height=`${B*100}%`,i.style.left=`${g}%`,i.style.top=`${g}%`,i.style.right="auto",i.style.bottom="auto"}},z=f=>{if(!i)return;let g=C(f),{x:M,y:H}=_(T,A),c=(M-g.x)/g.w-.5,E=(H-g.y)/g.h-.5,x=c*g.w*(1-B),I=E*g.h*(1-B);i.style.setProperty("translate",`${x.toFixed(2)}px ${I.toFixed(2)}px`)},$=()=>{w=null,d?.classList.remove(St),e&&(e.style.width="",e.style.height="",e.style.transitionProperty=wt,l&&(l.style.opacity=""),i&&(i.style.width="",i.style.height="",i.style.left="",i.style.top="",i.style.right="",i.style.bottom="",i.style.removeProperty("translate")))},et=f=>{f.pointerType==="mouse"&&(T=f.clientX,A=f.clientY,O(),S(),e&&(e.style.transitionProperty=wt,P(),cancelAnimationFrame(p),p=requestAnimationFrame(F)))},K=f=>{f.pointerType==="mouse"&&(T=f.clientX,A=f.clientY,O(),S())},nt=()=>{cancelAnimationFrame(p),p=0,a&&(a.style.transform=""),n&&(n.style.transform=""),o?.style.setProperty("translate","0px 0px"),$(),e&&(e.style.left="",e.style.top="",e.style.transitionProperty="",l&&(l.style.transform=""),h=0,b=0)};t.addEventListener("pointerenter",et),t.addEventListener("pointermove",K),t.addEventListener("pointerleave",nt);for(let f of u)f.addEventListener("pointerenter",g=>{g.pointerType==="mouse"&&k(f)}),f.addEventListener("pointermove",()=>{w===f&&z(f)}),f.addEventListener("pointerleave",()=>{w===f&&($(),P())})});var ne="display_none",ct=0,oe=".platform-layers_card",re=(t,{gsap:r,ScrollTrigger:a,reducedMotion:n})=>{if(n||!a)return;for(let p of t.querySelectorAll(oe))r.set(p,{autoAlpha:0,y:"1.5rem"}),a.create({trigger:p,start:"top 85%",once:!0,onEnter:()=>{r.to(p,{autoAlpha:1,y:0,duration:.9,ease:"power4.out"})}});let e=t.querySelector(".platform-layers_layout"),i=t.querySelector(".is-layer-top"),l=t.querySelector(".is-layer-middle"),o=t.querySelector(".is-layer-bottom");if(!e||!i||!l||!o)return;let s=()=>(l.offsetTop-i.offsetTop)/2,u=()=>(o.offsetTop-i.offsetTop)/2,d=!1;r.matchMedia().add("(min-width: 992px)",()=>{let p=document.querySelector('[data-anim="scroll-topbar"]'),h=()=>Math.max(p?.offsetHeight??0,(innerHeight-e.offsetHeight)/2);if(e.offsetHeight+(p?.offsetHeight??0)>innerHeight)return;if(d){r.set([l,o],{y:0});return}let b=r.timeline({paused:!0});b.fromTo(l,{y:s},{y:0,duration:1,ease:"none"},0),b.fromTo(o,{y:u},{y:0,duration:1,ease:"none"},0),a.create({trigger:e,start:()=>`top ${h()}px`,end:()=>`+=${innerHeight}`,pin:e,invalidateOnRefresh:!0,onRefresh:()=>{b.invalidate(),d&&b.progress(1)},onUpdate:L=>{L.progress>=1&&(d=!0),b.progress(d?1:L.progress)}})});for(let p of[i,l,o])p instanceof HTMLImageElement&&!p.complete&&p.addEventListener("load",()=>a.refresh(),{once:!0})};v("platform-hotspots",(t,r)=>{re(t,r);let a=0,n=Array.from(t.querySelectorAll("[data-platform-hotspot-wrap]")).flatMap(o=>{let s=o.querySelector("[data-platform-hotspot]"),u=o.querySelector("[data-platform-tooltip]");return!s||!u?(a+=1,[]):[{wrap:o,trigger:s,tooltip:u}]});if(a>0&&console.warn(`[shopic] platform-hotspots skipped ${a} malformed ${a===1?"group":"groups"} (a trigger and tooltip are required).`,t),n.length===0)return;n.forEach(({trigger:o,tooltip:s})=>{if(!s.id){do ct+=1;while(t.ownerDocument.getElementById(`platform-tooltip-${ct}`));s.id=`platform-tooltip-${ct}`}let u=new Set((o.getAttribute("aria-describedby")??"").split(/\s+/).filter(Boolean));u.add(s.id),o.setAttribute("aria-describedby",[...u].join(" "))});let e=(o,s)=>{o.tooltip.classList.toggle(ne,!s),o.tooltip.style.visibility=s?"visible":"hidden",o.tooltip.style.pointerEvents=s?"auto":"none",o.trigger.setAttribute("aria-expanded",String(s))},i=()=>n.forEach(o=>e(o,!1)),l=o=>{n.forEach(s=>e(s,s===o))};i(),n.forEach(o=>{let s=null;o.wrap.addEventListener("pointerenter",u=>{u.pointerType==="mouse"&&l(o)}),o.wrap.addEventListener("pointerleave",u=>{u.pointerType==="mouse"&&!o.wrap.contains(t.ownerDocument.activeElement)&&e(o,!1)}),o.wrap.addEventListener("focusout",u=>{(!(u.relatedTarget instanceof Node)||!o.wrap.contains(u.relatedTarget))&&e(o,!1)}),o.trigger.addEventListener("pointerdown",u=>{s=u.pointerType}),o.trigger.addEventListener("focus",()=>{s!=="touch"&&s!=="pen"&&l(o)}),o.trigger.addEventListener("click",u=>{s==="touch"||s==="pen"?o.trigger.getAttribute("aria-expanded")==="true"?e(o,!1):l(o):s===null&&u.detail===0&&l(o),s=null})}),t.ownerDocument.addEventListener("pointerdown",o=>{(!(o.target instanceof Node)||n.every(s=>!s.wrap.contains(o.target)))&&i()}),t.ownerDocument.addEventListener("keydown",o=>{o.key==="Escape"&&i()})});var xt="is-visible";v("reveal",(t,{reducedMotion:r})=>{let a=Number(t.dataset.animDelay??0);if(a&&(t.style.transitionDelay=`${a}ms`),r||!("IntersectionObserver"in window)){t.classList.add(xt);return}let n=new IntersectionObserver(e=>{for(let i of e)i.isIntersecting&&(i.target.classList.add(xt),n.unobserve(i.target))},{threshold:.15});n.observe(t)});var dt=.5,J="power2.out",se=.7,ut=.08,ie=".scene_box",ae=".scene_chip",le=".scene_node",ce=".camera_hotspot",de=".scene_card",ue=".scene_links path",fe=t=>({boxes:Array.from(t.querySelectorAll(ie)),chips:Array.from(t.querySelectorAll(ae)),nodes:Array.from(t.querySelectorAll(le)),reticles:Array.from(t.querySelectorAll(ce)),cards:Array.from(t.querySelectorAll(de)),curves:Array.from(t.querySelectorAll(ue))}),pe=t=>[...t.boxes,...t.chips,...t.nodes,...t.reticles,...t.cards,...t.curves],me=t=>{let r=typeof t.getTotalLength=="function"?t.getTotalLength():0;return r?(t.style.strokeDasharray=`${r}`,t.style.strokeDashoffset=`${r}`,r):0};v("scene",(t,{gsap:r,ScrollTrigger:a,reducedMotion:n})=>{let e=fe(t),i=pe(e);if(!i.length||n||!a)return;let l=e.curves.map(me);r.set(i,{opacity:0});let o=()=>{let s=r.timeline(),u=(d,y,p,h)=>{d.length&&s.fromTo(d,y,p,h)};u(e.boxes,{opacity:0,scale:.94},{opacity:1,scale:1,duration:dt,ease:J,stagger:ut}),u([...e.chips,...e.reticles],{opacity:0,y:4},{opacity:1,y:0,duration:dt,ease:J,stagger:ut},"-=0.25");for(let[d,y]of e.curves.entries()){if(!l[d]){s.set(y,{opacity:1},"<");continue}s.set(y,{opacity:1},d===0?"-=0.15":"<"),s.to(y,{strokeDashoffset:0,duration:se,ease:J},"<")}u(e.nodes,{opacity:0,scale:0},{opacity:1,scale:1,duration:.4,ease:"back.out(1.7)",stagger:ut},"-=0.4"),u(e.cards,{opacity:0,y:8},{opacity:1,y:0,duration:dt,ease:J},"-=0.2")};a.create({trigger:t,start:"top 80%",once:!0,onEnter:o})});v("scramble",(t,{reducedMotion:r})=>{let a={duration:Number(t.dataset.animDuration??1050),stagger:Number(t.dataset.animStagger??.75),reducedMotion:r};if(r||!("IntersectionObserver"in window)){V(t,a);return}let n=new IntersectionObserver(e=>{for(let i of e)i.isIntersecting&&(V(t,{...a,relaunchOnHover:!0}),n.unobserve(i.target))},{threshold:.2});n.observe(t)});v("scroll-topbar",t=>{let r=document.querySelector("[data-topbar-trigger]");if(!r){console.warn("[shopic] Scroll topbar is missing its trigger.");return}let a=0,n=()=>{a=0;let i=r.getBoundingClientRect().top<=t.offsetHeight;t.dataset.topbarVisible=String(i),t.style.visibility=i?"visible":"hidden",t.inert=!i,t.setAttribute("aria-hidden",String(!i))},e=()=>{a||(a=window.requestAnimationFrame(n))};window.addEventListener("scroll",e,{passive:!0}),window.addEventListener("resize",e),window.addEventListener("pageshow",e),new ResizeObserver(e).observe(document.body),n()});var Q=({grouped:t=!1,prefix:r="",suffix:a="",value:n})=>{let e=Math.round(n),i=t?e.toLocaleString("en-US"):String(e);return`${r}${i}${a}`};var ge=.5,At="power4.out",ye=.18,he="power2.in",Ee=.35,Te=1400,ve=.15,be=420,Le=10,X=null,Se=t=>{let r=t.querySelector("[data-stat-value]");return r||console.warn("[shopic] stats row is missing [data-stat-value]",t),r},ft=t=>({grouped:(t.dataset.statGrouped??t.closest('[data-anim="stats"]')?.dataset.statGrouped)==="true",prefix:t.dataset.statPrefix??t.closest('[data-anim="stats"]')?.dataset.statPrefix??"",suffix:t.dataset.statSuffix??t.closest('[data-anim="stats"]')?.dataset.statSuffix??""}),Ht=(t,r)=>{t.textContent=Q({...ft(t),value:r})},tt=(t,r)=>{t.classList.toggle("is-hovered",r);for(let a of t.querySelectorAll("[data-stat-label], [data-stat-hover]"))a.classList.toggle("is-hovered",r)},Mt=(t,r,a,n)=>{if(a){Ht(t,r);return}let e=performance.now(),i=l=>{if(n!==Number(t.dataset.statsGeneration))return;let o=Math.min((l-e)/Te,1),s=1-(1-o)**3;t.textContent=Q({...ft(t),value:r*s}),o<1&&requestAnimationFrame(i)};requestAnimationFrame(i)},we=(t,{gsap:r,reducedMotion:a})=>{let n=t,e=Se(n);if(!e)return;let i=n.dataset.statCount??e.dataset.statCount,l=i===void 0?null:Number(i),o=n.dataset.statTicker??e.dataset.statTicker,s=o===void 0?null:Number(o),u=n.dataset.statTickerInterval??e.dataset.statTickerInterval,d=u===void 0?Number.NaN:Number(u),y=d>0?d:be,p=null,h=0,b=!1,L=()=>{s!==null&&(e.textContent=Q({...ft(e),value:s}))},m=()=>{a||s===null||p!==null||(p=setInterval(()=>{s!==null&&(s+=1+Math.floor(Math.random()*3),L())},y))},T=()=>{p!==null&&(clearInterval(p),p=null)},A=()=>{h+=1,e.dataset.statsGeneration=String(h),l!==null?Ht(e,l):L(),r.set(e,{clearProps:"transform"})},w=S=>{h+=1,e.dataset.statsGeneration=String(h),r.killTweensOf(e),r.set(e,{yPercent:110}),r.to(e,{duration:ge,ease:At,yPercent:0}),S&&l!==null&&Mt(e,l,a,h)};if(a){A();return}L(),r.set(e,{yPercent:110});let R=()=>{b||(b=!0,w(!0))};if("IntersectionObserver"in window){let S=new IntersectionObserver(N=>{N.some(q=>q.isIntersecting)&&(R(),S.disconnect())},{threshold:ve});S.observe(n)}else R();s!==null&&("IntersectionObserver"in window?new IntersectionObserver(N=>{N.some(q=>q.isIntersecting)?m():T()}).observe(n):m());let _=()=>{tt(n,!0),h+=1,e.dataset.statsGeneration=String(h),r.killTweensOf(e),r.timeline().to(e,{duration:ye,ease:he,yPercent:-110}).set(e,{yPercent:110}).to(e,{duration:Ee,ease:At,onStart:()=>{l!==null&&Mt(e,l,a,h)},yPercent:0})};n.addEventListener("pointerenter",S=>{S.pointerType==="mouse"&&_()}),n.addEventListener("pointerleave",S=>{S.pointerType==="mouse"&&tt(n,!1)});let C=0,O=0;n.addEventListener("pointerdown",S=>{S.pointerType!=="mouse"&&(C=S.clientX,O=S.clientY)}),n.addEventListener("pointerup",S=>{if(S.pointerType!=="mouse"&&!(Math.hypot(S.clientX-C,S.clientY-O)>Le)){if(X&&X!==n&&tt(X,!1),X===n){tt(n,!1),X=null;return}X=n,_()}})};v("stats",we);var pt=t=>String(t).padStart(2,"0");v("timer",t=>{let r=()=>{let a=new Date;t.textContent=`${pt(a.getHours())}:${pt(a.getMinutes())}:${pt(a.getSeconds())}`};r(),setInterval(r,1e3)});var It="is-active",xe="(max-width: 991px)";v("versus-tabs",t=>{let r=Array.from(t.querySelectorAll('[role="tab"]')),a=t.nextElementSibling,n=a?Array.from(a.querySelectorAll(":scope > *")):[];if(r.length===0||r.length!==n.length){console.warn(`[shopic] versus-tabs expects one tab per panel; found ${r.length} tabs and ${n.length} panels.`,t);return}let e=window.matchMedia(xe),i=o=>{r.forEach((s,u)=>{s.classList.toggle(It,u===o),s.setAttribute("aria-selected",String(u===o))}),n.forEach((s,u)=>{s.hidden=e.matches&&u!==o})},l=()=>Math.max(0,r.indexOf(t.querySelector(`.${It}`)));r.forEach((o,s)=>{o.addEventListener("click",()=>i(s)),o.addEventListener("keydown",u=>{(u.key==="Enter"||u.key===" ")&&(u.preventDefault(),i(s))}),o.hasAttribute("tabindex")||(o.tabIndex=0)}),e.addEventListener("change",()=>i(l())),i(l())});var Rt=()=>{let{gsap:t,ScrollTrigger:r}=window;if(!t)throw new Error("[shopic] GSAP is not on the page. Enable it in Webflow \u2192 Site Settings \u2192 Custom Code \u2192 GSAP.");return r&&t.registerPlugin(r),{gsap:t,ScrollTrigger:r}},Ot=()=>window.matchMedia("(prefers-reduced-motion: reduce)").matches;window.Webflow||(window.Webflow=[]);window.Webflow.push(()=>{let{gsap:t,ScrollTrigger:r}=Rt();rt({gsap:t,ScrollTrigger:r,reducedMotion:Ot()})});})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shopic",
3
- "version": "0.2.7",
3
+ "version": "0.3.1",
4
4
  "description": "Custom code bundle for the Shopic Webflow site.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,