shopic 0.1.1 → 0.1.3
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.
- package/README.md +20 -3
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -59,7 +59,9 @@ the allow list, so every Webflow write still prompts.
|
|
|
59
59
|
That is the only granularity available. The MCP bundles reads and writes into one
|
|
60
60
|
tool — `data_style_tool` carries `get_styles` alongside `create_style` — so a
|
|
61
61
|
tool-level allow would auto-approve writes with the reads. Leaving Webflow off the
|
|
62
|
-
list entirely is what keeps the prompt.
|
|
62
|
+
list entirely is what keeps the prompt. The same file runs
|
|
63
|
+
`scripts/style-payload-hook.js` before every `data_style_tool` call; it rewrites
|
|
64
|
+
the payload and the prompt shows what changed.
|
|
63
65
|
|
|
64
66
|
Figma URLs and node ids belong in the ignored `DEV-LINKS.local.md` and must not
|
|
65
67
|
be committed. The staging URL is committed — it is stable and every agent needs
|
|
@@ -74,6 +76,20 @@ src/*.ts → esbuild → dist/*.js → npm publish → cdn.jsdelivr.net/
|
|
|
74
76
|
npm stores the versions; jsDelivr is the CDN that serves them. The published package
|
|
75
77
|
is public even though this repository is not — that is the price of a free CDN.
|
|
76
78
|
|
|
79
|
+
## Machine setup
|
|
80
|
+
|
|
81
|
+
Node and pnpm; `packageManager` pins the pnpm version and `corepack enable` installs
|
|
82
|
+
it. Publishing also needs **npm CLI 11.9 or newer** — older versions cannot drive the
|
|
83
|
+
passkey hand-off and ask for a code that does not exist.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
corepack enable
|
|
87
|
+
pnpm install
|
|
88
|
+
npm login # publishing only
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The environment is complete when `pnpm check`, `pnpm lint` and `pnpm build` pass.
|
|
92
|
+
|
|
77
93
|
## Local checks
|
|
78
94
|
|
|
79
95
|
```bash
|
|
@@ -217,8 +233,9 @@ Run by hand or from a build step; `scripts/README.md` says what each one proves.
|
|
|
217
233
|
|
|
218
234
|
| Command | Does |
|
|
219
235
|
| -------------------------------------------------------------- | --------------------------------------------------------------------- |
|
|
220
|
-
| `node scripts/class-index.js build \|
|
|
221
|
-
| `node scripts/
|
|
236
|
+
| `node scripts/class-index.js build \| find \| check \| append` | The class vocabulary from the published CSS, and the duplicate guard |
|
|
237
|
+
| `node scripts/style-payload-hook.js < hook-input.json` | What the PreToolUse hook does to a `data_style_tool` call |
|
|
238
|
+
| `node scripts/lint-style-payload.js <payload>` | The same rules as a report, for a harness with no hooks |
|
|
222
239
|
| `node scripts/check-runtime-classes.js` | Every class the bundle adds at runtime exists as a real Webflow style |
|
|
223
240
|
| `node scripts/check-agent-refs.js` | Agent and skill definitions still point at things that exist |
|
|
224
241
|
| `node scripts/preview-anim.js --seek <t> --measure <sel>` | The motion, on the real page, before the publish gate |
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(()=>{var W=new Map,y=(e,o)=>{if(W.has(e))throw new Error(`[shopic] Animation "${e}" is registered twice.`);W.set(e,o)},B=(e,o=document)=>{let a=o.querySelectorAll("[data-anim]");for(let t of a){let r=t.dataset.anim;if(!r||t.dataset.animState==="ready")continue;let l=W.get(r);if(!l){console.warn(`[shopic] No animation registered for data-anim="${r}".`,t);continue}t.dataset.animState="ready",l(t,e)}};var pe=2,me=150,ge=4,ye=1,he=5e3,ve=.75,Ee="power3.out",be=[0,.25,.5,.6,.7,.8,.9,1],Y="shopic:slide-enter";y("carousel",(e,{gsap:o,reducedMotion:a})=>{let t=Array.from(e.querySelectorAll(":scope > [data-slide]"));if(t.length<2)return;let r=e.closest("section")??e.parentElement??document.body,l=Array.from(r.querySelectorAll("[data-tab]")),d=a?0:ve,i=t.length,s=new Map(t.map((n,f)=>[n,f])),c=new Map;t.forEach((n,f)=>{let g=n.dataset.slide;g&&!c.has(g)&&c.set(g,f)});let u=[],A=()=>{let n=e.getBoundingClientRect().left,f=e.scrollLeft,g=parseFloat(getComputedStyle(e).paddingLeft)||0,E=e.scrollWidth-e.clientWidth;u=t.map(R=>Math.min(R.getBoundingClientRect().left-n+f-g,E))},I=n=>{for(let f of l){let g=f.dataset.tab===n;f.classList.toggle("is-active",g),g?f.setAttribute("aria-current","true"):f.removeAttribute("aria-current")}},O=-1,b=null,h=!1,T=!1,C,p,m=null,v=0,x=0,S=0,w=0,M=!1,_=()=>m!==null,H=()=>b!==null,L=()=>{clearTimeout(C),C=void 0},V=()=>!a&&!document.hidden&&T&&!_()&&!h&&!r.contains(document.activeElement),P=()=>{L(),V()&&(C=setTimeout(()=>{C=void 0,V()&&$((O+1)%i)},he))},K=n=>{let f=t[n],g=f.dataset.slide;if(g&&I(g),n!==O){O=n;for(let E of t)E.classList.toggle("is-current",E===f);f.dispatchEvent(new CustomEvent(Y))}},X=n=>{b=null,K(n),P()},z=()=>{clearTimeout(p),o.killTweensOf(e),b=null};function $(n){if(z(),b=n,d===0){e.scrollLeft=u[n],X(n);return}o.to(e,{scrollLeft:u[n],duration:d,ease:Ee,overwrite:"auto",onComplete:()=>X(n),onInterrupt:()=>{b=null}})}let Z=()=>{let n=e.scrollLeft,f=0;return u.forEach((g,E)=>{Math.abs(g-n)<Math.abs(u[f]-n)&&(f=E)}),f},D=()=>{let n=Z();Math.abs(u[n]-e.scrollLeft)<ye?X(n):$(n)},de=()=>{let n=v>0?u[v]-u[v-1]:1/0,f=v<i-1?u[v+1]-u[v]:1/0,g=Math.min(Math.abs(n),Math.abs(f));if(Math.abs(w)<g*.25){D();return}$((v+Math.sign(w)+i)%i)};for(let n of l)n.addEventListener("click",f=>{f.preventDefault();let g=n.dataset.tab??"",E=c.get(g);E!==void 0&&(L(),I(g),$(E))});let j=new Array(i).fill(0),fe=new IntersectionObserver(n=>{for(let E of n){let R=s.get(E.target);R!==void 0&&(j[R]=E.isIntersecting?E.intersectionRatio:0)}let f=-1,g=0;j.forEach((E,R)=>{E<=g||(g=E,f=R)}),f!==-1&&(b!==null&&f!==b||K(f))},{root:e,threshold:be});for(let n of t)fe.observe(n);A(),e.style.scrollSnapType="none",e.style.touchAction="pan-y",e.addEventListener("dragstart",n=>n.preventDefault());let[ue]=u;e.scrollLeft=ue;let J=new ResizeObserver(A);J.observe(e);for(let n of t)J.observe(n);"onscrollend"in window?e.addEventListener("scrollend",()=>{!H()&&!_()&&D()}):e.addEventListener("scroll",()=>{H()||_()||(clearTimeout(p),p=setTimeout(D,me))}),e.addEventListener("pointerdown",n=>{L(),z(),m=n.pointerId,M=!1,x=n.clientX,S=e.scrollLeft,w=0,v=Z()}),e.addEventListener("pointermove",n=>{if(n.pointerId!==m)return;let f=n.clientX-x;if(!M){if(Math.abs(f)<ge)return;M=!0,e.classList.add("is-dragging"),e.setPointerCapture(n.pointerId)}w=-f*pe,e.scrollLeft=S+w,n.pointerType==="mouse"&&n.preventDefault()});let Q=n=>{n.pointerId===m&&(m=null,e.hasPointerCapture(n.pointerId)&&e.releasePointerCapture(n.pointerId),M?(e.classList.remove("is-dragging"),de()):D())};window.addEventListener("pointerup",Q),window.addEventListener("pointercancel",Q),e.addEventListener("click",n=>{M&&(M=!1,n.preventDefault(),n.stopPropagation())},!0),r.addEventListener("pointerenter",n=>{n.pointerType==="mouse"&&(h=!0,L())}),r.addEventListener("pointerleave",n=>{n.pointerType==="mouse"&&(h=!1,P())}),r.addEventListener("focusin",L),r.addEventListener("focusout",()=>queueMicrotask(P)),document.addEventListener("visibilitychange",()=>{document.hidden?L():P()}),new IntersectionObserver(n=>{T=n.some(f=>f.isIntersecting),T?P():L()},{threshold:.2}).observe(e)});var k="!<>-_\\/[]{}=+*^?#$%01",q=new WeakMap,N=(e,{duration:o=1050,stagger:a=.75,text:t,reducedMotion:r=!1,relaunchOnHover:l=!1}={})=>{if(r){t!==void 0&&(e.textContent=t);return}if(t!==void 0)e.dataset.scrambleText=t;else if(!e.dataset.scrambleText){let h=e.textContent;if(!h||!h.trim())return;e.dataset.scrambleText=h}let d=e.dataset.scrambleText;if(!d||!d.trim())return;let i=Array.from(d),s=i.length,c=Array.from(e.children),u;c.length===s&&c.every(h=>h.tagName==="SPAN")?u=c:(u=i.map(h=>{let T=document.createElement("span");return T.textContent=h,T}),e.textContent="",e.append(...u));let A=Symbol("scramble");q.set(e,A);let I=i.map((h,T)=>s<=1?0:T/(s-1)*o*a),O=performance.now(),b=h=>{if(q.get(e)!==A)return;let T=h-O,C=!0;i.forEach((p,m)=>{if(p===" "){u[m].textContent=" ";return}T>=I[m]?u[m].textContent=p:(C=!1,u[m].textContent=k[Math.random()*k.length|0])}),C?q.delete(e):requestAnimationFrame(b)};requestAnimationFrame(b),l&&Te(e,{duration:o,stagger:a})},Te=(e,o)=>{e.dataset.scrambleHoverBound||(e.dataset.scrambleHoverBound="true",e.addEventListener("pointerenter",()=>{q.has(e)||N(e,o)}))};var Le=.5,Se="power2.out",Ae=".status-pill, .evidence_label, .evidence_sku",xe={duration:630,stagger:.6,relaunchOnHover:!0};y("evidence",(e,{gsap:o,reducedMotion:a})=>{let t=Array.from(e.children);if(!t.length)return;if(a){for(let s of t)s.style.height="auto",s.style.opacity="1";return}let r=()=>{o.killTweensOf(t),o.set(t,{height:0,opacity:0,overflow:"hidden"});let s=o.timeline();for(let c of t)s.call(()=>{for(let u of c.querySelectorAll(Ae))N(u,xe)}),s.to(c,{height:"auto",opacity:1,duration:Le,ease:Se,onComplete:()=>o.set(c,{height:"auto"})})},l=!1,d=!1,i=()=>{if(!l||d)return;let s=e.closest("[data-slide]");s&&!s.classList.contains("is-current")||(d=!0,r())};if("IntersectionObserver"in window){let s=new IntersectionObserver(c=>{for(let u of c)u.isIntersecting&&(l=!0,i(),d&&s.disconnect())},{threshold:.2});s.observe(e)}else l=!0,i();e.closest("[data-slide]")?.addEventListener(Y,()=>{d=!1,i()})});var ee=8;y("focus-drift",(e,{reducedMotion:o})=>{let a=e.querySelector(":scope > .camera_focus");!a||o||(e.addEventListener("pointermove",t=>{if(t.pointerType!=="mouse")return;let r=e.getBoundingClientRect(),l=(t.clientX-r.left)/r.width-.5,d=(t.clientY-r.top)/r.height-.5,i=(l*ee*2).toFixed(1),s=(d*ee*2).toFixed(1);a.style.transform=`translate(${i}px, ${s}px)`}),e.addEventListener("pointerleave",()=>{a.style.transform=""}))});var te="split_line",we="split_word",ne="split_word-inner",Me=e=>{let o=document.createDocumentFragment(),a=[],t=document.createElement("span");t.className=te,o.appendChild(t);let r=(d,i)=>{if(!d)return;let s=document.createElement("span");s.className=we;let c=document.createElement("span");c.className=i?`${ne} ${i}`:ne,c.textContent=d,s.appendChild(c),t.appendChild(s),a.push(c)},l=(d,i)=>{for(let s of d.split(/(\s+)/))s&&(/^\s+$/.test(s)?t.appendChild(document.createTextNode(" ")):r(s,i))};for(let d of Array.from(e.childNodes))d.nodeType===Node.TEXT_NODE?l(d.textContent??""):d instanceof HTMLBRElement?(t=document.createElement("span"),t.className=te,o.appendChild(t)):d instanceof HTMLElement&&l(d.textContent??"",d.className||void 0);return e.textContent="",e.appendChild(o),a},oe={yPercent:0,duration:.9,ease:"power4.out",stagger:.035};y("headline",(e,{gsap:o,ScrollTrigger:a,reducedMotion:t})=>{if(t){e.style.visibility="visible";return}let r=Me(e);if(o.set(r,{yPercent:110}),e.style.visibility="visible",e.dataset.animTrigger==="load"||!a){o.to(r,{...oe,delay:.3});return}o.to(r,{...oe,scrollTrigger:{trigger:e,start:"top 85%"}})});var Ie=26;y("marquee",(e,{gsap:o,reducedMotion:a})=>{if(a)return;let t=Number(e.dataset.animSets??4),r=Number(e.dataset.animDuration??Ie);if(!Number.isFinite(t)||t<2)return;let l=()=>e.scrollWidth/t,d=o.to(e,{x:()=>-l(),duration:r,ease:"none",repeat:-1,modifiers:{x:s=>`${Number.parseFloat(s)%l()}px`}}),i=e.parentElement;i&&(i.addEventListener("pointerenter",()=>d.pause()),i.addEventListener("pointerleave",()=>d.resume()))});var re=1.15,se=.18,F=8,Ce=.55,G=(e,o,a)=>Math.min(a,Math.max(o,e));y("photo-hover",(e,{reducedMotion:o})=>{let a=e.querySelector(":scope > img");if(!a)return;let t=e.querySelector(":scope > .camera_focus"),r=t?.querySelector(":scope > img:first-child")??null,l=t?.querySelector(":scope > img:nth-child(2)")??null;t&&(!r||!l)&&console.warn("[shopic] photo-hover expects two image layers inside the reticle.",t);let d=Array.from(e.querySelectorAll(".detect_box")),i=0,s=0,c=0,u=0,A=0,I=!1,O=p=>{let m=e.getBoundingClientRect(),v=e.offsetWidth,x=e.offsetHeight,S=m.width/v||1,w=(p.clientX-m.left)/S,M=(p.clientY-m.top)/S;return{x:w,y:M,width:v,height:x}},b=()=>{if(i=0,!!r){if(s-=s*se,c-=c*se,r.style.transform=`translate(${s.toFixed(2)}px, ${c.toFixed(2)}px)`,Math.abs(s)>.1||Math.abs(c)>.1){i=requestAnimationFrame(b);return}r.style.transform=""}},h=p=>{if(p.pointerType!=="mouse")return;let{x:m,y:v,width:x,height:S}=O(p),w=re-1,M=-(m/x-.5)*x*w,_=-(v/S-.5)*S*w;if(a.style.transform=`translate(${M.toFixed(2)}px, ${_.toFixed(2)}px) scale(${re})`,!t||I)return;let H=G(m,0,x),L=G(v,0,S);if(t.style.left=`${H.toFixed(2)}px`,t.style.top=`${L.toFixed(2)}px`,o){u=H,A=L;return}s-=H-u,c-=L-A,u=H,A=L,i||(i=requestAnimationFrame(b))},T=()=>{a.style.transform="",t&&(I=!1,t.style.left="",t.style.top="",t.style.width="",t.style.height="",t.style.transitionProperty="",l&&(l.style.transform=""),r&&(r.style.opacity="",r.style.transform=""),s=0,c=0,cancelAnimationFrame(i),i=0)},C=p=>{if(p.pointerType!=="mouse"||!t)return;t.style.transitionProperty="opacity, width, height";let{x:m,y:v,width:x,height:S}=O(p);u=G(m,0,x),A=G(v,0,S),s=0,c=0};e.addEventListener("pointerenter",C),e.addEventListener("pointermove",h),e.addEventListener("pointerleave",T);for(let p of d)p.addEventListener("pointerenter",m=>{m.pointerType!=="mouse"||!t||(I=!0,t.style.transitionProperty="",t.style.left=`${p.offsetLeft-F}px`,t.style.top=`${p.offsetTop-F}px`,t.style.width=`${p.offsetWidth+F*2}px`,t.style.height=`${p.offsetHeight+F*2}px`,r&&(r.style.opacity="0"),l&&(l.style.transform=`scale(${Ce})`))}),p.addEventListener("pointerleave",()=>{I=!1,r&&(r.style.opacity=""),l&&(l.style.transform="")})});var ie="is-visible";y("reveal",(e,{reducedMotion:o})=>{let a=Number(e.dataset.animDelay??0);if(a&&(e.style.transitionDelay=`${a}ms`),o||!("IntersectionObserver"in window)){e.classList.add(ie);return}let t=new IntersectionObserver(r=>{for(let l of r)l.isIntersecting&&(l.target.classList.add(ie),t.unobserve(l.target))},{threshold:.15});t.observe(e)});y("scramble",(e,{reducedMotion:o})=>{let a={duration:Number(e.dataset.animDuration??1050),stagger:Number(e.dataset.animStagger??.75),reducedMotion:o};if(o||!("IntersectionObserver"in window)){N(e,a);return}let t=new IntersectionObserver(r=>{for(let l of r)l.isIntersecting&&(N(e,{...a,relaunchOnHover:!0}),t.unobserve(l.target))},{threshold:.2});t.observe(e)});var U=e=>String(e).padStart(2,"0");y("timer",e=>{let o=()=>{let a=new Date;e.textContent=`${U(a.getHours())}:${U(a.getMinutes())}:${U(a.getSeconds())}`};o(),setInterval(o,1e3)});var ae="is-active",Oe="(max-width: 991px)";y("versus-tabs",e=>{let o=Array.from(e.querySelectorAll('[role="tab"]')),a=e.nextElementSibling,t=a?Array.from(a.querySelectorAll(":scope > *")):[];if(o.length===0||o.length!==t.length){console.warn(`[shopic] versus-tabs expects one tab per panel; found ${o.length} tabs and ${t.length} panels.`,e);return}let r=window.matchMedia(Oe),l=i=>{o.forEach((s,c)=>{s.classList.toggle(ae,c===i),s.setAttribute("aria-selected",String(c===i))}),t.forEach((s,c)=>{s.hidden=r.matches&&c!==i})},d=()=>Math.max(0,o.indexOf(e.querySelector(`.${ae}`)));o.forEach((i,s)=>{i.addEventListener("click",()=>l(s)),i.addEventListener("keydown",c=>{(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),l(s))}),i.hasAttribute("tabindex")||(i.tabIndex=0)}),r.addEventListener("change",()=>l(d())),l(d())});var le=()=>{let{gsap:e,ScrollTrigger:o}=window;if(!e)throw new Error("[shopic] GSAP is not on the page. Enable it in Webflow \u2192 Site Settings \u2192 Custom Code \u2192 GSAP.");return o&&e.registerPlugin(o),{gsap:e,ScrollTrigger:o}},ce=()=>window.matchMedia("(prefers-reduced-motion: reduce)").matches;window.Webflow||(window.Webflow=[]);window.Webflow.push(()=>{let{gsap:e,ScrollTrigger:o}=le();B({gsap:e,ScrollTrigger:o,reducedMotion:ce()})});})();
|
|
1
|
+
"use strict";(()=>{var tt=new Map,h=(t,o)=>{if(tt.has(t))throw new Error(`[shopic] Animation "${t}" is registered twice.`);tt.set(t,o)},et=(t,o=document)=>{let a=o.querySelectorAll("[data-anim]");for(let n of a){let e=n.dataset.anim;if(!e||n.dataset.animState==="ready")continue;let s=tt.get(e);if(!s){console.warn(`[shopic] No animation registered for data-anim="${e}".`,n);continue}n.dataset.animState="ready",s(n,t)}};var Mt=2,It=150,Ht=4,Ot=1,Ct=5e3,Rt=.75,_t="power3.out",Nt=[0,.25,.5,.6,.7,.8,.9,1],nt="shopic:slide-enter";h("carousel",(t,{gsap:o,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]")),r=a?0:Rt,d=n.length,l=new Map(n.map((i,y)=>[i,y])),f=new Map;n.forEach((i,y)=>{let T=i.dataset.slide;T&&!f.has(T)&&f.set(T,y)});let m=[],S=()=>{let i=t.getBoundingClientRect().left,y=t.scrollLeft,T=parseFloat(getComputedStyle(t).paddingLeft)||0,I=t.scrollWidth-t.clientWidth;m=n.map(V=>Math.min(V.getBoundingClientRect().left-i+y-T,I))},L=i=>{for(let y of s){let T=y.dataset.tab===i;y.classList.toggle("is-active",T),T?y.setAttribute("aria-current","true"):y.removeAttribute("aria-current")}},H=-1,x=null,E=!1,u=!1,g,b,v=null,A=0,N=0,C=0,O=0,R=!1,X=()=>v!==null,B=()=>x!==null,_=()=>{clearTimeout(g),g=void 0},W=()=>!a&&!document.hidden&&u&&!X()&&!E&&!e.contains(document.activeElement),P=()=>{_(),W()&&(g=setTimeout(()=>{g=void 0,W()&&q((H+1)%d)},Ct))},K=i=>{let y=n[i],T=y.dataset.slide;if(T&&L(T),i!==H){H=i;for(let I of n)I.classList.toggle("is-current",I===y);y.dispatchEvent(new CustomEvent(nt))}},k=i=>{x=null,K(i),P()},U=()=>{clearTimeout(b),o.killTweensOf(t),x=null};function q(i){if(U(),x=i,r===0){t.scrollLeft=m[i],k(i);return}o.to(t,{scrollLeft:m[i],duration:r,ease:_t,overwrite:"auto",onComplete:()=>k(i),onInterrupt:()=>{x=null}})}let Z=()=>{let i=t.scrollLeft,y=0;return m.forEach((T,I)=>{Math.abs(T-i)<Math.abs(m[y]-i)&&(y=I)}),y},$=()=>{let i=Z();Math.abs(m[i]-t.scrollLeft)<Ot?k(i):q(i)},c=()=>{let i=A>0?m[A]-m[A-1]:1/0,y=A<d-1?m[A+1]-m[A]:1/0,T=Math.min(Math.abs(i),Math.abs(y));if(Math.abs(O)<T*.25){$();return}q((A+Math.sign(O)+d)%d)};for(let i of s)i.addEventListener("click",y=>{y.preventDefault();let T=i.dataset.tab??"",I=f.get(T);I!==void 0&&(_(),L(T),q(I))});let p=new Array(d).fill(0),w=new IntersectionObserver(i=>{for(let I of i){let V=l.get(I.target);V!==void 0&&(p[V]=I.isIntersecting?I.intersectionRatio:0)}let y=-1,T=0;p.forEach((I,V)=>{I<=T||(T=I,y=V)}),y!==-1&&(x!==null&&y!==x||K(y))},{root:t,threshold:Nt});for(let i of n)w.observe(i);S(),t.style.scrollSnapType="none",t.style.touchAction="pan-y",t.addEventListener("dragstart",i=>i.preventDefault());let[M]=m;t.scrollLeft=M;let D=new ResizeObserver(S);D.observe(t);for(let i of n)D.observe(i);"onscrollend"in window?t.addEventListener("scrollend",()=>{!B()&&!X()&&$()}):t.addEventListener("scroll",()=>{B()||X()||(clearTimeout(b),b=setTimeout($,It))}),t.addEventListener("pointerdown",i=>{_(),U(),v=i.pointerId,R=!1,N=i.clientX,C=t.scrollLeft,O=0,A=Z()}),t.addEventListener("pointermove",i=>{if(i.pointerId!==v)return;let y=i.clientX-N;if(!R){if(Math.abs(y)<Ht)return;R=!0,t.classList.add("is-dragging"),t.setPointerCapture(i.pointerId)}O=-y*Mt,t.scrollLeft=C+O,i.pointerType==="mouse"&&i.preventDefault()});let F=i=>{i.pointerId===v&&(v=null,t.hasPointerCapture(i.pointerId)&&t.releasePointerCapture(i.pointerId),R?(t.classList.remove("is-dragging"),c()):$())};window.addEventListener("pointerup",F),window.addEventListener("pointercancel",F),t.addEventListener("click",i=>{R&&(R=!1,i.preventDefault(),i.stopPropagation())},!0),e.addEventListener("pointerenter",i=>{i.pointerType==="mouse"&&(E=!0,_())}),e.addEventListener("pointerleave",i=>{i.pointerType==="mouse"&&(E=!1,P())}),e.addEventListener("focusin",_),e.addEventListener("focusout",()=>queueMicrotask(P)),document.addEventListener("visibilitychange",()=>{document.hidden?_():P()}),new IntersectionObserver(i=>{u=i.some(y=>y.isIntersecting),u?P():_()},{threshold:.2}).observe(t)});var it="!<>-_\\/[]{}=+*^?#$%01",j=new WeakMap,G=(t,{duration:o=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 E=t.textContent;if(!E||!E.trim())return;t.dataset.scrambleText=E}let r=t.dataset.scrambleText;if(!r||!r.trim())return;let d=Array.from(r),l=d.length,f=Array.from(t.children),m;f.length===l&&f.every(E=>E.tagName==="SPAN")?m=f:(m=d.map(E=>{let u=document.createElement("span");return u.textContent=E,u}),t.textContent="",t.append(...m));let S=Symbol("scramble");j.set(t,S);let L=d.map((E,u)=>l<=1?0:u/(l-1)*o*a),H=performance.now(),x=E=>{if(j.get(t)!==S)return;let u=E-H,g=!0;d.forEach((b,v)=>{if(b===" "){m[v].textContent=" ";return}u>=L[v]?m[v].textContent=b:(g=!1,m[v].textContent=it[Math.random()*it.length|0])}),g?j.delete(t):requestAnimationFrame(x)};requestAnimationFrame(x),s&&Pt(t,{duration:o,stagger:a})},Pt=(t,o)=>{t.dataset.scrambleHoverBound||(t.dataset.scrambleHoverBound="true",t.addEventListener("pointerenter",()=>{j.has(t)||G(t,o)}))};var qt=.5,$t="power2.out",Dt=".status-pill, .evidence_label, .evidence_sku",Ft={duration:630,stagger:.6,relaunchOnHover:!0};h("evidence",(t,{gsap:o,reducedMotion:a})=>{let n=Array.from(t.children);if(!n.length)return;if(a){for(let l of n)l.style.height="auto",l.style.opacity="1";return}let e=()=>{o.killTweensOf(n),o.set(n,{height:0,opacity:0,overflow:"hidden"});let l=o.timeline();for(let f of n)l.call(()=>{for(let m of f.querySelectorAll(Dt))G(m,Ft)}),l.to(f,{height:"auto",opacity:1,duration:qt,ease:$t,onComplete:()=>o.set(f,{height:"auto"})})},s=!1,r=!1,d=()=>{if(!s||r)return;let l=t.closest("[data-slide]");l&&!l.classList.contains("is-current")||(r=!0,e())};if("IntersectionObserver"in window){let l=new IntersectionObserver(f=>{for(let m of f)m.isIntersecting&&(s=!0,d(),r&&l.disconnect())},{threshold:.2});l.observe(t)}else s=!0,d();t.closest("[data-slide]")?.addEventListener(nt,()=>{r=!1,d()})});var at="is-open",lt=".faq_row",ct=".faq_toggle";h("faq",t=>{let o=t.querySelectorAll(lt);if(o.length===0){console.warn(`[shopic] faq found no ${lt} to open.`,t);return}let a=[];for(let s of o){let r=s.querySelector(ct);if(!r){console.warn(`[shopic] faq row has no ${ct} to click.`,s);continue}a.push({row:s,toggle:r})}if(a.length===0)return;let n=s=>{for(let{row:r,toggle:d}of a){let l=r===s;r.classList.toggle(at,l),d.setAttribute("aria-expanded",String(l))}};for(let{row:s,toggle:r}of a)r.addEventListener("click",()=>{n(s.classList.contains(at)?null:s)}),r.addEventListener("keydown",d=>{d.key!=="Enter"&&d.key!==" "||(d.preventDefault(),r.click())}),r.hasAttribute("tabindex")||(r.tabIndex=0);let e=a.find(({toggle:s})=>s.getAttribute("aria-expanded")==="true");n((e??a[0]).row)});var dt=8;h("focus-drift",(t,{reducedMotion:o})=>{let a=t.querySelector(":scope > .camera_focus");!a||o||(t.addEventListener("pointermove",n=>{if(n.pointerType!=="mouse")return;let e=t.getBoundingClientRect(),s=(n.clientX-e.left)/e.width-.5,r=(n.clientY-e.top)/e.height-.5,d=(s*dt*2).toFixed(1),l=(r*dt*2).toFixed(1);a.style.transform=`translate(${d}px, ${l}px)`}),t.addEventListener("pointerleave",()=>{a.style.transform=""}))});var ut=42,ft=96,Vt=2600,Gt="is-scanned",Xt="is-fresh";h("foundation-rail",(t,{gsap:o,reducedMotion:a})=>{let n=t.closest(".camera_photo"),e=Array.from(t.querySelectorAll(":scope > .foundation_slot"),u=>({element:u,parts:Array.from(u.querySelectorAll(".foundation_photo, .foundation_card")),tile:u.querySelector(".foundation_scan"),setX:o.quickSetter(u,"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=o.quickSetter(t,"x","px"),r=0,d=0,l=u=>u,f=()=>{let[u]=e,g=u.element.offsetWidth,b=g+(parseFloat(getComputedStyle(t).columnGap)||0);r=b*e.length,d=r/ut*(Vt/1e3),l=o.utils.wrap(-r/2,r/2),r<n.offsetWidth+g&&console.warn(`[shopic] foundation-rail: ${e.length} slots span ${r}px but the tile needs ${n.offsetWidth+g}px to loop without a gap.`,t);let v=n.getBoundingClientRect(),A=v.width/n.offsetWidth||1,N=(u.element.getBoundingClientRect().left-v.left)/A+g/2-n.offsetWidth/2-(Number(o.getProperty(t,"x"))||0)-(Number(o.getProperty(u.element,"x"))||0);e.forEach((C,O)=>{C.home=N+O*b,C.setX(C.turn*r)})},m=u=>u>ft?"unseen":u>ft-d?"fresh":"seen",S=(u,g)=>{if(u.state!==g){u.state=g;for(let b of u.parts)b.classList.toggle(Gt,g!=="unseen");u.tile?.classList.toggle(Xt,g==="fresh")}},L=u=>{if(r){s(-u);for(let g of e){let b=l(g.home-u),v=Math.round((b-(g.home-u))/r);v!==g.turn&&(g.turn=v,g.setX(v*r)),S(g,m(b))}}},H={t:0},x=()=>H.t*r,E=a?null:o.to(H,{t:1,duration:ut,ease:"none",repeat:-1,paused:!0,onUpdate:()=>L(x())});new ResizeObserver(()=>{f(),L(x())}).observe(t),E&&new IntersectionObserver(u=>{E.paused(!u.some(g=>g.isIntersecting))}).observe(t)});var mt="split_line",Bt="split_word",pt="split_word-inner",Wt=t=>{let o=document.createDocumentFragment(),a=[],n=document.createElement("span");n.className=mt,o.appendChild(n);let e=(r,d)=>{if(!r)return;let l=document.createElement("span");l.className=Bt;let f=document.createElement("span");f.className=d?`${pt} ${d}`:pt,f.textContent=r,l.appendChild(f),n.appendChild(l),a.push(f)},s=(r,d)=>{for(let l of r.split(/(\s+)/))l&&(/^\s+$/.test(l)?n.appendChild(document.createTextNode(" ")):e(l,d))};for(let r of Array.from(t.childNodes))r.nodeType===Node.TEXT_NODE?s(r.textContent??""):r instanceof HTMLBRElement?(n=document.createElement("span"),n.className=mt,o.appendChild(n)):r instanceof HTMLElement&&s(r.textContent??"",r.className||void 0);return t.textContent="",t.appendChild(o),a},gt={yPercent:0,duration:.9,ease:"power4.out",stagger:.035};h("headline",(t,{gsap:o,ScrollTrigger:a,reducedMotion:n})=>{if(n){t.style.visibility="visible";return}let e=Wt(t);if(o.set(e,{yPercent:110}),t.style.visibility="visible",t.dataset.animTrigger==="load"||!a){o.to(e,{...gt,delay:.3});return}o.to(e,{...gt,scrollTrigger:{trigger:t,start:"top 85%"}})});var kt=26;h("marquee",(t,{gsap:o,reducedMotion:a})=>{if(a)return;let n=Number(t.dataset.animSets??4),e=Number(t.dataset.animDuration??kt);if(!Number.isFinite(n)||n<2)return;let s=()=>t.scrollWidth/n,r=o.to(t,{x:()=>-s(),duration:e,ease:"none",repeat:-1,modifiers:{x:l=>`${Number.parseFloat(l)%s()}px`}}),d=t.parentElement;d&&(d.addEventListener("pointerenter",()=>r.pause()),d.addEventListener("pointerleave",()=>r.resume()))});var ot=1.15,yt=.18,J=8,z=.55,ht="is-visible",Et="opacity, width, height",Ut=["name","price","packaging","sku"];h("photo-hover",(t,{reducedMotion:o})=>{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,r=e?.querySelector(".is-corners")??null;e&&(!s||!r)&&console.warn("[shopic] photo-hover expects is-ring and is-corners layers inside the reticle.",e);let d=Array.from(t.querySelectorAll(".detect_box")),l=t.querySelector('[data-match="card"]'),f=l?.querySelector('[data-match="thumb"]')??null,m=0,S=0,L=0,H=0,x=0,E=0,u=0,g=null,b=c=>c.width/t.offsetWidth||1,v=(c,p)=>{let w=t.getBoundingClientRect(),M=b(w);return{x:(c-w.left)/M,y:(p-w.top)/M,width:t.offsetWidth,height:t.offsetHeight}},A=c=>{let p=t.getBoundingClientRect(),w=c.getBoundingClientRect(),M=b(p);return{x:(w.left-p.left)/M-J,y:(w.top-p.top)/M-J,w:w.width/M+J*2,h:w.height/M+J*2}},N=()=>{let{x:c,y:p,width:w,height:M}=v(E,u),D=(c/w-.5)*w*(ot-1),F=(p/M-.5)*M*(ot-1),Y=`translate(${D.toFixed(2)}px, ${F.toFixed(2)}px) scale(${ot})`;a&&(a.style.transform=Y),n&&(n.style.transform=Y)},C=()=>{let{x:c,y:p}=v(E,u);return{x:c-(e?.offsetWidth??0)/2,y:p-(e?.offsetHeight??0)/2}},O=(c,p)=>{e&&(e.style.left=`${c.toFixed(2)}px`,e.style.top=`${p.toFixed(2)}px`)},R=()=>{let c=C();O(c.x,c.y),H=c.x,x=c.y,S=0,L=0,r&&(r.style.transform="")},X=()=>{let c=C();O(c.x,c.y),o||(S-=c.x-H,L-=c.y-x),H=c.x,x=c.y},B=c=>{if(!e)return;let p=A(c);O(p.x,p.y),e.style.width=`${p.w.toFixed(2)}px`,e.style.height=`${p.h.toFixed(2)}px`},_=()=>{if(r){if(S-=S*yt,L-=L*yt,Math.abs(S)>.1||Math.abs(L)>.1){r.style.transform=`translate(${S.toFixed(2)}px, ${L.toFixed(2)}px)`;return}S=0,L=0,r.style.transform=""}},W=()=>{g?B(g):X(),_(),m=requestAnimationFrame(W)},P=c=>{if(l){for(let p of Ut){let w=c.dataset[p],M=l.querySelector(`[data-match="${p}"]`);M&&w!==void 0&&(M.textContent=w)}if(f){let p=c.dataset.thumb;p&&(f.removeAttribute("srcset"),f.removeAttribute("sizes"),f.src=p),f.style.display=p?"":"none"}l.classList.add(ht)}},K=c=>{if(g=c,P(c),!!e&&(e.style.transitionProperty="",B(c),r&&(r.style.opacity="0"),s)){let p=(1-z)/2*100;s.style.width=`${z*100}%`,s.style.height=`${z*100}%`,s.style.left=`${p}%`,s.style.top=`${p}%`,s.style.right="auto",s.style.bottom="auto"}},k=c=>{if(!s)return;let p=A(c),{x:w,y:M}=v(E,u),D=(w-p.x)/p.w-.5,F=(M-p.y)/p.h-.5,Y=D*p.w*(1-z),i=F*p.h*(1-z);s.style.setProperty("translate",`${Y.toFixed(2)}px ${i.toFixed(2)}px`)},U=()=>{g=null,l?.classList.remove(ht),e&&(e.style.width="",e.style.height="",e.style.transitionProperty=Et,r&&(r.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")))},q=c=>{c.pointerType==="mouse"&&(E=c.clientX,u=c.clientY,N(),e&&(e.style.transitionProperty=Et,R(),cancelAnimationFrame(m),m=requestAnimationFrame(W)))},Z=c=>{c.pointerType==="mouse"&&(E=c.clientX,u=c.clientY,N())},$=()=>{cancelAnimationFrame(m),m=0,a&&(a.style.transform=""),n&&(n.style.transform=""),U(),e&&(e.style.left="",e.style.top="",e.style.transitionProperty="",r&&(r.style.transform=""),S=0,L=0)};t.addEventListener("pointerenter",q),t.addEventListener("pointermove",Z),t.addEventListener("pointerleave",$);for(let c of d)c.addEventListener("pointerenter",p=>{p.pointerType==="mouse"&&K(c)}),c.addEventListener("pointermove",()=>{g===c&&k(c)}),c.addEventListener("pointerleave",()=>{g===c&&(U(),R())})});var bt="is-visible";h("reveal",(t,{reducedMotion:o})=>{let a=Number(t.dataset.animDelay??0);if(a&&(t.style.transitionDelay=`${a}ms`),o||!("IntersectionObserver"in window)){t.classList.add(bt);return}let n=new IntersectionObserver(e=>{for(let s of e)s.isIntersecting&&(s.target.classList.add(bt),n.unobserve(s.target))},{threshold:.15});n.observe(t)});h("scramble",(t,{reducedMotion:o})=>{let a={duration:Number(t.dataset.animDuration??1050),stagger:Number(t.dataset.animStagger??.75),reducedMotion:o};if(o||!("IntersectionObserver"in window)){G(t,a);return}let n=new IntersectionObserver(e=>{for(let s of e)s.isIntersecting&&(G(t,{...a,relaunchOnHover:!0}),n.unobserve(s.target))},{threshold:.2});n.observe(t)});var Q=({grouped:t=!1,prefix:o="",suffix:a="",value:n})=>{let e=Math.round(n),s=t?e.toLocaleString("en-US"):String(e);return`${o}${s}${a}`};var Yt=.5,vt="power4.out",zt=.18,Kt="power2.in",Zt=.35,jt=1400,Jt=.15,Qt=420,te=t=>{let o=t.querySelector("[data-stat-value]");return o||console.warn("[shopic] stats row is missing [data-stat-value]",t),o},rt=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??""}),St=(t,o)=>{t.textContent=Q({...rt(t),value:o})},Tt=(t,o)=>{t.classList.toggle("is-hovered",o);for(let a of t.querySelectorAll("[data-stat-label], [data-stat-hover]"))a.classList.toggle("is-hovered",o)},Lt=(t,o,a,n)=>{if(a){St(t,o);return}let e=performance.now(),s=r=>{if(n!==Number(t.dataset.statsGeneration))return;let d=Math.min((r-e)/jt,1),l=1-(1-d)**3;t.textContent=Q({...rt(t),value:o*l}),d<1&&requestAnimationFrame(s)};requestAnimationFrame(s)},ee=(t,{gsap:o,reducedMotion:a})=>{let n=t,e=te(n);if(!e)return;let s=n.dataset.statCount??e.dataset.statCount,r=s===void 0?null:Number(s),d=n.dataset.statTicker??e.dataset.statTicker,l=d===void 0?null:Number(d),f=null,m=0,S=!1,L=()=>{l!==null&&(e.textContent=Q({...rt(e),value:l}))},H=()=>{a||l===null||f!==null||(f=setInterval(()=>{l!==null&&(l+=1+Math.floor(Math.random()*3),L())},Qt))},x=()=>{f!==null&&(clearInterval(f),f=null)},E=()=>{m+=1,e.dataset.statsGeneration=String(m),r!==null?St(e,r):L(),o.set(e,{clearProps:"transform"})},u=b=>{m+=1,e.dataset.statsGeneration=String(m),o.killTweensOf(e),o.set(e,{yPercent:110}),o.to(e,{duration:Yt,ease:vt,yPercent:0}),b&&r!==null&&Lt(e,r,a,m)};if(a){E();return}L(),o.set(e,{yPercent:110});let g=()=>{S||(S=!0,u(!0))};if("IntersectionObserver"in window){let b=new IntersectionObserver(v=>{v.some(A=>A.isIntersecting)&&(g(),b.disconnect())},{threshold:Jt});b.observe(n)}else g();l!==null&&("IntersectionObserver"in window?new IntersectionObserver(v=>{v.some(A=>A.isIntersecting)?H():x()}).observe(n):H()),n.addEventListener("pointerenter",b=>{b.pointerType==="mouse"&&(Tt(n,!0),m+=1,e.dataset.statsGeneration=String(m),o.killTweensOf(e),o.timeline().to(e,{duration:zt,ease:Kt,yPercent:-110}).set(e,{yPercent:110}).to(e,{duration:Zt,ease:vt,onStart:()=>{r!==null&&Lt(e,r,a,m)},yPercent:0}))}),n.addEventListener("pointerleave",()=>Tt(n,!1))};h("stats",ee);var st=t=>String(t).padStart(2,"0");h("timer",t=>{let o=()=>{let a=new Date;t.textContent=`${st(a.getHours())}:${st(a.getMinutes())}:${st(a.getSeconds())}`};o(),setInterval(o,1e3)});var xt="is-active",ne="(max-width: 991px)";h("versus-tabs",t=>{let o=Array.from(t.querySelectorAll('[role="tab"]')),a=t.nextElementSibling,n=a?Array.from(a.querySelectorAll(":scope > *")):[];if(o.length===0||o.length!==n.length){console.warn(`[shopic] versus-tabs expects one tab per panel; found ${o.length} tabs and ${n.length} panels.`,t);return}let e=window.matchMedia(ne),s=d=>{o.forEach((l,f)=>{l.classList.toggle(xt,f===d),l.setAttribute("aria-selected",String(f===d))}),n.forEach((l,f)=>{l.hidden=e.matches&&f!==d})},r=()=>Math.max(0,o.indexOf(t.querySelector(`.${xt}`)));o.forEach((d,l)=>{d.addEventListener("click",()=>s(l)),d.addEventListener("keydown",f=>{(f.key==="Enter"||f.key===" ")&&(f.preventDefault(),s(l))}),d.hasAttribute("tabindex")||(d.tabIndex=0)}),e.addEventListener("change",()=>s(r())),s(r())});var wt=()=>{let{gsap:t,ScrollTrigger:o}=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 o&&t.registerPlugin(o),{gsap:t,ScrollTrigger:o}},At=()=>window.matchMedia("(prefers-reduced-motion: reduce)").matches;window.Webflow||(window.Webflow=[]);window.Webflow.push(()=>{let{gsap:t,ScrollTrigger:o}=wt();et({gsap:t,ScrollTrigger:o,reducedMotion:At()})});})();
|