@ocarignan/vitrine 0.1.0 → 0.1.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.
package/README.md CHANGED
@@ -27,8 +27,17 @@ This repo is both the published library and a live demo:
27
27
 
28
28
  - Drag (with inertia + snap), wheel/trackpad scroll, and click-to-center.
29
29
  - Click to zoom into a fullscreen, swipeable lightbox.
30
- - Shared-element view transition between the panel and the lightbox image.
31
- - Optional looping muted **video** per panel, autoplaying only while active.
30
+ - Shared-element view transition between the panel and the lightbox image
31
+ each slider generates its own transition name, so several sliders can share
32
+ a page.
33
+ - Three track variants (`variant`): the scroll-snap **row** (default), a
34
+ deck-cycling **card stack**, and a 3D **coverflow**.
35
+ - Optional looping muted **video** per panel, autoplaying only while active,
36
+ with opt-in playback controls (`videoControls`): a hover play/pause toggle on
37
+ the panel, and a progress bar + mute / PiP / fullscreen in the lightbox.
38
+ - Optional prev/next **arrows** and **pagination** dots beside the caption.
39
+ - The lightbox can be disabled entirely (`lightbox={false}`), with an
40
+ `onItemClick` callback taking over the active panel's click.
32
41
  - Progressive hi-res image swap in the lightbox (low-res placeholder → hi-res).
33
42
  - Mobile-tuned: centered snap, depth scaling, and drag-down-to-dismiss the
34
43
  lightbox.
@@ -48,22 +57,25 @@ pnpm install # or npm install
48
57
  pnpm dev # then open the printed localhost URL
49
58
  ```
50
59
 
51
- The demo (`demo/src/App.jsx`, `demo/src/demo-data.js`) renders the slider with
52
- random artworks pulled live from the
53
- [Art Institute of Chicago API](https://api.artic.edu/docs/) — it searches for
54
- public-domain, image-bearing works under a random term each load, so you get a
55
- different set every refresh. A second slider below it (`demo/src/video-data.js`)
56
- drives looping `<video>` panels from the
57
- [Pexels Video API](https://www.pexels.com/api/) free, no-attribution MP4 stock
58
- clips showing the same component handling video items. That slider needs a free
59
- Pexels key in `VITE_PEXELS_KEY` (copy `demo/.env.example` to `demo/.env.local`);
60
- without it, the video section is simply skipped.
60
+ The demo is a small routed site: the landing page (`demo/src/pages/Home.jsx`,
61
+ `demo/src/demo-data.js`) renders the slider with random artworks pulled live
62
+ from the [Art Institute of Chicago API](https://api.artic.edu/docs/) — it
63
+ searches for public-domain, image-bearing works under a random term each load,
64
+ so you get a different set every refresh. A **docs section** at `/docs` has
65
+ getting-started and API reference pages plus one live demo page per feature:
66
+ the default carousel (with both caption modes), video (+ playback controls),
67
+ lightbox options, the morphing cursor, the coverflow and card-stack variants,
68
+ and arrows & pagination.
69
+ The video page (`demo/src/video-data.js`) drives looping `<video>` panels
70
+ from the [Pexels Video API](https://www.pexels.com/api/) — free, no-attribution
71
+ MP4 stock clips. It needs a free Pexels key in `VITE_PEXELS_KEY` (copy
72
+ `demo/.env.example` to `demo/.env.local`); without it, that demo is simply
73
+ skipped.
61
74
 
62
75
  ## Install
63
76
 
64
77
  ```bash
65
78
  pnpm add @ocarignan/vitrine
66
- # or: npm i @ocarignan/vitrine · bun add @ocarignan/vitrine · yarn add @ocarignan/vitrine
67
79
  ```
68
80
 
69
81
  `react` and `react-dom` (`>=18`) are peer dependencies; `motion` and
@@ -84,6 +96,80 @@ The stylesheet is self-contained — the custom zoom cursors are inlined as data
84
96
  URIs, so there are no asset files to host. Opt into a morphing icon cursor with
85
97
  the `morphCursor` prop (see below).
86
98
 
99
+ ### Variants
100
+
101
+ The `variant` prop swaps the track layout while keeping everything else —
102
+ captions, lightbox, keyboard nav, arrows/pagination:
103
+
104
+ ```jsx
105
+ <Slider items={items} /> // scroll-snap row (default)
106
+ <Slider items={items} variant="stack" /> // deck-cycling card stack
107
+ <Slider items={items} variant="coverflow" /> // 3D coverflow
108
+ ```
109
+
110
+ - **`stack`** — cards rest in a loose pile, each keeping its own aspect ratio
111
+ (differently-shaped photos, centered in a shared box) and leaning a few
112
+ degrees, with a peek and scale falloff. The top card
113
+ follows the cursor on both axes; throwing it past a threshold — any
114
+ direction — tilts it into a flip to the back of the deck, which only ever
115
+ moves forward. Pass `aspectRatio` for a tidy uniform deck instead of mixed
116
+ shapes. The stack has **no
117
+ lightbox** (`lightbox` is ignored): clicking the top card fires
118
+ `onItemClick` if given, otherwise nothing.
119
+ - **`coverflow`** — the row engine with every item centered and projected in
120
+ 3D: the centered panel lies flat, neighbors rotate toward the vanishing
121
+ point, recede and shrink. Its lightbox mirrors the track's styling: items
122
+ stay uniform cover-cropped boxes (so the zoom morphs crop → crop) and the
123
+ lightbox neighbors carry the same 3D rotation.
124
+
125
+ Both variants ignore `item.video` in the track (poster image only); the
126
+ coverflow lightbox still plays it. Both loop endlessly by default — pass
127
+ `loop={false}` to clamp at the ends, or `loop` to make the row variant loop
128
+ too.
129
+
130
+ ### Video playback controls
131
+
132
+ Items with a `video` URL autoplay muted and looping while active. Pass
133
+ `videoControls` to add playback UI — no persistent chrome on the panel: hovering
134
+ the active panel reveals a morphing play/pause toggle (and softly blurs the
135
+ clip). The lightbox adds a centered play/pause toggle and a progress bar that
136
+ glides with playback and previews the seek target on hover; unless you pass
137
+ `"minimal"`, the bar also expands on hover into a timestamp plus mute,
138
+ picture-in-picture, and fullscreen controls:
139
+
140
+ ```jsx
141
+ <Slider items={items} videoControls />
142
+ // Just play/pause + progress bar in the lightbox
143
+ <Slider items={items} videoControls="minimal" />
144
+ ```
145
+
146
+ The slider panel and the lightbox are separate `<video>` elements, so the mute
147
+ state and playback position don't carry across the zoom.
148
+
149
+ ### Arrows & pagination
150
+
151
+ ```jsx
152
+ <Slider items={items} arrows pagination />;
153
+ ```
154
+
155
+ `arrows` renders prev/next buttons beside the caption (disabled at the ends;
156
+ wrapping when the track loops). `pagination` renders one dot per panel — the
157
+ active dot tracks scrolling, and clicking a dot navigates.
158
+
159
+ ### Disabling the lightbox
160
+
161
+ ```jsx
162
+ <Slider
163
+ items={items}
164
+ lightbox={false}
165
+ onItemClick={(item, index) => openMyDetailPage(item)}
166
+ />;
167
+ ```
168
+
169
+ With `lightbox={false}` no lightbox is mounted and clicking the active panel
170
+ fires `onItemClick` instead (clicking a non-active panel still centers it).
171
+ Without an `onItemClick`, panels are display-only.
172
+
87
173
  ### Plain (non-animated) caption
88
174
 
89
175
  The meta caption morphs between projects by default (letter morphing via
@@ -144,16 +230,25 @@ To get the rest of the page to cross-fade during the zoom, also set
144
230
  | Prop | Type | Default | Description |
145
231
  | ------------------- | -------- | ---------------------------------- | ------------------------------------------------------------------ |
146
232
  | `items` | `Item[]` | — | The panels (see shape below). |
233
+ | `variant` | `"row" \| "stack" \| "coverflow"` | `"row"` | Track layout: scroll-snap carousel, deck-cycling card stack, or 3D coverflow. Stack and coverflow ignore `item.video` in the track; the stack has no lightbox; the coverflow lightbox mirrors the track's styling. |
147
234
  | `contentWidth` | `number` | `628` | Desktop width (px) of the active panel's content column. |
148
235
  | `gap` | `number` | `32` | Desktop gap (px) between panels. |
149
236
  | `columns` | `number` | `4` | Notional grid columns — only used to align the meta text. |
150
237
  | `metaOffsetColumns` | `number` | `0` | Shift the meta text right by N columns on desktop (0 = flush). |
151
238
  | `sideMargin` | `number` | `24` | Minimum viewport margin (px/side) the content column keeps. |
152
239
  | `maxItemHeight` | `number` | `520` | Max height (px) of a panel; taller images scale down keeping ratio.|
240
+ | `aspectRatio` | `number \| string` | — | Force panels into a fixed cover-cropped box — `1.5` or `"16/9"` / `"3:2"`. Off by default (`row` and `stack` keep each image's own ratio); `coverflow` always uses a fixed box (default ≈ 3:4) and this overrides it. Bounded by `maxItemHeight`. |
153
241
  | `sizes` | `string` | `(min-width: 700px) 628px, 82vw` | `sizes` hint for the panel `<img>`. |
154
242
  | `lightboxSizes` | `string` | `84vw` | `sizes` hint forwarded to the lightbox images. |
155
243
  | `Caption` | `Component` | `TextMorph` | Component used to render the meta title/subtitle. Receives `as` and `children`. Defaults to metamorphosis's morphing `TextMorph`; pass `PlainCaption` (or your own) to opt out. |
244
+ | `lightbox` | `boolean` | `true` | Set `false` to disable the lightbox: no zoom, no lightbox mounted; the active panel's click fires `onItemClick` instead. Ignored by `variant="stack"`, which never has a lightbox. |
156
245
  | `lightboxControls` | `boolean` | `false` | Show prev / close / next buttons in the lightbox (on all breakpoints). Off by default — the caption carries the context, and swipe / arrow keys navigate. |
246
+ | `onItemClick` | `Function` | — | Called with `(item, index)` when the active panel is clicked and the lightbox is disabled (or the variant is `"stack"`). |
247
+ | `loop` | `boolean` | variant-dependent | Endless scroll: the array loops seamlessly, in the slider and its lightbox. Defaults on for `stack` and `coverflow`, off for `row`. |
248
+ | `arrows` | `boolean` | `false` | Prev/next buttons beside the caption (disabled at the ends; wrapping when the track loops). |
249
+ | `pagination` | `boolean` | `false` | One dot per panel beside the caption; the active dot tracks scrolling, clicking a dot navigates. |
250
+ | `videoControls` | `boolean \| "minimal"` | `false` | Video playback UI: a hover play/pause toggle on the active panel; a play/pause toggle + gliding progress bar in the lightbox that, unless `"minimal"`, expands on hover into timestamp + mute / PiP / fullscreen. Videos still autoplay muted. |
251
+ | `transitionName` | `string` | auto | Override the auto-generated per-instance shared-element view-transition name. |
157
252
  | `morphCursor` | `boolean` | `false` | Replace the static SVG cursors with a morphing icon cursor: `+` over a panel, `×` over the active lightbox item / overlay, `←` / `→` over the previous / next items. Precise-pointer only; touch and no-JS keep the static cursors. |
158
253
 
159
254
  ## `<Lightbox>` props (internal)
@@ -167,7 +262,10 @@ its props:
167
262
  | `items` | `Item[]` | — | Same item array passed to `<Slider>`. |
168
263
  | `activeIndex` | `number` | — | Index to open on. |
169
264
  | `sizes` | `string` | `84vw` | `sizes` hint for the images. |
265
+ | `Caption` | `Component` | `TextMorph` | Caption renderer (takes `as` + `children`). |
170
266
  | `controls` | `boolean` | `false` | Render the prev / close / next buttons (on all breakpoints). |
267
+ | `videoControls` | `boolean \| "minimal"` | `false` | Play/pause toggle + progress bar over the active video item; unless `"minimal"`, the bar expands on hover into timestamp + mute / PiP / fullscreen. |
268
+ | `transitionName` | `string` | `"slider-active"` | Shared-element view-transition name; `<Slider>` passes its per-instance name. |
171
269
  | `onActiveIndexChange` | `Function` | — | Called with the new index as the user scrolls. |
172
270
  | `onClose` | `Function` | — | Called to dismiss the lightbox. |
173
271
 
@@ -201,6 +299,7 @@ All image fields are plain strings — bring your own CMS / image transform.
201
299
  highResSrcSet?,
202
300
  highResWebpSrcSet?,
203
301
  video?, // looping muted video URL; autoplays only while active
302
+ // (row variant + lightbox — stack/coverflow show the poster)
204
303
  }
205
304
  ```
206
305
 
@@ -211,5 +310,7 @@ placeholder/swap layer is rendered.
211
310
 
212
311
  - Don't wrap the app in `<StrictMode>` — its dev-only double-invoke of effects
213
312
  fights the one-pass measure / view-transition logic. See `demo/src/main.jsx`.
