Bundle data extracted to src/api/bundles.js (single source of truth shared by HomePage's grid and the new BundlePage). Each card on the home grid now links to the bundle's detail route. BundleCard's `imageFit` default flipped to `cover` to match the new /bundles/background/* artwork — full-bleed lifestyle scenes instead of padded product line-ups. The `contain` mode stays available for future bundles whose art needs breathing room. BundlePage layout: split brand-green hero with the bundle artwork on the left, name + items list (linking to component product pages where matched) + pricing + qty + add-to-cart on the right. Mirrors ProductPage chrome (Navbar, dynamic back button, CartDrawer) so the detail-page experience reads as one piece across SKUs and bundles. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 line
1.7 KiB
JavaScript
1 line
1.7 KiB
JavaScript
import{B as e,C as t,E as n,T as r,dt as i,ft as a,m as o,o as s,p as c,r as l,s as u,u as d,ut as f}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{t as p}from"./Icon-BCo6-bGH.js";var m={class:`flex items-center gap-3 mb-4 flex-wrap`},h={role:`tablist`,"aria-label":`Preview viewport`,class:`inline-flex items-center p-1 gap-0.5 rounded-pill border border-line bg-paper ml-auto`},g=[`aria-selected`,`onClick`],_={class:`rounded-md border border-line bg-surface p-6 overflow-x-auto`},v=[`src`,`title`],y={class:`mt-2 text-center font-mono text-[11px] text-muted`},b={__name:`DevicePreview`,props:{src:{type:String,required:!0},initial:{type:String,default:`desktop`,validator:e=>[`mobile`,`tablet`,`desktop`].includes(e)},height:{type:Number,default:560}},setup(b){let x=b,S=[{id:`mobile`,label:`Mobile`,width:390},{id:`tablet`,label:`Tablet`,width:820},{id:`desktop`,label:`Desktop`,width:1280}],C=e(x.initial),w=s(()=>S.find(e=>e.id===C.value));return(e,s)=>(t(),d(`div`,null,[u(`div`,m,[n(e.$slots,`controls`),u(`div`,h,[(t(),d(l,null,r(S,e=>u(`button`,{key:e.id,type:`button`,role:`tab`,"aria-selected":C.value===e.id,class:f([`inline-flex items-center gap-2 px-3 py-1.5 text-[12px] font-semibold tracking-label rounded-pill transition-colors duration-base`,C.value===e.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:t=>C.value=e.id},[o(p,{name:e.id,size:14},null,8,[`name`]),c(` `+a(e.label),1)],10,g)),64))])]),u(`div`,_,[u(`div`,{class:`mx-auto transition-[width] duration-base ease-out`,style:i({width:w.value.width+`px`})},[u(`iframe`,{src:b.src,title:`${w.value.label} preview`,style:i({height:b.height+`px`}),class:`w-full block rounded-sm border border-line bg-paper`,loading:`lazy`},null,12,v),u(`p`,y,a(w.value.width)+`px `,1)],4)])]))}};export{b as t}; |