214
- - The view transition uses a single shared name (`slider-active`), so render one
215
- `<Slider>` per page if you rely on the zoom animation.
313
+ - Each `<Slider>` generates its own per-instance view-transition name, so any
314
+ number can share a page (override it with the `transitionName` prop if you
315
+ need a stable name). Only mount one `morphCursor` slider per page — each
316
+ renders its own pointer-following cursor.
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),reactDom=require('react-dom'),react$1=require('motion/react'),react$2=require('@ocarignan/metamorphosis/react'),jsxRuntime=require('react/jsx-runtime');var Me=110,Ie=.55;function he({items:s,activeIndex:T,sizes:E="84vw",Caption:I=react$2.TextMorph,controls:q=false,onActiveIndexChange:N,onClose:R}){let x=react.useRef(null),F=react.useRef({isDragging:false,startX:0,scrollLeft:0}),[a,$]=react.useState(T),[,D]=react.useState(false),d=react.useRef(0),V=react.useRef(null),W=react.useRef({frozen:false,scrollLeft:0}),B=react.useRef(null),j=react.useRef(T),[L,se]=react.useState(false),[ue,y]=react.useState(false),ce=react.useRef(false),Y=react.useRef(false),Z=react.useRef(T);react.useEffect(()=>{let n=setTimeout(()=>{se(true),ce.current=true;let l=x.current;if(l){let _=l.querySelectorAll(".lightbox__item"),A=window.innerWidth/2;_.forEach(v=>{let b=v.getBoundingClientRect(),g=b.left+b.width/2,f=Math.abs(g-A),p=b.width/2,e=Math.max(0,f-p),t=Math.min(e/(window.innerWidth*.3),1);v.style.filter=`blur(0px) brightness(${1-t*.4})`,v.style.transform=`scale(${1-t*.01})`;});}},500),i=setTimeout(()=>y(true),1100);return ()=>{clearTimeout(i),clearTimeout(n);}},[]),react.useEffect(()=>(document.body.style.overflow="hidden",()=>{document.body.style.overflow="";}),[]),react.useLayoutEffect(()=>{let n=x.current;if(!n)return;let i=n.querySelectorAll(".lightbox__item")[j.current];i&&(n.scrollLeft=i.offsetLeft-(n.clientWidth-i.offsetWidth)/2);},[]);let ne=react.useCallback(()=>{Y.current||(Y.current=true,requestAnimationFrame(()=>{Y.current=false;let n=x.current;if(!n)return;let i=n.querySelectorAll(".lightbox__item"),l=window.innerWidth/2,_=new Array(i.length),A=0,v=1/0;for(let b=0;b<i.length;b++){let g=i[b].getBoundingClientRect();_[b]=g;let f=g.left+g.width/2,p=Math.abs(f-l);p<v&&(v=p,A=b);}if(ce.current){let b=window.innerWidth,g=Z.current,f=Math.min(A,g)-2,p=Math.max(A,g)+2;for(let e=Math.max(0,f);e<=Math.min(i.length-1,p);e++){let t=_[e],r=t.left+t.width/2,o=Math.abs(r-l),h=t.width/2,c=Math.max(0,o-h),u=Math.min(c/(b*.3),1);i[e].style.filter=`blur(0px) brightness(${1-u*.4})`,i[e].style.transform=`scale(${1-u*.01})`;}}Z.current=A,N(A),$(A);}));},[N]);react.useEffect(()=>{let n=x.current;if(n)return n.addEventListener("scroll",ne,{passive:true}),()=>n.removeEventListener("scroll",ne)},[ne]);let z=react.useCallback(n=>{let i=x.current;if(!i)return;let l=i.querySelectorAll(".lightbox__item");l[n]&&l[n].scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"});},[]);react.useEffect(()=>{let n=i=>{if(i.key==="Escape")R();else if(i.key==="ArrowRight"){let l=Math.min(a+1,s.length-1);l!==a&&z(l);}else if(i.key==="ArrowLeft"){let l=Math.max(a-1,0);l!==a&&z(l);}};return window.addEventListener("keydown",n),()=>window.removeEventListener("keydown",n)},[a,s.length,R,z]);let re=react.useCallback(()=>{let n=x.current,i=W.current;!n||!i.frozen||(n.style.overflow="",n.scrollLeft=i.scrollLeft,n.style.transform="",n.style.zIndex="",W.current={frozen:false,scrollLeft:0});},[]);react.useEffect(()=>()=>clearTimeout(B.current),[]);let le=react.useCallback(n=>{if(n.pointerType==="touch"){clearTimeout(B.current),d.current=0,V.current={startX:n.clientX,startY:n.clientY,locked:null,dy:0,startTime:Date.now()};return}let i=x.current;i&&(d.current=0,F.current={isDragging:true,startX:n.clientX,scrollLeft:i.scrollLeft,prevX:n.clientX,prevTime:Date.now(),velocity:0},D(true),i.style.scrollSnapType="none",i.setPointerCapture(n.pointerId));},[]),K=react.useCallback(n=>{if(n.pointerType==="touch"){let f=V.current;if(!f)return;let p=n.clientX-f.startX,e=n.clientY-f.startY;if(f.locked===null){if(Math.abs(p)<8&&Math.abs(e)<8)return;f.locked=Math.abs(e)>Math.abs(p)&&e>0?"v":"h";}if(f.locked!=="v")return;f.dy=Math.max(0,e),d.current=f.dy;let t=x.current;if(!t)return;W.current.frozen||(W.current={frozen:true,scrollLeft:t.scrollLeft},t.style.overflow="visible",t.style.transform=`translateX(${-W.current.scrollLeft}px)`,t.style.zIndex="5");let r=Math.max(.85,1-f.dy/1400),o=Math.max(0,1-f.dy/300),h=document.querySelector(".lightbox__backdrop"),c=document.querySelector(".lightbox__meta");t.querySelectorAll(".lightbox__item").forEach(u=>{u.classList.contains("lightbox__item--active")?(u.style.transition="none",u.style.transform=`translateY(${f.dy}px) scale(${r})`):(u.style.transition="none",u.style.opacity=String(o));}),h&&(h.style.transition="none",h.style.opacity=String(o)),c&&(c.style.transition="none",c.style.opacity=String(o));return}let i=F.current;if(!i.isDragging)return;let l=Date.now(),_=l-i.prevTime,A=n.clientX-i.prevX;_>0&&(i.velocity=A/_),i.prevX=n.clientX,i.prevTime=l,d.current=Math.abs(n.clientX-i.startX);let v=x.current,b=i.scrollLeft-(n.clientX-i.startX),g=v.scrollWidth-v.clientWidth;b<0?v.scrollLeft=b*.2:b>g?v.scrollLeft=g+(b-g)*.2:v.scrollLeft=b;},[]),G=react.useCallback(n=>{if(n.pointerType==="touch"){let g=V.current;if(V.current=null,!g||g.locked!=="v")return;let f=x.current,p=f?.querySelector(".lightbox__item--active"),e=document.querySelector(".lightbox__backdrop"),t=document.querySelector(".lightbox__meta"),r=g.dy/Math.max(Date.now()-g.startTime,1);if(g.dy>Me||r>Ie){R({fromDrag:true});return}let o="transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94)";p&&(p.style.transition=o,p.style.transform=""),f&&f.querySelectorAll(".lightbox__item").forEach(h=>{h.classList.contains("lightbox__item--active")||(h.style.transition="opacity 0.3s",h.style.opacity="");}),e&&(e.style.transition="opacity 0.3s",e.style.opacity=""),t&&(t.style.transition="opacity 0.3s",t.style.opacity=""),clearTimeout(B.current),B.current=setTimeout(()=>{p&&(p.style.transition=""),re();},300);return}let i=F.current;if(!i.isDragging)return;i.isDragging=false;let l=x.current;if(l.releasePointerCapture(n.pointerId),d.current<5){l.style.scrollSnapType="x mandatory",D(false);let g=document.elementFromPoint(n.clientX,n.clientY)?.closest(".lightbox__item");if(g){let p=Array.from(l.querySelectorAll(".lightbox__item")).indexOf(g);p>=0&&(p===a?R():z(p));}return}let _=-i.velocity*1e3,A=.92,v=performance.now(),b=g=>{let f=(g-v)/1e3;if(v=g,_*=A,l.scrollLeft+=_*f,Math.abs(_)>50)requestAnimationFrame(b);else {let p=l.querySelectorAll(".lightbox__item"),e=window.innerWidth/2,t=0,r=1/0;p.forEach((c,u)=>{let m=c.getBoundingClientRect(),S=m.left+m.width/2,w=Math.abs(S-e);w<r&&(r=w,t=u);});let o=()=>{clearTimeout(h),l.style.scrollSnapType="x mandatory",D(false),l.removeEventListener("scrollend",o);},h=setTimeout(o,300);l.addEventListener("scrollend",o,{once:true}),p[t].scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"});}};requestAnimationFrame(b);},[a,R,z]);react.useEffect(()=>{let n=x.current;if(!n)return;let i=n.querySelectorAll(".lightbox__item"),l=[];return i.forEach((_,A)=>{let v=_.querySelector("video");if(v)if(A===a){let g=setTimeout(()=>{v.currentTime=0,v.play();let f=()=>_.classList.add("lightbox__item--video-ready");v.readyState>=2?f():(v.addEventListener("canplay",f,{once:true}),l.push(()=>v.removeEventListener("canplay",f)));},300);l.push(()=>clearTimeout(g));}else v.pause();}),()=>l.forEach(_=>_())},[a]);let J=react.useCallback(n=>{d.current>=5||(n===a?R():z(n));},[a,R,z]);return jsxRuntime.jsxs("div",{className:`lightbox${L?" lightbox--revealed":""}${q?" lightbox--controls":""}`,children:[jsxRuntime.jsx(react$1.motion.div,{className:"lightbox__backdrop",onClick:R,initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.3}}),jsxRuntime.jsx("div",{className:"lightbox__track",ref:x,onPointerDown:le,onPointerMove:K,onPointerUp:G,onPointerCancel:G,onClick:n=>{if(d.current>=5)return;document.elementFromPoint(n.clientX,n.clientY)?.closest(".lightbox__item")||R();},style:{touchAction:"pan-x"},children:s.map((n,i)=>jsxRuntime.jsx(Re,{item:n,index:i,activeIndex:a,sizes:E,staggerDone:ue,onClick:J},n.id??i))}),jsxRuntime.jsxs("div",{className:"lightbox__meta","aria-live":"polite",children:[jsxRuntime.jsx(I,{as:"h2",children:s[a]?.title}),jsxRuntime.jsx(I,{as:"p",children:s[a]?.meta})]}),q&&jsxRuntime.jsxs("div",{className:"lightbox__controls",children:[jsxRuntime.jsx("button",{className:"lightbox__nav",onClick:()=>z(a-1),disabled:a===0,"aria-label":"Previous",children:jsxRuntime.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsxRuntime.jsx("path",{d:"M9 1L3 7L9 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}),jsxRuntime.jsx("button",{className:"lightbox__close",onClick:R,"aria-label":"Close",children:jsxRuntime.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsxRuntime.jsx("path",{d:"M1 1L13 13M13 1L1 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})}),jsxRuntime.jsx("button",{className:"lightbox__nav",onClick:()=>z(a+1),disabled:a===s.length-1,"aria-label":"Next",children:jsxRuntime.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsxRuntime.jsx("path",{d:"M5 1L11 7L5 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})})]})]})}function Re({item:s,index:T,activeIndex:E,sizes:I,staggerDone:q,onClick:N}){let R=!!s.highResSrc,x=s.video,F=T===E,a=Math.abs(T-E),[$,D]=react.useState(false);return jsxRuntime.jsxs("div",{className:`lightbox__item${F?" lightbox__item--active":""}`,"data-index":T,style:!F&&!q?{transitionDelay:`${a*.06}s`}:void 0,onClick:()=>N(T),children:[jsxRuntime.jsxs("picture",{className:"lightbox__img lightbox__img--low",children:[s.webpSrcSet&&jsxRuntime.jsx("source",{srcSet:s.webpSrcSet,sizes:I,type:"image/webp"}),jsxRuntime.jsx("img",{src:s.src,srcSet:s.srcSet,sizes:I,alt:s.alt||s.title,draggable:false,loading:a<=1?"eager":"lazy",decoding:"async"})]}),R&&jsxRuntime.jsxs("picture",{className:`lightbox__img lightbox__img--high${$?" lightbox__img--ready":""}`,children:[s.highResWebpSrcSet&&jsxRuntime.jsx("source",{srcSet:s.highResWebpSrcSet,sizes:I,type:"image/webp"}),jsxRuntime.jsx("img",{src:s.highResSrc,srcSet:s.highResSrcSet,sizes:I,alt:"","aria-hidden":"true",draggable:false,loading:a<=1?"eager":"lazy",decoding:"async",onLoad:()=>D(true)})]}),x&&jsxRuntime.jsx("video",{src:x,muted:true,playsInline:true,loop:true,preload:"none",draggable:false})]})}function Ae(s,T){if(!s||typeof s.closest!="function")return null;if(!T)return s.closest(".slider__item")?"plus":null;if(s.closest(".lightbox__item--active"))return "close";let E=s.closest(".lightbox__item");if(E){let I=Number(E.dataset.index),q=document.querySelector(".lightbox__item--active"),N=q?Number(q.dataset.index):I;return I<N?"arrow-left":"arrow-right"}return s.closest(".lightbox__backdrop, .lightbox__track")?"close":null}function we({lightboxOpen:s}){let T=react.useRef(null),E=react.useRef(0),I=react.useRef({x:0,y:0}),[q,N]=react.useState(false),[R,x]=react.useState(null),[F,a]=react.useState(false);return react.useEffect(()=>{if(typeof window>"u"||!window.matchMedia)return;let $=window.matchMedia("(pointer: fine)"),D=()=>N($.matches);return D(),$.addEventListener("change",D),()=>$.removeEventListener("change",D)},[]),react.useEffect(()=>{if(!q){a(false);return}let $=d=>{I.current={x:d.clientX,y:d.clientY},E.current||(E.current=requestAnimationFrame(()=>{E.current=0;let W=T.current;if(W){let{x:B,y:j}=I.current;W.style.transform=`translate(${B}px, ${j}px) translate(-50%, -50%)`;}}));let V=Ae(d.target,s);V?(x(V),a(true)):a(false);},D=d=>{d.relatedTarget||a(false);};return window.addEventListener("pointermove",$,{passive:true}),window.addEventListener("pointerout",D,{passive:true}),()=>{window.removeEventListener("pointermove",$),window.removeEventListener("pointerout",D),E.current&&cancelAnimationFrame(E.current),E.current=0;}},[q,s]),q?jsxRuntime.jsx("div",{ref:T,className:`morph-cursor${F?" morph-cursor--visible":""}`,"aria-hidden":"true",children:R&&jsxRuntime.jsx(react$2.IconMorph,{name:R,size:20,strokeWidth:1.75,color:"#fff",duration:250})}):null}var Pe=({as:s="span",children:T})=>jsxRuntime.jsx(s,{children:T}),Xe={initial:{},animate:{transition:{staggerChildren:.06}}},_e={initial:{opacity:0,y:8},animate:{opacity:1,y:0,transition:{duration:1,ease:[0,.55,.45,1]}}};function Ne({items:s,contentWidth:T=628,gap:E=32,columns:I=4,metaOffsetColumns:q=0,sideMargin:N=24,maxItemHeight:R=520,sizes:x="(min-width: 700px) 628px, 82vw",lightboxSizes:F="84vw",Caption:a=react$2.TextMorph,lightboxControls:$=false,morphCursor:D=false}){let d=react.useRef(null),V=react.useRef(null),W=react.useRef(false),B=react.useRef(null),j=react.useRef({isDragging:false,startX:0,scrollLeft:0}),[L,se]=react.useState(0),ue=react.useRef(0);ue.current=L;let[y,ce]=react.useState({inset:0,itemWidth:0,metaInset:0,metaInsetRight:0,endPad:0,isMobile:false}),[Y,Z]=react.useState(false),[ne,z]=react.useState(false),re=react.useRef(0),le=react.useRef(false),K=react.useRef(null),G=react.useRef(false);react.useEffect(()=>{let e=()=>{let o=window.innerWidth,h=window.matchMedia("(min-width: 700px)").matches,c=document.querySelector(".subgrid"),u=c?.closest(".grid")||document.querySelector(".grid");if(h){let m,S,w,M;if(c&&u){let Q=c.getBoundingClientRect();m=Q.left,S=Q.width,w=parseInt(getComputedStyle(u).getPropertyValue("--columns"),10)||I,M=parseFloat(getComputedStyle(c).columnGap)||E;}else S=Math.min(T,o-2*N),m=(o-S)/2,w=I,M=E;let C=(S-(w-1)*M)/w,P=m-12;ce({inset:P,itemWidth:S+24,metaInset:P+q*(C+M),metaInsetRight:P,endPad:o-P,isMobile:false});}else {let m;c&&u?m=c.getBoundingClientRect().left-u.getBoundingClientRect().left:m=N,ce({inset:m,itemWidth:o-2*m,metaInset:m,metaInsetRight:m,endPad:m,isMobile:true});}},t,r=()=>{clearTimeout(t),t=setTimeout(e,100);};return e(),window.addEventListener("resize",r),()=>{window.removeEventListener("resize",r),clearTimeout(t);}},[T,E,I,q,N]),react.useEffect(()=>{let e=d.current;e&&(e.scrollLeft=0);},[y.inset]);let J=react.useCallback(e=>{let t=d.current;if(!t||!y.itemWidth)return;let r=t.querySelectorAll(".slider__item");r[e]&&r[e].scrollIntoView({behavior:"smooth",block:"nearest",inline:y.isMobile?"center":"start"});},[y.itemWidth,y.isMobile]);react.useEffect(()=>{let e=t=>{if(!(t.key!=="ArrowRight"&&t.key!=="ArrowLeft"||Y||!(W.current||V.current&&V.current.contains(document.activeElement))))if(t.key==="ArrowRight"){let o=Math.min(L+1,s.length-1);o!==L&&(t.preventDefault(),J(o));}else {let o=Math.max(L-1,0);o!==L&&(t.preventDefault(),J(o));}};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[L,s.length,Y,J]);let n=react.useCallback(e=>{let t=e.querySelectorAll(".slider__item"),r=window.innerWidth/2,o=0,h=1/0;return t.forEach((c,u)=>{let m=c.getBoundingClientRect(),S=m.left+m.width/2,w=Math.abs(S-r);w<h&&(h=w,o=u);let M=m.width/2,C=Math.max(0,w-M),P=Math.min(C/(window.innerWidth*.3),1),Q=c.querySelector(".slider__item-inner");Q&&(Q.style.transformOrigin=S<r?"right center":"left center",Q.style.transform=`scale(${1-P*.05})`,Q.style.filter=`brightness(${1-P*.15})`);}),o},[]),i=react.useCallback(()=>{if(d.current&&!le.current){if(y.isMobile){if(G.current)return;G.current=true,requestAnimationFrame(()=>{G.current=false;let t=d.current;if(!t)return;let r=n(t);se(r),clearTimeout(B.current);});return}G.current||(G.current=true,requestAnimationFrame(()=>{G.current=false;let t=d.current;if(!t)return;let r=t.querySelectorAll(".slider__item"),o=y.inset,h=0,c=1/0;r.forEach((u,m)=>{let S=Math.abs(u.getBoundingClientRect().left-o);S<c&&(c=S,h=m);}),se(h);}));}},[y.inset,y.isMobile,n]);react.useEffect(()=>{let e=d.current;if(e)return e.addEventListener("scroll",i,{passive:true}),()=>e.removeEventListener("scroll",i)},[i]),react.useEffect(()=>{let e=d.current;e&&(y.isMobile?requestAnimationFrame(()=>n(e)):e.querySelectorAll(".slider__item-inner").forEach(t=>{t.style.transform="",t.style.filter="",t.style.transformOrigin="";}));},[y.isMobile,n]);let l=react.useCallback(()=>{let e=ue.current,t=d.current?.querySelectorAll(".slider__item");if(t?.[e]&&!K.current)if(document.startViewTransition){t[e].classList.add("slider__item--transitioning"),t[e].style.viewTransitionName="slider-active",document.documentElement.style.viewTransitionName="none";let r=document.startViewTransition(()=>{t[e].style.viewTransitionName="",reactDom.flushSync(()=>Z(true));});K.current=r,r.finished.then(()=>{K.current=null,t[e].classList.remove("slider__item--transitioning"),document.documentElement.style.viewTransitionName="";});}else Z(true);},[]),_=react.useCallback(e=>{if(e===L){l();return}let t=d.current;J(e);let r=()=>{clearTimeout(o),t?.removeEventListener("scrollend",r),l();},o=setTimeout(r,600);t?.addEventListener("scrollend",r,{once:true});},[L,l,J]),A=react.useCallback(e=>{if(e.pointerType==="touch")return;let t=d.current;t&&(re.current=0,j.current={isDragging:true,startX:e.clientX,scrollLeft:t.scrollLeft,prevX:e.clientX,prevTime:Date.now(),velocity:0},t.style.scrollSnapType="none",t.setPointerCapture(e.pointerId));},[]),v=react.useCallback(e=>{let t=j.current;if(!t.isDragging)return;let r=Date.now(),o=r-t.prevTime,h=e.clientX-t.prevX;o>0&&(t.velocity=h/o),t.prevX=e.clientX,t.prevTime=r,re.current=Math.abs(e.clientX-t.startX),d.current.scrollLeft=t.scrollLeft-(e.clientX-t.startX);},[]),b=react.useCallback(e=>{let t=j.current;if(!t.isDragging)return;t.isDragging=false;let r=d.current;if(r.releasePointerCapture(e.pointerId),re.current<5){r.style.scrollSnapType="x mandatory";let m=document.elementFromPoint(e.clientX,e.clientY)?.closest(".slider__item");if(m){let w=Array.from(r.querySelectorAll(".slider__item")).indexOf(m);w>=0&&_(w);}return}let o=-t.velocity*1e3,h=.92,c=performance.now(),u=m=>{let S=(m-c)/1e3;if(c=m,o*=h,r.scrollLeft+=o*S,Math.abs(o)>50)requestAnimationFrame(u);else {let w=r.querySelectorAll(".slider__item"),M=0,C=1/0;w.forEach((Le,Se)=>{let ve=Math.abs(Le.getBoundingClientRect().left-y.inset);ve<C&&(C=ve,M=Se);});let P=()=>{clearTimeout(Q),r.style.scrollSnapType="x mandatory",r.removeEventListener("scrollend",P);},Q=setTimeout(P,300);r.addEventListener("scrollend",P,{once:true}),w[M].scrollIntoView({behavior:"smooth",block:"nearest",inline:"start"});}};requestAnimationFrame(u);},[y.inset,_]);react.useEffect(()=>{if(Y){let e=setTimeout(()=>z(true),300);return ()=>clearTimeout(e)}else z(false);},[Y]),react.useEffect(()=>{let e=d.current;if(!e)return;let t=e.querySelectorAll(".slider__item"),r=[];return t.forEach((o,h)=>{let c=o.querySelector("video");if(c)if(ne)c.pause(),c.style.visibility="hidden",o.classList.remove("slider__item--video-ready");else if(c.style.visibility="",h===L){c.currentTime=0,c.play();let u=()=>o.classList.add("slider__item--video-ready");c.readyState>=2?u():(c.addEventListener("canplay",u,{once:true}),r.push(()=>c.removeEventListener("canplay",u)));}else c.pause(),o.classList.remove("slider__item--video-ready");}),()=>r.forEach(o=>o())},[L,ne]);let g=react.useCallback(e=>{let t=e?.fromDrag===true;if(K.current)return;let r=d.current?.querySelectorAll(".slider__item");if(!r?.[L]){Z(false);return}let o=document.querySelector(".lightbox");o&&!t&&o.classList.add("lightbox--closing");let h=y.isMobile?"center":"start",c=d.current,u=()=>{let w=r[L];if(!w)return;let M=w.getBoundingClientRect(),C=h==="center"?window.innerWidth/2:y.inset,P=h==="center"?M.left+M.width/2:M.left;Math.abs(P-C)<4||w.scrollIntoView({behavior:"instant",block:"nearest",inline:h});};c?.addEventListener("scroll",u);let m=()=>c?.removeEventListener("scroll",u),S=()=>{if(K.current){m();return}if(document.startViewTransition){r.forEach(M=>{let C=M.querySelector("video");C&&(C.style.visibility="");}),document.documentElement.style.viewTransitionName="none";let w=document.startViewTransition(()=>{let M=document.querySelector(".lightbox__item--active");M&&(M.style.viewTransitionName="none");let C=document.querySelector(".lightbox");C&&(C.style.display="none"),u(),r[L].style.viewTransitionName="slider-active",reactDom.flushSync(()=>Z(false));});K.current=w,w.finished.then(()=>{K.current=null,r[L].style.viewTransitionName="",document.documentElement.style.viewTransitionName="",m();});}else u(),Z(false),setTimeout(m,400);};t?requestAnimationFrame(S):o?setTimeout(S,350):S();},[L,y.isMobile]),f=react.useCallback(e=>{se(e),le.current=true,J(e),clearTimeout(B.current),B.current=setTimeout(()=>{le.current=false;},300);},[J]),p=s[L];return jsxRuntime.jsxs(react$1.motion.div,{className:`slider${D?" slider--morph-cursor":""}`,ref:V,variants:Xe,onPointerEnter:()=>W.current=true,onPointerLeave:()=>W.current=false,children:[jsxRuntime.jsx(react$1.motion.div,{className:"slider__track",ref:d,tabIndex:-1,onPointerDown:A,onPointerMove:v,onPointerUp:b,onPointerCancel:b,style:{paddingLeft:`${y.inset}px`,paddingRight:`${y.endPad}px`,scrollPaddingLeft:y.isMobile?void 0:`${y.inset}px`,touchAction:"pan-x pan-y"},children:s.map((e,t)=>{let r=e.id??t;return jsxRuntime.jsx(react$1.motion.div,{className:`slider__item${t===L?" slider__item--active":""}`,variants:_e,role:"button",tabIndex:0,"aria-label":e.title,style:{"--item-max-w":`${y.itemWidth}px`,"--item-max-h":`${R}px`,cursor:D?"none":"zoom-in"},onClick:()=>{re.current<5&&_(t);},onKeyDown:o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),_(t));},children:jsxRuntime.jsxs("div",{className:"slider__item-inner",children:[jsxRuntime.jsxs("picture",{children:[e.webpSrcSet&&jsxRuntime.jsx("source",{srcSet:e.webpSrcSet,sizes:x,type:"image/webp"}),jsxRuntime.jsx("img",{src:e.src,srcSet:e.srcSet,sizes:x,alt:e.alt||e.title,draggable:false,fetchPriority:t===0?"high":void 0,loading:t<=1?"eager":"lazy",decoding:t<=1?"sync":"async",style:e.blurDataURL?{backgroundImage:`url(${e.blurDataURL})`,backgroundSize:"cover",backgroundRepeat:"no-repeat",backgroundPosition:"center"}:void 0})]}),e.video&&jsxRuntime.jsx("video",{src:e.video,muted:true,playsInline:true,loop:true,preload:"none",draggable:false})]})},r)})}),jsxRuntime.jsx(react$1.motion.div,{className:"slider__meta",style:{paddingLeft:`${y.metaInset}px`,paddingRight:`${y.metaInsetRight}px`},variants:_e,children:jsxRuntime.jsxs("div",{className:"slider__meta-inner",children:[jsxRuntime.jsx(a,{as:"h3",children:p?.title}),jsxRuntime.jsx("br",{}),jsxRuntime.jsx(a,{as:"p",children:p?.meta})]})}),jsxRuntime.jsx(react$1.AnimatePresence,{children:Y&&jsxRuntime.jsx(he,{items:s,activeIndex:L,sizes:F,Caption:a,controls:$,onActiveIndexChange:f,onClose:g})}),D&&jsxRuntime.jsx(we,{lightboxOpen:Y})]})}
2
- exports.Lightbox=he;exports.PlainCaption=Pe;exports.Slider=Ne;
1
+ 'use strict';var react=require('react'),reactDom=require('react-dom'),react$1=require('motion/react'),react$2=require('@ocarignan/metamorphosis/react'),jsxRuntime=require('react/jsx-runtime');var Ae=()=>jsxRuntime.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M9 1L3 7L9 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})}),De=()=>jsxRuntime.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M5 1L11 7L5 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})});var je=()=>jsxRuntime.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsxRuntime.jsx("path",{d:"M1.5 5H4L7.5 2V12L4 9H1.5V5Z",fill:"currentColor",stroke:"currentColor",strokeWidth:"1",strokeLinejoin:"round"}),jsxRuntime.jsx("path",{d:"M10 4.5C11.3 5.8 11.3 8.2 10 9.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),et=()=>jsxRuntime.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsxRuntime.jsx("path",{d:"M1.5 5H4L7.5 2V12L4 9H1.5V5Z",fill:"currentColor",stroke:"currentColor",strokeWidth:"1",strokeLinejoin:"round"}),jsxRuntime.jsx("path",{d:"M9.75 5.5L12.75 8.5M12.75 5.5L9.75 8.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),tt=()=>jsxRuntime.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsxRuntime.jsx("rect",{x:"1",y:"2.5",width:"12",height:"9",rx:"1.5",stroke:"currentColor",strokeWidth:"1.3"}),jsxRuntime.jsx("rect",{x:"6.75",y:"6.25",width:"5.25",height:"4.25",rx:"1",fill:"currentColor"})]}),nt=()=>jsxRuntime.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M5 1H1V5M9 1H13V5M5 13H1V9M9 13H13V9",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round",strokeLinejoin:"round"})}),rt={lines:[[9,6,18,12],[18,12,9,18],[9,18,9,6]]},ot={lines:[[9.5,6,9.5,18],[14.5,6,14.5,18],[12,12,12,12]]},it=()=>jsxRuntime.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M1 1L13 13M13 1L1 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})});function st({playing:n,size:d=26,color:p="#fff",strokeWidth:v=2}){return jsxRuntime.jsx(react$2.IconMorph,{name:n?"pause":"play",icon:n?ot:rt,size:d,color:p,strokeWidth:v,duration:220})}function Ne({videoRef:n,size:d=44}){let[p,v]=react.useState(true);react.useEffect(()=>{let E=n.current;if(!E)return;let y=()=>v(true),D=()=>v(false);return v(!E.paused),E.addEventListener("play",y),E.addEventListener("pause",D),()=>{E.removeEventListener("play",y),E.removeEventListener("pause",D);}},[n]);let x=E=>{E.stopPropagation();let y=n.current;y&&(y.paused?y.play():y.pause());},k=E=>E.stopPropagation();return jsxRuntime.jsx("button",{type:"button",className:"vitrine-video-toggle",onClick:x,onPointerDown:k,onPointerUp:k,"aria-label":p?"Pause":"Play",children:jsxRuntime.jsx(st,{playing:p,size:d,strokeWidth:1.8})})}function at(n){(!Number.isFinite(n)||n<0)&&(n=0);let d=Math.floor(n/60),p=Math.floor(n%60);return `${d}:${String(p).padStart(2,"0")}`}function ut({videoRef:n,minimal:d=false}){let[p,v]=react.useState(true),[x,k]=react.useState(0),[E,y]=react.useState(0),[D,A]=react.useState(false),W=react.useRef(null),N=react.useRef(null),L=react.useRef(false);react.useEffect(()=>{let c=n.current;if(!c)return;let F=()=>v(c.muted),C=()=>{L.current||y(c.currentTime);},m=()=>k(c.duration||0),O=()=>A(true),j=()=>A(false);return v(c.muted),k(c.duration||0),y(c.currentTime),A(document.pictureInPictureElement===c),c.addEventListener("volumechange",F),c.addEventListener("timeupdate",C),c.addEventListener("loadedmetadata",m),c.addEventListener("enterpictureinpicture",O),c.addEventListener("leavepictureinpicture",j),()=>{c.removeEventListener("volumechange",F),c.removeEventListener("timeupdate",C),c.removeEventListener("loadedmetadata",m),c.removeEventListener("enterpictureinpicture",O),c.removeEventListener("leavepictureinpicture",j);}},[n]),react.useEffect(()=>{let c,F=()=>{let C=n.current,m=W.current;C&&m&&C.duration&&(m.style.width=`${Math.min(C.currentTime/C.duration,1)*100}%`),c=requestAnimationFrame(F);};return c=requestAnimationFrame(F),()=>cancelAnimationFrame(c)},[n]);let M=()=>{let c=n.current;c&&(c.muted=!c.muted);},g=async()=>{let c=n.current;if(c)try{document.pictureInPictureElement?await document.exitPictureInPicture():await c.requestPictureInPicture();}catch{}},V=()=>{let c=n.current;c&&(document.fullscreenElement?document.exitFullscreen():c.requestFullscreen?c.requestFullscreen():c.webkitEnterFullscreen&&c.webkitEnterFullscreen());},z=c=>{let F=c.currentTarget.getBoundingClientRect();return Math.min(Math.max((c.clientX-F.left)/F.width,0),1)},$=c=>{let F=n.current;!F||!x||(F.currentTime=c*x,y(c*x),W.current&&(W.current.style.width=`${c*100}%`));},de=c=>{N.current&&(N.current.style.width=`${z(c)*100}%`),L.current&&$(z(c));},X=c=>c.stopPropagation(),ie=typeof document<"u"&&document.pictureInPictureEnabled;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(Ne,{videoRef:n,size:60}),jsxRuntime.jsxs("div",{className:`vitrine-lb-video${d?" vitrine-lb-video--minimal":""}`,onPointerDown:X,onPointerMove:X,onPointerUp:X,onClick:X,onKeyDown:X,children:[!d&&jsxRuntime.jsxs("div",{className:"vitrine-lb-video__bar",children:[jsxRuntime.jsxs("span",{className:"vitrine-lb-video__time",children:[at(E)," / ",at(x)]}),jsxRuntime.jsxs("div",{className:"vitrine-lb-video__actions",children:[jsxRuntime.jsx("button",{type:"button",className:"vitrine-lb-video__btn",onClick:M,"aria-label":p?"Unmute":"Mute",children:p?jsxRuntime.jsx(et,{}):jsxRuntime.jsx(je,{})}),ie&&jsxRuntime.jsx("button",{type:"button",className:"vitrine-lb-video__btn",onClick:g,"aria-label":D?"Exit picture in picture":"Picture in picture",children:jsxRuntime.jsx(tt,{})}),jsxRuntime.jsx("button",{type:"button",className:"vitrine-lb-video__btn",onClick:V,"aria-label":"Fullscreen",children:jsxRuntime.jsx(nt,{})})]})]}),jsxRuntime.jsxs("div",{className:"vitrine-lb-video__progress",role:"slider","aria-label":"Seek","aria-valuemin":0,"aria-valuemax":Math.round(x)||0,"aria-valuenow":Math.round(E),tabIndex:0,onPointerDown:c=>{L.current=true,c.currentTarget.setPointerCapture(c.pointerId),$(z(c)),X(c);},onPointerMove:de,onPointerUp:c=>{L.current=false;try{c.currentTarget.releasePointerCapture(c.pointerId);}catch{}X(c);},children:[jsxRuntime.jsx("div",{className:"vitrine-lb-video__preview",ref:N}),jsxRuntime.jsx("div",{className:"vitrine-lb-video__progress-fill",ref:W})]})]})]})}var Nt=110,qt=.55,$t=35,Ft=160,Wt=1400;function He(n,d,p,v){let x=d.left+d.width/2,k=Math.abs(x-p),E=Math.max(0,k-d.width/2),y=Math.min(E/(window.innerWidth*.3),1);if(n.style.filter=`blur(0px) brightness(${1-y*.4})`,v){let D=Math.max(-2,Math.min(2,(x-p)/d.width)),A=Math.min(Math.abs(D),1),W=n.firstElementChild;W.style.transform=`perspective(${Wt}px) rotateY(${(-Math.sign(D)*A*$t).toFixed(2)}deg) translateZ(${(-Math.abs(D)*Ft).toFixed(1)}px) scale(${(1-Math.abs(D)*.06).toFixed(4)})`,n.style.zIndex=String(100-Math.round(Math.abs(D)*10));}else n.style.transform=`scale(${1-y*.01})`;}function Ye({items:n,activeIndex:d,sizes:p="84vw",Caption:v=react$2.TextMorph,controls:x=false,videoControls:k=false,transitionName:E="slider-active",coverflow:y=false,itemAspect:D,loop:A=false,onActiveIndexChange:W,onClose:N}){let L=react.useRef(null),M=react.useRef({isDragging:false,startX:0,scrollLeft:0}),[g,V]=react.useState(d),[,z]=react.useState(false),$=react.useRef(0),de=react.useRef("mouse"),[X,ie]=react.useState(false),c=react.useRef(null),F=react.useRef({frozen:false,scrollLeft:0}),C=react.useRef(null),m=react.useRef(d),[O,j]=react.useState(false),[H,ee]=react.useState(false),Y=react.useRef(false),b=react.useRef(false),S=n.length,P=A&&S>0?Math.max(2,Math.ceil(8/S)):0,T=2*P+1,q=react.useRef(false),Q=react.useRef(null),se=react.useRef(null),_e=react.useRef(P*S+d),ce=react.useCallback((e,r)=>r.offsetLeft-(e.clientWidth-r.offsetWidth)/2,[]),B=react.useCallback(()=>{q.current=true,clearTimeout(Q.current),Q.current=setTimeout(()=>{q.current=false;},800);},[]),te=react.useCallback(()=>{let e=L.current;if(!e||!P||M.current.isDragging||F.current.frozen)return;let r=e.querySelectorAll(".lightbox__item");if(S===0||r.length!==T*S)return;let u=r[S].offsetLeft-r[0].offsetLeft;if(!u)return;let w=0,_=1/0;for(let o=0;o<r.length;o++){let i=Math.abs(ce(e,r[o])-e.scrollLeft);i<_&&(_=i,w=o);}let t=Math.floor(w/S);t!==P&&(e.scrollLeft+=(P-t)*u),q.current=false;},[P,T,S,ce]);react.useEffect(()=>{let e=L.current;if(!e||!P)return;let r=()=>te();return e.addEventListener("scrollend",r),()=>e.removeEventListener("scrollend",r)},[P,te]),react.useEffect(()=>{let e=setTimeout(()=>{j(true),Y.current=true;let u=L.current;if(u){let w=u.querySelectorAll(".lightbox__item"),_=window.innerWidth/2;w.forEach(t=>{He(t,t.getBoundingClientRect(),_,y);});}},500),r=setTimeout(()=>ee(true),1100);return ()=>{clearTimeout(r),clearTimeout(e);}},[y]),react.useEffect(()=>(document.body.style.overflow="hidden",()=>{document.body.style.overflow="";}),[]),react.useLayoutEffect(()=>{let e=L.current;if(!e)return;let r=e.querySelectorAll(".lightbox__item"),u=r[P*S+m.current];if(u&&(e.scrollLeft=u.offsetLeft-(e.clientWidth-u.offsetWidth)/2,y)){let w=window.innerWidth/2;r.forEach(_=>He(_,_.getBoundingClientRect(),w,true));}},[y,P,S]);let ae=react.useCallback(()=>{b.current||(b.current=true,requestAnimationFrame(()=>{b.current=false;let e=L.current;if(!e)return;let r=e.querySelectorAll(".lightbox__item"),u=window.innerWidth/2;if(P&&!q.current&&!F.current.frozen&&S>0&&r.length===T*S){let i=r[S].offsetLeft-r[0].offsetLeft,s=ce(e,r[P*S]),l=e.scrollLeft,a=0;i&&l<s-i*.75?a=i:i&&l>s+i*1.75&&(a=-i),a&&(e.scrollLeft=l+a,M.current.isDragging&&(M.current.scrollLeft+=a));}P&&(clearTimeout(se.current),se.current=setTimeout(te,200));let w=new Array(r.length),_=0,t=1/0;for(let i=0;i<r.length;i++){let s=r[i].getBoundingClientRect();w[i]=s;let l=s.left+s.width/2,a=Math.abs(l-u);a<t&&(t=a,_=i);}if(Y.current){let i=_e.current,s=Math.min(_,i)-2,l=Math.max(_,i)+2;for(let a=Math.max(0,s);a<=Math.min(r.length-1,l);a++)He(r[a],w[a],u,y);}_e.current=_;let o=P?_%S:_;W(o),V(o);}));},[W,y,P,T,S,ce,te]);react.useEffect(()=>{let e=L.current;if(e)return e.addEventListener("scroll",ae,{passive:true}),()=>e.removeEventListener("scroll",ae)},[ae]);let U=react.useCallback(e=>{let r=L.current;if(!r)return;let u=r.querySelectorAll(".lightbox__item"),w;if(P){let _=(e%S+S)%S,t=1/0;for(let o=0;o<T;o++){let i=u[o*S+_];if(!i)continue;let s=Math.abs(ce(r,i)-r.scrollLeft);s<t&&(t=s,w=i);}w&&B();}else w=u[e];w&&w.scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"});},[P,T,S,ce,B]);react.useEffect(()=>{let e=r=>{if(r.key==="Escape")N();else if(r.key==="ArrowRight"){let u=A?g+1:Math.min(g+1,n.length-1);u!==g&&U(u);}else if(r.key==="ArrowLeft"){let u=A?g-1:Math.max(g-1,0);u!==g&&U(u);}};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[g,n.length,A,N,U]);let ve=react.useCallback(()=>{let e=L.current,r=F.current;!e||!r.frozen||(e.style.overflow="",e.scrollLeft=r.scrollLeft,e.style.transform="",e.style.zIndex="",F.current={frozen:false,scrollLeft:0});},[]);react.useEffect(()=>()=>clearTimeout(C.current),[]);let xe=react.useCallback(e=>{if(de.current=e.pointerType,e.pointerType==="touch"){clearTimeout(C.current),$.current=0,c.current={startX:e.clientX,startY:e.clientY,locked:null,dy:0,startTime:Date.now()};return}let r=L.current;r&&($.current=0,M.current={isDragging:true,startX:e.clientX,scrollLeft:r.scrollLeft,prevX:e.clientX,prevTime:Date.now(),velocity:0},z(true),r.style.scrollSnapType="none",r.setPointerCapture(e.pointerId));},[]),fe=react.useCallback(e=>{if(e.pointerType==="touch"){let s=c.current;if(!s)return;let l=e.clientX-s.startX,a=e.clientY-s.startY;if(s.locked===null){if(Math.abs(l)<8&&Math.abs(a)<8)return;s.locked=Math.abs(a)>Math.abs(l)&&a>0?"v":"h";}if(s.locked!=="v")return;s.dy=Math.max(0,a),$.current=s.dy;let h=L.current;if(!h)return;F.current.frozen||(F.current={frozen:true,scrollLeft:h.scrollLeft},h.style.overflow="visible",h.style.transform=`translateX(${-F.current.scrollLeft}px)`,h.style.zIndex="5");let f=Math.max(.85,1-s.dy/1400),I=Math.max(0,1-s.dy/300),R=document.querySelector(".lightbox__backdrop"),K=document.querySelector(".lightbox__meta");h.querySelectorAll(".lightbox__item").forEach(Z=>{Z.classList.contains("lightbox__item--active")?(Z.style.transition="none",Z.style.transform=`translateY(${s.dy}px) scale(${f})`):(Z.style.transition="none",Z.style.opacity=String(I));}),R&&(R.style.transition="none",R.style.opacity=String(I)),K&&(K.style.transition="none",K.style.opacity=String(I));return}let r=M.current;if(!r.isDragging)return;let u=Date.now(),w=u-r.prevTime,_=e.clientX-r.prevX;w>0&&(r.velocity=_/w),r.prevX=e.clientX,r.prevTime=u,$.current=Math.abs(e.clientX-r.startX);let t=L.current,o=r.scrollLeft-(e.clientX-r.startX),i=t.scrollWidth-t.clientWidth;o<0?t.scrollLeft=o*.2:o>i?t.scrollLeft=i+(o-i)*.2:t.scrollLeft=o;},[]),ye=react.useCallback(e=>{if(e.pointerType==="touch"){let i=c.current;if(c.current=null,!i||i.locked!=="v")return;let s=L.current,l=s?.querySelector(".lightbox__item--active"),a=document.querySelector(".lightbox__backdrop"),h=document.querySelector(".lightbox__meta"),f=i.dy/Math.max(Date.now()-i.startTime,1);if(i.dy>Nt||f>qt){N({fromDrag:true});return}let I="transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94)";l&&(l.style.transition=I,l.style.transform=""),s&&s.querySelectorAll(".lightbox__item").forEach(R=>{R.classList.contains("lightbox__item--active")||(R.style.transition="opacity 0.3s",R.style.opacity="");}),a&&(a.style.transition="opacity 0.3s",a.style.opacity=""),h&&(h.style.transition="opacity 0.3s",h.style.opacity=""),clearTimeout(C.current),C.current=setTimeout(()=>{l&&(l.style.transition=""),ve();},300);return}let r=M.current;if(!r.isDragging)return;r.isDragging=false;let u=L.current;if(u.releasePointerCapture(e.pointerId),$.current<5){u.style.scrollSnapType="x mandatory",z(false);let i=document.elementFromPoint(e.clientX,e.clientY)?.closest(".lightbox__item");if(i){let l=Array.from(u.querySelectorAll(".lightbox__item")).indexOf(i);if(l>=0){let a=P?P*S+g:g;l===a?N():P?(B(),i.scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"})):U(l);}}return}let w=-r.velocity*1e3,_=.92,t=performance.now(),o=i=>{let s=(i-t)/1e3;if(t=i,w*=_,u.scrollLeft+=w*s,Math.abs(w)>50)requestAnimationFrame(o);else {let l=u.querySelectorAll(".lightbox__item"),a=window.innerWidth/2,h=0,f=1/0;l.forEach((K,Z)=>{let ne=K.getBoundingClientRect(),G=ne.left+ne.width/2,me=Math.abs(G-a);me<f&&(f=me,h=Z);});let I=()=>{clearTimeout(R),u.style.scrollSnapType="x mandatory",z(false),u.removeEventListener("scrollend",I);},R=setTimeout(I,300);u.addEventListener("scrollend",I,{once:true}),P&&B(),l[h].scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"});}};requestAnimationFrame(o);},[g,N,U,P,S,B]);react.useEffect(()=>{ie(false);},[g]),react.useEffect(()=>{let e=L.current;if(!e)return;let r=e.querySelectorAll(".lightbox__item:not([data-clone])"),u=[];return r.forEach((w,_)=>{let t=w.querySelector("video");if(t)if(_===g){let i=setTimeout(()=>{t.currentTime=0,t.play();let s=()=>w.classList.add("lightbox__item--video-ready");t.readyState>=2?s():(t.addEventListener("canplay",s,{once:true}),u.push(()=>t.removeEventListener("canplay",s)));},300);u.push(()=>clearTimeout(i));}else t.pause();}),()=>u.forEach(w=>w())},[g]);let be=react.useCallback(e=>{if($.current>=5)return;let r=P?P*S+g:g;if(e===r){if(k&&!!n[g]?.video&&de.current==="touch"){ie(w=>!w);return}N();}else if(P){let u=L.current?.querySelectorAll(".lightbox__item")[e];u&&(B(),u.scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"}));}else U(e);},[g,N,U,P,S,B,n,k]);return jsxRuntime.jsxs("div",{className:`lightbox${O?" lightbox--revealed":""}${x?" lightbox--controls":""}${y?" lightbox--coverflow":""}`,style:y&&D?{"--lb-item-aspect":D}:void 0,children:[jsxRuntime.jsx(react$1.motion.div,{className:"lightbox__backdrop",onClick:N,initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.3}}),jsxRuntime.jsx("div",{className:"lightbox__track",ref:L,onPointerDown:xe,onPointerMove:fe,onPointerUp:ye,onPointerCancel:ye,onClick:e=>{if($.current>=5)return;document.elementFromPoint(e.clientX,e.clientY)?.closest(".lightbox__item")||N();},style:{touchAction:"pan-x"},children:Array.from({length:T*S},(e,r)=>{let u=r%S;return jsxRuntime.jsx(Vt,{item:n[u],index:u,pos:r,clone:P>0&&Math.floor(r/S)!==P,activeIndex:g,sizes:p,staggerDone:H,transitionName:E,videoControls:k,showControls:X,onClick:be},`${Math.floor(r/S)}:${n[u].id??u}`)})}),jsxRuntime.jsxs("div",{className:"lightbox__meta","aria-live":"polite",children:[jsxRuntime.jsx(v,{as:"h2",children:n[g]?.title}),jsxRuntime.jsx(v,{as:"p",children:n[g]?.meta})]}),x&&jsxRuntime.jsxs("div",{className:"lightbox__controls",children:[jsxRuntime.jsx("button",{className:"lightbox__nav",onClick:()=>U(g-1),disabled:!A&&g===0,"aria-label":"Previous",children:jsxRuntime.jsx(Ae,{})}),jsxRuntime.jsx("button",{className:"lightbox__close",onClick:N,"aria-label":"Close",children:jsxRuntime.jsx(it,{})}),jsxRuntime.jsx("button",{className:"lightbox__nav",onClick:()=>U(g+1),disabled:!A&&g===n.length-1,"aria-label":"Next",children:jsxRuntime.jsx(De,{})})]})]})}function Vt({item:n,index:d,pos:p=d,clone:v=false,activeIndex:x,sizes:k,staggerDone:E,transitionName:y,videoControls:D,showControls:A=false,onClick:W}){let N=!!n.highResSrc,L=v?void 0:n.video,M=react.useRef(null),g=!v&&d===x,V=Math.abs(d-x),[z,$]=react.useState(false);return jsxRuntime.jsx("div",{className:`lightbox__item${g?" lightbox__item--active":""}${g&&A?" lightbox__item--show-controls":""}`,"data-index":d,"data-clone":v?"":void 0,"aria-hidden":v?true:void 0,style:g?{viewTransitionName:y,viewTransitionClass:"vitrine-shared"}:E?void 0:{transitionDelay:`${V*.06}s`},onClick:()=>W(p),children:jsxRuntime.jsxs("div",{className:"lightbox__item-inner",children:[jsxRuntime.jsxs("picture",{className:"lightbox__img lightbox__img--low",children:[n.webpSrcSet&&jsxRuntime.jsx("source",{srcSet:n.webpSrcSet,sizes:k,type:"image/webp"}),jsxRuntime.jsx("img",{src:n.src,srcSet:n.srcSet,sizes:k,alt:n.alt||n.title,draggable:false,loading:V<=1?"eager":"lazy",decoding:"async"})]}),N&&jsxRuntime.jsxs("picture",{className:`lightbox__img lightbox__img--high${z?" lightbox__img--ready":""}`,children:[n.highResWebpSrcSet&&jsxRuntime.jsx("source",{srcSet:n.highResWebpSrcSet,sizes:k,type:"image/webp"}),jsxRuntime.jsx("img",{src:n.highResSrc,srcSet:n.highResSrcSet,sizes:k,alt:"","aria-hidden":"true",draggable:false,loading:V<=1?"eager":"lazy",decoding:"async",onLoad:()=>$(true)})]}),L&&jsxRuntime.jsx("video",{ref:M,src:L,muted:true,playsInline:true,loop:true,preload:D?"metadata":"none",draggable:false}),L&&D&&g&&jsxRuntime.jsx(ut,{videoRef:M,minimal:D==="minimal"})]})})}function Xt(n,d,p){if(!n||typeof n.closest!="function"||n.closest(".vitrine-video-toggle, .vitrine-lb-video"))return null;if(!d){let x=n.closest(".slider__item");return p&&x?.closest(".slider--morph-cursor")?"plus":null}if(n.closest(".lightbox__item--active"))return "close";let v=n.closest(".lightbox__item");if(v){let x=Number(v.dataset.index),k=document.querySelector(".lightbox__item--active"),E=k?Number(k.dataset.index):x;return x<E?"arrow-left":"arrow-right"}return n.closest(".lightbox__backdrop, .lightbox__track")?"close":null}function mt({lightboxOpen:n,itemsClickable:d=true}){let p=react.useRef(null),v=react.useRef(0),x=react.useRef({x:0,y:0}),[k,E]=react.useState(false),[y,D]=react.useState(null),[A,W]=react.useState(false);return react.useEffect(()=>{if(typeof window>"u"||!window.matchMedia)return;let N=window.matchMedia("(pointer: fine)"),L=()=>E(N.matches);return L(),N.addEventListener("change",L),()=>N.removeEventListener("change",L)},[]),react.useEffect(()=>{if(!k){W(false);return}let N=M=>{x.current={x:M.clientX,y:M.clientY},v.current||(v.current=requestAnimationFrame(()=>{v.current=0;let V=p.current;if(V){let{x:z,y:$}=x.current;V.style.transform=`translate(${z}px, ${$}px) translate(-50%, -50%)`;}}));let g=Xt(M.target,n,d);g?(D(g),W(true)):W(false);},L=M=>{M.relatedTarget||W(false);};return window.addEventListener("pointermove",N,{passive:true}),window.addEventListener("pointerout",L,{passive:true}),()=>{window.removeEventListener("pointermove",N),window.removeEventListener("pointerout",L),v.current&&cancelAnimationFrame(v.current),v.current=0;}},[k,n,d]),k?jsxRuntime.jsx("div",{ref:p,className:`morph-cursor${A?" morph-cursor--visible":""}`,"aria-hidden":"true",children:y&&jsxRuntime.jsx(react$2.IconMorph,{name:y,size:20,strokeWidth:1.75,color:"#fff",duration:250})}):null}function Fe({item:n,index:d,sizes:p,video:v=true,videoControls:x=false,isActive:k=false}){let E=react.useRef(null),y=v&&!!n.video;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("picture",{children:[n.webpSrcSet&&jsxRuntime.jsx("source",{srcSet:n.webpSrcSet,sizes:p,type:"image/webp"}),jsxRuntime.jsx("img",{src:n.src,srcSet:n.srcSet,sizes:p,alt:n.alt||n.title,draggable:false,fetchPriority:d===0?"high":void 0,loading:d<=1?"eager":"lazy",decoding:d<=1?"sync":"async",style:n.blurDataURL?{backgroundImage:`url(${n.blurDataURL})`,backgroundSize:"cover",backgroundRepeat:"no-repeat",backgroundPosition:"center"}:void 0})]}),y&&jsxRuntime.jsx("video",{ref:E,src:n.video,muted:true,playsInline:true,loop:true,preload:x?"metadata":"none",draggable:false}),y&&x&&k&&jsxRuntime.jsx(Ne,{videoRef:E,size:40})]})}var gt={initial:{},animate:{transition:{staggerChildren:.06}}},Ie={initial:{opacity:0,y:8},animate:{opacity:1,y:0,transition:{duration:1,ease:[0,.55,.45,1]}}};var Ve=react.forwardRef(function({items:d,activeIndex:p,contentWidth:v,gap:x,columns:k,metaOffsetColumns:E,sideMargin:y,maxItemHeight:D,aspectRatio:A,sizes:W,videoControls:N,itemsClickable:L,itemCursor:M,onActiveIndexChange:g,onItemOpen:V,openOnSettle:z,onLayoutChange:$,mode:de="row",projector:X,trackClassName:ie,video:c=true,loop:F=false},C){let m=react.useRef(null),O=react.useRef({isDragging:false,startX:0,scrollLeft:0}),j=react.useRef(0),H=react.useRef(false),ee=react.useRef(null),Y=react.useRef(false),[b,S]=react.useState({inset:0,itemWidth:0,itemHeight:0,metaInset:0,metaInsetRight:0,endPad:0,isMobile:false,centered:false}),P=de==="coverflow",T=d.length,q=F&&T>0?Math.max(2,Math.ceil(8/T)):0,Q=2*q+1,se=react.useRef(false),_e=react.useRef(null),ce=react.useRef(null);react.useEffect(()=>{let t=()=>{let s=window.innerWidth,l=window.matchMedia("(min-width: 700px)").matches,a=document.querySelector(".subgrid"),h=a?.closest(".grid")||document.querySelector(".grid");if(P){let f,I,R;if(a&&h){let G=a.getBoundingClientRect();f=G.left,I=G.width,R=l?f:G.left-h.getBoundingClientRect().left;}else I=Math.min(v,s-2*y),f=(s-I)/2,R=l?f:y;let K=l?Math.round(Math.min(v*.62,s-2*y)):s-2*R,Z=l?D:Math.round(K*.75);A&&(Z=Math.round(K/A),Z>D&&(Z=D,K=Math.round(Z*A)));let ne=Math.max((s-K)/2,0);S({inset:ne,itemWidth:K,itemHeight:Z,metaInset:l?f:R,metaInsetRight:l?f:R,endPad:ne,isMobile:!l,centered:true});return}if(l){let f,I,R,K;if(a&&h){let Re=a.getBoundingClientRect();f=Re.left,I=Re.width,R=parseInt(getComputedStyle(h).getPropertyValue("--columns"),10)||k,K=parseFloat(getComputedStyle(a).columnGap)||x;}else I=Math.min(v,s-2*y),f=(s-I)/2,R=k,K=x;let Z=(I-(R-1)*K)/R,ne=f-12,G=I+24,me=0;A&&(G=I,me=Math.round(G/A),me>D&&(me=D,G=Math.round(me*A))),S({inset:ne,itemWidth:G,itemHeight:me,metaInset:ne+E*(Z+K),metaInsetRight:ne,endPad:s-ne,isMobile:false,centered:false,fixedAspect:!!A});}else {let f;a&&h?f=a.getBoundingClientRect().left-h.getBoundingClientRect().left:f=y;let I=s-2*f,R=0;A&&(R=Math.round(I/A),R>D&&(R=D,I=Math.round(R*A))),S({inset:f,itemWidth:I,itemHeight:R,metaInset:f,metaInsetRight:f,endPad:f,isMobile:true,centered:false,fixedAspect:!!A});}},o,i=()=>{clearTimeout(o),o=setTimeout(t,100);};return t(),window.addEventListener("resize",i),()=>{window.removeEventListener("resize",i),clearTimeout(o);}},[v,x,k,E,y,D,A,P]),react.useEffect(()=>{$?.(b);},[b,$]);let B=b.centered||b.isMobile?"center":"start",te=react.useCallback((t,o)=>o.offsetLeft-(B==="center"?(t.clientWidth-o.offsetWidth)/2:b.inset),[B,b.inset]);react.useEffect(()=>{let t=m.current;if(!t)return;if(!q){t.scrollLeft=0;return}let o=t.querySelectorAll(".slider__item")[q*T];o&&(t.scrollLeft=te(t,o));},[b.inset,q,T,te]);let ae=react.useCallback(()=>{se.current=true,clearTimeout(_e.current),_e.current=setTimeout(()=>{se.current=false;},800);},[]),U=react.useCallback(()=>{let t=m.current;if(!t||!q||O.current.isDragging)return;let o=t.querySelectorAll(".slider__item");if(T===0||o.length!==Q*T)return;let i=o[T].offsetLeft-o[0].offsetLeft;if(!i)return;let s=0,l=1/0;for(let h=0;h<o.length;h++){let f=Math.abs(te(t,o[h])-t.scrollLeft);f<l&&(l=f,s=h);}let a=Math.floor(s/T);a!==q&&(t.scrollLeft+=(q-a)*i),se.current=false;},[q,Q,T,te]);react.useEffect(()=>{let t=m.current;if(!t||!q)return;let o=()=>U();return t.addEventListener("scrollend",o),()=>t.removeEventListener("scrollend",o)},[q,U]);let ve=react.useCallback(t=>{let o=m.current;if(!o||!b.itemWidth)return;let i=o.querySelectorAll(".slider__item"),s;if(q){let l=(t%T+T)%T,a=1/0;for(let h=0;h<Q;h++){let f=i[h*T+l];if(!f)continue;let I=Math.abs(te(o,f)-o.scrollLeft);I<a&&(a=I,s=f);}s&&ae();}else s=i[t];s&&s.scrollIntoView({behavior:"smooth",block:"nearest",inline:B});},[b.itemWidth,B,q,Q,T,te,ae]),xe=react.useCallback((t,o)=>{o?.external&&(H.current=true,clearTimeout(ee.current),ee.current=setTimeout(()=>{H.current=false;},300)),ve(t);},[ve]),fe=react.useCallback(t=>{let o=t.querySelectorAll(".slider__item"),i=window.innerWidth/2,s=0,l=1/0;return o.forEach((a,h)=>{let f=a.getBoundingClientRect(),I=f.left+f.width/2,R=Math.abs(I-i);R<l&&(l=R,s=h);let K=f.width/2,Z=Math.max(0,R-K),ne=Math.min(Z/(window.innerWidth*.3),1),G=a.querySelector(".slider__item-inner");G&&(G.style.transformOrigin=I<i?"right center":"left center",G.style.transform=`scale(${1-ne*.05})`,G.style.filter=`brightness(${1-ne*.15})`);}),s},[]),ye=react.useRef(0),be=react.useCallback(t=>{let o=t.querySelectorAll(".slider__item"),i=window.innerWidth,s=i/2,l=new Array(o.length),a=0,h=1/0;for(let f=0;f<o.length;f++){l[f]=o[f].getBoundingClientRect();let I=Math.abs(l[f].left+l[f].width/2-s);I<h&&(h=I,a=f);}if(X){let f=Math.max(0,Math.min(a,ye.current)-3),I=Math.min(o.length-1,Math.max(a,ye.current)+3);X({itemEls:o,rects:l,center:s,vw:i,lo:f,hi:I});}return ye.current=a,a},[X]),e=react.useCallback(()=>{let t=m.current;if(!t)return;if(q){if(!se.current){let i=t.querySelectorAll(".slider__item");if(T>0&&i.length===Q*T){let s=i[T].offsetLeft-i[0].offsetLeft,l=te(t,i[q*T]),a=t.scrollLeft,h=0;s&&a<l-s*.75?h=s:s&&a>l+s*1.75&&(h=-s),h&&(t.scrollLeft=a+h,O.current.isDragging&&(O.current.scrollLeft+=h));}}clearTimeout(ce.current),ce.current=setTimeout(U,200);}let o=i=>q?i%T:i;if(b.centered){if(Y.current)return;Y.current=true,requestAnimationFrame(()=>{Y.current=false;let i=m.current;if(!i)return;let s=be(i);H.current||(g(o(s)),clearTimeout(ee.current));});return}if(b.isMobile){if(Y.current)return;Y.current=true,requestAnimationFrame(()=>{Y.current=false;let i=m.current;if(!i)return;let s=fe(i);H.current||(g(o(s)),clearTimeout(ee.current));});return}H.current||Y.current||(Y.current=true,requestAnimationFrame(()=>{Y.current=false;let i=m.current;if(!i)return;let s=i.querySelectorAll(".slider__item"),l=b.inset,a=0,h=1/0;s.forEach((f,I)=>{let R=Math.abs(f.getBoundingClientRect().left-l);R<h&&(h=R,a=I);}),g(o(a));}));},[b.inset,b.centered,b.isMobile,fe,be,g,q,Q,T,te,U]);react.useEffect(()=>{let t=m.current;if(t)return t.addEventListener("scroll",e,{passive:true}),()=>t.removeEventListener("scroll",e)},[e]),react.useEffect(()=>{let t=m.current;t&&(b.centered?requestAnimationFrame(()=>be(t)):b.isMobile?requestAnimationFrame(()=>fe(t)):t.querySelectorAll(".slider__item-inner").forEach(o=>{o.style.transform="",o.style.filter="",o.style.transformOrigin="";}));},[b.centered,b.isMobile,fe,be]);let r=react.useCallback(t=>{let o=q?t%T:t,i=q?q*T+p:p;if(t===i){V?.(o);return}let s=m.current;if(q){let h=s?.querySelectorAll(".slider__item")[t];h&&(ae(),h.scrollIntoView({behavior:"smooth",block:"nearest",inline:B}));}else ve(t);if(!z)return;let l=()=>{clearTimeout(a),s?.removeEventListener("scrollend",l),U(),V?.(o);},a=setTimeout(l,600);s?.addEventListener("scrollend",l,{once:true});},[p,V,z,ve,q,T,B,ae,U]),u=react.useCallback(t=>{if(t.pointerType==="touch")return;let o=m.current;o&&(j.current=0,O.current={isDragging:true,startX:t.clientX,scrollLeft:o.scrollLeft,prevX:t.clientX,prevTime:Date.now(),velocity:0},o.style.scrollSnapType="none",o.setPointerCapture(t.pointerId));},[]),w=react.useCallback(t=>{let o=O.current;if(!o.isDragging)return;let i=Date.now(),s=i-o.prevTime,l=t.clientX-o.prevX;s>0&&(o.velocity=l/s),o.prevX=t.clientX,o.prevTime=i,j.current=Math.abs(t.clientX-o.startX),m.current.scrollLeft=o.scrollLeft-(t.clientX-o.startX);},[]),_=react.useCallback(t=>{let o=O.current;if(!o.isDragging)return;o.isDragging=false;let i=m.current;if(i.releasePointerCapture(t.pointerId),j.current<5){i.style.scrollSnapType="x mandatory";let f=document.elementFromPoint(t.clientX,t.clientY)?.closest(".slider__item");if(f){let R=Array.from(i.querySelectorAll(".slider__item")).indexOf(f);R>=0&&r(R);}return}let s=-o.velocity*1e3,l=.92,a=performance.now(),h=f=>{let I=(f-a)/1e3;if(a=f,s*=l,i.scrollLeft+=s*I,Math.abs(s)>50)requestAnimationFrame(h);else {let R=i.querySelectorAll(".slider__item"),K=window.innerWidth/2,Z=0,ne=1/0;R.forEach((Re,Tt)=>{let Xe=Re.getBoundingClientRect(),Qe=Math.abs(B==="center"?Xe.left+Xe.width/2-K:Xe.left-b.inset);Qe<ne&&(ne=Qe,Z=Tt);});let G=()=>{clearTimeout(me),i.style.scrollSnapType="x mandatory",i.removeEventListener("scrollend",G);},me=setTimeout(G,300);i.addEventListener("scrollend",G,{once:true}),q&&ae(),R[Z].scrollIntoView({behavior:"smooth",block:"nearest",inline:B});}};requestAnimationFrame(h);},[b.inset,B,r,q,ae]);return react.useImperativeHandle(C,()=>({goTo:xe,park:t=>{let o=m.current,i=o?.querySelectorAll(".slider__item:not([data-clone])")[t];if(!o||!i)return {apply:()=>{},release:()=>{}};let s=B,l=()=>{U();let a=i.getBoundingClientRect(),h=s==="center"?window.innerWidth/2:b.inset,f=s==="center"?a.left+a.width/2:a.left;Math.abs(f-h)<4||i.scrollIntoView({behavior:"instant",block:"nearest",inline:s});};return o.addEventListener("scroll",l),{apply:l,release:()=>o.removeEventListener("scroll",l)}},getItemEls:()=>m.current?.querySelectorAll(".slider__item:not([data-clone])")??[]}),[xe,B,b.inset,U]),jsxRuntime.jsx(react$1.motion.div,{className:`slider__track${ie?` ${ie}`:""}${b.fixedAspect?" slider__track--fixed":""}`,ref:m,tabIndex:-1,onPointerDown:u,onPointerMove:w,onPointerUp:_,onPointerCancel:_,style:{paddingLeft:`${b.inset}px`,paddingRight:`${b.endPad}px`,scrollPaddingLeft:b.isMobile||b.centered?void 0:`${b.inset}px`,touchAction:"pan-x pan-y"},children:Array.from({length:Q*T},(t,o)=>{let i=o%T,s=d[i],l=q>0&&Math.floor(o/T)!==q,a=!l&&i===p,h=!l&&L;return jsxRuntime.jsx(react$1.motion.div,{"data-clone":l?"":void 0,className:`slider__item${a?" slider__item--active":""}`,variants:l?void 0:Ie,role:h?"button":void 0,tabIndex:h?0:void 0,"aria-label":h?s.title:void 0,"aria-hidden":l?true:void 0,style:{"--item-max-w":`${b.itemWidth}px`,"--item-max-h":`${b.itemHeight||D}px`,cursor:M},onClick:()=>{j.current<5&&r(o);},onKeyDown:h?f=>{(f.key==="Enter"||f.key===" ")&&(f.preventDefault(),r(o));}:void 0,children:jsxRuntime.jsx("div",{className:"slider__item-inner",children:jsxRuntime.jsx(Fe,{item:s,index:i,sizes:W,video:c&&!l,videoControls:N,isActive:a})})},`${Math.floor(o/T)}:${s.id??i}`)})})});var _t=3,en=.04,tn=90,nn=400,xt=(n,d)=>{let p=Math.sin((n+1)*d)*1e4;return p-Math.floor(p)},rn=n=>(xt(n,12.9898)-.5)*7,on=n=>(xt(n,78.233)-.5)*18,Lt=react.forwardRef(function({items:d,activeIndex:p,contentWidth:v,sideMargin:x,maxItemHeight:k,aspectRatio:E,sizes:y,itemsClickable:D,itemCursor:A,onActiveIndexChange:W,onItemOpen:N,onLayoutChange:L,loop:M=true},g){let V=react.useRef(null),z=react.useRef(false),[$,de]=react.useState({colLeft:0,colWidth:0,cardWidth:0,cardHeight:0,isMobile:false}),X=d.length;react.useEffect(()=>{let F=()=>{let O=window.innerWidth,j=window.matchMedia("(min-width: 700px)").matches,H=document.querySelector(".subgrid"),ee=H?.closest(".grid")||document.querySelector(".grid"),Y,b;if(j)if(H&&ee){let T=H.getBoundingClientRect();Y=T.left,b=T.width;}else b=Math.min(v,O-2*x),Y=(O-b)/2;else {let T=H&&ee?H.getBoundingClientRect().left-ee.getBoundingClientRect().left:x;b=O-2*T,Y=T;}let S=b,P=j?k:Math.round(b*.75);E&&(P=Math.round(S/E),P>k&&(P=k,S=Math.round(P*E))),de({colLeft:Y,colWidth:b,cardWidth:S,cardHeight:P,isMobile:!j,fixedAspect:!!E});},C,m=()=>{clearTimeout(C),C=setTimeout(F,100);};return F(),window.addEventListener("resize",m),()=>{window.removeEventListener("resize",m),clearTimeout(C);}},[v,x,k,E]),react.useEffect(()=>{L?.({metaInset:$.colLeft,metaInsetRight:$.colLeft,isMobile:$.isMobile});},[$,L]);let ie=react.useCallback(F=>{W(M?(F%X+X)%X:Math.max(0,Math.min(F,X-1)));},[X,W,M]);react.useImperativeHandle(g,()=>({goTo:ie,park:()=>({apply:()=>{},release:()=>{}}),getItemEls:()=>V.current?.querySelectorAll(".slider__item")??[]}),[ie]);let c=react.useCallback((F,C)=>{let m=Math.hypot(C.offset.x,C.offset.y),O=Math.hypot(C.velocity.x,C.velocity.y);(m>tn||O>nn)&&ie(p+1),requestAnimationFrame(()=>{z.current=false;});},[p,ie]);return jsxRuntime.jsx("div",{className:`slider__track slider__track--stack${$.fixedAspect?" slider__track--stack-fixed":""}`,ref:V,style:{height:`${$.cardHeight}px`},children:jsxRuntime.jsx("div",{className:"slider__stack-stage",style:{left:`${$.colLeft}px`,width:`${$.colWidth}px`,height:`${$.cardHeight}px`,"--stack-w":`${$.cardWidth}px`,"--stack-h":`${$.cardHeight}px`},children:d.map((F,C)=>{let m=M?(C-p+X)%X:C-p;return jsxRuntime.jsx(sn,{item:F,index:C,depth:m,n:X,sizes:y,itemsClickable:D,itemCursor:A,wasDraggingRef:z,onDragEnd:c,onItemOpen:N,onActiveIndexChange:W},F.id??C)})})})});function sn({item:n,index:d,depth:p,n:v,sizes:x,itemsClickable:k,itemCursor:E,wasDraggingRef:y,onDragEnd:D,onItemOpen:A,onActiveIndexChange:W}){let N=p<0,L=Math.min(Math.max(p,0),_t),M=p===0,g=react$1.useMotionValue(0),V=react$1.useTransform(g,[-360,0,360],[-14,0,14],{clamp:true});return jsxRuntime.jsx(react$1.motion.div,{className:`slider__item${M?" slider__item--active":""}`,role:k?"button":void 0,tabIndex:k&&M?0:void 0,"aria-label":k?n.title:void 0,"aria-hidden":M?void 0:true,style:{zIndex:N?v+1:v-p,cursor:M?void 0:E,transformOrigin:"center",pointerEvents:N?"none":void 0,x:g},initial:false,animate:N?{y:24,rotate:0,scale:1.04,opacity:0}:{x:M?0:on(d),y:-12*L,rotate:M?0:rn(d),scale:1-en*L,opacity:p>_t?0:1},transition:{type:"spring",stiffness:300,damping:30},drag:M,dragSnapToOrigin:true,dragMomentum:false,onDragStart:M?()=>y.current=true:void 0,onDragEnd:M?D:void 0,onTap:()=>{y.current||(M?A?.(d):W(d));},onKeyDown:k&&M?z=>{(z.key==="Enter"||z.key===" ")&&(z.preventDefault(),A?.(d));}:void 0,children:jsxRuntime.jsx(react$1.motion.div,{className:"slider__item-inner",style:{rotate:V},children:jsxRuntime.jsx(Fe,{item:n,index:d,sizes:x,video:false})})})}var kt=react.forwardRef(function(d,p){let v=react.useCallback(({itemEls:x,rects:k,center:E,vw:y,lo:D,hi:A})=>{let W=y<700,N=W?30:45,L=W?60:120;for(let M=D;M<=A;M++){let g=k[M],V=Math.max(-2,Math.min(2,(g.left+g.width/2-E)/g.width)),z=Math.min(Math.abs(V),1),$=x[M].querySelector(".slider__item-inner");$&&($.style.transform=`perspective(1200px) rotateY(${-Math.sign(V)*z*N}deg) translateZ(${-Math.abs(V)*L}px) scale(${1-Math.abs(V)*.08})`),x[M].style.zIndex=String(100-Math.round(Math.abs(V)*10));}},[]);return jsxRuntime.jsx(Ve,{...d,ref:p,mode:"coverflow",projector:v,trackClassName:"slider__track--coverflow",video:false})});var mn=({as:n="span",children:d})=>jsxRuntime.jsx(n,{children:d}),Le=null;function hn(n){if(n==null)return null;if(typeof n=="number")return n>0?n:null;if(typeof n=="string"){let d=n.split(/[/:]/);if(d.length===2){let v=parseFloat(d[0]),x=parseFloat(d[1]);return v>0&&x>0?v/x:null}let p=parseFloat(n);return p>0?p:null}return null}function gn({items:n,variant:d="row",contentWidth:p=628,gap:v=32,columns:x=4,metaOffsetColumns:k=0,sideMargin:E=24,maxItemHeight:y=520,aspectRatio:D,sizes:A="(min-width: 700px) 628px, 82vw",lightboxSizes:W="84vw",Caption:N=react$2.TextMorph,lightbox:L=true,lightboxControls:M=false,onItemClick:g,loop:V,arrows:z=false,pagination:$=false,videoControls:de=false,morphCursor:X=false,transitionName:ie}){let c=react.useRef(null),F=react.useRef(false),C=react.useRef(null),[m,O]=react.useState(0),j=react.useRef(0);j.current=m;let[H,ee]=react.useState(false),[Y,b]=react.useState(false),[S,P]=react.useState({metaInset:0,metaInsetRight:0}),T=react.useId(),q=ie??`vitrine-${T.replace(/[^a-zA-Z0-9_-]/g,"")}`,Q=L&&d!=="stack",se=V??d!=="row",_e=hn(D),ce=react.useRef(null),B=react.useCallback(e=>{P(r=>r.metaInset===e.metaInset&&r.metaInsetRight===e.metaInsetRight?r:{metaInset:e.metaInset,metaInsetRight:e.metaInsetRight});},[]);react.useEffect(()=>{let e=r=>{if(r.key!=="ArrowRight"&&r.key!=="ArrowLeft"||H||!(F.current||c.current&&c.current.contains(document.activeElement)))return;let w=se;if(r.key==="ArrowRight"){let _=w?m+1:Math.min(m+1,n.length-1);_!==m&&(r.preventDefault(),C.current?.goTo(_));}else {let _=w?m-1:Math.max(m-1,0);_!==m&&(r.preventDefault(),C.current?.goTo(_));}};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[m,n.length,H,se]);let te=react.useCallback(()=>{let e=j.current,r=C.current?.getItemEls();if(!r?.[e]||Le)return;let u=r[e].getBoundingClientRect();if(ce.current=u.height>0?u.width/u.height:1,document.startViewTransition){r[e].classList.add("slider__item--transitioning"),r[e].style.viewTransitionName=q,r[e].style.viewTransitionClass="vitrine-shared",document.documentElement.style.viewTransitionName="none";let w=document.startViewTransition(()=>{r[e].style.viewTransitionName="",reactDom.flushSync(()=>ee(true));});Le=w,w.finished.finally(()=>{Le=null,r[e].classList.remove("slider__item--transitioning"),r[e].style.viewTransitionClass="",document.documentElement.style.viewTransitionName="";});}else ee(true);},[q]),ae=react.useCallback(e=>{Q?te():g?.(n[e],e);},[Q,g,n,te]);react.useEffect(()=>{if(H){let e=setTimeout(()=>b(true),300);return ()=>clearTimeout(e)}else b(false);},[H]),react.useEffect(()=>{let e=C.current?.getItemEls();if(!e?.length)return;let r=[];return e.forEach((u,w)=>{let _=u.querySelector("video");if(_)if(Y)_.pause(),_.style.visibility="hidden",u.classList.remove("slider__item--video-ready");else if(_.style.visibility="",w===m){_.currentTime=0,_.play();let t=()=>u.classList.add("slider__item--video-ready");_.readyState>=2?t():(_.addEventListener("canplay",t,{once:true}),r.push(()=>_.removeEventListener("canplay",t)));}else _.pause(),u.classList.remove("slider__item--video-ready");}),()=>r.forEach(u=>u())},[m,Y]);let U=react.useCallback(e=>{let r=e?.fromDrag===true;if(Le)return;let u=C.current,w=u?.getItemEls();if(!w?.[m]){ee(false);return}let _=document.querySelector(".lightbox");_&&!r&&_.classList.add("lightbox--closing");let t=u.park(m),o=()=>{if(Le){t.release();return}if(document.startViewTransition){w.forEach(s=>{let l=s.querySelector("video");l&&(l.style.visibility="");}),document.documentElement.style.viewTransitionName="none";let i=document.startViewTransition(()=>{let s=document.querySelector(".lightbox__item--active");s&&(s.style.viewTransitionName="none");let l=document.querySelector(".lightbox");l&&(l.style.display="none"),t.apply(),w[m].style.viewTransitionName=q,w[m].style.viewTransitionClass="vitrine-shared",reactDom.flushSync(()=>ee(false));});Le=i,i.finished.finally(()=>{Le=null,w[m].style.viewTransitionName="",w[m].style.viewTransitionClass="",document.documentElement.style.viewTransitionName="",t.release();});}else t.apply(),ee(false),setTimeout(()=>t.release(),400);};r?requestAnimationFrame(o):_?setTimeout(o,350):o();},[m,q]),ve=react.useCallback(e=>{O(e),C.current?.goTo(e,{external:true});},[]),xe=n[m],fe=Q||typeof g=="function",ye=X?fe?"none":"default":Q?"zoom-in":fe?"pointer":"default",be=d==="stack"?Lt:d==="coverflow"?kt:Ve;return jsxRuntime.jsxs(react$1.motion.div,{className:`slider slider--${d}${X?" slider--morph-cursor":""}`,ref:c,variants:gt,onPointerEnter:()=>F.current=true,onPointerLeave:()=>F.current=false,children:[jsxRuntime.jsx(be,{ref:C,items:n,activeIndex:m,contentWidth:p,gap:v,columns:x,metaOffsetColumns:k,sideMargin:E,maxItemHeight:y,aspectRatio:_e,sizes:A,videoControls:de,itemsClickable:fe,itemCursor:ye,loop:se,onActiveIndexChange:O,onItemOpen:ae,openOnSettle:Q,onLayoutChange:B}),jsxRuntime.jsx(react$1.motion.div,{className:"slider__meta",style:{paddingLeft:`${S.metaInset}px`,paddingRight:`${S.metaInsetRight}px`},variants:Ie,children:jsxRuntime.jsxs("div",{className:"slider__meta-inner",children:[jsxRuntime.jsx(N,{as:"h3",children:xe?.title}),jsxRuntime.jsx("br",{}),jsxRuntime.jsx(N,{as:"p",children:xe?.meta})]})}),(z||$)&&jsxRuntime.jsxs(react$1.motion.div,{className:"slider__controls",variants:Ie,children:[z&&jsxRuntime.jsx("button",{type:"button",className:"slider__nav",onClick:()=>C.current?.goTo(m-1),disabled:!se&&m===0,"aria-label":"Previous",children:jsxRuntime.jsx(Ae,{})}),$&&jsxRuntime.jsx("div",{className:"slider__dots",children:n.map((e,r)=>jsxRuntime.jsx("button",{type:"button",className:`slider__dot${r===m?" slider__dot--active":""}`,"aria-label":`Go to slide ${r+1}`,"aria-current":r===m?"true":void 0,onClick:()=>C.current?.goTo(r)},e.id??r))}),z&&jsxRuntime.jsx("button",{type:"button",className:"slider__nav",onClick:()=>C.current?.goTo(m+1),disabled:!se&&m===n.length-1,"aria-label":"Next",children:jsxRuntime.jsx(De,{})})]}),jsxRuntime.jsx(react$1.AnimatePresence,{children:Q&&H&&jsxRuntime.jsx(Ye,{items:n,activeIndex:m,sizes:W,Caption:N,controls:M,videoControls:de,transitionName:q,coverflow:d==="coverflow",itemAspect:ce.current,loop:se,onActiveIndexChange:ve,onClose:U})}),X&&jsxRuntime.jsx(mt,{lightboxOpen:H,itemsClickable:fe})]})}
2
+ exports.Lightbox=Ye;exports.PlainCaption=mn;exports.Slider=gn;
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import {useRef,useState,useEffect,useLayoutEffect,useCallback}from'react';import {flushSync}from'react-dom';import {motion,AnimatePresence}from'motion/react';import {TextMorph,IconMorph}from'@ocarignan/metamorphosis/react';import {jsxs,jsx}from'react/jsx-runtime';var Me=110,Ie=.55;function he({items:s,activeIndex:T,sizes:E="84vw",Caption:I=TextMorph,controls:q=false,onActiveIndexChange:N,onClose:R}){let x=useRef(null),F=useRef({isDragging:false,startX:0,scrollLeft:0}),[a,$]=useState(T),[,D]=useState(false),d=useRef(0),V=useRef(null),W=useRef({frozen:false,scrollLeft:0}),B=useRef(null),j=useRef(T),[L,se]=useState(false),[ue,y]=useState(false),ce=useRef(false),Y=useRef(false),Z=useRef(T);useEffect(()=>{let n=setTimeout(()=>{se(true),ce.current=true;let l=x.current;if(l){let _=l.querySelectorAll(".lightbox__item"),A=window.innerWidth/2;_.forEach(v=>{let b=v.getBoundingClientRect(),g=b.left+b.width/2,f=Math.abs(g-A),p=b.width/2,e=Math.max(0,f-p),t=Math.min(e/(window.innerWidth*.3),1);v.style.filter=`blur(0px) brightness(${1-t*.4})`,v.style.transform=`scale(${1-t*.01})`;});}},500),i=setTimeout(()=>y(true),1100);return ()=>{clearTimeout(i),clearTimeout(n);}},[]),useEffect(()=>(document.body.style.overflow="hidden",()=>{document.body.style.overflow="";}),[]),useLayoutEffect(()=>{let n=x.current;if(!n)return;let i=n.querySelectorAll(".lightbox__item")[j.current];i&&(n.scrollLeft=i.offsetLeft-(n.clientWidth-i.offsetWidth)/2);},[]);let ne=useCallback(()=>{Y.current||(Y.current=true,requestAnimationFrame(()=>{Y.current=false;let n=x.current;if(!n)return;let i=n.querySelectorAll(".lightbox__item"),l=window.innerWidth/2,_=new Array(i.length),A=0,v=1/0;for(let b=0;b<i.length;b++){let g=i[b].getBoundingClientRect();_[b]=g;let f=g.left+g.width/2,p=Math.abs(f-l);p<v&&(v=p,A=b);}if(ce.current){let b=window.innerWidth,g=Z.current,f=Math.min(A,g)-2,p=Math.max(A,g)+2;for(let e=Math.max(0,f);e<=Math.min(i.length-1,p);e++){let t=_[e],r=t.left+t.width/2,o=Math.abs(r-l),h=t.width/2,c=Math.max(0,o-h),u=Math.min(c/(b*.3),1);i[e].style.filter=`blur(0px) brightness(${1-u*.4})`,i[e].style.transform=`scale(${1-u*.01})`;}}Z.current=A,N(A),$(A);}));},[N]);useEffect(()=>{let n=x.current;if(n)return n.addEventListener("scroll",ne,{passive:true}),()=>n.removeEventListener("scroll",ne)},[ne]);let z=useCallback(n=>{let i=x.current;if(!i)return;let l=i.querySelectorAll(".lightbox__item");l[n]&&l[n].scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"});},[]);useEffect(()=>{let n=i=>{if(i.key==="Escape")R();else if(i.key==="ArrowRight"){let l=Math.min(a+1,s.length-1);l!==a&&z(l);}else if(i.key==="ArrowLeft"){let l=Math.max(a-1,0);l!==a&&z(l);}};return window.addEventListener("keydown",n),()=>window.removeEventListener("keydown",n)},[a,s.length,R,z]);let re=useCallback(()=>{let n=x.current,i=W.current;!n||!i.frozen||(n.style.overflow="",n.scrollLeft=i.scrollLeft,n.style.transform="",n.style.zIndex="",W.current={frozen:false,scrollLeft:0});},[]);useEffect(()=>()=>clearTimeout(B.current),[]);let le=useCallback(n=>{if(n.pointerType==="touch"){clearTimeout(B.current),d.current=0,V.current={startX:n.clientX,startY:n.clientY,locked:null,dy:0,startTime:Date.now()};return}let i=x.current;i&&(d.current=0,F.current={isDragging:true,startX:n.clientX,scrollLeft:i.scrollLeft,prevX:n.clientX,prevTime:Date.now(),velocity:0},D(true),i.style.scrollSnapType="none",i.setPointerCapture(n.pointerId));},[]),K=useCallback(n=>{if(n.pointerType==="touch"){let f=V.current;if(!f)return;let p=n.clientX-f.startX,e=n.clientY-f.startY;if(f.locked===null){if(Math.abs(p)<8&&Math.abs(e)<8)return;f.locked=Math.abs(e)>Math.abs(p)&&e>0?"v":"h";}if(f.locked!=="v")return;f.dy=Math.max(0,e),d.current=f.dy;let t=x.current;if(!t)return;W.current.frozen||(W.current={frozen:true,scrollLeft:t.scrollLeft},t.style.overflow="visible",t.style.transform=`translateX(${-W.current.scrollLeft}px)`,t.style.zIndex="5");let r=Math.max(.85,1-f.dy/1400),o=Math.max(0,1-f.dy/300),h=document.querySelector(".lightbox__backdrop"),c=document.querySelector(".lightbox__meta");t.querySelectorAll(".lightbox__item").forEach(u=>{u.classList.contains("lightbox__item--active")?(u.style.transition="none",u.style.transform=`translateY(${f.dy}px) scale(${r})`):(u.style.transition="none",u.style.opacity=String(o));}),h&&(h.style.transition="none",h.style.opacity=String(o)),c&&(c.style.transition="none",c.style.opacity=String(o));return}let i=F.current;if(!i.isDragging)return;let l=Date.now(),_=l-i.prevTime,A=n.clientX-i.prevX;_>0&&(i.velocity=A/_),i.prevX=n.clientX,i.prevTime=l,d.current=Math.abs(n.clientX-i.startX);let v=x.current,b=i.scrollLeft-(n.clientX-i.startX),g=v.scrollWidth-v.clientWidth;b<0?v.scrollLeft=b*.2:b>g?v.scrollLeft=g+(b-g)*.2:v.scrollLeft=b;},[]),G=useCallback(n=>{if(n.pointerType==="touch"){let g=V.current;if(V.current=null,!g||g.locked!=="v")return;let f=x.current,p=f?.querySelector(".lightbox__item--active"),e=document.querySelector(".lightbox__backdrop"),t=document.querySelector(".lightbox__meta"),r=g.dy/Math.max(Date.now()-g.startTime,1);if(g.dy>Me||r>Ie){R({fromDrag:true});return}let o="transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94)";p&&(p.style.transition=o,p.style.transform=""),f&&f.querySelectorAll(".lightbox__item").forEach(h=>{h.classList.contains("lightbox__item--active")||(h.style.transition="opacity 0.3s",h.style.opacity="");}),e&&(e.style.transition="opacity 0.3s",e.style.opacity=""),t&&(t.style.transition="opacity 0.3s",t.style.opacity=""),clearTimeout(B.current),B.current=setTimeout(()=>{p&&(p.style.transition=""),re();},300);return}let i=F.current;if(!i.isDragging)return;i.isDragging=false;let l=x.current;if(l.releasePointerCapture(n.pointerId),d.current<5){l.style.scrollSnapType="x mandatory",D(false);let g=document.elementFromPoint(n.clientX,n.clientY)?.closest(".lightbox__item");if(g){let p=Array.from(l.querySelectorAll(".lightbox__item")).indexOf(g);p>=0&&(p===a?R():z(p));}return}let _=-i.velocity*1e3,A=.92,v=performance.now(),b=g=>{let f=(g-v)/1e3;if(v=g,_*=A,l.scrollLeft+=_*f,Math.abs(_)>50)requestAnimationFrame(b);else {let p=l.querySelectorAll(".lightbox__item"),e=window.innerWidth/2,t=0,r=1/0;p.forEach((c,u)=>{let m=c.getBoundingClientRect(),S=m.left+m.width/2,w=Math.abs(S-e);w<r&&(r=w,t=u);});let o=()=>{clearTimeout(h),l.style.scrollSnapType="x mandatory",D(false),l.removeEventListener("scrollend",o);},h=setTimeout(o,300);l.addEventListener("scrollend",o,{once:true}),p[t].scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"});}};requestAnimationFrame(b);},[a,R,z]);useEffect(()=>{let n=x.current;if(!n)return;let i=n.querySelectorAll(".lightbox__item"),l=[];return i.forEach((_,A)=>{let v=_.querySelector("video");if(v)if(A===a){let g=setTimeout(()=>{v.currentTime=0,v.play();let f=()=>_.classList.add("lightbox__item--video-ready");v.readyState>=2?f():(v.addEventListener("canplay",f,{once:true}),l.push(()=>v.removeEventListener("canplay",f)));},300);l.push(()=>clearTimeout(g));}else v.pause();}),()=>l.forEach(_=>_())},[a]);let J=useCallback(n=>{d.current>=5||(n===a?R():z(n));},[a,R,z]);return jsxs("div",{className:`lightbox${L?" lightbox--revealed":""}${q?" lightbox--controls":""}`,children:[jsx(motion.div,{className:"lightbox__backdrop",onClick:R,initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.3}}),jsx("div",{className:"lightbox__track",ref:x,onPointerDown:le,onPointerMove:K,onPointerUp:G,onPointerCancel:G,onClick:n=>{if(d.current>=5)return;document.elementFromPoint(n.clientX,n.clientY)?.closest(".lightbox__item")||R();},style:{touchAction:"pan-x"},children:s.map((n,i)=>jsx(Re,{item:n,index:i,activeIndex:a,sizes:E,staggerDone:ue,onClick:J},n.id??i))}),jsxs("div",{className:"lightbox__meta","aria-live":"polite",children:[jsx(I,{as:"h2",children:s[a]?.title}),jsx(I,{as:"p",children:s[a]?.meta})]}),q&&jsxs("div",{className:"lightbox__controls",children:[jsx("button",{className:"lightbox__nav",onClick:()=>z(a-1),disabled:a===0,"aria-label":"Previous",children:jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsx("path",{d:"M9 1L3 7L9 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}),jsx("button",{className:"lightbox__close",onClick:R,"aria-label":"Close",children:jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsx("path",{d:"M1 1L13 13M13 1L1 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})}),jsx("button",{className:"lightbox__nav",onClick:()=>z(a+1),disabled:a===s.length-1,"aria-label":"Next",children:jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsx("path",{d:"M5 1L11 7L5 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})})]})]})}function Re({item:s,index:T,activeIndex:E,sizes:I,staggerDone:q,onClick:N}){let R=!!s.highResSrc,x=s.video,F=T===E,a=Math.abs(T-E),[$,D]=useState(false);return jsxs("div",{className:`lightbox__item${F?" lightbox__item--active":""}`,"data-index":T,style:!F&&!q?{transitionDelay:`${a*.06}s`}:void 0,onClick:()=>N(T),children:[jsxs("picture",{className:"lightbox__img lightbox__img--low",children:[s.webpSrcSet&&jsx("source",{srcSet:s.webpSrcSet,sizes:I,type:"image/webp"}),jsx("img",{src:s.src,srcSet:s.srcSet,sizes:I,alt:s.alt||s.title,draggable:false,loading:a<=1?"eager":"lazy",decoding:"async"})]}),R&&jsxs("picture",{className:`lightbox__img lightbox__img--high${$?" lightbox__img--ready":""}`,children:[s.highResWebpSrcSet&&jsx("source",{srcSet:s.highResWebpSrcSet,sizes:I,type:"image/webp"}),jsx("img",{src:s.highResSrc,srcSet:s.highResSrcSet,sizes:I,alt:"","aria-hidden":"true",draggable:false,loading:a<=1?"eager":"lazy",decoding:"async",onLoad:()=>D(true)})]}),x&&jsx("video",{src:x,muted:true,playsInline:true,loop:true,preload:"none",draggable:false})]})}function Ae(s,T){if(!s||typeof s.closest!="function")return null;if(!T)return s.closest(".slider__item")?"plus":null;if(s.closest(".lightbox__item--active"))return "close";let E=s.closest(".lightbox__item");if(E){let I=Number(E.dataset.index),q=document.querySelector(".lightbox__item--active"),N=q?Number(q.dataset.index):I;return I<N?"arrow-left":"arrow-right"}return s.closest(".lightbox__backdrop, .lightbox__track")?"close":null}function we({lightboxOpen:s}){let T=useRef(null),E=useRef(0),I=useRef({x:0,y:0}),[q,N]=useState(false),[R,x]=useState(null),[F,a]=useState(false);return useEffect(()=>{if(typeof window>"u"||!window.matchMedia)return;let $=window.matchMedia("(pointer: fine)"),D=()=>N($.matches);return D(),$.addEventListener("change",D),()=>$.removeEventListener("change",D)},[]),useEffect(()=>{if(!q){a(false);return}let $=d=>{I.current={x:d.clientX,y:d.clientY},E.current||(E.current=requestAnimationFrame(()=>{E.current=0;let W=T.current;if(W){let{x:B,y:j}=I.current;W.style.transform=`translate(${B}px, ${j}px) translate(-50%, -50%)`;}}));let V=Ae(d.target,s);V?(x(V),a(true)):a(false);},D=d=>{d.relatedTarget||a(false);};return window.addEventListener("pointermove",$,{passive:true}),window.addEventListener("pointerout",D,{passive:true}),()=>{window.removeEventListener("pointermove",$),window.removeEventListener("pointerout",D),E.current&&cancelAnimationFrame(E.current),E.current=0;}},[q,s]),q?jsx("div",{ref:T,className:`morph-cursor${F?" morph-cursor--visible":""}`,"aria-hidden":"true",children:R&&jsx(IconMorph,{name:R,size:20,strokeWidth:1.75,color:"#fff",duration:250})}):null}var Pe=({as:s="span",children:T})=>jsx(s,{children:T}),Xe={initial:{},animate:{transition:{staggerChildren:.06}}},_e={initial:{opacity:0,y:8},animate:{opacity:1,y:0,transition:{duration:1,ease:[0,.55,.45,1]}}};function Ne({items:s,contentWidth:T=628,gap:E=32,columns:I=4,metaOffsetColumns:q=0,sideMargin:N=24,maxItemHeight:R=520,sizes:x="(min-width: 700px) 628px, 82vw",lightboxSizes:F="84vw",Caption:a=TextMorph,lightboxControls:$=false,morphCursor:D=false}){let d=useRef(null),V=useRef(null),W=useRef(false),B=useRef(null),j=useRef({isDragging:false,startX:0,scrollLeft:0}),[L,se]=useState(0),ue=useRef(0);ue.current=L;let[y,ce]=useState({inset:0,itemWidth:0,metaInset:0,metaInsetRight:0,endPad:0,isMobile:false}),[Y,Z]=useState(false),[ne,z]=useState(false),re=useRef(0),le=useRef(false),K=useRef(null),G=useRef(false);useEffect(()=>{let e=()=>{let o=window.innerWidth,h=window.matchMedia("(min-width: 700px)").matches,c=document.querySelector(".subgrid"),u=c?.closest(".grid")||document.querySelector(".grid");if(h){let m,S,w,M;if(c&&u){let Q=c.getBoundingClientRect();m=Q.left,S=Q.width,w=parseInt(getComputedStyle(u).getPropertyValue("--columns"),10)||I,M=parseFloat(getComputedStyle(c).columnGap)||E;}else S=Math.min(T,o-2*N),m=(o-S)/2,w=I,M=E;let C=(S-(w-1)*M)/w,P=m-12;ce({inset:P,itemWidth:S+24,metaInset:P+q*(C+M),metaInsetRight:P,endPad:o-P,isMobile:false});}else {let m;c&&u?m=c.getBoundingClientRect().left-u.getBoundingClientRect().left:m=N,ce({inset:m,itemWidth:o-2*m,metaInset:m,metaInsetRight:m,endPad:m,isMobile:true});}},t,r=()=>{clearTimeout(t),t=setTimeout(e,100);};return e(),window.addEventListener("resize",r),()=>{window.removeEventListener("resize",r),clearTimeout(t);}},[T,E,I,q,N]),useEffect(()=>{let e=d.current;e&&(e.scrollLeft=0);},[y.inset]);let J=useCallback(e=>{let t=d.current;if(!t||!y.itemWidth)return;let r=t.querySelectorAll(".slider__item");r[e]&&r[e].scrollIntoView({behavior:"smooth",block:"nearest",inline:y.isMobile?"center":"start"});},[y.itemWidth,y.isMobile]);useEffect(()=>{let e=t=>{if(!(t.key!=="ArrowRight"&&t.key!=="ArrowLeft"||Y||!(W.current||V.current&&V.current.contains(document.activeElement))))if(t.key==="ArrowRight"){let o=Math.min(L+1,s.length-1);o!==L&&(t.preventDefault(),J(o));}else {let o=Math.max(L-1,0);o!==L&&(t.preventDefault(),J(o));}};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[L,s.length,Y,J]);let n=useCallback(e=>{let t=e.querySelectorAll(".slider__item"),r=window.innerWidth/2,o=0,h=1/0;return t.forEach((c,u)=>{let m=c.getBoundingClientRect(),S=m.left+m.width/2,w=Math.abs(S-r);w<h&&(h=w,o=u);let M=m.width/2,C=Math.max(0,w-M),P=Math.min(C/(window.innerWidth*.3),1),Q=c.querySelector(".slider__item-inner");Q&&(Q.style.transformOrigin=S<r?"right center":"left center",Q.style.transform=`scale(${1-P*.05})`,Q.style.filter=`brightness(${1-P*.15})`);}),o},[]),i=useCallback(()=>{if(d.current&&!le.current){if(y.isMobile){if(G.current)return;G.current=true,requestAnimationFrame(()=>{G.current=false;let t=d.current;if(!t)return;let r=n(t);se(r),clearTimeout(B.current);});return}G.current||(G.current=true,requestAnimationFrame(()=>{G.current=false;let t=d.current;if(!t)return;let r=t.querySelectorAll(".slider__item"),o=y.inset,h=0,c=1/0;r.forEach((u,m)=>{let S=Math.abs(u.getBoundingClientRect().left-o);S<c&&(c=S,h=m);}),se(h);}));}},[y.inset,y.isMobile,n]);useEffect(()=>{let e=d.current;if(e)return e.addEventListener("scroll",i,{passive:true}),()=>e.removeEventListener("scroll",i)},[i]),useEffect(()=>{let e=d.current;e&&(y.isMobile?requestAnimationFrame(()=>n(e)):e.querySelectorAll(".slider__item-inner").forEach(t=>{t.style.transform="",t.style.filter="",t.style.transformOrigin="";}));},[y.isMobile,n]);let l=useCallback(()=>{let e=ue.current,t=d.current?.querySelectorAll(".slider__item");if(t?.[e]&&!K.current)if(document.startViewTransition){t[e].classList.add("slider__item--transitioning"),t[e].style.viewTransitionName="slider-active",document.documentElement.style.viewTransitionName="none";let r=document.startViewTransition(()=>{t[e].style.viewTransitionName="",flushSync(()=>Z(true));});K.current=r,r.finished.then(()=>{K.current=null,t[e].classList.remove("slider__item--transitioning"),document.documentElement.style.viewTransitionName="";});}else Z(true);},[]),_=useCallback(e=>{if(e===L){l();return}let t=d.current;J(e);let r=()=>{clearTimeout(o),t?.removeEventListener("scrollend",r),l();},o=setTimeout(r,600);t?.addEventListener("scrollend",r,{once:true});},[L,l,J]),A=useCallback(e=>{if(e.pointerType==="touch")return;let t=d.current;t&&(re.current=0,j.current={isDragging:true,startX:e.clientX,scrollLeft:t.scrollLeft,prevX:e.clientX,prevTime:Date.now(),velocity:0},t.style.scrollSnapType="none",t.setPointerCapture(e.pointerId));},[]),v=useCallback(e=>{let t=j.current;if(!t.isDragging)return;let r=Date.now(),o=r-t.prevTime,h=e.clientX-t.prevX;o>0&&(t.velocity=h/o),t.prevX=e.clientX,t.prevTime=r,re.current=Math.abs(e.clientX-t.startX),d.current.scrollLeft=t.scrollLeft-(e.clientX-t.startX);},[]),b=useCallback(e=>{let t=j.current;if(!t.isDragging)return;t.isDragging=false;let r=d.current;if(r.releasePointerCapture(e.pointerId),re.current<5){r.style.scrollSnapType="x mandatory";let m=document.elementFromPoint(e.clientX,e.clientY)?.closest(".slider__item");if(m){let w=Array.from(r.querySelectorAll(".slider__item")).indexOf(m);w>=0&&_(w);}return}let o=-t.velocity*1e3,h=.92,c=performance.now(),u=m=>{let S=(m-c)/1e3;if(c=m,o*=h,r.scrollLeft+=o*S,Math.abs(o)>50)requestAnimationFrame(u);else {let w=r.querySelectorAll(".slider__item"),M=0,C=1/0;w.forEach((Le,Se)=>{let ve=Math.abs(Le.getBoundingClientRect().left-y.inset);ve<C&&(C=ve,M=Se);});let P=()=>{clearTimeout(Q),r.style.scrollSnapType="x mandatory",r.removeEventListener("scrollend",P);},Q=setTimeout(P,300);r.addEventListener("scrollend",P,{once:true}),w[M].scrollIntoView({behavior:"smooth",block:"nearest",inline:"start"});}};requestAnimationFrame(u);},[y.inset,_]);useEffect(()=>{if(Y){let e=setTimeout(()=>z(true),300);return ()=>clearTimeout(e)}else z(false);},[Y]),useEffect(()=>{let e=d.current;if(!e)return;let t=e.querySelectorAll(".slider__item"),r=[];return t.forEach((o,h)=>{let c=o.querySelector("video");if(c)if(ne)c.pause(),c.style.visibility="hidden",o.classList.remove("slider__item--video-ready");else if(c.style.visibility="",h===L){c.currentTime=0,c.play();let u=()=>o.classList.add("slider__item--video-ready");c.readyState>=2?u():(c.addEventListener("canplay",u,{once:true}),r.push(()=>c.removeEventListener("canplay",u)));}else c.pause(),o.classList.remove("slider__item--video-ready");}),()=>r.forEach(o=>o())},[L,ne]);let g=useCallback(e=>{let t=e?.fromDrag===true;if(K.current)return;let r=d.current?.querySelectorAll(".slider__item");if(!r?.[L]){Z(false);return}let o=document.querySelector(".lightbox");o&&!t&&o.classList.add("lightbox--closing");let h=y.isMobile?"center":"start",c=d.current,u=()=>{let w=r[L];if(!w)return;let M=w.getBoundingClientRect(),C=h==="center"?window.innerWidth/2:y.inset,P=h==="center"?M.left+M.width/2:M.left;Math.abs(P-C)<4||w.scrollIntoView({behavior:"instant",block:"nearest",inline:h});};c?.addEventListener("scroll",u);let m=()=>c?.removeEventListener("scroll",u),S=()=>{if(K.current){m();return}if(document.startViewTransition){r.forEach(M=>{let C=M.querySelector("video");C&&(C.style.visibility="");}),document.documentElement.style.viewTransitionName="none";let w=document.startViewTransition(()=>{let M=document.querySelector(".lightbox__item--active");M&&(M.style.viewTransitionName="none");let C=document.querySelector(".lightbox");C&&(C.style.display="none"),u(),r[L].style.viewTransitionName="slider-active",flushSync(()=>Z(false));});K.current=w,w.finished.then(()=>{K.current=null,r[L].style.viewTransitionName="",document.documentElement.style.viewTransitionName="",m();});}else u(),Z(false),setTimeout(m,400);};t?requestAnimationFrame(S):o?setTimeout(S,350):S();},[L,y.isMobile]),f=useCallback(e=>{se(e),le.current=true,J(e),clearTimeout(B.current),B.current=setTimeout(()=>{le.current=false;},300);},[J]),p=s[L];return jsxs(motion.div,{className:`slider${D?" slider--morph-cursor":""}`,ref:V,variants:Xe,onPointerEnter:()=>W.current=true,onPointerLeave:()=>W.current=false,children:[jsx(motion.div,{className:"slider__track",ref:d,tabIndex:-1,onPointerDown:A,onPointerMove:v,onPointerUp:b,onPointerCancel:b,style:{paddingLeft:`${y.inset}px`,paddingRight:`${y.endPad}px`,scrollPaddingLeft:y.isMobile?void 0:`${y.inset}px`,touchAction:"pan-x pan-y"},children:s.map((e,t)=>{let r=e.id??t;return jsx(motion.div,{className:`slider__item${t===L?" slider__item--active":""}`,variants:_e,role:"button",tabIndex:0,"aria-label":e.title,style:{"--item-max-w":`${y.itemWidth}px`,"--item-max-h":`${R}px`,cursor:D?"none":"zoom-in"},onClick:()=>{re.current<5&&_(t);},onKeyDown:o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),_(t));},children:jsxs("div",{className:"slider__item-inner",children:[jsxs("picture",{children:[e.webpSrcSet&&jsx("source",{srcSet:e.webpSrcSet,sizes:x,type:"image/webp"}),jsx("img",{src:e.src,srcSet:e.srcSet,sizes:x,alt:e.alt||e.title,draggable:false,fetchPriority:t===0?"high":void 0,loading:t<=1?"eager":"lazy",decoding:t<=1?"sync":"async",style:e.blurDataURL?{backgroundImage:`url(${e.blurDataURL})`,backgroundSize:"cover",backgroundRepeat:"no-repeat",backgroundPosition:"center"}:void 0})]}),e.video&&jsx("video",{src:e.video,muted:true,playsInline:true,loop:true,preload:"none",draggable:false})]})},r)})}),jsx(motion.div,{className:"slider__meta",style:{paddingLeft:`${y.metaInset}px`,paddingRight:`${y.metaInsetRight}px`},variants:_e,children:jsxs("div",{className:"slider__meta-inner",children:[jsx(a,{as:"h3",children:p?.title}),jsx("br",{}),jsx(a,{as:"p",children:p?.meta})]})}),jsx(AnimatePresence,{children:Y&&jsx(he,{items:s,activeIndex:L,sizes:F,Caption:a,controls:$,onActiveIndexChange:f,onClose:g})}),D&&jsx(we,{lightboxOpen:Y})]})}
2
- export{he as Lightbox,Pe as PlainCaption,Ne as Slider};
1
+ import {forwardRef,useRef,useState,useEffect,useCallback,useImperativeHandle,useLayoutEffect,useId}from'react';import {flushSync}from'react-dom';import {motion,useMotionValue,useTransform,AnimatePresence}from'motion/react';import {IconMorph,TextMorph}from'@ocarignan/metamorphosis/react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var Ae=()=>jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsx("path",{d:"M9 1L3 7L9 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})}),De=()=>jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsx("path",{d:"M5 1L11 7L5 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})});var je=()=>jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsx("path",{d:"M1.5 5H4L7.5 2V12L4 9H1.5V5Z",fill:"currentColor",stroke:"currentColor",strokeWidth:"1",strokeLinejoin:"round"}),jsx("path",{d:"M10 4.5C11.3 5.8 11.3 8.2 10 9.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),et=()=>jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsx("path",{d:"M1.5 5H4L7.5 2V12L4 9H1.5V5Z",fill:"currentColor",stroke:"currentColor",strokeWidth:"1",strokeLinejoin:"round"}),jsx("path",{d:"M9.75 5.5L12.75 8.5M12.75 5.5L9.75 8.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),tt=()=>jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsx("rect",{x:"1",y:"2.5",width:"12",height:"9",rx:"1.5",stroke:"currentColor",strokeWidth:"1.3"}),jsx("rect",{x:"6.75",y:"6.25",width:"5.25",height:"4.25",rx:"1",fill:"currentColor"})]}),nt=()=>jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsx("path",{d:"M5 1H1V5M9 1H13V5M5 13H1V9M9 13H13V9",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round",strokeLinejoin:"round"})}),rt={lines:[[9,6,18,12],[18,12,9,18],[9,18,9,6]]},ot={lines:[[9.5,6,9.5,18],[14.5,6,14.5,18],[12,12,12,12]]},it=()=>jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsx("path",{d:"M1 1L13 13M13 1L1 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})});function st({playing:n,size:d=26,color:p="#fff",strokeWidth:v=2}){return jsx(IconMorph,{name:n?"pause":"play",icon:n?ot:rt,size:d,color:p,strokeWidth:v,duration:220})}function Ne({videoRef:n,size:d=44}){let[p,v]=useState(true);useEffect(()=>{let E=n.current;if(!E)return;let y=()=>v(true),D=()=>v(false);return v(!E.paused),E.addEventListener("play",y),E.addEventListener("pause",D),()=>{E.removeEventListener("play",y),E.removeEventListener("pause",D);}},[n]);let x=E=>{E.stopPropagation();let y=n.current;y&&(y.paused?y.play():y.pause());},k=E=>E.stopPropagation();return jsx("button",{type:"button",className:"vitrine-video-toggle",onClick:x,onPointerDown:k,onPointerUp:k,"aria-label":p?"Pause":"Play",children:jsx(st,{playing:p,size:d,strokeWidth:1.8})})}function at(n){(!Number.isFinite(n)||n<0)&&(n=0);let d=Math.floor(n/60),p=Math.floor(n%60);return `${d}:${String(p).padStart(2,"0")}`}function ut({videoRef:n,minimal:d=false}){let[p,v]=useState(true),[x,k]=useState(0),[E,y]=useState(0),[D,A]=useState(false),W=useRef(null),N=useRef(null),L=useRef(false);useEffect(()=>{let c=n.current;if(!c)return;let F=()=>v(c.muted),C=()=>{L.current||y(c.currentTime);},m=()=>k(c.duration||0),O=()=>A(true),j=()=>A(false);return v(c.muted),k(c.duration||0),y(c.currentTime),A(document.pictureInPictureElement===c),c.addEventListener("volumechange",F),c.addEventListener("timeupdate",C),c.addEventListener("loadedmetadata",m),c.addEventListener("enterpictureinpicture",O),c.addEventListener("leavepictureinpicture",j),()=>{c.removeEventListener("volumechange",F),c.removeEventListener("timeupdate",C),c.removeEventListener("loadedmetadata",m),c.removeEventListener("enterpictureinpicture",O),c.removeEventListener("leavepictureinpicture",j);}},[n]),useEffect(()=>{let c,F=()=>{let C=n.current,m=W.current;C&&m&&C.duration&&(m.style.width=`${Math.min(C.currentTime/C.duration,1)*100}%`),c=requestAnimationFrame(F);};return c=requestAnimationFrame(F),()=>cancelAnimationFrame(c)},[n]);let M=()=>{let c=n.current;c&&(c.muted=!c.muted);},g=async()=>{let c=n.current;if(c)try{document.pictureInPictureElement?await document.exitPictureInPicture():await c.requestPictureInPicture();}catch{}},V=()=>{let c=n.current;c&&(document.fullscreenElement?document.exitFullscreen():c.requestFullscreen?c.requestFullscreen():c.webkitEnterFullscreen&&c.webkitEnterFullscreen());},z=c=>{let F=c.currentTarget.getBoundingClientRect();return Math.min(Math.max((c.clientX-F.left)/F.width,0),1)},$=c=>{let F=n.current;!F||!x||(F.currentTime=c*x,y(c*x),W.current&&(W.current.style.width=`${c*100}%`));},de=c=>{N.current&&(N.current.style.width=`${z(c)*100}%`),L.current&&$(z(c));},X=c=>c.stopPropagation(),ie=typeof document<"u"&&document.pictureInPictureEnabled;return jsxs(Fragment,{children:[jsx(Ne,{videoRef:n,size:60}),jsxs("div",{className:`vitrine-lb-video${d?" vitrine-lb-video--minimal":""}`,onPointerDown:X,onPointerMove:X,onPointerUp:X,onClick:X,onKeyDown:X,children:[!d&&jsxs("div",{className:"vitrine-lb-video__bar",children:[jsxs("span",{className:"vitrine-lb-video__time",children:[at(E)," / ",at(x)]}),jsxs("div",{className:"vitrine-lb-video__actions",children:[jsx("button",{type:"button",className:"vitrine-lb-video__btn",onClick:M,"aria-label":p?"Unmute":"Mute",children:p?jsx(et,{}):jsx(je,{})}),ie&&jsx("button",{type:"button",className:"vitrine-lb-video__btn",onClick:g,"aria-label":D?"Exit picture in picture":"Picture in picture",children:jsx(tt,{})}),jsx("button",{type:"button",className:"vitrine-lb-video__btn",onClick:V,"aria-label":"Fullscreen",children:jsx(nt,{})})]})]}),jsxs("div",{className:"vitrine-lb-video__progress",role:"slider","aria-label":"Seek","aria-valuemin":0,"aria-valuemax":Math.round(x)||0,"aria-valuenow":Math.round(E),tabIndex:0,onPointerDown:c=>{L.current=true,c.currentTarget.setPointerCapture(c.pointerId),$(z(c)),X(c);},onPointerMove:de,onPointerUp:c=>{L.current=false;try{c.currentTarget.releasePointerCapture(c.pointerId);}catch{}X(c);},children:[jsx("div",{className:"vitrine-lb-video__preview",ref:N}),jsx("div",{className:"vitrine-lb-video__progress-fill",ref:W})]})]})]})}var Nt=110,qt=.55,$t=35,Ft=160,Wt=1400;function He(n,d,p,v){let x=d.left+d.width/2,k=Math.abs(x-p),E=Math.max(0,k-d.width/2),y=Math.min(E/(window.innerWidth*.3),1);if(n.style.filter=`blur(0px) brightness(${1-y*.4})`,v){let D=Math.max(-2,Math.min(2,(x-p)/d.width)),A=Math.min(Math.abs(D),1),W=n.firstElementChild;W.style.transform=`perspective(${Wt}px) rotateY(${(-Math.sign(D)*A*$t).toFixed(2)}deg) translateZ(${(-Math.abs(D)*Ft).toFixed(1)}px) scale(${(1-Math.abs(D)*.06).toFixed(4)})`,n.style.zIndex=String(100-Math.round(Math.abs(D)*10));}else n.style.transform=`scale(${1-y*.01})`;}function Ye({items:n,activeIndex:d,sizes:p="84vw",Caption:v=TextMorph,controls:x=false,videoControls:k=false,transitionName:E="slider-active",coverflow:y=false,itemAspect:D,loop:A=false,onActiveIndexChange:W,onClose:N}){let L=useRef(null),M=useRef({isDragging:false,startX:0,scrollLeft:0}),[g,V]=useState(d),[,z]=useState(false),$=useRef(0),de=useRef("mouse"),[X,ie]=useState(false),c=useRef(null),F=useRef({frozen:false,scrollLeft:0}),C=useRef(null),m=useRef(d),[O,j]=useState(false),[H,ee]=useState(false),Y=useRef(false),b=useRef(false),S=n.length,P=A&&S>0?Math.max(2,Math.ceil(8/S)):0,T=2*P+1,q=useRef(false),Q=useRef(null),se=useRef(null),_e=useRef(P*S+d),ce=useCallback((e,r)=>r.offsetLeft-(e.clientWidth-r.offsetWidth)/2,[]),B=useCallback(()=>{q.current=true,clearTimeout(Q.current),Q.current=setTimeout(()=>{q.current=false;},800);},[]),te=useCallback(()=>{let e=L.current;if(!e||!P||M.current.isDragging||F.current.frozen)return;let r=e.querySelectorAll(".lightbox__item");if(S===0||r.length!==T*S)return;let u=r[S].offsetLeft-r[0].offsetLeft;if(!u)return;let w=0,_=1/0;for(let o=0;o<r.length;o++){let i=Math.abs(ce(e,r[o])-e.scrollLeft);i<_&&(_=i,w=o);}let t=Math.floor(w/S);t!==P&&(e.scrollLeft+=(P-t)*u),q.current=false;},[P,T,S,ce]);useEffect(()=>{let e=L.current;if(!e||!P)return;let r=()=>te();return e.addEventListener("scrollend",r),()=>e.removeEventListener("scrollend",r)},[P,te]),useEffect(()=>{let e=setTimeout(()=>{j(true),Y.current=true;let u=L.current;if(u){let w=u.querySelectorAll(".lightbox__item"),_=window.innerWidth/2;w.forEach(t=>{He(t,t.getBoundingClientRect(),_,y);});}},500),r=setTimeout(()=>ee(true),1100);return ()=>{clearTimeout(r),clearTimeout(e);}},[y]),useEffect(()=>(document.body.style.overflow="hidden",()=>{document.body.style.overflow="";}),[]),useLayoutEffect(()=>{let e=L.current;if(!e)return;let r=e.querySelectorAll(".lightbox__item"),u=r[P*S+m.current];if(u&&(e.scrollLeft=u.offsetLeft-(e.clientWidth-u.offsetWidth)/2,y)){let w=window.innerWidth/2;r.forEach(_=>He(_,_.getBoundingClientRect(),w,true));}},[y,P,S]);let ae=useCallback(()=>{b.current||(b.current=true,requestAnimationFrame(()=>{b.current=false;let e=L.current;if(!e)return;let r=e.querySelectorAll(".lightbox__item"),u=window.innerWidth/2;if(P&&!q.current&&!F.current.frozen&&S>0&&r.length===T*S){let i=r[S].offsetLeft-r[0].offsetLeft,s=ce(e,r[P*S]),l=e.scrollLeft,a=0;i&&l<s-i*.75?a=i:i&&l>s+i*1.75&&(a=-i),a&&(e.scrollLeft=l+a,M.current.isDragging&&(M.current.scrollLeft+=a));}P&&(clearTimeout(se.current),se.current=setTimeout(te,200));let w=new Array(r.length),_=0,t=1/0;for(let i=0;i<r.length;i++){let s=r[i].getBoundingClientRect();w[i]=s;let l=s.left+s.width/2,a=Math.abs(l-u);a<t&&(t=a,_=i);}if(Y.current){let i=_e.current,s=Math.min(_,i)-2,l=Math.max(_,i)+2;for(let a=Math.max(0,s);a<=Math.min(r.length-1,l);a++)He(r[a],w[a],u,y);}_e.current=_;let o=P?_%S:_;W(o),V(o);}));},[W,y,P,T,S,ce,te]);useEffect(()=>{let e=L.current;if(e)return e.addEventListener("scroll",ae,{passive:true}),()=>e.removeEventListener("scroll",ae)},[ae]);let U=useCallback(e=>{let r=L.current;if(!r)return;let u=r.querySelectorAll(".lightbox__item"),w;if(P){let _=(e%S+S)%S,t=1/0;for(let o=0;o<T;o++){let i=u[o*S+_];if(!i)continue;let s=Math.abs(ce(r,i)-r.scrollLeft);s<t&&(t=s,w=i);}w&&B();}else w=u[e];w&&w.scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"});},[P,T,S,ce,B]);useEffect(()=>{let e=r=>{if(r.key==="Escape")N();else if(r.key==="ArrowRight"){let u=A?g+1:Math.min(g+1,n.length-1);u!==g&&U(u);}else if(r.key==="ArrowLeft"){let u=A?g-1:Math.max(g-1,0);u!==g&&U(u);}};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[g,n.length,A,N,U]);let ve=useCallback(()=>{let e=L.current,r=F.current;!e||!r.frozen||(e.style.overflow="",e.scrollLeft=r.scrollLeft,e.style.transform="",e.style.zIndex="",F.current={frozen:false,scrollLeft:0});},[]);useEffect(()=>()=>clearTimeout(C.current),[]);let xe=useCallback(e=>{if(de.current=e.pointerType,e.pointerType==="touch"){clearTimeout(C.current),$.current=0,c.current={startX:e.clientX,startY:e.clientY,locked:null,dy:0,startTime:Date.now()};return}let r=L.current;r&&($.current=0,M.current={isDragging:true,startX:e.clientX,scrollLeft:r.scrollLeft,prevX:e.clientX,prevTime:Date.now(),velocity:0},z(true),r.style.scrollSnapType="none",r.setPointerCapture(e.pointerId));},[]),fe=useCallback(e=>{if(e.pointerType==="touch"){let s=c.current;if(!s)return;let l=e.clientX-s.startX,a=e.clientY-s.startY;if(s.locked===null){if(Math.abs(l)<8&&Math.abs(a)<8)return;s.locked=Math.abs(a)>Math.abs(l)&&a>0?"v":"h";}if(s.locked!=="v")return;s.dy=Math.max(0,a),$.current=s.dy;let h=L.current;if(!h)return;F.current.frozen||(F.current={frozen:true,scrollLeft:h.scrollLeft},h.style.overflow="visible",h.style.transform=`translateX(${-F.current.scrollLeft}px)`,h.style.zIndex="5");let f=Math.max(.85,1-s.dy/1400),I=Math.max(0,1-s.dy/300),R=document.querySelector(".lightbox__backdrop"),K=document.querySelector(".lightbox__meta");h.querySelectorAll(".lightbox__item").forEach(Z=>{Z.classList.contains("lightbox__item--active")?(Z.style.transition="none",Z.style.transform=`translateY(${s.dy}px) scale(${f})`):(Z.style.transition="none",Z.style.opacity=String(I));}),R&&(R.style.transition="none",R.style.opacity=String(I)),K&&(K.style.transition="none",K.style.opacity=String(I));return}let r=M.current;if(!r.isDragging)return;let u=Date.now(),w=u-r.prevTime,_=e.clientX-r.prevX;w>0&&(r.velocity=_/w),r.prevX=e.clientX,r.prevTime=u,$.current=Math.abs(e.clientX-r.startX);let t=L.current,o=r.scrollLeft-(e.clientX-r.startX),i=t.scrollWidth-t.clientWidth;o<0?t.scrollLeft=o*.2:o>i?t.scrollLeft=i+(o-i)*.2:t.scrollLeft=o;},[]),ye=useCallback(e=>{if(e.pointerType==="touch"){let i=c.current;if(c.current=null,!i||i.locked!=="v")return;let s=L.current,l=s?.querySelector(".lightbox__item--active"),a=document.querySelector(".lightbox__backdrop"),h=document.querySelector(".lightbox__meta"),f=i.dy/Math.max(Date.now()-i.startTime,1);if(i.dy>Nt||f>qt){N({fromDrag:true});return}let I="transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94)";l&&(l.style.transition=I,l.style.transform=""),s&&s.querySelectorAll(".lightbox__item").forEach(R=>{R.classList.contains("lightbox__item--active")||(R.style.transition="opacity 0.3s",R.style.opacity="");}),a&&(a.style.transition="opacity 0.3s",a.style.opacity=""),h&&(h.style.transition="opacity 0.3s",h.style.opacity=""),clearTimeout(C.current),C.current=setTimeout(()=>{l&&(l.style.transition=""),ve();},300);return}let r=M.current;if(!r.isDragging)return;r.isDragging=false;let u=L.current;if(u.releasePointerCapture(e.pointerId),$.current<5){u.style.scrollSnapType="x mandatory",z(false);let i=document.elementFromPoint(e.clientX,e.clientY)?.closest(".lightbox__item");if(i){let l=Array.from(u.querySelectorAll(".lightbox__item")).indexOf(i);if(l>=0){let a=P?P*S+g:g;l===a?N():P?(B(),i.scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"})):U(l);}}return}let w=-r.velocity*1e3,_=.92,t=performance.now(),o=i=>{let s=(i-t)/1e3;if(t=i,w*=_,u.scrollLeft+=w*s,Math.abs(w)>50)requestAnimationFrame(o);else {let l=u.querySelectorAll(".lightbox__item"),a=window.innerWidth/2,h=0,f=1/0;l.forEach((K,Z)=>{let ne=K.getBoundingClientRect(),G=ne.left+ne.width/2,me=Math.abs(G-a);me<f&&(f=me,h=Z);});let I=()=>{clearTimeout(R),u.style.scrollSnapType="x mandatory",z(false),u.removeEventListener("scrollend",I);},R=setTimeout(I,300);u.addEventListener("scrollend",I,{once:true}),P&&B(),l[h].scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"});}};requestAnimationFrame(o);},[g,N,U,P,S,B]);useEffect(()=>{ie(false);},[g]),useEffect(()=>{let e=L.current;if(!e)return;let r=e.querySelectorAll(".lightbox__item:not([data-clone])"),u=[];return r.forEach((w,_)=>{let t=w.querySelector("video");if(t)if(_===g){let i=setTimeout(()=>{t.currentTime=0,t.play();let s=()=>w.classList.add("lightbox__item--video-ready");t.readyState>=2?s():(t.addEventListener("canplay",s,{once:true}),u.push(()=>t.removeEventListener("canplay",s)));},300);u.push(()=>clearTimeout(i));}else t.pause();}),()=>u.forEach(w=>w())},[g]);let be=useCallback(e=>{if($.current>=5)return;let r=P?P*S+g:g;if(e===r){if(k&&!!n[g]?.video&&de.current==="touch"){ie(w=>!w);return}N();}else if(P){let u=L.current?.querySelectorAll(".lightbox__item")[e];u&&(B(),u.scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"}));}else U(e);},[g,N,U,P,S,B,n,k]);return jsxs("div",{className:`lightbox${O?" lightbox--revealed":""}${x?" lightbox--controls":""}${y?" lightbox--coverflow":""}`,style:y&&D?{"--lb-item-aspect":D}:void 0,children:[jsx(motion.div,{className:"lightbox__backdrop",onClick:N,initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.3}}),jsx("div",{className:"lightbox__track",ref:L,onPointerDown:xe,onPointerMove:fe,onPointerUp:ye,onPointerCancel:ye,onClick:e=>{if($.current>=5)return;document.elementFromPoint(e.clientX,e.clientY)?.closest(".lightbox__item")||N();},style:{touchAction:"pan-x"},children:Array.from({length:T*S},(e,r)=>{let u=r%S;return jsx(Vt,{item:n[u],index:u,pos:r,clone:P>0&&Math.floor(r/S)!==P,activeIndex:g,sizes:p,staggerDone:H,transitionName:E,videoControls:k,showControls:X,onClick:be},`${Math.floor(r/S)}:${n[u].id??u}`)})}),jsxs("div",{className:"lightbox__meta","aria-live":"polite",children:[jsx(v,{as:"h2",children:n[g]?.title}),jsx(v,{as:"p",children:n[g]?.meta})]}),x&&jsxs("div",{className:"lightbox__controls",children:[jsx("button",{className:"lightbox__nav",onClick:()=>U(g-1),disabled:!A&&g===0,"aria-label":"Previous",children:jsx(Ae,{})}),jsx("button",{className:"lightbox__close",onClick:N,"aria-label":"Close",children:jsx(it,{})}),jsx("button",{className:"lightbox__nav",onClick:()=>U(g+1),disabled:!A&&g===n.length-1,"aria-label":"Next",children:jsx(De,{})})]})]})}function Vt({item:n,index:d,pos:p=d,clone:v=false,activeIndex:x,sizes:k,staggerDone:E,transitionName:y,videoControls:D,showControls:A=false,onClick:W}){let N=!!n.highResSrc,L=v?void 0:n.video,M=useRef(null),g=!v&&d===x,V=Math.abs(d-x),[z,$]=useState(false);return jsx("div",{className:`lightbox__item${g?" lightbox__item--active":""}${g&&A?" lightbox__item--show-controls":""}`,"data-index":d,"data-clone":v?"":void 0,"aria-hidden":v?true:void 0,style:g?{viewTransitionName:y,viewTransitionClass:"vitrine-shared"}:E?void 0:{transitionDelay:`${V*.06}s`},onClick:()=>W(p),children:jsxs("div",{className:"lightbox__item-inner",children:[jsxs("picture",{className:"lightbox__img lightbox__img--low",children:[n.webpSrcSet&&jsx("source",{srcSet:n.webpSrcSet,sizes:k,type:"image/webp"}),jsx("img",{src:n.src,srcSet:n.srcSet,sizes:k,alt:n.alt||n.title,draggable:false,loading:V<=1?"eager":"lazy",decoding:"async"})]}),N&&jsxs("picture",{className:`lightbox__img lightbox__img--high${z?" lightbox__img--ready":""}`,children:[n.highResWebpSrcSet&&jsx("source",{srcSet:n.highResWebpSrcSet,sizes:k,type:"image/webp"}),jsx("img",{src:n.highResSrc,srcSet:n.highResSrcSet,sizes:k,alt:"","aria-hidden":"true",draggable:false,loading:V<=1?"eager":"lazy",decoding:"async",onLoad:()=>$(true)})]}),L&&jsx("video",{ref:M,src:L,muted:true,playsInline:true,loop:true,preload:D?"metadata":"none",draggable:false}),L&&D&&g&&jsx(ut,{videoRef:M,minimal:D==="minimal"})]})})}function Xt(n,d,p){if(!n||typeof n.closest!="function"||n.closest(".vitrine-video-toggle, .vitrine-lb-video"))return null;if(!d){let x=n.closest(".slider__item");return p&&x?.closest(".slider--morph-cursor")?"plus":null}if(n.closest(".lightbox__item--active"))return "close";let v=n.closest(".lightbox__item");if(v){let x=Number(v.dataset.index),k=document.querySelector(".lightbox__item--active"),E=k?Number(k.dataset.index):x;return x<E?"arrow-left":"arrow-right"}return n.closest(".lightbox__backdrop, .lightbox__track")?"close":null}function mt({lightboxOpen:n,itemsClickable:d=true}){let p=useRef(null),v=useRef(0),x=useRef({x:0,y:0}),[k,E]=useState(false),[y,D]=useState(null),[A,W]=useState(false);return useEffect(()=>{if(typeof window>"u"||!window.matchMedia)return;let N=window.matchMedia("(pointer: fine)"),L=()=>E(N.matches);return L(),N.addEventListener("change",L),()=>N.removeEventListener("change",L)},[]),useEffect(()=>{if(!k){W(false);return}let N=M=>{x.current={x:M.clientX,y:M.clientY},v.current||(v.current=requestAnimationFrame(()=>{v.current=0;let V=p.current;if(V){let{x:z,y:$}=x.current;V.style.transform=`translate(${z}px, ${$}px) translate(-50%, -50%)`;}}));let g=Xt(M.target,n,d);g?(D(g),W(true)):W(false);},L=M=>{M.relatedTarget||W(false);};return window.addEventListener("pointermove",N,{passive:true}),window.addEventListener("pointerout",L,{passive:true}),()=>{window.removeEventListener("pointermove",N),window.removeEventListener("pointerout",L),v.current&&cancelAnimationFrame(v.current),v.current=0;}},[k,n,d]),k?jsx("div",{ref:p,className:`morph-cursor${A?" morph-cursor--visible":""}`,"aria-hidden":"true",children:y&&jsx(IconMorph,{name:y,size:20,strokeWidth:1.75,color:"#fff",duration:250})}):null}function Fe({item:n,index:d,sizes:p,video:v=true,videoControls:x=false,isActive:k=false}){let E=useRef(null),y=v&&!!n.video;return jsxs(Fragment,{children:[jsxs("picture",{children:[n.webpSrcSet&&jsx("source",{srcSet:n.webpSrcSet,sizes:p,type:"image/webp"}),jsx("img",{src:n.src,srcSet:n.srcSet,sizes:p,alt:n.alt||n.title,draggable:false,fetchPriority:d===0?"high":void 0,loading:d<=1?"eager":"lazy",decoding:d<=1?"sync":"async",style:n.blurDataURL?{backgroundImage:`url(${n.blurDataURL})`,backgroundSize:"cover",backgroundRepeat:"no-repeat",backgroundPosition:"center"}:void 0})]}),y&&jsx("video",{ref:E,src:n.video,muted:true,playsInline:true,loop:true,preload:x?"metadata":"none",draggable:false}),y&&x&&k&&jsx(Ne,{videoRef:E,size:40})]})}var gt={initial:{},animate:{transition:{staggerChildren:.06}}},Ie={initial:{opacity:0,y:8},animate:{opacity:1,y:0,transition:{duration:1,ease:[0,.55,.45,1]}}};var Ve=forwardRef(function({items:d,activeIndex:p,contentWidth:v,gap:x,columns:k,metaOffsetColumns:E,sideMargin:y,maxItemHeight:D,aspectRatio:A,sizes:W,videoControls:N,itemsClickable:L,itemCursor:M,onActiveIndexChange:g,onItemOpen:V,openOnSettle:z,onLayoutChange:$,mode:de="row",projector:X,trackClassName:ie,video:c=true,loop:F=false},C){let m=useRef(null),O=useRef({isDragging:false,startX:0,scrollLeft:0}),j=useRef(0),H=useRef(false),ee=useRef(null),Y=useRef(false),[b,S]=useState({inset:0,itemWidth:0,itemHeight:0,metaInset:0,metaInsetRight:0,endPad:0,isMobile:false,centered:false}),P=de==="coverflow",T=d.length,q=F&&T>0?Math.max(2,Math.ceil(8/T)):0,Q=2*q+1,se=useRef(false),_e=useRef(null),ce=useRef(null);useEffect(()=>{let t=()=>{let s=window.innerWidth,l=window.matchMedia("(min-width: 700px)").matches,a=document.querySelector(".subgrid"),h=a?.closest(".grid")||document.querySelector(".grid");if(P){let f,I,R;if(a&&h){let G=a.getBoundingClientRect();f=G.left,I=G.width,R=l?f:G.left-h.getBoundingClientRect().left;}else I=Math.min(v,s-2*y),f=(s-I)/2,R=l?f:y;let K=l?Math.round(Math.min(v*.62,s-2*y)):s-2*R,Z=l?D:Math.round(K*.75);A&&(Z=Math.round(K/A),Z>D&&(Z=D,K=Math.round(Z*A)));let ne=Math.max((s-K)/2,0);S({inset:ne,itemWidth:K,itemHeight:Z,metaInset:l?f:R,metaInsetRight:l?f:R,endPad:ne,isMobile:!l,centered:true});return}if(l){let f,I,R,K;if(a&&h){let Re=a.getBoundingClientRect();f=Re.left,I=Re.width,R=parseInt(getComputedStyle(h).getPropertyValue("--columns"),10)||k,K=parseFloat(getComputedStyle(a).columnGap)||x;}else I=Math.min(v,s-2*y),f=(s-I)/2,R=k,K=x;let Z=(I-(R-1)*K)/R,ne=f-12,G=I+24,me=0;A&&(G=I,me=Math.round(G/A),me>D&&(me=D,G=Math.round(me*A))),S({inset:ne,itemWidth:G,itemHeight:me,metaInset:ne+E*(Z+K),metaInsetRight:ne,endPad:s-ne,isMobile:false,centered:false,fixedAspect:!!A});}else {let f;a&&h?f=a.getBoundingClientRect().left-h.getBoundingClientRect().left:f=y;let I=s-2*f,R=0;A&&(R=Math.round(I/A),R>D&&(R=D,I=Math.round(R*A))),S({inset:f,itemWidth:I,itemHeight:R,metaInset:f,metaInsetRight:f,endPad:f,isMobile:true,centered:false,fixedAspect:!!A});}},o,i=()=>{clearTimeout(o),o=setTimeout(t,100);};return t(),window.addEventListener("resize",i),()=>{window.removeEventListener("resize",i),clearTimeout(o);}},[v,x,k,E,y,D,A,P]),useEffect(()=>{$?.(b);},[b,$]);let B=b.centered||b.isMobile?"center":"start",te=useCallback((t,o)=>o.offsetLeft-(B==="center"?(t.clientWidth-o.offsetWidth)/2:b.inset),[B,b.inset]);useEffect(()=>{let t=m.current;if(!t)return;if(!q){t.scrollLeft=0;return}let o=t.querySelectorAll(".slider__item")[q*T];o&&(t.scrollLeft=te(t,o));},[b.inset,q,T,te]);let ae=useCallback(()=>{se.current=true,clearTimeout(_e.current),_e.current=setTimeout(()=>{se.current=false;},800);},[]),U=useCallback(()=>{let t=m.current;if(!t||!q||O.current.isDragging)return;let o=t.querySelectorAll(".slider__item");if(T===0||o.length!==Q*T)return;let i=o[T].offsetLeft-o[0].offsetLeft;if(!i)return;let s=0,l=1/0;for(let h=0;h<o.length;h++){let f=Math.abs(te(t,o[h])-t.scrollLeft);f<l&&(l=f,s=h);}let a=Math.floor(s/T);a!==q&&(t.scrollLeft+=(q-a)*i),se.current=false;},[q,Q,T,te]);useEffect(()=>{let t=m.current;if(!t||!q)return;let o=()=>U();return t.addEventListener("scrollend",o),()=>t.removeEventListener("scrollend",o)},[q,U]);let ve=useCallback(t=>{let o=m.current;if(!o||!b.itemWidth)return;let i=o.querySelectorAll(".slider__item"),s;if(q){let l=(t%T+T)%T,a=1/0;for(let h=0;h<Q;h++){let f=i[h*T+l];if(!f)continue;let I=Math.abs(te(o,f)-o.scrollLeft);I<a&&(a=I,s=f);}s&&ae();}else s=i[t];s&&s.scrollIntoView({behavior:"smooth",block:"nearest",inline:B});},[b.itemWidth,B,q,Q,T,te,ae]),xe=useCallback((t,o)=>{o?.external&&(H.current=true,clearTimeout(ee.current),ee.current=setTimeout(()=>{H.current=false;},300)),ve(t);},[ve]),fe=useCallback(t=>{let o=t.querySelectorAll(".slider__item"),i=window.innerWidth/2,s=0,l=1/0;return o.forEach((a,h)=>{let f=a.getBoundingClientRect(),I=f.left+f.width/2,R=Math.abs(I-i);R<l&&(l=R,s=h);let K=f.width/2,Z=Math.max(0,R-K),ne=Math.min(Z/(window.innerWidth*.3),1),G=a.querySelector(".slider__item-inner");G&&(G.style.transformOrigin=I<i?"right center":"left center",G.style.transform=`scale(${1-ne*.05})`,G.style.filter=`brightness(${1-ne*.15})`);}),s},[]),ye=useRef(0),be=useCallback(t=>{let o=t.querySelectorAll(".slider__item"),i=window.innerWidth,s=i/2,l=new Array(o.length),a=0,h=1/0;for(let f=0;f<o.length;f++){l[f]=o[f].getBoundingClientRect();let I=Math.abs(l[f].left+l[f].width/2-s);I<h&&(h=I,a=f);}if(X){let f=Math.max(0,Math.min(a,ye.current)-3),I=Math.min(o.length-1,Math.max(a,ye.current)+3);X({itemEls:o,rects:l,center:s,vw:i,lo:f,hi:I});}return ye.current=a,a},[X]),e=useCallback(()=>{let t=m.current;if(!t)return;if(q){if(!se.current){let i=t.querySelectorAll(".slider__item");if(T>0&&i.length===Q*T){let s=i[T].offsetLeft-i[0].offsetLeft,l=te(t,i[q*T]),a=t.scrollLeft,h=0;s&&a<l-s*.75?h=s:s&&a>l+s*1.75&&(h=-s),h&&(t.scrollLeft=a+h,O.current.isDragging&&(O.current.scrollLeft+=h));}}clearTimeout(ce.current),ce.current=setTimeout(U,200);}let o=i=>q?i%T:i;if(b.centered){if(Y.current)return;Y.current=true,requestAnimationFrame(()=>{Y.current=false;let i=m.current;if(!i)return;let s=be(i);H.current||(g(o(s)),clearTimeout(ee.current));});return}if(b.isMobile){if(Y.current)return;Y.current=true,requestAnimationFrame(()=>{Y.current=false;let i=m.current;if(!i)return;let s=fe(i);H.current||(g(o(s)),clearTimeout(ee.current));});return}H.current||Y.current||(Y.current=true,requestAnimationFrame(()=>{Y.current=false;let i=m.current;if(!i)return;let s=i.querySelectorAll(".slider__item"),l=b.inset,a=0,h=1/0;s.forEach((f,I)=>{let R=Math.abs(f.getBoundingClientRect().left-l);R<h&&(h=R,a=I);}),g(o(a));}));},[b.inset,b.centered,b.isMobile,fe,be,g,q,Q,T,te,U]);useEffect(()=>{let t=m.current;if(t)return t.addEventListener("scroll",e,{passive:true}),()=>t.removeEventListener("scroll",e)},[e]),useEffect(()=>{let t=m.current;t&&(b.centered?requestAnimationFrame(()=>be(t)):b.isMobile?requestAnimationFrame(()=>fe(t)):t.querySelectorAll(".slider__item-inner").forEach(o=>{o.style.transform="",o.style.filter="",o.style.transformOrigin="";}));},[b.centered,b.isMobile,fe,be]);let r=useCallback(t=>{let o=q?t%T:t,i=q?q*T+p:p;if(t===i){V?.(o);return}let s=m.current;if(q){let h=s?.querySelectorAll(".slider__item")[t];h&&(ae(),h.scrollIntoView({behavior:"smooth",block:"nearest",inline:B}));}else ve(t);if(!z)return;let l=()=>{clearTimeout(a),s?.removeEventListener("scrollend",l),U(),V?.(o);},a=setTimeout(l,600);s?.addEventListener("scrollend",l,{once:true});},[p,V,z,ve,q,T,B,ae,U]),u=useCallback(t=>{if(t.pointerType==="touch")return;let o=m.current;o&&(j.current=0,O.current={isDragging:true,startX:t.clientX,scrollLeft:o.scrollLeft,prevX:t.clientX,prevTime:Date.now(),velocity:0},o.style.scrollSnapType="none",o.setPointerCapture(t.pointerId));},[]),w=useCallback(t=>{let o=O.current;if(!o.isDragging)return;let i=Date.now(),s=i-o.prevTime,l=t.clientX-o.prevX;s>0&&(o.velocity=l/s),o.prevX=t.clientX,o.prevTime=i,j.current=Math.abs(t.clientX-o.startX),m.current.scrollLeft=o.scrollLeft-(t.clientX-o.startX);},[]),_=useCallback(t=>{let o=O.current;if(!o.isDragging)return;o.isDragging=false;let i=m.current;if(i.releasePointerCapture(t.pointerId),j.current<5){i.style.scrollSnapType="x mandatory";let f=document.elementFromPoint(t.clientX,t.clientY)?.closest(".slider__item");if(f){let R=Array.from(i.querySelectorAll(".slider__item")).indexOf(f);R>=0&&r(R);}return}let s=-o.velocity*1e3,l=.92,a=performance.now(),h=f=>{let I=(f-a)/1e3;if(a=f,s*=l,i.scrollLeft+=s*I,Math.abs(s)>50)requestAnimationFrame(h);else {let R=i.querySelectorAll(".slider__item"),K=window.innerWidth/2,Z=0,ne=1/0;R.forEach((Re,Tt)=>{let Xe=Re.getBoundingClientRect(),Qe=Math.abs(B==="center"?Xe.left+Xe.width/2-K:Xe.left-b.inset);Qe<ne&&(ne=Qe,Z=Tt);});let G=()=>{clearTimeout(me),i.style.scrollSnapType="x mandatory",i.removeEventListener("scrollend",G);},me=setTimeout(G,300);i.addEventListener("scrollend",G,{once:true}),q&&ae(),R[Z].scrollIntoView({behavior:"smooth",block:"nearest",inline:B});}};requestAnimationFrame(h);},[b.inset,B,r,q,ae]);return useImperativeHandle(C,()=>({goTo:xe,park:t=>{let o=m.current,i=o?.querySelectorAll(".slider__item:not([data-clone])")[t];if(!o||!i)return {apply:()=>{},release:()=>{}};let s=B,l=()=>{U();let a=i.getBoundingClientRect(),h=s==="center"?window.innerWidth/2:b.inset,f=s==="center"?a.left+a.width/2:a.left;Math.abs(f-h)<4||i.scrollIntoView({behavior:"instant",block:"nearest",inline:s});};return o.addEventListener("scroll",l),{apply:l,release:()=>o.removeEventListener("scroll",l)}},getItemEls:()=>m.current?.querySelectorAll(".slider__item:not([data-clone])")??[]}),[xe,B,b.inset,U]),jsx(motion.div,{className:`slider__track${ie?` ${ie}`:""}${b.fixedAspect?" slider__track--fixed":""}`,ref:m,tabIndex:-1,onPointerDown:u,onPointerMove:w,onPointerUp:_,onPointerCancel:_,style:{paddingLeft:`${b.inset}px`,paddingRight:`${b.endPad}px`,scrollPaddingLeft:b.isMobile||b.centered?void 0:`${b.inset}px`,touchAction:"pan-x pan-y"},children:Array.from({length:Q*T},(t,o)=>{let i=o%T,s=d[i],l=q>0&&Math.floor(o/T)!==q,a=!l&&i===p,h=!l&&L;return jsx(motion.div,{"data-clone":l?"":void 0,className:`slider__item${a?" slider__item--active":""}`,variants:l?void 0:Ie,role:h?"button":void 0,tabIndex:h?0:void 0,"aria-label":h?s.title:void 0,"aria-hidden":l?true:void 0,style:{"--item-max-w":`${b.itemWidth}px`,"--item-max-h":`${b.itemHeight||D}px`,cursor:M},onClick:()=>{j.current<5&&r(o);},onKeyDown:h?f=>{(f.key==="Enter"||f.key===" ")&&(f.preventDefault(),r(o));}:void 0,children:jsx("div",{className:"slider__item-inner",children:jsx(Fe,{item:s,index:i,sizes:W,video:c&&!l,videoControls:N,isActive:a})})},`${Math.floor(o/T)}:${s.id??i}`)})})});var _t=3,en=.04,tn=90,nn=400,xt=(n,d)=>{let p=Math.sin((n+1)*d)*1e4;return p-Math.floor(p)},rn=n=>(xt(n,12.9898)-.5)*7,on=n=>(xt(n,78.233)-.5)*18,Lt=forwardRef(function({items:d,activeIndex:p,contentWidth:v,sideMargin:x,maxItemHeight:k,aspectRatio:E,sizes:y,itemsClickable:D,itemCursor:A,onActiveIndexChange:W,onItemOpen:N,onLayoutChange:L,loop:M=true},g){let V=useRef(null),z=useRef(false),[$,de]=useState({colLeft:0,colWidth:0,cardWidth:0,cardHeight:0,isMobile:false}),X=d.length;useEffect(()=>{let F=()=>{let O=window.innerWidth,j=window.matchMedia("(min-width: 700px)").matches,H=document.querySelector(".subgrid"),ee=H?.closest(".grid")||document.querySelector(".grid"),Y,b;if(j)if(H&&ee){let T=H.getBoundingClientRect();Y=T.left,b=T.width;}else b=Math.min(v,O-2*x),Y=(O-b)/2;else {let T=H&&ee?H.getBoundingClientRect().left-ee.getBoundingClientRect().left:x;b=O-2*T,Y=T;}let S=b,P=j?k:Math.round(b*.75);E&&(P=Math.round(S/E),P>k&&(P=k,S=Math.round(P*E))),de({colLeft:Y,colWidth:b,cardWidth:S,cardHeight:P,isMobile:!j,fixedAspect:!!E});},C,m=()=>{clearTimeout(C),C=setTimeout(F,100);};return F(),window.addEventListener("resize",m),()=>{window.removeEventListener("resize",m),clearTimeout(C);}},[v,x,k,E]),useEffect(()=>{L?.({metaInset:$.colLeft,metaInsetRight:$.colLeft,isMobile:$.isMobile});},[$,L]);let ie=useCallback(F=>{W(M?(F%X+X)%X:Math.max(0,Math.min(F,X-1)));},[X,W,M]);useImperativeHandle(g,()=>({goTo:ie,park:()=>({apply:()=>{},release:()=>{}}),getItemEls:()=>V.current?.querySelectorAll(".slider__item")??[]}),[ie]);let c=useCallback((F,C)=>{let m=Math.hypot(C.offset.x,C.offset.y),O=Math.hypot(C.velocity.x,C.velocity.y);(m>tn||O>nn)&&ie(p+1),requestAnimationFrame(()=>{z.current=false;});},[p,ie]);return jsx("div",{className:`slider__track slider__track--stack${$.fixedAspect?" slider__track--stack-fixed":""}`,ref:V,style:{height:`${$.cardHeight}px`},children:jsx("div",{className:"slider__stack-stage",style:{left:`${$.colLeft}px`,width:`${$.colWidth}px`,height:`${$.cardHeight}px`,"--stack-w":`${$.cardWidth}px`,"--stack-h":`${$.cardHeight}px`},children:d.map((F,C)=>{let m=M?(C-p+X)%X:C-p;return jsx(sn,{item:F,index:C,depth:m,n:X,sizes:y,itemsClickable:D,itemCursor:A,wasDraggingRef:z,onDragEnd:c,onItemOpen:N,onActiveIndexChange:W},F.id??C)})})})});function sn({item:n,index:d,depth:p,n:v,sizes:x,itemsClickable:k,itemCursor:E,wasDraggingRef:y,onDragEnd:D,onItemOpen:A,onActiveIndexChange:W}){let N=p<0,L=Math.min(Math.max(p,0),_t),M=p===0,g=useMotionValue(0),V=useTransform(g,[-360,0,360],[-14,0,14],{clamp:true});return jsx(motion.div,{className:`slider__item${M?" slider__item--active":""}`,role:k?"button":void 0,tabIndex:k&&M?0:void 0,"aria-label":k?n.title:void 0,"aria-hidden":M?void 0:true,style:{zIndex:N?v+1:v-p,cursor:M?void 0:E,transformOrigin:"center",pointerEvents:N?"none":void 0,x:g},initial:false,animate:N?{y:24,rotate:0,scale:1.04,opacity:0}:{x:M?0:on(d),y:-12*L,rotate:M?0:rn(d),scale:1-en*L,opacity:p>_t?0:1},transition:{type:"spring",stiffness:300,damping:30},drag:M,dragSnapToOrigin:true,dragMomentum:false,onDragStart:M?()=>y.current=true:void 0,onDragEnd:M?D:void 0,onTap:()=>{y.current||(M?A?.(d):W(d));},onKeyDown:k&&M?z=>{(z.key==="Enter"||z.key===" ")&&(z.preventDefault(),A?.(d));}:void 0,children:jsx(motion.div,{className:"slider__item-inner",style:{rotate:V},children:jsx(Fe,{item:n,index:d,sizes:x,video:false})})})}var kt=forwardRef(function(d,p){let v=useCallback(({itemEls:x,rects:k,center:E,vw:y,lo:D,hi:A})=>{let W=y<700,N=W?30:45,L=W?60:120;for(let M=D;M<=A;M++){let g=k[M],V=Math.max(-2,Math.min(2,(g.left+g.width/2-E)/g.width)),z=Math.min(Math.abs(V),1),$=x[M].querySelector(".slider__item-inner");$&&($.style.transform=`perspective(1200px) rotateY(${-Math.sign(V)*z*N}deg) translateZ(${-Math.abs(V)*L}px) scale(${1-Math.abs(V)*.08})`),x[M].style.zIndex=String(100-Math.round(Math.abs(V)*10));}},[]);return jsx(Ve,{...d,ref:p,mode:"coverflow",projector:v,trackClassName:"slider__track--coverflow",video:false})});var mn=({as:n="span",children:d})=>jsx(n,{children:d}),Le=null;function hn(n){if(n==null)return null;if(typeof n=="number")return n>0?n:null;if(typeof n=="string"){let d=n.split(/[/:]/);if(d.length===2){let v=parseFloat(d[0]),x=parseFloat(d[1]);return v>0&&x>0?v/x:null}let p=parseFloat(n);return p>0?p:null}return null}function gn({items:n,variant:d="row",contentWidth:p=628,gap:v=32,columns:x=4,metaOffsetColumns:k=0,sideMargin:E=24,maxItemHeight:y=520,aspectRatio:D,sizes:A="(min-width: 700px) 628px, 82vw",lightboxSizes:W="84vw",Caption:N=TextMorph,lightbox:L=true,lightboxControls:M=false,onItemClick:g,loop:V,arrows:z=false,pagination:$=false,videoControls:de=false,morphCursor:X=false,transitionName:ie}){let c=useRef(null),F=useRef(false),C=useRef(null),[m,O]=useState(0),j=useRef(0);j.current=m;let[H,ee]=useState(false),[Y,b]=useState(false),[S,P]=useState({metaInset:0,metaInsetRight:0}),T=useId(),q=ie??`vitrine-${T.replace(/[^a-zA-Z0-9_-]/g,"")}`,Q=L&&d!=="stack",se=V??d!=="row",_e=hn(D),ce=useRef(null),B=useCallback(e=>{P(r=>r.metaInset===e.metaInset&&r.metaInsetRight===e.metaInsetRight?r:{metaInset:e.metaInset,metaInsetRight:e.metaInsetRight});},[]);useEffect(()=>{let e=r=>{if(r.key!=="ArrowRight"&&r.key!=="ArrowLeft"||H||!(F.current||c.current&&c.current.contains(document.activeElement)))return;let w=se;if(r.key==="ArrowRight"){let _=w?m+1:Math.min(m+1,n.length-1);_!==m&&(r.preventDefault(),C.current?.goTo(_));}else {let _=w?m-1:Math.max(m-1,0);_!==m&&(r.preventDefault(),C.current?.goTo(_));}};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[m,n.length,H,se]);let te=useCallback(()=>{let e=j.current,r=C.current?.getItemEls();if(!r?.[e]||Le)return;let u=r[e].getBoundingClientRect();if(ce.current=u.height>0?u.width/u.height:1,document.startViewTransition){r[e].classList.add("slider__item--transitioning"),r[e].style.viewTransitionName=q,r[e].style.viewTransitionClass="vitrine-shared",document.documentElement.style.viewTransitionName="none";let w=document.startViewTransition(()=>{r[e].style.viewTransitionName="",flushSync(()=>ee(true));});Le=w,w.finished.finally(()=>{Le=null,r[e].classList.remove("slider__item--transitioning"),r[e].style.viewTransitionClass="",document.documentElement.style.viewTransitionName="";});}else ee(true);},[q]),ae=useCallback(e=>{Q?te():g?.(n[e],e);},[Q,g,n,te]);useEffect(()=>{if(H){let e=setTimeout(()=>b(true),300);return ()=>clearTimeout(e)}else b(false);},[H]),useEffect(()=>{let e=C.current?.getItemEls();if(!e?.length)return;let r=[];return e.forEach((u,w)=>{let _=u.querySelector("video");if(_)if(Y)_.pause(),_.style.visibility="hidden",u.classList.remove("slider__item--video-ready");else if(_.style.visibility="",w===m){_.currentTime=0,_.play();let t=()=>u.classList.add("slider__item--video-ready");_.readyState>=2?t():(_.addEventListener("canplay",t,{once:true}),r.push(()=>_.removeEventListener("canplay",t)));}else _.pause(),u.classList.remove("slider__item--video-ready");}),()=>r.forEach(u=>u())},[m,Y]);let U=useCallback(e=>{let r=e?.fromDrag===true;if(Le)return;let u=C.current,w=u?.getItemEls();if(!w?.[m]){ee(false);return}let _=document.querySelector(".lightbox");_&&!r&&_.classList.add("lightbox--closing");let t=u.park(m),o=()=>{if(Le){t.release();return}if(document.startViewTransition){w.forEach(s=>{let l=s.querySelector("video");l&&(l.style.visibility="");}),document.documentElement.style.viewTransitionName="none";let i=document.startViewTransition(()=>{let s=document.querySelector(".lightbox__item--active");s&&(s.style.viewTransitionName="none");let l=document.querySelector(".lightbox");l&&(l.style.display="none"),t.apply(),w[m].style.viewTransitionName=q,w[m].style.viewTransitionClass="vitrine-shared",flushSync(()=>ee(false));});Le=i,i.finished.finally(()=>{Le=null,w[m].style.viewTransitionName="",w[m].style.viewTransitionClass="",document.documentElement.style.viewTransitionName="",t.release();});}else t.apply(),ee(false),setTimeout(()=>t.release(),400);};r?requestAnimationFrame(o):_?setTimeout(o,350):o();},[m,q]),ve=useCallback(e=>{O(e),C.current?.goTo(e,{external:true});},[]),xe=n[m],fe=Q||typeof g=="function",ye=X?fe?"none":"default":Q?"zoom-in":fe?"pointer":"default",be=d==="stack"?Lt:d==="coverflow"?kt:Ve;return jsxs(motion.div,{className:`slider slider--${d}${X?" slider--morph-cursor":""}`,ref:c,variants:gt,onPointerEnter:()=>F.current=true,onPointerLeave:()=>F.current=false,children:[jsx(be,{ref:C,items:n,activeIndex:m,contentWidth:p,gap:v,columns:x,metaOffsetColumns:k,sideMargin:E,maxItemHeight:y,aspectRatio:_e,sizes:A,videoControls:de,itemsClickable:fe,itemCursor:ye,loop:se,onActiveIndexChange:O,onItemOpen:ae,openOnSettle:Q,onLayoutChange:B}),jsx(motion.div,{className:"slider__meta",style:{paddingLeft:`${S.metaInset}px`,paddingRight:`${S.metaInsetRight}px`},variants:Ie,children:jsxs("div",{className:"slider__meta-inner",children:[jsx(N,{as:"h3",children:xe?.title}),jsx("br",{}),jsx(N,{as:"p",children:xe?.meta})]})}),(z||$)&&jsxs(motion.div,{className:"slider__controls",variants:Ie,children:[z&&jsx("button",{type:"button",className:"slider__nav",onClick:()=>C.current?.goTo(m-1),disabled:!se&&m===0,"aria-label":"Previous",children:jsx(Ae,{})}),$&&jsx("div",{className:"slider__dots",children:n.map((e,r)=>jsx("button",{type:"button",className:`slider__dot${r===m?" slider__dot--active":""}`,"aria-label":`Go to slide ${r+1}`,"aria-current":r===m?"true":void 0,onClick:()=>C.current?.goTo(r)},e.id??r))}),z&&jsx("button",{type:"button",className:"slider__nav",onClick:()=>C.current?.goTo(m+1),disabled:!se&&m===n.length-1,"aria-label":"Next",children:jsx(De,{})})]}),jsx(AnimatePresence,{children:Q&&H&&jsx(Ye,{items:n,activeIndex:m,sizes:W,Caption:N,controls:M,videoControls:de,transitionName:q,coverflow:d==="coverflow",itemAspect:ce.current,loop:se,onActiveIndexChange:ve,onClose:U})}),X&&jsx(mt,{lightboxOpen:H,itemsClickable:fe})]})}
2
+ export{Ye as Lightbox,mn as PlainCaption,gn as Slider};
package/dist/styles.css CHANGED
@@ -1 +1 @@
1
- :root{--slider-cursor-zoom-in: url(data:image/svg+xml,%3Csvg%20width%3D%2217%22%20height%3D%2217%22%20viewBox%3D%220%200%2017%2017%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Cpath%20d%3D%22M9.19643%207.80357H15V9.19643H9.19643V15H7.80357V9.19643H2V7.80357H7.80357V2H9.19643V7.80357Z%22%20fill%3D%22black%22%20stroke%3D%22white%22%20stroke-width%3D%220.3%22%20stroke-linejoin%3D%22round%22%2F%3E%0A%3C%2Fsvg%3E) 8 8, zoom-in}.slider{width:100vw;margin-top:3lh;margin-bottom:4.75lh;margin-left:calc(-50vw + 50%);@media(min-width:700px){margin-top:4lh;margin-bottom:6.75lh}.slider__track{display:flex;align-items:flex-end;gap:var(--gap);overflow-x:auto;@media(max-width:699px){gap:1.6rem}overflow-y:clip;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;padding-block:48px;margin-block:-48px;&::-webkit-scrollbar{display:none}&:focus{outline:none}}.slider__item{flex-shrink:0;width:fit-content;max-width:var(--item-max-w);scroll-snap-align:start;&:focus-visible{outline:2px solid var(--accent-color);outline-offset:4px;border-radius:18px}@media(max-width:699px){scroll-snap-align:center;width:var(--item-max-w);max-width:none}.slider__item-inner{position:relative;border-radius:16px;overflow:hidden;filter:none;transition:translate .35s cubic-bezier(.2,0,0,1),transform .35s cubic-bezier(.2,0,0,1),filter .35s cubic-bezier(.2,0,0,1);@media(max-width:699px){transition:none;border-radius:12px;will-change:transform,filter}@media(hover:hover){&:hover{translate:0 -6px;transform:scale(1.01);filter:drop-shadow(0 4px 10px rgba(0,0,0,.05)) drop-shadow(0 2px 4px rgba(0,0,0,.02))}}}&.slider__item--transitioning .slider__item-inner{filter:none;transition:none}img,video{display:block;border-radius:16px;cursor:var(--slider-cursor-zoom-in);width:auto;height:auto;max-width:var(--item-max-w);max-height:var(--item-max-h);@media(max-width:699px){width:100%;height:auto;max-width:none;max-height:none}}video{position:absolute;inset:0;width:100%;height:100%;max-width:none;max-height:none;object-fit:cover;opacity:0;transition:opacity .3s ease}&.slider__item--active video{opacity:1}&.slider__item--video-ready img{opacity:0}}.slider__meta{margin-top:.75lh;h3{color:var(--accent-color);margin:0}p{color:var(--text-color)}}}:root{--lightbox-cursor-zoom-out: url(data:image/svg+xml,%3Csvg%20width%3D%2217%22%20height%3D%2217%22%20viewBox%3D%220%200%2017%2017%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Cpath%20d%3D%22M9.54074%208.48008L13.9602%2012.8995L12.8995%2013.9602L8.48008%209.54074L4.06066%2013.9602L3%2012.8995L7.41942%208.48008L3%204.06066L4.06066%203L8.48008%207.41942L12.8995%203L13.9602%204.06066L9.54074%208.48008Z%22%20fill%3D%22black%22%20stroke%3D%22white%22%20stroke-width%3D%220.3%22%20stroke-linejoin%3D%22round%22%2F%3E%0A%3C%2Fsvg%3E) 8 8, zoom-out}.lightbox{position:fixed;inset:0;z-index:100;display:flex;align-items:center;--lb-caption-space: 8rem;--lb-controls-space: 0rem;padding-bottom:calc(var(--lb-caption-space) + var(--lb-controls-space));--lb-max-width: 95vw;--lb-max-height: calc( 100dvh - 96px - var(--lb-caption-space) - var(--lb-controls-space) );--lb-gap: 1.6rem;--lb-peek: 2.4rem;--lb-item-width: calc(100vw - 2 * (var(--lb-gap) + var(--lb-peek)));@media(min-width:700px){--lb-caption-space: 9.6rem;--lb-max-width: calc(100vw - 80px) ;--lb-max-height: calc( 100dvh - 40px - var(--lb-caption-space) - var(--lb-controls-space) )}&.lightbox--controls{--lb-controls-space: 6.4rem}.lightbox__backdrop{position:absolute;inset:0;background-color:#0000001a;backdrop-filter:blur(20px);cursor:var(--lightbox-cursor-zoom-out)}.lightbox__track{position:relative;display:flex;align-items:flex-end;gap:6.4rem;cursor:var(--lightbox-cursor-zoom-out);@media(max-width:699px){gap:var(--lb-gap)}overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;width:100%;padding-inline:50%;&::-webkit-scrollbar{display:none}}.lightbox__item{flex-shrink:0;width:fit-content;scroll-snap-align:center;position:relative;cursor:pointer;@media(max-width:699px){width:var(--lb-item-width)}}&:not(.lightbox--revealed) .lightbox__item:not(.lightbox__item--active){opacity:0;filter:blur(4px);transform:scale(.92);transition:opacity 1s cubic-bezier(0,.55,.45,1),transform 1s cubic-bezier(0,.55,.45,1),filter 1s cubic-bezier(0,.55,.45,1)}.lightbox__item img,.lightbox__item video{display:block;width:auto;height:auto;max-width:var(--lb-max-width);max-height:var(--lb-max-height);border-radius:12px;user-select:none;-webkit-user-drag:none;@media screen{border-radius:16px}@media(max-width:699px){width:100%;height:auto;max-width:none;max-height:var(--lb-max-height);object-fit:cover}}.lightbox__img{display:block}.lightbox__img--high{position:absolute;inset:0;opacity:0;transition:opacity .4s ease}.lightbox__img--high.lightbox__img--ready{opacity:1}.lightbox__img--high img{width:100%;height:100%;max-width:none;max-height:none;object-fit:cover}.lightbox__item video{position:absolute;inset:0;width:100%;height:100%;max-width:none;max-height:none;object-fit:cover;opacity:0}.lightbox__item--active{cursor:var(--lightbox-cursor-zoom-out);video{opacity:1}}.lightbox__item--video-ready img{opacity:0}.lightbox__meta{position:fixed;left:0;right:0;bottom:var(--lb-controls-space);height:var(--lb-caption-space);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.2rem;padding:0 2.4rem;text-align:center;pointer-events:none;opacity:0;transition:opacity 1s cubic-bezier(0,.55,.45,1);h2{margin:0;color:var(--accent-color)}p{margin:0;color:var(--text-color)}}.lightbox__controls{display:flex;gap:.8rem;position:fixed;bottom:1.6rem;left:50%;transform:translate(-50%);z-index:10;opacity:0;transition:opacity 1s cubic-bezier(0,.55,.45,1)}.lightbox__close,.lightbox__nav{display:flex;align-items:center;justify-content:center;width:4.4rem;height:4.4rem;padding:0;border:none;border-radius:12px;color:var(--color-text);cursor:pointer;background:color-mix(in srgb,var(--accent-color) 10%,transparent);backdrop-filter:blur(12px)}.lightbox__nav:disabled{opacity:.35;cursor:default}&.lightbox--revealed .lightbox__item{opacity:1;filter:blur(0px);transition:filter .4s cubic-bezier(.25,.46,.45,.94),transform .4s cubic-bezier(.25,.46,.45,.94);video{transition:opacity .3s ease}}&.lightbox--revealed .lightbox__item--active{transform:scale(1)}&.lightbox--revealed .lightbox__controls,&.lightbox--revealed .lightbox__meta{opacity:1}&.lightbox--closing .lightbox__backdrop{opacity:0;transition:opacity .3s cubic-bezier(0,.55,.45,1)}&.lightbox--closing .lightbox__item:not(.lightbox__item--active){opacity:0;filter:blur(4px);transform:scale(.92);transition:opacity .3s cubic-bezier(0,.55,.45,1),filter .3s cubic-bezier(0,.55,.45,1),transform .3s cubic-bezier(0,.55,.45,1)}&.lightbox--closing .lightbox__controls,&.lightbox--closing .lightbox__meta{opacity:0;transition:opacity .3s cubic-bezier(0,.55,.45,1)}&.lightbox--closing .lightbox__item--active{opacity:0;transition:opacity 0s linear .4s}}.lightbox__item--active{view-transition-name:slider-active}::view-transition-group(slider-active){animation-duration:.6s;animation-timing-function:cubic-bezier(.4,0,0,1)}::view-transition-old(slider-active),::view-transition-new(slider-active){animation-duration:.6s;animation-timing-function:cubic-bezier(.4,0,0,1)}.morph-cursor{position:fixed;top:0;left:0;z-index:2147483647;pointer-events:none;line-height:0;color:#fff;opacity:0;transition:opacity .15s ease;will-change:transform;filter:drop-shadow(0 0 1px rgba(0,0,0,.9)) drop-shadow(0 0 1px rgba(0,0,0,.6))}.morph-cursor--visible{opacity:1}.slider--morph-cursor .slider__item,.slider--morph-cursor .slider__item img,.slider--morph-cursor .slider__item video,.slider--morph-cursor .lightbox__backdrop,.slider--morph-cursor .lightbox__track,.slider--morph-cursor .lightbox__item,.slider--morph-cursor .lightbox__item--active{cursor:none}
1
+ :root{--slider-cursor-zoom-in: url(data:image/svg+xml,%3Csvg%20width%3D%2217%22%20height%3D%2217%22%20viewBox%3D%220%200%2017%2017%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Cpath%20d%3D%22M9.19643%207.80357H15V9.19643H9.19643V15H7.80357V9.19643H2V7.80357H7.80357V2H9.19643V7.80357Z%22%20fill%3D%22black%22%20stroke%3D%22white%22%20stroke-width%3D%220.3%22%20stroke-linejoin%3D%22round%22%2F%3E%0A%3C%2Fsvg%3E) 8 8, zoom-in}.slider{width:100vw;margin-top:3lh;margin-bottom:4.75lh;margin-left:calc(-50vw + 50%);@media(min-width:700px){margin-top:4lh;margin-bottom:6.75lh}.slider__track{display:flex;align-items:flex-end;gap:var(--gap);overflow-x:auto;@media(max-width:699px){gap:1.6rem}overflow-y:clip;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;padding-block:48px;margin-block:-48px;&::-webkit-scrollbar{display:none}&:focus{outline:none}}.slider__item{flex-shrink:0;width:fit-content;max-width:var(--item-max-w);scroll-snap-align:start;&:focus-visible{outline:2px solid var(--accent-color);outline-offset:4px;border-radius:18px}@media(max-width:699px){scroll-snap-align:center;width:var(--item-max-w);max-width:none}.slider__item-inner{position:relative;border-radius:16px;overflow:hidden;filter:none;transition:translate .35s cubic-bezier(.2,0,0,1),transform .35s cubic-bezier(.2,0,0,1),filter .35s cubic-bezier(.2,0,0,1);@media(max-width:699px){border-radius:12px;will-change:transform,filter}@media(hover:hover){&:hover{translate:0 -6px;transform:scale(1.01);filter:drop-shadow(0 4px 10px rgba(0,0,0,.05)) drop-shadow(0 2px 4px rgba(0,0,0,.02))}}}&.slider__item--transitioning .slider__item-inner{filter:none;transition:none}img,video{display:block;border-radius:16px;cursor:var(--slider-cursor-zoom-in);width:auto;height:auto;max-width:var(--item-max-w);max-height:var(--item-max-h);@media(max-width:699px){width:100%;height:auto;max-width:none;max-height:none}}video{position:absolute;inset:0;width:100%;height:100%;max-width:none;max-height:none;object-fit:cover;opacity:0;transition:opacity .3s ease,filter .25s ease}&.slider__item--active video{opacity:1}&.slider__item--video-ready img{opacity:0}}.slider__track--stack{display:block;overflow:visible;scroll-snap-type:none;gap:0;padding-block:0;margin-block:0;position:relative;isolation:isolate;.slider__stack-stage{position:absolute;top:0}.slider__item{position:absolute;inset:0;margin:auto;width:fit-content;height:fit-content;max-width:100%;max-height:100%;will-change:transform}.slider__item-inner{width:fit-content;height:fit-content;transition:none;@media(hover:hover){&:hover{translate:none;transform:none;filter:drop-shadow(0 6px 24px rgba(0,0,0,.1))}}}picture{display:block;width:fit-content;height:fit-content}.slider__item img{display:block;width:auto;height:auto;max-width:var(--stack-w);max-height:var(--stack-h);cursor:inherit}.slider__item:not(.slider__item--active) .slider__item-inner{box-shadow:0 -4px 16px #00000014}.slider__item--active{cursor:grab;&:active{cursor:grabbing}}}.slider__track--stack-fixed{.slider__item{width:var(--stack-w);height:var(--stack-h)}.slider__item-inner,picture{width:100%;height:100%}.slider__item img{width:100%;height:100%;max-width:none;max-height:none;object-fit:cover}}.slider__track--coverflow{isolation:isolate;padding-block:96px;margin-block:-96px;gap:0;.slider__item{position:relative;scroll-snap-align:center;width:var(--item-max-w);height:var(--item-max-h);max-width:none;margin-inline:calc(var(--item-max-w) * -.08)}.slider__item-inner{width:100%;height:100%;transition:none;will-change:transform;@media(hover:hover){&:hover{translate:none;filter:none}}}picture{display:block;width:100%;height:100%}.slider__item img{width:100%;height:100%;max-width:none;max-height:none;object-fit:cover}}.slider__track--fixed{.slider__item{width:var(--item-max-w);height:var(--item-max-h);max-width:none}.slider__item-inner{width:100%;height:100%}picture{display:block;width:100%;height:100%}.slider__item img{width:100%;height:100%;max-width:none;max-height:none;object-fit:cover}}.slider__meta{margin-top:.75lh;display:flex;align-items:flex-start;justify-content:space-between;gap:1.6rem;h3{color:var(--accent-color);margin:0}p{color:var(--text-color);margin:0}}.slider__meta-inner{display:flex;flex-direction:column;br{display:none}}&.slider--coverflow,&.slider--stack{.slider__meta{justify-content:center}.slider__meta-inner{align-items:center;text-align:center}}.slider__controls{margin-top:1.6rem;display:flex;justify-content:center;align-items:center;gap:.8rem}.slider__nav{display:flex;align-items:center;justify-content:center;width:4rem;height:4rem;padding:0;border:none;border-radius:50%;color:var(--color-text);cursor:pointer;background:color-mix(in srgb,var(--accent-color) 8%,transparent);transition:background .25s ease;@media(hover:hover){&:hover:not(:disabled){background:color-mix(in srgb,var(--accent-color) 15%,transparent)}}&:disabled{opacity:.35;cursor:default}&:focus-visible{outline:2px solid var(--accent-color);outline-offset:2px}}.slider__dots{display:flex;align-items:center;gap:.7rem;height:4rem;padding-inline:1.4rem;border-radius:999px;background:color-mix(in srgb,var(--accent-color) 8%,transparent)}.slider__dot{width:.7rem;height:.7rem;padding:0;border:none;border-radius:999px;cursor:pointer;background:color-mix(in srgb,var(--accent-color) 28%,transparent);transition:background .25s ease,width .25s ease;@media(hover:hover){&:hover{background:color-mix(in srgb,var(--accent-color) 45%,transparent)}}&.slider__dot--active{width:2rem;background:var(--accent-color)}&:focus-visible{outline:2px solid var(--accent-color);outline-offset:2px}}}:root{--lightbox-cursor-zoom-out: url(data:image/svg+xml,%3Csvg%20width%3D%2217%22%20height%3D%2217%22%20viewBox%3D%220%200%2017%2017%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Cpath%20d%3D%22M9.54074%208.48008L13.9602%2012.8995L12.8995%2013.9602L8.48008%209.54074L4.06066%2013.9602L3%2012.8995L7.41942%208.48008L3%204.06066L4.06066%203L8.48008%207.41942L12.8995%203L13.9602%204.06066L9.54074%208.48008Z%22%20fill%3D%22black%22%20stroke%3D%22white%22%20stroke-width%3D%220.3%22%20stroke-linejoin%3D%22round%22%2F%3E%0A%3C%2Fsvg%3E) 8 8, zoom-out}.lightbox{position:fixed;inset:0;z-index:100;display:flex;align-items:center;--lb-caption-space: 8rem;--lb-controls-space: 0rem;padding-bottom:calc(var(--lb-caption-space) + var(--lb-controls-space));--lb-max-width: 95vw;--lb-max-height: calc( 100dvh - 96px - var(--lb-caption-space) - var(--lb-controls-space) );--lb-gap: 1.6rem;--lb-peek: 2.4rem;--lb-item-width: calc(100vw - 2 * (var(--lb-gap) + var(--lb-peek)));@media(min-width:700px){--lb-caption-space: 9.6rem;--lb-max-width: calc(100vw - 80px) ;--lb-max-height: calc( 100dvh - 40px - var(--lb-caption-space) - var(--lb-controls-space) )}&.lightbox--controls{--lb-controls-space: 6.4rem}.lightbox__backdrop{position:absolute;inset:0;background-color:#0000001a;backdrop-filter:blur(20px);cursor:var(--lightbox-cursor-zoom-out)}.lightbox__track{position:relative;display:flex;align-items:flex-end;gap:6.4rem;cursor:var(--lightbox-cursor-zoom-out);@media(max-width:699px){gap:var(--lb-gap)}overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;width:100%;padding-inline:50%;&::-webkit-scrollbar{display:none}}.lightbox__item{flex-shrink:0;width:fit-content;scroll-snap-align:center;position:relative;cursor:pointer;@media(max-width:699px){width:var(--lb-item-width)}}&:not(.lightbox--revealed) .lightbox__item:not(.lightbox__item--active){opacity:0;filter:blur(4px);transform:scale(.92);transition:opacity 1s cubic-bezier(0,.55,.45,1),transform 1s cubic-bezier(0,.55,.45,1),filter 1s cubic-bezier(0,.55,.45,1)}.lightbox__item img,.lightbox__item video{display:block;width:auto;height:auto;max-width:var(--lb-max-width);max-height:var(--lb-max-height);border-radius:12px;user-select:none;-webkit-user-drag:none;@media screen{border-radius:16px}@media(max-width:699px){width:100%;height:auto;max-width:none;max-height:var(--lb-max-height);object-fit:cover}}.lightbox__img{display:block}.lightbox__img--high{position:absolute;inset:0;opacity:0;transition:opacity .4s ease}.lightbox__img--high.lightbox__img--ready{opacity:1}.lightbox__img--high img{width:100%;height:100%;max-width:none;max-height:none;object-fit:cover}.lightbox__item video{position:absolute;inset:0;width:100%;height:100%;max-width:none;max-height:none;object-fit:cover;opacity:0}.lightbox__item--active{cursor:var(--lightbox-cursor-zoom-out);video{opacity:1}}.lightbox__item--video-ready img{opacity:0}&.lightbox--coverflow{.lightbox__track{gap:3.2rem}.lightbox__item{aspect-ratio:var(--lb-item-aspect, 1.5);width:min(calc(var(--lb-max-height) * var(--lb-item-aspect, 1.5)),var(--lb-max-width));height:auto;@media(max-width:699px){width:var(--lb-item-width)}}.lightbox__item-inner{width:100%;height:100%;will-change:transform}.lightbox__img{width:100%;height:100%}.lightbox__item img{width:100%;height:100%;max-width:none;max-height:none;object-fit:cover}}.lightbox__meta{position:fixed;left:0;right:0;bottom:var(--lb-controls-space);height:var(--lb-caption-space);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.2rem;padding:0 2.4rem;text-align:center;pointer-events:none;opacity:0;transition:opacity 1s cubic-bezier(0,.55,.45,1);h2{margin:0;color:var(--accent-color)}p{margin:0;color:var(--text-color)}}.lightbox__controls{display:flex;gap:.8rem;position:fixed;bottom:1.6rem;left:50%;transform:translate(-50%);z-index:10;opacity:0;transition:opacity 1s cubic-bezier(0,.55,.45,1)}.lightbox__close,.lightbox__nav{display:flex;align-items:center;justify-content:center;width:4.4rem;height:4.4rem;padding:0;border:none;border-radius:12px;color:var(--color-text);cursor:pointer;background:color-mix(in srgb,var(--accent-color) 10%,transparent);backdrop-filter:blur(12px)}.lightbox__nav:disabled{opacity:.35;cursor:default}&.lightbox--revealed .lightbox__item{opacity:1;filter:blur(0px);transition:filter .4s cubic-bezier(.25,.46,.45,.94),transform .4s cubic-bezier(.25,.46,.45,.94);video{transition:opacity .3s ease}}&.lightbox--revealed .lightbox__item--active{transform:scale(1)}&.lightbox--revealed .lightbox__controls,&.lightbox--revealed .lightbox__meta{opacity:1}&.lightbox--closing .lightbox__backdrop{opacity:0;transition:opacity .3s cubic-bezier(0,.55,.45,1)}&.lightbox--closing .lightbox__item:not(.lightbox__item--active){opacity:0;filter:blur(4px);transform:scale(.92);transition:opacity .3s cubic-bezier(0,.55,.45,1),filter .3s cubic-bezier(0,.55,.45,1),transform .3s cubic-bezier(0,.55,.45,1)}&.lightbox--closing .lightbox__controls,&.lightbox--closing .lightbox__meta{opacity:0;transition:opacity .3s cubic-bezier(0,.55,.45,1)}&.lightbox--closing .lightbox__item--active{opacity:0;transition:opacity 0s linear .4s}}::view-transition-group(.vitrine-shared){animation-duration:.6s;animation-timing-function:cubic-bezier(.4,0,0,1)}::view-transition-old(.vitrine-shared),::view-transition-new(.vitrine-shared){animation-duration:.6s;animation-timing-function:cubic-bezier(.4,0,0,1)}.morph-cursor{position:fixed;top:0;left:0;z-index:2147483647;pointer-events:none;line-height:0;color:#fff;opacity:0;transition:opacity .15s ease;will-change:transform;filter:drop-shadow(0 0 1px rgba(0,0,0,.9)) drop-shadow(0 0 1px rgba(0,0,0,.6))}.morph-cursor--visible{opacity:1}.slider--morph-cursor .slider__item,.slider--morph-cursor .slider__item img,.slider--morph-cursor .slider__item video,.slider--morph-cursor .lightbox__backdrop,.slider--morph-cursor .lightbox__track,.slider--morph-cursor .lightbox__item,.slider--morph-cursor .lightbox__item--active{cursor:none}.vitrine-video-toggle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%) scale(.9);z-index:4;display:flex;align-items:center;justify-content:center;padding:0;border:none;background:none;color:#fff;cursor:pointer;filter:drop-shadow(0 2px 7px rgba(0,0,0,.5));opacity:0;pointer-events:none;transition:opacity .2s ease,transform .2s ease;&:focus-visible{outline:2px solid rgba(255,255,255,.9);outline-offset:6px;border-radius:50%}}@media(hover:hover){.slider__item--active .slider__item-inner:hover .vitrine-video-toggle,.lightbox__item:hover .vitrine-video-toggle{opacity:1;pointer-events:auto;transform:translate(-50%,-50%) scale(1)}.slider__item--active .slider__item-inner:hover video{filter:blur(3px) brightness(.92)}}.vitrine-lb-video{position:absolute;left:0;right:0;bottom:0;padding:0 1.4rem 1.2rem;color:#fff;cursor:auto;pointer-events:none;opacity:0;transition:opacity .3s ease}.lightbox__item--video-ready .vitrine-lb-video{opacity:1}.vitrine-lb-video__bar{display:flex;align-items:center;justify-content:space-between;gap:1.2rem;margin-bottom:.7rem;opacity:0;transform:translateY(6px);pointer-events:none;filter:drop-shadow(0 1px 4px rgba(0,0,0,.5));transition:opacity .25s ease,transform .25s ease}.vitrine-lb-video__time{font-size:1.3rem;font-variant-numeric:tabular-nums;letter-spacing:-.01em;text-shadow:0 1px 3px rgba(0,0,0,.5)}.vitrine-lb-video__actions{display:flex;align-items:center;gap:.4rem}.vitrine-lb-video__btn{display:flex;align-items:center;justify-content:center;width:3rem;height:3rem;padding:0;border:none;border-radius:50%;color:inherit;background:none;cursor:pointer;transition:background .2s ease;@media(hover:hover){&:hover{background:#ffffff2e}}&:focus-visible{outline:2px solid #fff;outline-offset:1px}}.vitrine-lb-video__progress{position:relative;height:3px;border-radius:999px;background:#ffffff4d;cursor:pointer;pointer-events:auto;mix-blend-mode:difference;backdrop-filter:saturate(.6) blur(2px);-webkit-backdrop-filter:saturate(.6) blur(2px);touch-action:none;transition:height .2s ease;&:before{content:"";position:absolute;inset:-9px 0}&:focus-visible{outline:2px solid #fff;outline-offset:3px}}.vitrine-lb-video__preview{position:absolute;left:0;top:0;width:0;height:100%;border-radius:inherit;background:#fff6;opacity:0;transition:opacity .15s ease}.vitrine-lb-video__progress-fill{position:absolute;left:0;top:0;height:100%;border-radius:inherit;background:#fff}@media(hover:hover){.vitrine-lb-video__progress:hover .vitrine-lb-video__preview{opacity:1}}@media(hover:hover){.lightbox__item:hover .vitrine-lb-video__bar{opacity:1;transform:none;pointer-events:auto}.lightbox__item:hover .vitrine-lb-video__progress{height:5px}}.lightbox__item--show-controls .vitrine-video-toggle{opacity:1;pointer-events:auto;transform:translate(-50%,-50%) scale(1)}.lightbox__item--show-controls .vitrine-lb-video__bar{opacity:1;transform:none;pointer-events:auto}.lightbox__item--show-controls .vitrine-lb-video__progress{height:5px}
package/index.d.ts CHANGED
@@ -22,10 +22,17 @@ export interface SliderItem {
22
22
  highResSrc?: string;
23
23
  highResSrcSet?: string;
24
24
  highResWebpSrcSet?: string;
25
- /** Looping muted video URL; autoplays only while the panel is active. */
25
+ /**
26
+ * Looping muted video URL; autoplays only while the panel is active.
27
+ * Ignored by the `stack` and `coverflow` track variants (poster only) —
28
+ * the coverflow lightbox still plays it.
29
+ */
26
30
  video?: string;
27
31
  }
28
32
 
33
+ /** Track layout of the slider. */
34
+ export type SliderVariant = "row" | "stack" | "coverflow";
35
+
29
36
  /** Props passed to the `Caption` component (matching metamorphosis's `TextMorph`). */
30
37
  export interface CaptionProps {
31
38
  as?: ElementType;
@@ -35,6 +42,15 @@ export interface CaptionProps {
35
42
  export interface SliderProps {
36
43
  /** The panels. */
37
44
  items: SliderItem[];
45
+ /**
46
+ * Track layout: the scroll-snap carousel (default), a deck-cycling card
47
+ * stack, or a 3D coverflow. Stack and coverflow ignore `item.video` in the
48
+ * track (poster only). The stack has no lightbox (`lightbox` is ignored;
49
+ * clicking the top card fires `onItemClick` if given). The coverflow
50
+ * lightbox mirrors the track's styling: cover-cropped boxes and 3D-rotated
51
+ * neighbors. Default `"row"`.
52
+ */
53
+ variant?: SliderVariant;
38
54
  /** Desktop width (px) of the active panel's content column. Default `628`. */
39
55
  contentWidth?: number;
40
56
  /** Desktop gap (px) between panels. Default `32`. */
@@ -47,6 +63,13 @@ export interface SliderProps {
47
63
  sideMargin?: number;
48
64
  /** Max height (px) of a panel; taller images scale down keeping ratio. Default `520`. */
49
65
  maxItemHeight?: number;
66
+ /**
67
+ * Force every panel into a fixed width/height box (cover-cropped): a number
68
+ * (`1.5`) or ratio string (`"16/9"`, `"3:2"`). Off by default — `row` and
69
+ * `stack` keep each image's own aspect ratio. `coverflow` always uses a
70
+ * fixed box (default ≈ 3:4) and this overrides it. Bounded by `maxItemHeight`.
71
+ */
72
+ aspectRatio?: number | string;
50
73
  /** `sizes` hint for the panel `<img>`. */
51
74
  sizes?: string;
52
75
  /** `sizes` hint forwarded to the lightbox images. Default `"84vw"`. */
@@ -57,6 +80,48 @@ export interface SliderProps {
57
80
  * `PlainCaption` (or your own) to opt out of the animation.
58
81
  */
59
82
  Caption?: ComponentType<CaptionProps>;
83
+ /**
84
+ * Set `false` to disable the lightbox entirely: clicking a panel no longer
85
+ * zooms; the active panel's click instead fires `onItemClick` (if given).
86
+ * Ignored by `variant="stack"`, which never has a lightbox.
87
+ * Default `true`.
88
+ */
89
+ lightbox?: boolean;
90
+ /**
91
+ * Show prev / close / next buttons in the lightbox (on all breakpoints).
92
+ * Default `false`.
93
+ */
94
+ lightboxControls?: boolean;
95
+ /** Called with `(item, index)` when the active panel is clicked and the lightbox is disabled (or the variant is `"stack"`). */
96
+ onItemClick?: (item: SliderItem, index: number) => void;
97
+ /**
98
+ * Endless scroll: the item array loops seamlessly. Arrow keys and the
99
+ * `arrows` buttons wrap when looping. Defaults on for `"stack"` and
100
+ * `"coverflow"`, off for `"row"`.
101
+ */
102
+ loop?: boolean;
103
+ /** Show prev/next buttons beside the caption. Default `false`. */
104
+ arrows?: boolean;
105
+ /**
106
+ * Show one dot per panel beside the caption; the active dot tracks
107
+ * scrolling and clicking a dot navigates. Default `false`.
108
+ */
109
+ pagination?: boolean;
110
+ /**
111
+ * Video playback UI. On the slider panel: hovering the active panel reveals a
112
+ * morphing play/pause toggle (and softly blurs the clip). In the lightbox: a
113
+ * centered play/pause toggle plus a progress bar that glides with playback
114
+ * and previews the seek target on hover — and, unless set to `"minimal"`,
115
+ * expands on hover into a timestamp plus mute, picture-in-picture, and
116
+ * fullscreen controls. `"minimal"` keeps only the play/pause + progress bar.
117
+ * Videos still autoplay muted. Default `false`.
118
+ */
119
+ videoControls?: boolean | "minimal";
120
+ /**
121
+ * Override the auto-generated per-instance shared-element
122
+ * view-transition name.
123
+ */
124
+ transitionName?: string;
60
125
  /**
61
126
  * Replace the static SVG cursors with a morphing icon cursor that follows the
62
127
  * pointer (metamorphosis `IconMorph`): `+` over a slider panel, `×` over the
@@ -79,6 +144,29 @@ export interface LightboxProps {
79
144
  activeIndex: number;
80
145
  /** `sizes` hint for the images. Default `"84vw"`. */
81
146
  sizes?: string;
147
+ /** Caption renderer (takes `as` + `children`); defaults to metamorphosis's morphing `TextMorph`. */
148
+ Caption?: ComponentType<CaptionProps>;
149
+ /** Render the prev / close / next buttons (on all breakpoints). Default `false`. */
150
+ controls?: boolean;
151
+ /** Play/pause toggle + progress bar over the active video item; unless `"minimal"`, the bar expands on hover into timestamp + mute / PiP / fullscreen. Default `false`. */
152
+ videoControls?: boolean | "minimal";
153
+ /**
154
+ * Shared-element view-transition name; `<Slider>` passes its per-instance
155
+ * name. Default `"slider-active"`.
156
+ */
157
+ transitionName?: string;
158
+ /**
159
+ * Mirror the coverflow track: items become uniform cover-cropped boxes and
160
+ * neighbors carry the 3D rotation. Default `false`.
161
+ */
162
+ coverflow?: boolean;
163
+ /** Box ratio (w/h) for coverflow items; `<Slider>` captures it from the active card at open time. */
164
+ itemAspect?: number;
165
+ /**
166
+ * Endless scroll, mirroring the slider's loop state: the item array loops
167
+ * and arrow keys / controls wrap. Default `false`.
168
+ */
169
+ loop?: boolean;
82
170
  /** Called with the new index as the user scrolls. */
83
171
  onActiveIndexChange?: (index: number) => void;
84
172
  /** Called to dismiss the lightbox. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ocarignan/vitrine",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "A draggable project slider with a shared-element zoom lightbox for React. Self-contained, prop-driven, installable from npm.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -41,7 +41,7 @@
41
41
  "react-dom": ">=18"
42
42
  },
43
43
  "dependencies": {
44
- "@ocarignan/metamorphosis": "^0.1.0",
44
+ "@ocarignan/metamorphosis": "^0.1.1",
45
45
  "motion": "^12.19.1"
46
46
  },
47
47
  "devDependencies": {