changes since conversation categories and layout fixes andshop
This commit is contained in:
1
dist/assets/About--uXlb06p.js
vendored
1
dist/assets/About--uXlb06p.js
vendored
@@ -1 +0,0 @@
|
||||
import{C as e,T as t,c as n,j as r,l as i,lt as a,p as o,r as s,s as c,st as l,u}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as d}from"./_plugin-vue_export-helper-BOai-rQB.js";import{t as f}from"./Badge-DcvgVKep.js";var p={id:`about`,class:`bg-cream text-ink`},m={class:`mx-auto w-full max-w-6xl px-6 py-16 sm:px-8 sm:py-20 md:px-12 md:py-24 lg:px-16 lg:py-28`},h={class:`flex flex-col items-center text-center gap-4 max-w-3xl mx-auto`},g={key:1,class:`font-display font-normal leading-[1.05] tracking-tight text-ink`,style:{"font-size":`clamp(2.25rem, 5vw, 3.75rem)`}},_={key:2,class:`text-lg leading-relaxed text-muted max-w-2xl`},v={key:0,class:`timeline-track hidden md:grid md:grid-cols-3 mt-16`,"aria-hidden":`true`},y={key:1,class:`timeline-list mt-6 md:mt-8 grid gap-0 md:gap-6 md:grid-cols-3`},b={class:`timeline-mobile-marker`},x=d({__name:`About`,props:{eyebrow:{type:String,default:``},headline:{type:String,default:``},sub:{type:String,default:``},milestones:{type:Array,default:()=>[],validator:e=>e.every(e=>e&&typeof e==`object`&&typeof e.year==`string`&&typeof e.title==`string`&&typeof e.text==`string`)}},setup(d){let x=[{card:`bg-cream border-line`,title:`text-ink`,body:`text-muted`,pill:`pill-paper`},{card:`bg-paper border-line`,title:`text-ink`,body:`text-muted`,pill:`pill-brand-soft`},{card:`bg-brand border-transparent`,title:`text-cream`,body:`text-cream/80`,pill:`pill-accent`}];return(S,C)=>(e(),u(`section`,p,[c(`div`,m,[c(`div`,h,[d.eyebrow?(e(),n(f,{key:0,variant:`brand`},{default:r(()=>[o(a(d.eyebrow),1)]),_:1})):i(``,!0),d.headline?(e(),u(`h2`,g,a(d.headline),1)):i(``,!0),d.sub?(e(),u(`p`,_,a(d.sub),1)):i(``,!0)]),d.milestones.length?(e(),u(`div`,v,[(e(!0),u(s,null,t(d.milestones.slice(0,3),(t,n)=>(e(),u(`div`,{key:`track-`+n,class:`timeline-cell`},[c(`span`,{class:l([`timeline-pill`,x[n].pill])},a(t.year),3)]))),128))])):i(``,!0),d.milestones.length?(e(),u(`ol`,y,[(e(!0),u(s,null,t(d.milestones.slice(0,3),(t,n)=>(e(),u(`li`,{key:t.year+t.title,class:`timeline-item flex flex-col`},[c(`div`,b,[c(`span`,{class:l([`timeline-pill`,x[n].pill])},a(t.year),3)]),c(`div`,{class:l([`flex flex-col gap-3 rounded-md border p-6 md:p-7`,x[n].card])},[c(`h3`,{class:l([`font-display text-2xl font-normal leading-tight`,x[n].title])},a(t.title),3),c(`p`,{class:l([`text-sm leading-relaxed`,x[n].body])},a(t.text),3)],2)]))),128))])):i(``,!0)])]))}},[[`__scopeId`,`data-v-39877af8`]]);export{x as t};
|
||||
@@ -1 +1 @@
|
||||
.timeline-pill[data-v-39877af8]{border-radius:var(--radius-pill);font-family:var(--font-sans);letter-spacing:var(--tracking-eyebrow);text-transform:uppercase;white-space:nowrap;z-index:1;border:1px solid #0000;justify-content:center;align-items:center;padding:.375rem .875rem;font-size:.75rem;font-weight:700;display:inline-flex;position:relative}.pill-paper[data-v-39877af8]{background:var(--color-paper);color:var(--color-brand);border-color:var(--color-line-strong)}.pill-brand-soft[data-v-39877af8]{background:color-mix(in srgb, var(--color-brand) 14%, var(--color-cream));color:var(--color-brand);border-color:color-mix(in srgb, var(--color-brand) 28%, transparent)}.pill-accent[data-v-39877af8]{background:var(--color-accent);color:var(--color-brand);border-color:color-mix(in srgb, var(--color-accent) 70%, var(--color-brand))}.timeline-track[data-v-39877af8]{align-items:center;margin-bottom:.5rem;position:relative}.timeline-track[data-v-39877af8]:before{content:"";background:var(--color-line-strong);height:1px;position:absolute;top:50%;left:16.6667%;right:16.6667%;transform:translateY(-.5px)}.timeline-cell[data-v-39877af8]{justify-content:center;display:flex}@media (width<=767px){.timeline-mobile-marker[data-v-39877af8]{justify-content:center;align-items:center;padding:1.75rem 0;display:flex;position:relative}.timeline-mobile-marker[data-v-39877af8]:before{content:"";background:var(--color-line-strong);width:1px;position:absolute;top:0;bottom:50%;left:50%;transform:translate(-.5px)}.timeline-mobile-marker[data-v-39877af8]:after{content:"";background:var(--color-line-strong);width:1px;position:absolute;top:50%;bottom:0;left:50%;transform:translate(-.5px)}.timeline-item:first-child .timeline-mobile-marker[data-v-39877af8]:before{display:none}}@media (width>=768px){.timeline-mobile-marker[data-v-39877af8]{display:none}}
|
||||
.timeline-pill[data-v-7d574710]{border-radius:var(--radius-pill);font-family:var(--font-sans);letter-spacing:var(--tracking-eyebrow);text-transform:uppercase;white-space:nowrap;z-index:1;border:1px solid #0000;justify-content:center;align-items:center;padding:.375rem .875rem;font-size:.75rem;font-weight:700;display:inline-flex;position:relative}.pill-paper[data-v-7d574710]{background:var(--color-paper);color:var(--color-brand);border-color:var(--color-line-strong)}.pill-brand-soft[data-v-7d574710]{background:color-mix(in srgb, var(--color-brand) 14%, var(--color-cream));color:var(--color-brand);border-color:color-mix(in srgb, var(--color-brand) 28%, transparent)}.pill-accent[data-v-7d574710]{background:var(--color-accent);color:var(--color-brand);border-color:color-mix(in srgb, var(--color-accent) 70%, var(--color-brand))}.timeline-track[data-v-7d574710]{align-items:center;margin-bottom:.5rem;position:relative}.timeline-track[data-v-7d574710]:before{content:"";background:var(--color-line-strong);height:1px;position:absolute;top:50%;left:16.6667%;right:16.6667%;transform:translateY(-.5px)}.timeline-cell[data-v-7d574710]{justify-content:center;display:flex}@media (width<=767px){.timeline-mobile-marker[data-v-7d574710]{justify-content:center;align-items:center;padding:1.75rem 0;display:flex;position:relative}.timeline-mobile-marker[data-v-7d574710]:before{content:"";background:var(--color-line-strong);width:1px;position:absolute;top:0;bottom:50%;left:50%;transform:translate(-.5px)}.timeline-mobile-marker[data-v-7d574710]:after{content:"";background:var(--color-line-strong);width:1px;position:absolute;top:50%;bottom:0;left:50%;transform:translate(-.5px)}.timeline-item:first-child .timeline-mobile-marker[data-v-7d574710]:before{display:none}}@media (width>=768px){.timeline-mobile-marker[data-v-7d574710]{display:none}}
|
||||
1
dist/assets/About-rqnuePZN.js
vendored
Normal file
1
dist/assets/About-rqnuePZN.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{C as e,T as t,c as n,j as r,l as i,lt as a,p as o,r as s,s as c,st as l,u}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as d}from"./_plugin-vue_export-helper-BOai-rQB.js";import{t as f}from"./Badge-DcvgVKep.js";var p={id:`about`,class:`bg-cream text-ink`},m={class:`mx-auto w-full max-w-6xl px-6 py-16 sm:px-8 sm:py-20 md:px-12 md:py-24 lg:px-16 lg:py-28`},h={class:`flex flex-col items-center text-center gap-4 max-w-3xl mx-auto`},g={key:1,class:`font-display font-normal leading-[1.05] tracking-tight text-ink text-headline-lg`},_={key:2,class:`text-lg leading-relaxed text-muted max-w-2xl`},v={key:0,class:`timeline-track hidden md:grid md:grid-cols-3 mt-16`,"aria-hidden":`true`},y={key:1,class:`timeline-list mt-6 md:mt-8 grid gap-0 md:gap-6 md:grid-cols-3`},b={class:`timeline-mobile-marker`},x=d({__name:`About`,props:{eyebrow:{type:String,default:``},headline:{type:String,default:``},sub:{type:String,default:``},milestones:{type:Array,default:()=>[],validator:e=>e.every(e=>e&&typeof e==`object`&&typeof e.year==`string`&&typeof e.title==`string`&&typeof e.text==`string`)}},setup(d){let x=[{card:`bg-cream border-line`,title:`text-ink`,body:`text-muted`,pill:`pill-paper`},{card:`bg-paper border-line`,title:`text-ink`,body:`text-muted`,pill:`pill-brand-soft`},{card:`bg-brand border-transparent`,title:`text-cream`,body:`text-cream/80`,pill:`pill-accent`}];return(S,C)=>(e(),u(`section`,p,[c(`div`,m,[c(`div`,h,[d.eyebrow?(e(),n(f,{key:0,variant:`brand`},{default:r(()=>[o(a(d.eyebrow),1)]),_:1})):i(``,!0),d.headline?(e(),u(`h2`,g,a(d.headline),1)):i(``,!0),d.sub?(e(),u(`p`,_,a(d.sub),1)):i(``,!0)]),d.milestones.length?(e(),u(`div`,v,[(e(!0),u(s,null,t(d.milestones.slice(0,3),(t,n)=>(e(),u(`div`,{key:`track-`+n,class:`timeline-cell`},[c(`span`,{class:l([`timeline-pill`,x[n].pill])},a(t.year),3)]))),128))])):i(``,!0),d.milestones.length?(e(),u(`ol`,y,[(e(!0),u(s,null,t(d.milestones.slice(0,3),(t,n)=>(e(),u(`li`,{key:t.year+t.title,class:`timeline-item flex flex-col md:h-full`},[c(`div`,b,[c(`span`,{class:l([`timeline-pill`,x[n].pill])},a(t.year),3)]),c(`div`,{class:l([`flex flex-col gap-3 rounded-md border p-6 md:p-7 md:flex-1 md:h-full`,x[n].card])},[c(`h3`,{class:l([`font-display text-2xl font-normal leading-tight`,x[n].title])},a(t.title),3),c(`p`,{class:l([`text-sm leading-relaxed`,x[n].body])},a(t.text),3)],2)]))),128))])):i(``,!0)])]))}},[[`__scopeId`,`data-v-7d574710`]]);export{x as t};
|
||||
@@ -1 +1 @@
|
||||
import{C as e,G as t,m as n,o as r,u as i}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as a}from"./i18n-DrTQks20.js";import{t as o}from"./About--uXlb06p.js";var s={class:`min-h-screen bg-cream`},c={__name:`AboutPreview`,setup(c){let{t:l}=a(),u=r(()=>[1,2,3].map(e=>({year:l(`about.milestone.${e}.year`),title:l(`about.milestone.${e}.title`),text:l(`about.milestone.${e}.text`)})));return(r,a)=>(e(),i(`div`,s,[n(o,{eyebrow:t(l)(`about.eyebrow`),headline:t(l)(`about.headline`),sub:t(l)(`about.sub`),milestones:u.value},null,8,[`eyebrow`,`headline`,`sub`,`milestones`])]))}};export{c as default};
|
||||
import{C as e,G as t,m as n,o as r,u as i}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as a}from"./i18n-CJQl3WLC.js";import{t as o}from"./About-rqnuePZN.js";var s={class:`min-h-screen bg-cream`},c={__name:`AboutPreview`,setup(c){let{t:l}=a(),u=r(()=>[1,2,3].map(e=>({year:l(`about.milestone.${e}.year`),title:l(`about.milestone.${e}.title`),text:l(`about.milestone.${e}.text`)})));return(r,a)=>(e(),i(`div`,s,[n(o,{eyebrow:t(l)(`about.eyebrow`),headline:t(l)(`about.headline`),sub:t(l)(`about.sub`),milestones:u.value},null,8,[`eyebrow`,`headline`,`sub`,`milestones`])]))}};export{c as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,p as o,s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as c}from"./i18n-DrTQks20.js";import{t as l}from"./SectionShell-BEISUYi8.js";import{t as u}from"./DevicePreview-DvIWByfU.js";var d={class:`eyebrow mb-5`},f=`/design/preview/about`,p={__name:`AboutSection`,setup(p){let{t:m}=c();return(c,p)=>(e(),n(l,{eyebrow:t(m)(`ds.eyebrow.components`),title:t(m)(`ds.about.title`),description:t(m)(`ds.about.description`),wide:``},{default:r(()=>[s(`section`,null,[a(u,{src:f,initial:`desktop`,height:820})]),s(`section`,null,[s(`h2`,d,i(t(m)(`ds.heading.usage`)),1),p[0]||=s(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[s(`pre`,{class:`whitespace-pre-wrap`},`<About
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,p as o,s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as c}from"./i18n-CJQl3WLC.js";import{t as l}from"./SectionShell-Cd_Fu3uI.js";import{t as u}from"./DevicePreview-Dx8DzWeH.js";var d={class:`eyebrow mb-5`},f=`/design/preview/about`,p={__name:`AboutSection`,setup(p){let{t:m}=c();return(c,p)=>(e(),n(l,{eyebrow:t(m)(`ds.eyebrow.components`),title:t(m)(`ds.about.title`),description:t(m)(`ds.about.description`),wide:``},{default:r(()=>[s(`section`,null,[a(u,{src:f,initial:`desktop`,height:820})]),s(`section`,null,[s(`h2`,d,i(t(m)(`ds.heading.usage`)),1),p[0]||=s(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[s(`pre`,{class:`whitespace-pre-wrap`},`<About
|
||||
:eyebrow="t('about.eyebrow')"
|
||||
:headline="t('about.headline')"
|
||||
:sub="t('about.sub')"
|
||||
@@ -1 +1 @@
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,p as o,s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as c}from"./i18n-DrTQks20.js";import{t as l}from"./Badge-DcvgVKep.js";import{t as u}from"./SectionShell-BEISUYi8.js";import{t as d}from"./Card-DM27vc3f.js";var f={class:`eyebrow mb-5`},p={class:`flex flex-wrap gap-3`},m={class:`eyebrow mb-5`},h={class:`flex flex-wrap gap-3`},g={__name:`BadgesSection`,setup(g){let{t:_}=c();return(c,g)=>(e(),n(u,{eyebrow:t(_)(`ds.eyebrow.components`),title:t(_)(`ds.badges.title`),description:t(_)(`ds.badges.description`)},{default:r(()=>[s(`section`,null,[s(`h2`,f,i(t(_)(`ds.heading.variants`)),1),a(d,{tone:`paper`},{default:r(()=>[s(`div`,p,[a(l,{variant:`neutral`},{default:r(()=>[o(i(t(_)(`ds.badges.neutral`)),1)]),_:1}),a(l,{variant:`brand`},{default:r(()=>[o(i(t(_)(`ds.badges.brand`)),1)]),_:1}),a(l,{variant:`accent`},{default:r(()=>[o(i(t(_)(`ds.badges.accent`)),1)]),_:1}),a(l,{variant:`subtle`},{default:r(()=>[o(i(t(_)(`ds.badges.subtle`)),1)]),_:1}),a(l,{variant:`success`},{default:r(()=>[o(i(t(_)(`ds.badges.success`)),1)]),_:1}),a(l,{variant:`warning`},{default:r(()=>[o(i(t(_)(`ds.badges.warning`)),1)]),_:1}),a(l,{variant:`danger`},{default:r(()=>[o(i(t(_)(`ds.badges.danger`)),1)]),_:1})])]),_:1})]),s(`section`,null,[s(`h2`,m,i(t(_)(`ds.heading.nonUppercase`)),1),a(d,{tone:`paper`},{default:r(()=>[s(`div`,h,[a(l,{variant:`brand`,uppercase:!1},{default:r(()=>[o(i(t(_)(`ds.badges.newRelease`)),1)]),_:1}),a(l,{variant:`accent`,uppercase:!1},{default:r(()=>[o(i(t(_)(`ds.badges.featured`)),1)]),_:1}),a(l,{variant:`subtle`,uppercase:!1},{default:r(()=>[...g[0]||=[o(`v2.1.0`,-1)]]),_:1})])]),_:1})])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{g as default};
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,p as o,s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as c}from"./i18n-CJQl3WLC.js";import{t as l}from"./Badge-DcvgVKep.js";import{t as u}from"./SectionShell-Cd_Fu3uI.js";import{t as d}from"./Card-pgd8VnYH.js";var f={class:`eyebrow mb-5`},p={class:`flex flex-wrap gap-3`},m={class:`eyebrow mb-5`},h={class:`flex flex-wrap gap-3`},g={__name:`BadgesSection`,setup(g){let{t:_}=c();return(c,g)=>(e(),n(u,{eyebrow:t(_)(`ds.eyebrow.components`),title:t(_)(`ds.badges.title`),description:t(_)(`ds.badges.description`)},{default:r(()=>[s(`section`,null,[s(`h2`,f,i(t(_)(`ds.heading.variants`)),1),a(d,{tone:`paper`},{default:r(()=>[s(`div`,p,[a(l,{variant:`neutral`},{default:r(()=>[o(i(t(_)(`ds.badges.neutral`)),1)]),_:1}),a(l,{variant:`brand`},{default:r(()=>[o(i(t(_)(`ds.badges.brand`)),1)]),_:1}),a(l,{variant:`accent`},{default:r(()=>[o(i(t(_)(`ds.badges.accent`)),1)]),_:1}),a(l,{variant:`subtle`},{default:r(()=>[o(i(t(_)(`ds.badges.subtle`)),1)]),_:1}),a(l,{variant:`success`},{default:r(()=>[o(i(t(_)(`ds.badges.success`)),1)]),_:1}),a(l,{variant:`warning`},{default:r(()=>[o(i(t(_)(`ds.badges.warning`)),1)]),_:1}),a(l,{variant:`danger`},{default:r(()=>[o(i(t(_)(`ds.badges.danger`)),1)]),_:1})])]),_:1})]),s(`section`,null,[s(`h2`,m,i(t(_)(`ds.heading.nonUppercase`)),1),a(d,{tone:`paper`},{default:r(()=>[s(`div`,h,[a(l,{variant:`brand`,uppercase:!1},{default:r(()=>[o(i(t(_)(`ds.badges.newRelease`)),1)]),_:1}),a(l,{variant:`accent`,uppercase:!1},{default:r(()=>[o(i(t(_)(`ds.badges.featured`)),1)]),_:1}),a(l,{variant:`subtle`,uppercase:!1},{default:r(()=>[...g[0]||=[o(`v2.1.0`,-1)]]),_:1})])]),_:1})])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{g as default};
|
||||
@@ -1 +1 @@
|
||||
import{C as e,G as t,O as n,T as r,c as i,j as a,l as o,lt as s,m as c,o as l,p as u,r as d,s as f,st as p,u as m}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as h}from"./Icon-BCRRMV3J.js";import{t as g}from"./i18n-DrTQks20.js";import{t as _}from"./Badge-DcvgVKep.js";import{t as v}from"./Button-DkdaDkuf.js";var y=[`src`,`alt`],b={class:`flex flex-col gap-1.5`},x={key:0,class:`text-xs font-semibold tracking-label text-muted uppercase`},S={class:`flex flex-col gap-1.5`},C={key:0,class:`text-sm text-muted tracking-label`},w={class:`flex flex-col gap-0.5`},T={class:`text-xs tracking-label text-muted uppercase`},E={class:`font-display text-2xl font-normal text-brand leading-none`},D={key:0,class:`text-xs text-muted mt-1`},O={key:1,class:`text-xs font-semibold tracking-label uppercase text-danger mt-1`},k=3,A={__name:`BundleCard`,props:{name:{type:String,required:!0},items:{type:Array,required:!0},price:{type:Number,required:!0},memberPrice:{type:Number,default:null},usage:{type:String,default:``},image:{type:String,required:!0},imageAlt:{type:String,default:``},badge:{type:String,default:``},badgeVariant:{type:String,default:`accent`,validator:e=>[`neutral`,`brand`,`accent`,`subtle`,`success`,`warning`,`danger`].includes(e)},tone:{type:String,default:`paper`,validator:e=>[`paper`,`cream`].includes(e)},layout:{type:String,default:`vertical`,validator:e=>[`vertical`,`horizontal`].includes(e)},inStock:{type:Boolean,default:!0},currency:{type:String,default:`€`},href:{type:String,default:``}},emits:[`add`],setup(A){let j=A,{t:M}=g(),N={paper:{surface:`bg-paper`,media:`bg-cream`,border:`border-line`},cream:{surface:`bg-cream`,media:`bg-paper`,border:`border-line`}},P=l(()=>N[j.tone]);function F(e){return`${j.currency} ${e.toFixed(2).replace(`.`,`,`)}`}let I=l(()=>F(j.price)),L=l(()=>j.memberPrice==null?``:F(j.memberPrice)),R=l(()=>j.items.slice(0,k)),z=l(()=>Math.max(0,j.items.length-k));return(l,g)=>(e(),m(`article`,{class:p([`group flex overflow-hidden rounded-md border transition-all duration-base ease-out`,A.layout===`horizontal`?`flex-col md:flex-row`:`flex-col`,P.value.surface,P.value.border,`hover:-translate-y-1 hover:shadow-md hover:border-brand-soft`])},[(e(),i(n(A.href?`a`:`div`),{href:A.href||null,class:p([`relative block overflow-hidden`,A.layout===`horizontal`?`aspect-[4/3] md:aspect-auto md:w-[38%] md:shrink-0 md:min-h-[300px]`:`aspect-[4/3]`,P.value.media])},{default:a(()=>[A.badge?(e(),i(_,{key:0,variant:A.badgeVariant,class:`absolute top-4 left-4 z-[1]`},{default:a(()=>[u(s(A.badge),1)]),_:1},8,[`variant`])):o(``,!0),f(`img`,{src:A.image,alt:A.imageAlt||A.name,loading:`lazy`,decoding:`async`,class:p([`absolute inset-0 w-full h-full object-contain transition-transform duration-slow ease-out group-hover:scale-105`,A.layout===`horizontal`?`p-6 md:p-5`:`p-8`])},null,10,y)]),_:1},8,[`href`,`class`])),f(`div`,{class:p([`flex flex-col gap-4 p-6`,A.layout===`horizontal`?`md:p-6 md:flex-1`:``])},[f(`div`,b,[A.usage?(e(),m(`span`,x,s(A.usage),1)):o(``,!0),(e(),i(n(A.href?`a`:`h3`),{href:A.href||null,class:p([`font-display text-xl font-normal leading-tight text-ink`,A.href?`hover:text-brand transition-colors duration-base`:``])},{default:a(()=>[u(s(A.name),1)]),_:1},8,[`href`,`class`]))]),f(`ul`,S,[(e(!0),m(d,null,r(R.value,t=>(e(),m(`li`,{key:t,class:`text-sm text-ink/80 leading-relaxed`},s(t),1))),128)),z.value>0?(e(),m(`li`,C,`+ `+s(z.value)+` `+s(t(M)(`bundles.card.moreItems`)),1)):o(``,!0)]),f(`div`,{class:p([`mt-auto pt-4 border-t border-line flex gap-3`,A.layout===`horizontal`?`flex-col sm:flex-row sm:items-end sm:justify-between`:`flex-col`])},[f(`div`,w,[f(`span`,T,s(t(M)(`bundles.card.priceLabel`)),1),f(`span`,E,s(I.value),1),L.value?(e(),m(`span`,D,s(t(M)(`bundles.card.memberPrefix`))+` `+s(L.value),1)):o(``,!0),A.inStock?o(``,!0):(e(),m(`span`,O,s(t(M)(`ds.product.outOfStock`)),1))]),c(v,{variant:`primary`,size:`md`,block:A.layout===`vertical`,disabled:!A.inStock,onClick:g[0]||=e=>l.$emit(`add`)},{before:a(()=>[c(h,{name:`plus`,size:16})]),default:a(()=>[u(` `+s(t(M)(`ds.buttons.addToCart`)),1)]),_:1},8,[`block`,`disabled`])],2)],2)],2))}};export{A as t};
|
||||
import{C as e,G as t,O as n,T as r,c as i,j as a,l as o,lt as s,m as c,o as l,p as u,r as d,s as f,st as p,u as m}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as h}from"./Icon-BCRRMV3J.js";import{t as g}from"./i18n-CJQl3WLC.js";import{t as _}from"./Badge-DcvgVKep.js";import{t as v}from"./Button-DkdaDkuf.js";var y=[`src`,`alt`],b={class:`flex flex-col gap-1.5`},x={key:0,class:`text-xs font-semibold tracking-label text-muted uppercase`},S={class:`flex flex-col gap-1.5`},C={key:0,class:`text-sm text-muted tracking-label`},w={class:`flex flex-col gap-0.5`},T={class:`text-xs tracking-label text-muted uppercase`},E={class:`font-display text-2xl font-normal text-brand leading-none`},D={key:0,class:`text-xs text-muted mt-1`},O={key:1,class:`text-xs font-semibold tracking-label uppercase text-danger mt-1`},k=3,A={__name:`BundleCard`,props:{name:{type:String,required:!0},items:{type:Array,required:!0},price:{type:Number,required:!0},memberPrice:{type:Number,default:null},usage:{type:String,default:``},image:{type:String,required:!0},imageAlt:{type:String,default:``},badge:{type:String,default:``},badgeVariant:{type:String,default:`accent`,validator:e=>[`neutral`,`brand`,`accent`,`subtle`,`success`,`warning`,`danger`].includes(e)},tone:{type:String,default:`paper`,validator:e=>[`paper`,`cream`].includes(e)},layout:{type:String,default:`vertical`,validator:e=>[`vertical`,`horizontal`].includes(e)},inStock:{type:Boolean,default:!0},currency:{type:String,default:`€`},href:{type:String,default:``}},emits:[`add`],setup(A){let j=A,{t:M}=g(),N={paper:{surface:`bg-paper`,media:`bg-cream`,border:`border-line`},cream:{surface:`bg-cream`,media:`bg-paper`,border:`border-line`}},P=l(()=>N[j.tone]);function F(e){return`${j.currency} ${e.toFixed(2).replace(`.`,`,`)}`}let I=l(()=>F(j.price)),L=l(()=>j.memberPrice==null?``:F(j.memberPrice)),R=l(()=>j.items.slice(0,k)),z=l(()=>Math.max(0,j.items.length-k));return(l,g)=>(e(),m(`article`,{class:p([`group flex overflow-hidden rounded-md border transition-all duration-base ease-out`,A.layout===`horizontal`?`flex-col md:flex-row`:`flex-col`,P.value.surface,P.value.border,`hover:-translate-y-1 hover:shadow-md hover:border-brand-soft`])},[(e(),i(n(A.href?`a`:`div`),{href:A.href||null,class:p([`relative block overflow-hidden`,A.layout===`horizontal`?`aspect-[4/3] md:aspect-auto md:w-[38%] md:shrink-0 md:min-h-[300px]`:`aspect-[4/3]`,P.value.media])},{default:a(()=>[A.badge?(e(),i(_,{key:0,variant:A.badgeVariant,class:`absolute top-4 left-4 z-[1]`},{default:a(()=>[u(s(A.badge),1)]),_:1},8,[`variant`])):o(``,!0),f(`img`,{src:A.image,alt:A.imageAlt||A.name,loading:`lazy`,decoding:`async`,class:p([`absolute inset-0 w-full h-full object-contain transition-transform duration-slow ease-out group-hover:scale-105`,A.layout===`horizontal`?`p-6 md:p-5`:`p-8`])},null,10,y)]),_:1},8,[`href`,`class`])),f(`div`,{class:p([`flex flex-col gap-4 p-6`,A.layout===`horizontal`?`md:p-6 md:flex-1`:``])},[f(`div`,b,[A.usage?(e(),m(`span`,x,s(A.usage),1)):o(``,!0),(e(),i(n(A.href?`a`:`h3`),{href:A.href||null,class:p([`font-display text-xl font-normal leading-tight text-ink`,A.href?`hover:text-brand transition-colors duration-base`:``])},{default:a(()=>[u(s(A.name),1)]),_:1},8,[`href`,`class`]))]),f(`ul`,S,[(e(!0),m(d,null,r(R.value,t=>(e(),m(`li`,{key:t,class:`text-sm text-ink/80 leading-relaxed`},s(t),1))),128)),z.value>0?(e(),m(`li`,C,`+ `+s(z.value)+` `+s(t(M)(`bundles.card.moreItems`)),1)):o(``,!0)]),f(`div`,{class:p([`mt-auto pt-4 border-t border-line flex gap-3`,A.layout===`horizontal`?`flex-col sm:flex-row sm:items-end sm:justify-between`:`flex-col`])},[f(`div`,w,[f(`span`,T,s(t(M)(`bundles.card.priceLabel`)),1),f(`span`,E,s(I.value),1),L.value?(e(),m(`span`,D,s(t(M)(`bundles.card.memberPrefix`))+` `+s(L.value),1)):o(``,!0),A.inStock?o(``,!0):(e(),m(`span`,O,s(t(M)(`ds.product.outOfStock`)),1))]),c(v,{variant:`primary`,size:`md`,block:A.layout===`vertical`,disabled:!A.inStock,onClick:g[0]||=e=>l.$emit(`add`)},{before:a(()=>[c(h,{name:`plus`,size:16})]),default:a(()=>[u(` `+s(t(M)(`ds.buttons.addToCart`)),1)]),_:1},8,[`block`,`disabled`])],2)],2)],2))}};export{A as t};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{B as e,C as t,G as n,c as r,j as i,l as a,lt as o,m as s,p as c,s as l,u,y as d}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as f}from"./i18n-DrTQks20.js";import{t as p}from"./BundleCard-Dzd67GYz.js";import{t as m}from"./SectionShell-BEISUYi8.js";var h={class:`eyebrow mb-5`},g={class:`grid sm:grid-cols-2 lg:grid-cols-3 gap-6`},_={key:0,class:`mt-5 text-sm text-muted`},v={class:`font-mono text-[12px]`},y={class:`grid gap-6`},b={class:`eyebrow mb-5`},x={class:`grid sm:grid-cols-2 gap-6`},S={class:`eyebrow mb-5`},C=`/products/cutouts/kaiser-natron-pulver-250-g-grosspackung-removebg-preview-1.png`,w={__name:`BundleCardSection`,setup(w){let{t:T}=f(),E=e(``);function D(e){E.value=e,setTimeout(()=>{E.value===e&&(E.value=``)},2e3)}let O={name:`Haushalts-Bundle`,usage:`2–3× pro Quartal empfohlen`,items:[`1× Kaiser-Natron Pulver 250 g`,`1× Allzweck-Spray 500 ml`,`1× Spülmittel 500 ml`],price:24.9,memberPrice:21.17,image:C,imageAlt:`Haushalts-Bundle`},k={...O,items:[...O.items,`1× Holste Wasch-Soda 500 g`,`1× Allzweckreiniger 750 ml`]};return(e,f)=>(t(),r(m,{eyebrow:n(T)(`ds.eyebrow.components`),title:n(T)(`ds.bundleCard.title`),description:n(T)(`ds.bundleCard.description`)},{default:i(()=>[l(`section`,null,[l(`h2`,h,o(n(T)(`ds.heading.default`)),1),l(`div`,g,[s(p,d(O,{onAdd:f[0]||=e=>D(`default`)}),null,16),s(p,d(O,{badge:`Bestseller`,"badge-variant":`accent`,onAdd:f[1]||=e=>D(`bestseller`)}),null,16),s(p,d(O,{tone:`cream`,onAdd:f[2]||=e=>D(`cream`)}),null,16)]),E.value?(t(),u(`p`,_,[c(o(n(T)(`ds.product.added`))+`: `,1),l(`code`,v,o(E.value),1)])):a(``,!0)]),l(`section`,null,[f[5]||=l(`h2`,{class:`eyebrow mb-5`},`Horizontal layout`,-1),f[6]||=l(`p`,{class:`text-sm text-muted mb-5 max-w-2xl`},[c(` Passed as `),l(`code`,{class:`font-mono text-[12px]`},`layout="horizontal"`),c(`. From `),l(`code`,{class:`font-mono text-[12px]`},`md`),c(` up the media takes ~38% of the row and the body fills the rest, with the CTA inlined next to the price block. Below `),l(`code`,{class:`font-mono text-[12px]`},`md`),c(` it collapses back to vertical. `)],-1),l(`div`,y,[s(p,d(O,{layout:`horizontal`,badge:`Bestseller`,"badge-variant":`accent`,onAdd:f[3]||=e=>D(`horizontal`)}),null,16)])]),l(`section`,null,[l(`h2`,b,o(n(T)(`ds.heading.states`)),1),f[7]||=l(`p`,{class:`text-sm text-muted mb-5 max-w-2xl`},` Same bundle across both cards — only the state being demonstrated changes. `,-1),l(`div`,x,[s(p,d(O,{"in-stock":!1}),null,16),s(p,d(k,{onAdd:f[4]||=e=>D(`overflow`)}),null,16)]),f[8]||=l(`p`,{class:`mt-3 text-sm text-muted max-w-2xl`},[c(` More than three items collapse the tail into a `),l(`code`,{class:`font-mono text-[12px]`},`+ N weitere`),c(` line so the card stays scannable. `)],-1)]),l(`section`,null,[l(`h2`,S,o(n(T)(`ds.heading.usage`)),1),f[9]||=l(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[l(`pre`,{class:`whitespace-pre-wrap`},`<BundleCard
|
||||
import{B as e,C as t,G as n,c as r,j as i,l as a,lt as o,m as s,p as c,s as l,u,y as d}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as f}from"./i18n-CJQl3WLC.js";import{t as p}from"./BundleCard-BNbtPMJE.js";import{t as m}from"./SectionShell-Cd_Fu3uI.js";var h={class:`eyebrow mb-5`},g={class:`grid sm:grid-cols-2 lg:grid-cols-3 gap-6`},_={key:0,class:`mt-5 text-sm text-muted`},v={class:`font-mono text-[12px]`},y={class:`grid gap-6`},b={class:`eyebrow mb-5`},x={class:`grid sm:grid-cols-2 gap-6`},S={class:`eyebrow mb-5`},C=`/products/cutouts/kaiser-natron-pulver-250-g-grosspackung-removebg-preview-1.png`,w={__name:`BundleCardSection`,setup(w){let{t:T}=f(),E=e(``);function D(e){E.value=e,setTimeout(()=>{E.value===e&&(E.value=``)},2e3)}let O={name:`Haushalts-Bundle`,usage:`2–3× pro Quartal empfohlen`,items:[`1× Kaiser-Natron Pulver 250 g`,`1× Allzweck-Spray 500 ml`,`1× Spülmittel 500 ml`],price:24.9,memberPrice:21.17,image:C,imageAlt:`Haushalts-Bundle`},k={...O,items:[...O.items,`1× Holste Wasch-Soda 500 g`,`1× Allzweckreiniger 750 ml`]};return(e,f)=>(t(),r(m,{eyebrow:n(T)(`ds.eyebrow.components`),title:n(T)(`ds.bundleCard.title`),description:n(T)(`ds.bundleCard.description`)},{default:i(()=>[l(`section`,null,[l(`h2`,h,o(n(T)(`ds.heading.default`)),1),l(`div`,g,[s(p,d(O,{onAdd:f[0]||=e=>D(`default`)}),null,16),s(p,d(O,{badge:`Bestseller`,"badge-variant":`accent`,onAdd:f[1]||=e=>D(`bestseller`)}),null,16),s(p,d(O,{tone:`cream`,onAdd:f[2]||=e=>D(`cream`)}),null,16)]),E.value?(t(),u(`p`,_,[c(o(n(T)(`ds.product.added`))+`: `,1),l(`code`,v,o(E.value),1)])):a(``,!0)]),l(`section`,null,[f[5]||=l(`h2`,{class:`eyebrow mb-5`},`Horizontal layout`,-1),f[6]||=l(`p`,{class:`text-sm text-muted mb-5 max-w-2xl`},[c(` Passed as `),l(`code`,{class:`font-mono text-[12px]`},`layout="horizontal"`),c(`. From `),l(`code`,{class:`font-mono text-[12px]`},`md`),c(` up the media takes ~38% of the row and the body fills the rest, with the CTA inlined next to the price block. Below `),l(`code`,{class:`font-mono text-[12px]`},`md`),c(` it collapses back to vertical. `)],-1),l(`div`,y,[s(p,d(O,{layout:`horizontal`,badge:`Bestseller`,"badge-variant":`accent`,onAdd:f[3]||=e=>D(`horizontal`)}),null,16)])]),l(`section`,null,[l(`h2`,b,o(n(T)(`ds.heading.states`)),1),f[7]||=l(`p`,{class:`text-sm text-muted mb-5 max-w-2xl`},` Same bundle across both cards — only the state being demonstrated changes. `,-1),l(`div`,x,[s(p,d(O,{"in-stock":!1}),null,16),s(p,d(k,{onAdd:f[4]||=e=>D(`overflow`)}),null,16)]),f[8]||=l(`p`,{class:`mt-3 text-sm text-muted max-w-2xl`},[c(` More than three items collapse the tail into a `),l(`code`,{class:`font-mono text-[12px]`},`+ N weitere`),c(` line so the card stays scannable. `)],-1)]),l(`section`,null,[l(`h2`,S,o(n(T)(`ds.heading.usage`)),1),f[9]||=l(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[l(`pre`,{class:`whitespace-pre-wrap`},`<BundleCard
|
||||
name="Haushalts-Bundle"
|
||||
usage="2–3× pro Quartal empfohlen"
|
||||
:items="[
|
||||
1
dist/assets/Bundles-BUFH-aMm.js
vendored
Normal file
1
dist/assets/Bundles-BUFH-aMm.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/assets/Bundles-Bv4Zw5GG.css
vendored
Normal file
1
dist/assets/Bundles-Bv4Zw5GG.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.no-scrollbar[data-v-2edf5d69]::-webkit-scrollbar{display:none}.no-scrollbar[data-v-2edf5d69]{scrollbar-width:none;-ms-overflow-style:none}
|
||||
1
dist/assets/Bundles-Cq8LBYMP.css
vendored
1
dist/assets/Bundles-Cq8LBYMP.css
vendored
@@ -1 +0,0 @@
|
||||
.no-scrollbar[data-v-d1080e83]::-webkit-scrollbar{display:none}.no-scrollbar[data-v-d1080e83]{scrollbar-width:none;-ms-overflow-style:none}
|
||||
1
dist/assets/Bundles-ak0UwRx6.js
vendored
1
dist/assets/Bundles-ak0UwRx6.js
vendored
File diff suppressed because one or more lines are too long
1
dist/assets/BundlesPreview-BEQIST2k.js
vendored
1
dist/assets/BundlesPreview-BEQIST2k.js
vendored
@@ -1 +0,0 @@
|
||||
import{C as e,G as t,m as n,o as r,u as i}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as a}from"./i18n-DrTQks20.js";import{t as o}from"./Bundles-ak0UwRx6.js";var s={class:`min-h-screen bg-surface`},c={__name:`BundlesPreview`,setup(c){let{t:l}=a(),u=[{id:`haushalt`,name:`Haushalts-Bundle`,usage:`2–3× pro Quartal empfohlen`,items:[`1× Kaiser-Natron Pulver 250 g`,`1× Allzweck-Spray 500 ml`,`1× Spülmittel 500 ml`],price:24.9,memberPrice:21.17,image:`/products/cutouts/kaiser-natron-pulver-250-g-grosspackung-removebg-preview-1.png`,imageAlt:`Haushalts-Bundle mit Kaiser-Natron`,badge:`Bestseller`,badgeVariant:`accent`},{id:`waesche`,name:`Wäsche & Pflege`,usage:`1–2× pro Quartal`,items:[`1× Holste Wasch-Soda 500 g`,`1× Gazelle Wäschestärke 1 l`,`1× Linda Fleckenweg 200 ml`],price:22.9,memberPrice:19.47,image:`/products/holste-wasch-soda-500-g-beutel.jpg`,imageAlt:`Wäsche & Pflege Bundle`},{id:`wohlfuehl`,name:`Wohlfühl-Bundle`,usage:`1× pro Quartal`,items:[`1× Kaiser-Natron Tabletten 100 g`,`1× Kaiser-Natron Bad 500 g`,`1× Kaiser-Natron Fußbad 500 g`],price:29.9,memberPrice:25.42,image:`/products/kaiser-natron-bad-500-g.jpg`,imageAlt:`Wohlfühl-Bundle`}],d=r(()=>[l(`bundles.benefit.1.title`),l(`bundles.benefit.2.title`),l(`bundles.benefit.3.title`)]);return(r,a)=>(e(),i(`div`,s,[n(o,{bundles:u,headline:t(l)(`bundles.headline.a`),"headline-em":t(l)(`bundles.headline.em`),sub:t(l)(`bundles.sub`),benefits:d.value,"join-cta":t(l)(`bundles.joinCta`)},null,8,[`headline`,`headline-em`,`sub`,`benefits`,`join-cta`])]))}};export{c as default};
|
||||
1
dist/assets/BundlesPreview-BZq5Lj4V.js
vendored
Normal file
1
dist/assets/BundlesPreview-BZq5Lj4V.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{C as e,G as t,m as n,o as r,u as i}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{a}from"./vue-router-QRVDVSxc.js";import{t as o}from"./i18n-CJQl3WLC.js";import{t as s}from"./Bundles-BUFH-aMm.js";var c={class:`min-h-screen bg-surface`},l={__name:`BundlesPreview`,setup(l){let{t:u}=o(),d=a(),f=r(()=>d.query.layout===`stacked`?`stacked`:`sidebar`),p=[{id:`haushalt`,name:`Haushalts-Bundle`,usage:`2–3× pro Quartal empfohlen`,items:[`1× Kaiser-Natron Pulver 250 g`,`1× Allzweck-Spray 500 ml`,`1× Spülmittel 500 ml`],price:24.9,memberPrice:21.17,image:`/products/cutouts/kaiser-natron-pulver-250-g-grosspackung-removebg-preview-1.png`,imageAlt:`Haushalts-Bundle mit Kaiser-Natron`,badge:`Bestseller`,badgeVariant:`accent`},{id:`waesche`,name:`Wäsche & Pflege`,usage:`1–2× pro Quartal`,items:[`1× Holste Wasch-Soda 500 g`,`1× Gazelle Wäschestärke 1 l`,`1× Linda Fleckenweg 200 ml`],price:22.9,memberPrice:19.47,image:`/products/holste-wasch-soda-500-g-beutel.jpg`,imageAlt:`Wäsche & Pflege Bundle`},{id:`wohlfuehl`,name:`Wohlfühl-Bundle`,usage:`1× pro Quartal`,items:[`1× Kaiser-Natron Tabletten 100 g`,`1× Kaiser-Natron Bad 500 g`,`1× Kaiser-Natron Fußbad 500 g`],price:29.9,memberPrice:25.42,image:`/products/kaiser-natron-bad-500-g.jpg`,imageAlt:`Wohlfühl-Bundle`}],m=r(()=>[u(`bundles.benefit.1.title`),u(`bundles.benefit.2.title`),u(`bundles.benefit.3.title`)]);return(r,a)=>(e(),i(`div`,c,[n(s,{layout:f.value,bundles:p,headline:t(u)(`bundles.headline.a`),"headline-em":t(u)(`bundles.headline.em`),sub:t(u)(`bundles.sub`),benefits:m.value,"join-cta":t(u)(`bundles.joinCta`)},null,8,[`layout`,`headline`,`headline-em`,`sub`,`benefits`,`join-cta`])]))}};export{l as default};
|
||||
14
dist/assets/BundlesSection-Bw3L83wT.js
vendored
Normal file
14
dist/assets/BundlesSection-Bw3L83wT.js
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import{B as e,C as t,G as n,T as r,c as i,j as a,lt as o,m as s,o as c,p as l,r as u,s as d,st as f,u as p}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as m}from"./i18n-CJQl3WLC.js";import{t as h}from"./SectionShell-Cd_Fu3uI.js";import{t as g}from"./DevicePreview-Dx8DzWeH.js";var _={role:`tablist`,"aria-label":`Layout variant`,class:`inline-flex items-center p-1 gap-0.5 rounded-pill border border-line bg-paper`},v=[`aria-selected`,`onClick`],y={class:`eyebrow mb-5`},b={__name:`BundlesSection`,setup(b){let{t:x}=m(),S=[{id:`sidebar`,label:`Option 1`},{id:`stacked`,label:`Option 2`}],C=e(`sidebar`),w=c(()=>`/design/preview/bundles?layout=${C.value}`);return(e,c)=>(t(),i(h,{eyebrow:n(x)(`ds.eyebrow.components`),title:n(x)(`ds.bundles.title`),description:n(x)(`ds.bundles.description`),wide:``},{default:a(()=>[d(`section`,null,[s(g,{src:w.value,initial:`desktop`,height:1080},{controls:a(()=>[d(`div`,_,[(t(),p(u,null,r(S,e=>d(`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(e.label),11,v)),64))])]),_:1},8,[`src`])]),d(`section`,null,[d(`h2`,y,o(n(x)(`ds.heading.usage`)),1),c[0]||=d(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[d(`pre`,{class:`whitespace-pre-wrap`},`<Bundles
|
||||
:bundles="bundles"
|
||||
:headline="t('bundles.headline.a')"
|
||||
:headline-em="t('bundles.headline.em')"
|
||||
:sub="t('bundles.sub')"
|
||||
:benefits="[
|
||||
t('bundles.benefit.1.title'),
|
||||
t('bundles.benefit.2.title'),
|
||||
t('bundles.benefit.3.title'),
|
||||
]"
|
||||
:join-cta="t('bundles.joinCta')"
|
||||
@add="addBundle(bundleId)"
|
||||
@join="openSignup()"
|
||||
/>`)],-1)]),c[1]||=d(`section`,null,[d(`h2`,{class:`eyebrow mb-5`},`Props`),d(`div`,{class:`rounded-md border border-line bg-paper overflow-x-auto`},[d(`table`,{class:`w-full text-left text-[13px]`},[d(`thead`,{class:`bg-surface border-b border-line`},[d(`tr`,null,[d(`th`,{class:`px-5 py-3 font-semibold tracking-label text-muted uppercase text-[11px]`},`Prop`),d(`th`,{class:`px-5 py-3 font-semibold tracking-label text-muted uppercase text-[11px]`},`Type`),d(`th`,{class:`px-5 py-3 font-semibold tracking-label text-muted uppercase text-[11px]`},`Purpose`)])]),d(`tbody`,{class:`divide-y divide-line`},[d(`tr`,null,[d(`td`,{class:`px-5 py-3 font-mono text-[12px]`},`bundles`),d(`td`,{class:`px-5 py-3 text-muted`},`Array`),d(`td`,{class:`px-5 py-3`},`Required. Array of bundle records rendered by BundleCard.`)]),d(`tr`,null,[d(`td`,{class:`px-5 py-3 font-mono text-[12px]`},`headline / headlineEm / sub`),d(`td`,{class:`px-5 py-3 text-muted`},`String`),d(`td`,{class:`px-5 py-3`},[l(`Sidebar copy; `),d(`code`,{class:`font-mono text-[12px]`},`headlineEm`),l(` is the italicised highlight.`)])]),d(`tr`,null,[d(`td`,{class:`px-5 py-3 font-mono text-[12px]`},`benefits`),d(`td`,{class:`px-5 py-3 text-muted`},`String[]`),d(`td`,{class:`px-5 py-3`},`Sidebar benefit bullets. First three are shown.`)]),d(`tr`,null,[d(`td`,{class:`px-5 py-3 font-mono text-[12px]`},`joinCta`),d(`td`,{class:`px-5 py-3 text-muted`},`String`),d(`td`,{class:`px-5 py-3`},[l(`Label for the sidebar's primary button. Emits `),d(`code`,{class:`font-mono text-[12px]`},`join`),l(`.`)])]),d(`tr`,null,[d(`td`,{class:`px-5 py-3 font-mono text-[12px]`},`carousel*Label`),d(`td`,{class:`px-5 py-3 text-muted`},`String`),d(`td`,{class:`px-5 py-3`},`Override the default carousel a11y labels (prev / next / goToSlide / region label).`)])])])])],-1)]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{b as default};
|
||||
14
dist/assets/BundlesSection-CWM5TPZh.js
vendored
14
dist/assets/BundlesSection-CWM5TPZh.js
vendored
@@ -1,14 +0,0 @@
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,p as o,s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as c}from"./i18n-DrTQks20.js";import{t as l}from"./SectionShell-BEISUYi8.js";import{t as u}from"./DevicePreview-DvIWByfU.js";var d={class:`eyebrow mb-5`},f=`/design/preview/bundles`,p={__name:`BundlesSection`,setup(p){let{t:m}=c();return(c,p)=>(e(),n(l,{eyebrow:t(m)(`ds.eyebrow.components`),title:t(m)(`ds.bundles.title`),description:t(m)(`ds.bundles.description`),wide:``},{default:r(()=>[s(`section`,null,[a(u,{src:f,initial:`desktop`,height:1080})]),s(`section`,null,[s(`h2`,d,i(t(m)(`ds.heading.usage`)),1),p[0]||=s(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[s(`pre`,{class:`whitespace-pre-wrap`},`<Bundles
|
||||
:bundles="bundles"
|
||||
:headline="t('bundles.headline.a')"
|
||||
:headline-em="t('bundles.headline.em')"
|
||||
:sub="t('bundles.sub')"
|
||||
:benefits="[
|
||||
t('bundles.benefit.1.title'),
|
||||
t('bundles.benefit.2.title'),
|
||||
t('bundles.benefit.3.title'),
|
||||
]"
|
||||
:join-cta="t('bundles.joinCta')"
|
||||
@add="addBundle(bundleId)"
|
||||
@join="openSignup()"
|
||||
/>`)],-1)]),p[1]||=s(`section`,null,[s(`h2`,{class:`eyebrow mb-5`},`Props`),s(`div`,{class:`rounded-md border border-line bg-paper overflow-x-auto`},[s(`table`,{class:`w-full text-left text-[13px]`},[s(`thead`,{class:`bg-surface border-b border-line`},[s(`tr`,null,[s(`th`,{class:`px-5 py-3 font-semibold tracking-label text-muted uppercase text-[11px]`},`Prop`),s(`th`,{class:`px-5 py-3 font-semibold tracking-label text-muted uppercase text-[11px]`},`Type`),s(`th`,{class:`px-5 py-3 font-semibold tracking-label text-muted uppercase text-[11px]`},`Purpose`)])]),s(`tbody`,{class:`divide-y divide-line`},[s(`tr`,null,[s(`td`,{class:`px-5 py-3 font-mono text-[12px]`},`bundles`),s(`td`,{class:`px-5 py-3 text-muted`},`Array`),s(`td`,{class:`px-5 py-3`},`Required. Array of bundle records rendered by BundleCard.`)]),s(`tr`,null,[s(`td`,{class:`px-5 py-3 font-mono text-[12px]`},`headline / headlineEm / sub`),s(`td`,{class:`px-5 py-3 text-muted`},`String`),s(`td`,{class:`px-5 py-3`},[o(`Sidebar copy; `),s(`code`,{class:`font-mono text-[12px]`},`headlineEm`),o(` is the italicised highlight.`)])]),s(`tr`,null,[s(`td`,{class:`px-5 py-3 font-mono text-[12px]`},`benefits`),s(`td`,{class:`px-5 py-3 text-muted`},`String[]`),s(`td`,{class:`px-5 py-3`},`Sidebar benefit bullets. First three are shown.`)]),s(`tr`,null,[s(`td`,{class:`px-5 py-3 font-mono text-[12px]`},`joinCta`),s(`td`,{class:`px-5 py-3 text-muted`},`String`),s(`td`,{class:`px-5 py-3`},[o(`Label for the sidebar's primary button. Emits `),s(`code`,{class:`font-mono text-[12px]`},`join`),o(`.`)])]),s(`tr`,null,[s(`td`,{class:`px-5 py-3 font-mono text-[12px]`},`carousel*Label`),s(`td`,{class:`px-5 py-3 text-muted`},`String`),s(`td`,{class:`px-5 py-3`},`Override the default carousel a11y labels (prev / next / goToSlide / region label).`)])])])])],-1)]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{p as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,p as o,s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as c}from"./Icon-BCRRMV3J.js";import{t as l}from"./i18n-DrTQks20.js";import{t as u}from"./Button-DkdaDkuf.js";import{t as d}from"./SectionShell-BEISUYi8.js";import{t as f}from"./Card-DM27vc3f.js";var p={class:`eyebrow mb-5`},m={class:`flex flex-wrap gap-3`},h={class:`eyebrow mb-5`},g={class:`grid md:grid-cols-3 gap-4`},_={class:`eyebrow mb-4`},v={class:`flex flex-wrap gap-3`},y={class:`eyebrow mb-4`},b={class:`flex flex-wrap gap-3`},x={class:`eyebrow mb-4 !text-cream opacity-80`},S={class:`flex flex-wrap gap-3`},C={class:`eyebrow mb-5`},w={class:`flex flex-wrap items-center gap-3`},T={class:`eyebrow mb-5`},E={class:`flex flex-wrap items-center gap-3`},D={class:`eyebrow mb-5`},O={class:`flex flex-wrap gap-3 items-center`},k={class:`eyebrow mb-5`},A={class:`max-w-md space-y-3`},j={class:`eyebrow mb-5`},M={class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},N={class:`whitespace-pre-wrap`},P={__name:`ButtonsSection`,setup(P){let{t:F}=l();return(l,P)=>(e(),n(d,{eyebrow:t(F)(`ds.eyebrow.components`),title:t(F)(`ds.buttons.title`),description:t(F)(`ds.buttons.description`)},{default:r(()=>[s(`section`,null,[s(`h2`,p,i(t(F)(`ds.heading.variants`)),1),a(f,{tone:`paper`},{default:r(()=>[s(`div`,m,[a(u,{variant:`primary`},{default:r(()=>[o(i(t(F)(`ds.buttons.primary`)),1)]),_:1}),a(u,{variant:`accent`},{default:r(()=>[o(i(t(F)(`ds.buttons.accent`)),1)]),_:1}),a(u,{variant:`secondary`},{default:r(()=>[o(i(t(F)(`ds.buttons.secondary`)),1)]),_:1}),a(u,{variant:`ghost`},{default:r(()=>[o(i(t(F)(`ds.buttons.ghost`)),1)]),_:1}),a(u,{variant:`danger`},{default:r(()=>[o(i(t(F)(`ds.buttons.danger`)),1)]),_:1})])]),_:1})]),s(`section`,null,[s(`h2`,h,i(t(F)(`ds.heading.onDifferentSurfaces`)),1),s(`div`,g,[a(f,{tone:`paper`},{default:r(()=>[s(`p`,_,i(t(F)(`ds.cards.paper`)),1),s(`div`,v,[a(u,{variant:`primary`},{before:r(()=>[a(c,{name:`cart`,size:18})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.addToCart`)),1)]),_:1}),a(u,{variant:`ghost`},{default:r(()=>[o(i(t(F)(`ds.buttons.learnMore`)),1)]),_:1})])]),_:1}),a(f,{tone:`cream`},{default:r(()=>[s(`p`,y,i(t(F)(`ds.cards.cream`)),1),s(`div`,b,[a(u,{variant:`primary`},{before:r(()=>[a(c,{name:`cart`,size:18})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.addToCart`)),1)]),_:1}),a(u,{variant:`ghost`},{default:r(()=>[o(i(t(F)(`ds.buttons.learnMore`)),1)]),_:1})])]),_:1}),a(f,{tone:`brand`},{default:r(()=>[s(`p`,x,i(t(F)(`ds.cards.brand`)),1),s(`div`,S,[a(u,{variant:`accent`},{before:r(()=>[a(c,{name:`cart`,size:18})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.addToCart`)),1)]),_:1}),a(u,{variant:`ghost`,class:`!text-cream hover:!bg-cream-wash`},{default:r(()=>[o(i(t(F)(`ds.buttons.learnMore`)),1)]),_:1})])]),_:1})])]),s(`section`,null,[s(`h2`,C,i(t(F)(`ds.heading.sizes`)),1),a(f,{tone:`paper`},{default:r(()=>[s(`div`,w,[a(u,{size:`sm`},{default:r(()=>[o(i(t(F)(`ds.buttons.small`)),1)]),_:1}),a(u,{size:`md`},{default:r(()=>[o(i(t(F)(`ds.buttons.medium`)),1)]),_:1}),a(u,{size:`lg`},{default:r(()=>[o(i(t(F)(`ds.buttons.large`)),1)]),_:1})])]),_:1})]),s(`section`,null,[s(`h2`,T,i(t(F)(`ds.heading.withIcons`)),1),a(f,{tone:`paper`},{default:r(()=>[s(`div`,E,[a(u,{variant:`primary`},{before:r(()=>[a(c,{name:`cart`,size:18})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.addToCart`)),1)]),_:1}),a(u,{variant:`secondary`},{after:r(()=>[a(c,{name:`arrow-right`,size:18})]),default:r(()=>[o(i(t(F)(`ds.buttons.learnMore`))+` `,1)]),_:1}),a(u,{variant:`ghost`},{before:r(()=>[a(c,{name:`heart`,size:18})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.save`)),1)]),_:1}),a(u,{variant:`accent`,size:`sm`},{before:r(()=>[a(c,{name:`check`,size:16})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.confirm`)),1)]),_:1})])]),_:1})]),s(`section`,null,[s(`h2`,D,i(t(F)(`ds.heading.states`)),1),a(f,{tone:`paper`},{default:r(()=>[s(`div`,O,[a(u,null,{default:r(()=>[o(i(t(F)(`ds.heading.default`)),1)]),_:1}),a(u,{disabled:``},{default:r(()=>[o(i(t(F)(`ds.buttons.disabled`)),1)]),_:1}),a(u,{loading:``},{default:r(()=>[o(i(t(F)(`ds.buttons.loading`)),1)]),_:1})])]),_:1})]),s(`section`,null,[s(`h2`,k,i(t(F)(`ds.heading.block`)),1),a(f,{tone:`paper`},{default:r(()=>[s(`div`,A,[a(u,{block:``,variant:`primary`},{before:r(()=>[a(c,{name:`cart`,size:18})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.addToCart`)),1)]),_:1}),a(u,{block:``,variant:`secondary`},{default:r(()=>[o(i(t(F)(`ds.buttons.continueShopping`)),1)]),_:1})])]),_:1})]),s(`section`,null,[s(`h2`,j,i(t(F)(`ds.heading.usage`)),1),s(`div`,M,[s(`pre`,N,`<Button variant="primary" size="md">
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,p as o,s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as c}from"./Icon-BCRRMV3J.js";import{t as l}from"./i18n-CJQl3WLC.js";import{t as u}from"./Button-DkdaDkuf.js";import{t as d}from"./SectionShell-Cd_Fu3uI.js";import{t as f}from"./Card-pgd8VnYH.js";var p={class:`eyebrow mb-5`},m={class:`flex flex-wrap gap-3`},h={class:`eyebrow mb-5`},g={class:`grid md:grid-cols-3 gap-4`},_={class:`eyebrow mb-4`},v={class:`flex flex-wrap gap-3`},y={class:`eyebrow mb-4`},b={class:`flex flex-wrap gap-3`},x={class:`eyebrow mb-4 !text-cream opacity-80`},S={class:`flex flex-wrap gap-3`},C={class:`eyebrow mb-5`},w={class:`flex flex-wrap items-center gap-3`},T={class:`eyebrow mb-5`},E={class:`flex flex-wrap items-center gap-3`},D={class:`eyebrow mb-5`},O={class:`flex flex-wrap gap-3 items-center`},k={class:`eyebrow mb-5`},A={class:`max-w-md space-y-3`},j={class:`eyebrow mb-5`},M={class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},N={class:`whitespace-pre-wrap`},P={__name:`ButtonsSection`,setup(P){let{t:F}=l();return(l,P)=>(e(),n(d,{eyebrow:t(F)(`ds.eyebrow.components`),title:t(F)(`ds.buttons.title`),description:t(F)(`ds.buttons.description`)},{default:r(()=>[s(`section`,null,[s(`h2`,p,i(t(F)(`ds.heading.variants`)),1),a(f,{tone:`paper`},{default:r(()=>[s(`div`,m,[a(u,{variant:`primary`},{default:r(()=>[o(i(t(F)(`ds.buttons.primary`)),1)]),_:1}),a(u,{variant:`accent`},{default:r(()=>[o(i(t(F)(`ds.buttons.accent`)),1)]),_:1}),a(u,{variant:`secondary`},{default:r(()=>[o(i(t(F)(`ds.buttons.secondary`)),1)]),_:1}),a(u,{variant:`ghost`},{default:r(()=>[o(i(t(F)(`ds.buttons.ghost`)),1)]),_:1}),a(u,{variant:`danger`},{default:r(()=>[o(i(t(F)(`ds.buttons.danger`)),1)]),_:1})])]),_:1})]),s(`section`,null,[s(`h2`,h,i(t(F)(`ds.heading.onDifferentSurfaces`)),1),s(`div`,g,[a(f,{tone:`paper`},{default:r(()=>[s(`p`,_,i(t(F)(`ds.cards.paper`)),1),s(`div`,v,[a(u,{variant:`primary`},{before:r(()=>[a(c,{name:`cart`,size:18})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.addToCart`)),1)]),_:1}),a(u,{variant:`ghost`},{default:r(()=>[o(i(t(F)(`ds.buttons.learnMore`)),1)]),_:1})])]),_:1}),a(f,{tone:`cream`},{default:r(()=>[s(`p`,y,i(t(F)(`ds.cards.cream`)),1),s(`div`,b,[a(u,{variant:`primary`},{before:r(()=>[a(c,{name:`cart`,size:18})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.addToCart`)),1)]),_:1}),a(u,{variant:`ghost`},{default:r(()=>[o(i(t(F)(`ds.buttons.learnMore`)),1)]),_:1})])]),_:1}),a(f,{tone:`brand`},{default:r(()=>[s(`p`,x,i(t(F)(`ds.cards.brand`)),1),s(`div`,S,[a(u,{variant:`accent`},{before:r(()=>[a(c,{name:`cart`,size:18})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.addToCart`)),1)]),_:1}),a(u,{variant:`ghost`,class:`!text-cream hover:!bg-cream-wash`},{default:r(()=>[o(i(t(F)(`ds.buttons.learnMore`)),1)]),_:1})])]),_:1})])]),s(`section`,null,[s(`h2`,C,i(t(F)(`ds.heading.sizes`)),1),a(f,{tone:`paper`},{default:r(()=>[s(`div`,w,[a(u,{size:`sm`},{default:r(()=>[o(i(t(F)(`ds.buttons.small`)),1)]),_:1}),a(u,{size:`md`},{default:r(()=>[o(i(t(F)(`ds.buttons.medium`)),1)]),_:1}),a(u,{size:`lg`},{default:r(()=>[o(i(t(F)(`ds.buttons.large`)),1)]),_:1})])]),_:1})]),s(`section`,null,[s(`h2`,T,i(t(F)(`ds.heading.withIcons`)),1),a(f,{tone:`paper`},{default:r(()=>[s(`div`,E,[a(u,{variant:`primary`},{before:r(()=>[a(c,{name:`cart`,size:18})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.addToCart`)),1)]),_:1}),a(u,{variant:`secondary`},{after:r(()=>[a(c,{name:`arrow-right`,size:18})]),default:r(()=>[o(i(t(F)(`ds.buttons.learnMore`))+` `,1)]),_:1}),a(u,{variant:`ghost`},{before:r(()=>[a(c,{name:`heart`,size:18})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.save`)),1)]),_:1}),a(u,{variant:`accent`,size:`sm`},{before:r(()=>[a(c,{name:`check`,size:16})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.confirm`)),1)]),_:1})])]),_:1})]),s(`section`,null,[s(`h2`,D,i(t(F)(`ds.heading.states`)),1),a(f,{tone:`paper`},{default:r(()=>[s(`div`,O,[a(u,null,{default:r(()=>[o(i(t(F)(`ds.heading.default`)),1)]),_:1}),a(u,{disabled:``},{default:r(()=>[o(i(t(F)(`ds.buttons.disabled`)),1)]),_:1}),a(u,{loading:``},{default:r(()=>[o(i(t(F)(`ds.buttons.loading`)),1)]),_:1})])]),_:1})]),s(`section`,null,[s(`h2`,k,i(t(F)(`ds.heading.block`)),1),a(f,{tone:`paper`},{default:r(()=>[s(`div`,A,[a(u,{block:``,variant:`primary`},{before:r(()=>[a(c,{name:`cart`,size:18})]),default:r(()=>[o(` `+i(t(F)(`ds.buttons.addToCart`)),1)]),_:1}),a(u,{block:``,variant:`secondary`},{default:r(()=>[o(i(t(F)(`ds.buttons.continueShopping`)),1)]),_:1})])]),_:1})]),s(`section`,null,[s(`h2`,j,i(t(F)(`ds.heading.usage`)),1),s(`div`,M,[s(`pre`,N,`<Button variant="primary" size="md">
|
||||
<template #before><Icon name="cart" :size="18" /></template>
|
||||
`+i(t(F)(`ds.buttons.addToCart`))+`
|
||||
</Button>`,1)])])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{P as default};
|
||||
@@ -1 +1 @@
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,p as o,s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as c}from"./i18n-DrTQks20.js";import{t as l}from"./Badge-DcvgVKep.js";import{t as u}from"./SectionShell-BEISUYi8.js";import{t as d}from"./Card-DM27vc3f.js";var f={class:`eyebrow mb-5`},p={class:`grid md:grid-cols-3 gap-6`},m={class:`font-display text-2xl font-normal mb-2`},h={class:`text-[14px] text-muted leading-relaxed`},g={class:`font-display text-2xl font-normal mb-2`},_={class:`text-[14px] text-muted leading-relaxed`},v={class:`font-display text-2xl font-normal mb-2`},y={class:`text-[14px] opacity-80 leading-relaxed`},b={class:`eyebrow mb-5`},x={class:`grid md:grid-cols-2 gap-6`},S={class:`font-display text-2xl font-normal mb-2`},C={class:`text-[14px] text-muted leading-relaxed`},w={class:`font-display text-2xl font-normal mb-2`},T={class:`text-[14px] text-muted leading-relaxed`},E={class:`eyebrow mb-5`},D={class:`p-7`},O={class:`font-display text-2xl font-normal mb-2`},k={class:`text-[14px] text-muted leading-relaxed`},A={__name:`CardsSection`,setup(A){let{t:j}=c();return(c,A)=>(e(),n(u,{eyebrow:t(j)(`ds.eyebrow.components`),title:t(j)(`ds.cards.title`),description:t(j)(`ds.cards.description`)},{default:r(()=>[s(`section`,null,[s(`h2`,f,i(t(j)(`ds.heading.tones`)),1),s(`div`,p,[a(d,{tone:`paper`},{default:r(()=>[a(l,{variant:`subtle`,class:`mb-4`},{default:r(()=>[o(i(t(j)(`ds.cards.paper`)),1)]),_:1}),s(`h3`,m,i(t(j)(`ds.cards.paperTitle`)),1),s(`p`,h,i(t(j)(`ds.cards.paperBody`)),1)]),_:1}),a(d,{tone:`cream`},{default:r(()=>[a(l,{variant:`subtle`,class:`mb-4`},{default:r(()=>[o(i(t(j)(`ds.cards.cream`)),1)]),_:1}),s(`h3`,g,i(t(j)(`ds.cards.creamTitle`)),1),s(`p`,_,i(t(j)(`ds.cards.creamBody`)),1)]),_:1}),a(d,{tone:`brand`},{default:r(()=>[a(l,{variant:`accent`,class:`mb-4`},{default:r(()=>[o(i(t(j)(`ds.cards.brand`)),1)]),_:1}),s(`h3`,v,i(t(j)(`ds.cards.brandTitle`)),1),s(`p`,y,i(t(j)(`ds.cards.brandBody`)),1)]),_:1})])]),s(`section`,null,[s(`h2`,b,i(t(j)(`ds.heading.interactive`)),1),s(`div`,x,[a(d,{tone:`paper`,interactive:``},{default:r(()=>[s(`h3`,S,i(t(j)(`ds.cards.hoverMe`)),1),s(`p`,C,i(t(j)(`ds.cards.hoverBody`)),1)]),_:1}),a(d,{tone:`cream`,interactive:``},{default:r(()=>[s(`h3`,w,i(t(j)(`ds.cards.hoverMeToo`)),1),s(`p`,T,i(t(j)(`ds.cards.hoverBodyAlt`)),1)]),_:1})])]),s(`section`,null,[s(`h2`,E,i(t(j)(`ds.heading.withoutPadding`)),1),a(d,{tone:`paper`,padded:!1},{default:r(()=>[A[2]||=s(`div`,{class:`h-40 bg-cream rounded-t-md`},null,-1),s(`div`,D,[s(`h3`,O,i(t(j)(`ds.cards.mediaTitle`)),1),s(`p`,k,[o(i(t(j)(`ds.cards.mediaBody`))+` `,1),A[0]||=s(`code`,{class:`font-mono text-[12px]`},`:padded="false"`,-1),A[1]||=o(`. `,-1)])])]),_:1})])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{A as default};
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,p as o,s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as c}from"./i18n-CJQl3WLC.js";import{t as l}from"./Badge-DcvgVKep.js";import{t as u}from"./SectionShell-Cd_Fu3uI.js";import{t as d}from"./Card-pgd8VnYH.js";var f={class:`eyebrow mb-5`},p={class:`grid md:grid-cols-3 gap-6`},m={class:`font-display text-2xl font-normal mb-2`},h={class:`text-[14px] text-muted leading-relaxed`},g={class:`font-display text-2xl font-normal mb-2`},_={class:`text-[14px] text-muted leading-relaxed`},v={class:`font-display text-2xl font-normal mb-2`},y={class:`text-[14px] opacity-80 leading-relaxed`},b={class:`eyebrow mb-5`},x={class:`grid md:grid-cols-2 gap-6`},S={class:`font-display text-2xl font-normal mb-2`},C={class:`text-[14px] text-muted leading-relaxed`},w={class:`font-display text-2xl font-normal mb-2`},T={class:`text-[14px] text-muted leading-relaxed`},E={class:`eyebrow mb-5`},D={class:`p-7`},O={class:`font-display text-2xl font-normal mb-2`},k={class:`text-[14px] text-muted leading-relaxed`},A={__name:`CardsSection`,setup(A){let{t:j}=c();return(c,A)=>(e(),n(u,{eyebrow:t(j)(`ds.eyebrow.components`),title:t(j)(`ds.cards.title`),description:t(j)(`ds.cards.description`)},{default:r(()=>[s(`section`,null,[s(`h2`,f,i(t(j)(`ds.heading.tones`)),1),s(`div`,p,[a(d,{tone:`paper`},{default:r(()=>[a(l,{variant:`subtle`,class:`mb-4`},{default:r(()=>[o(i(t(j)(`ds.cards.paper`)),1)]),_:1}),s(`h3`,m,i(t(j)(`ds.cards.paperTitle`)),1),s(`p`,h,i(t(j)(`ds.cards.paperBody`)),1)]),_:1}),a(d,{tone:`cream`},{default:r(()=>[a(l,{variant:`subtle`,class:`mb-4`},{default:r(()=>[o(i(t(j)(`ds.cards.cream`)),1)]),_:1}),s(`h3`,g,i(t(j)(`ds.cards.creamTitle`)),1),s(`p`,_,i(t(j)(`ds.cards.creamBody`)),1)]),_:1}),a(d,{tone:`brand`},{default:r(()=>[a(l,{variant:`accent`,class:`mb-4`},{default:r(()=>[o(i(t(j)(`ds.cards.brand`)),1)]),_:1}),s(`h3`,v,i(t(j)(`ds.cards.brandTitle`)),1),s(`p`,y,i(t(j)(`ds.cards.brandBody`)),1)]),_:1})])]),s(`section`,null,[s(`h2`,b,i(t(j)(`ds.heading.interactive`)),1),s(`div`,x,[a(d,{tone:`paper`,interactive:``},{default:r(()=>[s(`h3`,S,i(t(j)(`ds.cards.hoverMe`)),1),s(`p`,C,i(t(j)(`ds.cards.hoverBody`)),1)]),_:1}),a(d,{tone:`cream`,interactive:``},{default:r(()=>[s(`h3`,w,i(t(j)(`ds.cards.hoverMeToo`)),1),s(`p`,T,i(t(j)(`ds.cards.hoverBodyAlt`)),1)]),_:1})])]),s(`section`,null,[s(`h2`,E,i(t(j)(`ds.heading.withoutPadding`)),1),a(d,{tone:`paper`,padded:!1},{default:r(()=>[A[2]||=s(`div`,{class:`h-40 bg-cream rounded-t-md`},null,-1),s(`div`,D,[s(`h3`,O,i(t(j)(`ds.cards.mediaTitle`)),1),s(`p`,k,[o(i(t(j)(`ds.cards.mediaBody`))+` `,1),A[0]||=s(`code`,{class:`font-mono text-[12px]`},`:padded="false"`,-1),A[1]||=o(`. `,-1)])])]),_:1})])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{A as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
import{B as e,C as t,G as n,S as r,c as i,j as a,lt as o,m as s,p as c,s as l}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as u}from"./Icon-BCRRMV3J.js";import{t as d}from"./i18n-DrTQks20.js";import{a as f,i as p,n as m,o as h,r as g,t as _}from"./api-S-LVXOcC.js";import{t as v}from"./Button-DkdaDkuf.js";import{t as y}from"./CartDrawer-B4LbpROl.js";import{t as b}from"./SectionShell-BEISUYi8.js";var x={class:`eyebrow mb-5`},S={class:`rounded-md border border-line bg-paper p-6 flex flex-col sm:flex-row sm:items-center gap-4`},C={class:`text-[13px] text-muted`},w={class:`eyebrow mb-5`},T={class:`text-[15px] text-muted leading-relaxed mb-4 max-w-2xl`},E={class:`eyebrow mb-5`},D={__name:`CartDrawerSection`,setup(D){let{t:O}=d(),k=h(),A=e(!1);async function j(){await m(),await _(`kaiser-natron-pulver-250-g-grosspackung`,2),await _(`kaiser-natron-bad-500-g`,1),A.value=!0}async function M({productId:e,quantity:t}){await f(e,t)}async function N(e){await p(e)}return r(()=>{g()}),(e,r)=>(t(),i(b,{eyebrow:n(O)(`ds.eyebrow.components`),title:n(O)(`ds.cartDrawer.title`),description:n(O)(`ds.cartDrawer.description`)},{default:a(()=>[l(`section`,null,[l(`h2`,x,o(n(O)(`ds.heading.default`)),1),l(`div`,S,[s(v,{variant:`primary`,onClick:j},{before:a(()=>[s(u,{name:`cart`,size:18})]),default:a(()=>[c(` `+o(n(O)(`ds.cartDrawer.demoLabel`)),1)]),_:1}),l(`p`,C,o(n(O)(`ds.cartDrawer.demoHint`)),1)])]),l(`section`,null,[l(`h2`,w,o(n(O)(`ds.cartDrawer.integrationTitle`)),1),l(`p`,T,o(n(O)(`ds.cartDrawer.integrationBody`)),1),r[2]||=l(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[l(`pre`,{class:`whitespace-pre-wrap`},`import {
|
||||
import{B as e,C as t,G as n,S as r,c as i,j as a,lt as o,m as s,p as c,s as l}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as u}from"./Icon-BCRRMV3J.js";import{t as d}from"./i18n-CJQl3WLC.js";import{a as f,i as p,n as m,o as h,r as g,t as _}from"./api-tyvtUCGz.js";import{t as v}from"./Button-DkdaDkuf.js";import{t as y}from"./CartDrawer-GmlNs2mL.js";import{t as b}from"./SectionShell-Cd_Fu3uI.js";var x={class:`eyebrow mb-5`},S={class:`rounded-md border border-line bg-paper p-6 flex flex-col sm:flex-row sm:items-center gap-4`},C={class:`text-[13px] text-muted`},w={class:`eyebrow mb-5`},T={class:`text-[15px] text-muted leading-relaxed mb-4 max-w-2xl`},E={class:`eyebrow mb-5`},D={__name:`CartDrawerSection`,setup(D){let{t:O}=d(),k=h(),A=e(!1);async function j(){await m(),await _(`kaiser-natron-pulver-250-g-grosspackung`,2),await _(`kaiser-natron-bad-500-g`,1),A.value=!0}async function M({productId:e,quantity:t}){await f(e,t)}async function N(e){await p(e)}return r(()=>{g()}),(e,r)=>(t(),i(b,{eyebrow:n(O)(`ds.eyebrow.components`),title:n(O)(`ds.cartDrawer.title`),description:n(O)(`ds.cartDrawer.description`)},{default:a(()=>[l(`section`,null,[l(`h2`,x,o(n(O)(`ds.heading.default`)),1),l(`div`,S,[s(v,{variant:`primary`,onClick:j},{before:a(()=>[s(u,{name:`cart`,size:18})]),default:a(()=>[c(` `+o(n(O)(`ds.cartDrawer.demoLabel`)),1)]),_:1}),l(`p`,C,o(n(O)(`ds.cartDrawer.demoHint`)),1)])]),l(`section`,null,[l(`h2`,w,o(n(O)(`ds.cartDrawer.integrationTitle`)),1),l(`p`,T,o(n(O)(`ds.cartDrawer.integrationBody`)),1),r[2]||=l(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[l(`pre`,{class:`whitespace-pre-wrap`},`import {
|
||||
fetchCart,
|
||||
addToCart,
|
||||
updateCartItem,
|
||||
@@ -1 +1 @@
|
||||
import{C as e,G as t,T as n,c as r,ct as i,j as a,lt as o,o as s,r as c,s as l,u}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as d}from"./i18n-DrTQks20.js";import{t as f}from"./SectionShell-BEISUYi8.js";var p={class:`eyebrow mb-5`},m={class:`grid grid-cols-2 sm:grid-cols-3 gap-4`},h={class:`px-4 py-3`},g={class:`font-mono text-[12px] text-ink block`},_={__name:`ColorsSection`,setup(_){let{t:v}=d(),y=s(()=>[{title:v(`ds.colors.group.brand`),names:[`brand`,`brand-hover`,`brand-soft`]},{title:v(`ds.colors.group.accent`),names:[`accent`,`accent-soft`,`accent-ink`]},{title:v(`ds.colors.group.surface`),names:[`surface`,`paper`,`cream`]},{title:v(`ds.colors.group.ink`),names:[`ink`,`muted`]},{title:v(`ds.colors.group.line`),names:[`line`,`line-strong`]},{title:v(`ds.colors.group.semantic`),names:[`success`,`warning`,`danger`]}]);return(s,d)=>(e(),r(f,{eyebrow:t(v)(`ds.eyebrow.tokens`),title:t(v)(`ds.colors.title`),description:t(v)(`ds.colors.description`)},{default:a(()=>[(e(!0),u(c,null,n(y.value,t=>(e(),u(`section`,{key:t.title},[l(`h2`,p,o(t.title),1),l(`div`,m,[(e(!0),u(c,null,n(t.names,t=>(e(),u(`div`,{key:t,class:`rounded-md border border-line overflow-hidden bg-paper`},[l(`div`,{class:`h-28 border-b border-line`,style:i({background:`var(--color-${t})`})},null,4),l(`div`,h,[l(`code`,g,`--color-`+o(t),1)])]))),128))])]))),128))]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{_ as default};
|
||||
import{C as e,G as t,T as n,c as r,ct as i,j as a,lt as o,o as s,r as c,s as l,u}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as d}from"./i18n-CJQl3WLC.js";import{t as f}from"./SectionShell-Cd_Fu3uI.js";var p={class:`eyebrow mb-5`},m={class:`grid grid-cols-2 sm:grid-cols-3 gap-4`},h={class:`px-4 py-3`},g={class:`font-mono text-[12px] text-ink block`},_={__name:`ColorsSection`,setup(_){let{t:v}=d(),y=s(()=>[{title:v(`ds.colors.group.brand`),names:[`brand`,`brand-hover`,`brand-soft`]},{title:v(`ds.colors.group.accent`),names:[`accent`,`accent-soft`,`accent-ink`]},{title:v(`ds.colors.group.surface`),names:[`surface`,`paper`,`cream`]},{title:v(`ds.colors.group.ink`),names:[`ink`,`muted`]},{title:v(`ds.colors.group.line`),names:[`line`,`line-strong`]},{title:v(`ds.colors.group.semantic`),names:[`success`,`warning`,`danger`]}]);return(s,d)=>(e(),r(f,{eyebrow:t(v)(`ds.eyebrow.tokens`),title:t(v)(`ds.colors.title`),description:t(v)(`ds.colors.description`)},{default:a(()=>[(e(!0),u(c,null,n(y.value,t=>(e(),u(`section`,{key:t.title},[l(`h2`,p,o(t.title),1),l(`div`,m,[(e(!0),u(c,null,n(t.names,t=>(e(),u(`div`,{key:t,class:`rounded-md border border-line overflow-hidden bg-paper`},[l(`div`,{class:`h-28 border-b border-line`,style:i({background:`var(--color-${t})`})},null,4),l(`div`,h,[l(`code`,g,`--color-`+o(t),1)])]))),128))])]))),128))]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{_ as default};
|
||||
File diff suppressed because one or more lines are too long
1
dist/assets/Hero-B6Qkpe_4.js
vendored
1
dist/assets/Hero-B6Qkpe_4.js
vendored
File diff suppressed because one or more lines are too long
1
dist/assets/Hero-CBIJn5YV.js
vendored
Normal file
1
dist/assets/Hero-CBIJn5YV.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/assets/Hero-CNFv3JDa.css
vendored
Normal file
1
dist/assets/Hero-CNFv3JDa.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.hero-section[data-v-1e8eafc0]{overflow-clip-margin:1rem}.hero-headline[data-v-1e8eafc0]{overflow-wrap:anywhere;word-break:normal}
|
||||
@@ -1 +1 @@
|
||||
import{C as e,G as t,j as n,lt as r,m as i,o as a,p as o,r as s,s as c,st as l,u}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{a as d}from"./vue-router-QRVDVSxc.js";import{t as f}from"./i18n-DrTQks20.js";import{t as p}from"./Navbar-DTKm8Xku.js";import{t as m}from"./Hero-B6Qkpe_4.js";var h={class:`italic font-light text-brand-soft`},g={class:`italic font-light text-brand-soft`},_=`/products/cutouts/kaiser-natron-pulver-250-g-grosspackung-removebg-preview-3.png`,v=`/products/kaiser-natron-bad-500-g.jpg`,y={__name:`HeroPreview`,setup(y){let b=d(),{t:x}=f(),S=a(()=>[`split`,`centered`].includes(b.query.variant)?b.query.variant:`split`),C=a(()=>[`cream`,`paper`,`brand`].includes(b.query.tone)?b.query.tone:`cream`),w=a(()=>b.query.reverse===`1`),T=a(()=>C.value===`brand`?`brand`:C.value),E=a(()=>w.value?v:_),D=a(()=>w.value?`Kaiser-Natron Bad 500 g`:`Kaiser-Natron Pulver 250 g Großpackung`);return(a,d)=>(e(),u(`div`,{class:l([`min-h-screen`,C.value===`brand`?`bg-brand`:`bg-surface`])},[i(p,{variant:T.value,"cart-count":0},null,8,[`variant`]),i(m,{variant:S.value,tone:C.value,reverse:w.value,eyebrow:w.value?t(x)(`home.banner.eyebrow`):t(x)(`ds.hero.eyebrow`),subheadline:w.value?t(x)(`home.banner.sub`):t(x)(`ds.hero.sub`),image:E.value,"image-alt":D.value,badge:w.value?``:t(x)(`ds.badges.featured`),"cta-label":t(x)(`ds.buttons.addToCart`),"secondary-label":t(x)(`ds.buttons.learnMore`)},{headline:n(()=>[w.value?(e(),u(s,{key:0},[o(r(t(x)(`home.banner.headline.a`))+` `,1),c(`em`,h,r(t(x)(`home.banner.headline.em`)),1),o(` `+r(t(x)(`home.banner.headline.b`)),1)],64)):(e(),u(s,{key:1},[o(r(t(x)(`ds.hero.headline.a`))+` `,1),c(`em`,g,r(t(x)(`ds.hero.headline.em`)),1),o(` `+r(t(x)(`ds.hero.headline.b`)),1)],64))]),_:1},8,[`variant`,`tone`,`reverse`,`eyebrow`,`subheadline`,`image`,`image-alt`,`badge`,`cta-label`,`secondary-label`])],2))}};export{y as default};
|
||||
import{C as e,G as t,j as n,lt as r,m as i,o as a,p as o,r as s,s as c,st as l,u}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{a as d}from"./vue-router-QRVDVSxc.js";import{t as f}from"./i18n-CJQl3WLC.js";import{t as p}from"./Navbar-DRsVuXxb.js";import{t as m}from"./Hero-CBIJn5YV.js";var h={class:`italic font-light text-brand-soft`},g={class:`italic font-light text-brand-soft`},_=`/products/cutouts/kaiser-natron-pulver-250-g-grosspackung-removebg-preview-3.png`,v=`/products/kaiser-natron-bad-500-g.jpg`,y={__name:`HeroPreview`,setup(y){let b=d(),{t:x}=f(),S=a(()=>[`split`,`centered`].includes(b.query.variant)?b.query.variant:`split`),C=a(()=>[`cream`,`paper`,`brand`].includes(b.query.tone)?b.query.tone:`cream`),w=a(()=>b.query.reverse===`1`),T=a(()=>C.value===`brand`?`brand`:C.value),E=a(()=>w.value?v:_),D=a(()=>w.value?`Kaiser-Natron Bad 500 g`:`Kaiser-Natron Pulver 250 g Großpackung`);return(a,d)=>(e(),u(`div`,{class:l([`min-h-screen`,C.value===`brand`?`bg-brand`:`bg-surface`])},[i(p,{variant:T.value,"cart-count":0},null,8,[`variant`]),i(m,{variant:S.value,tone:C.value,reverse:w.value,eyebrow:w.value?t(x)(`home.banner.eyebrow`):t(x)(`ds.hero.eyebrow`),subheadline:w.value?t(x)(`home.banner.sub`):t(x)(`ds.hero.sub`),image:E.value,"image-alt":D.value,badge:w.value?``:t(x)(`ds.badges.featured`),"cta-label":t(x)(`ds.buttons.addToCart`),"secondary-label":t(x)(`ds.buttons.learnMore`)},{headline:n(()=>[w.value?(e(),u(s,{key:0},[o(r(t(x)(`home.banner.headline.a`))+` `,1),c(`em`,h,r(t(x)(`home.banner.headline.em`)),1),o(` `+r(t(x)(`home.banner.headline.b`)),1)],64)):(e(),u(s,{key:1},[o(r(t(x)(`ds.hero.headline.a`))+` `,1),c(`em`,g,r(t(x)(`ds.hero.headline.em`)),1),o(` `+r(t(x)(`ds.hero.headline.b`)),1)],64))]),_:1},8,[`variant`,`tone`,`reverse`,`eyebrow`,`subheadline`,`image`,`image-alt`,`badge`,`cta-label`,`secondary-label`])],2))}};export{y as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{B as e,C as t,G as n,T as r,c as i,ct as a,j as o,lt as s,m as c,o as l,p as u,r as d,s as f,st as p,u as m}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as h}from"./i18n-DrTQks20.js";import{t as g}from"./SectionShell-BEISUYi8.js";import{t as _}from"./DevicePreview-DvIWByfU.js";var v=[`aria-label`],y=[`aria-selected`,`onClick`],b=[`aria-label`],x=[`aria-selected`,`onClick`],S={class:`eyebrow mb-5`},C={__name:`HeroSection`,setup(C){let{t:w}=h(),T=l(()=>[{id:`split`,label:w(`ds.hero.variant.split`)},{id:`centered`,label:w(`ds.hero.variant.centered`)}]),E=l(()=>[{id:`cream`,label:w(`ds.navbar.tone.cream`),swatch:`var(--color-cream)`},{id:`paper`,label:w(`ds.navbar.tone.paper`),swatch:`#ffffff`},{id:`brand`,label:w(`ds.navbar.tone.brand`),swatch:`var(--color-brand)`}]),D=e(`split`),O=e(`cream`),k=l(()=>`/design/preview/hero?variant=${D.value}&tone=${O.value}`);return(e,l)=>(t(),i(g,{eyebrow:n(w)(`ds.eyebrow.components`),title:n(w)(`ds.hero.title`),description:n(w)(`ds.hero.description`),wide:``},{default:o(()=>[f(`section`,null,[c(_,{src:k.value,initial:`desktop`,height:760},{controls:o(()=>[f(`div`,{role:`tablist`,"aria-label":n(w)(`ds.hero.variant.label`),class:`inline-flex items-center p-1 gap-0.5 rounded-pill border border-line bg-paper`},[(t(!0),m(d,null,r(T.value,e=>(t(),m(`button`,{key:e.id,type:`button`,role:`tab`,"aria-selected":D.value===e.id,class:p([`px-3 py-1.5 text-[12px] font-semibold tracking-label rounded-pill transition-colors duration-base`,D.value===e.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:t=>D.value=e.id},s(e.label),11,y))),128))],8,v),f(`div`,{role:`tablist`,"aria-label":n(w)(`ds.navbar.tone`),class:`inline-flex items-center p-1 gap-0.5 rounded-pill border border-line bg-paper`},[(t(!0),m(d,null,r(E.value,e=>(t(),m(`button`,{key:e.id,type:`button`,role:`tab`,"aria-selected":O.value===e.id,class:p([`inline-flex items-center gap-2 px-3 py-1.5 text-[12px] font-semibold tracking-label rounded-pill transition-colors duration-base`,O.value===e.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:t=>O.value=e.id},[f(`span`,{class:`w-2.5 h-2.5 rounded-full border border-line-strong`,style:a({backgroundColor:e.swatch})},null,4),u(` `+s(e.label),1)],10,x))),128))],8,b)]),_:1},8,[`src`])]),f(`section`,null,[f(`h2`,S,s(n(w)(`ds.heading.usage`)),1),l[0]||=f(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[f(`pre`,{class:`whitespace-pre-wrap`},`<Hero
|
||||
import{B as e,C as t,G as n,T as r,c as i,ct as a,j as o,lt as s,m as c,o as l,p as u,r as d,s as f,st as p,u as m}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as h}from"./i18n-CJQl3WLC.js";import{t as g}from"./SectionShell-Cd_Fu3uI.js";import{t as _}from"./DevicePreview-Dx8DzWeH.js";var v=[`aria-label`],y=[`aria-selected`,`onClick`],b=[`aria-label`],x=[`aria-selected`,`onClick`],S={class:`eyebrow mb-5`},C={__name:`HeroSection`,setup(C){let{t:w}=h(),T=l(()=>[{id:`split`,label:w(`ds.hero.variant.split`)},{id:`centered`,label:w(`ds.hero.variant.centered`)}]),E=l(()=>[{id:`cream`,label:w(`ds.navbar.tone.cream`),swatch:`var(--color-cream)`},{id:`paper`,label:w(`ds.navbar.tone.paper`),swatch:`#ffffff`},{id:`brand`,label:w(`ds.navbar.tone.brand`),swatch:`var(--color-brand)`}]),D=e(`split`),O=e(`cream`),k=l(()=>`/design/preview/hero?variant=${D.value}&tone=${O.value}`);return(e,l)=>(t(),i(g,{eyebrow:n(w)(`ds.eyebrow.components`),title:n(w)(`ds.hero.title`),description:n(w)(`ds.hero.description`),wide:``},{default:o(()=>[f(`section`,null,[c(_,{src:k.value,initial:`desktop`,height:760},{controls:o(()=>[f(`div`,{role:`tablist`,"aria-label":n(w)(`ds.hero.variant.label`),class:`inline-flex items-center p-1 gap-0.5 rounded-pill border border-line bg-paper`},[(t(!0),m(d,null,r(T.value,e=>(t(),m(`button`,{key:e.id,type:`button`,role:`tab`,"aria-selected":D.value===e.id,class:p([`px-3 py-1.5 text-[12px] font-semibold tracking-label rounded-pill transition-colors duration-base`,D.value===e.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:t=>D.value=e.id},s(e.label),11,y))),128))],8,v),f(`div`,{role:`tablist`,"aria-label":n(w)(`ds.navbar.tone`),class:`inline-flex items-center p-1 gap-0.5 rounded-pill border border-line bg-paper`},[(t(!0),m(d,null,r(E.value,e=>(t(),m(`button`,{key:e.id,type:`button`,role:`tab`,"aria-selected":O.value===e.id,class:p([`inline-flex items-center gap-2 px-3 py-1.5 text-[12px] font-semibold tracking-label rounded-pill transition-colors duration-base`,O.value===e.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:t=>O.value=e.id},[f(`span`,{class:`w-2.5 h-2.5 rounded-full border border-line-strong`,style:a({backgroundColor:e.swatch})},null,4),u(` `+s(e.label),1)],10,x))),128))],8,b)]),_:1},8,[`src`])]),f(`section`,null,[f(`h2`,S,s(n(w)(`ds.heading.usage`)),1),l[0]||=f(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[f(`pre`,{class:`whitespace-pre-wrap`},`<Hero
|
||||
variant="split"
|
||||
tone="cream"
|
||||
eyebrow="Neu"
|
||||
1
dist/assets/HomePage-BC7_lA69.js
vendored
1
dist/assets/HomePage-BC7_lA69.js
vendored
File diff suppressed because one or more lines are too long
1
dist/assets/HomePage-BLHHqKIy.css
vendored
1
dist/assets/HomePage-BLHHqKIy.css
vendored
@@ -1 +0,0 @@
|
||||
@media (width>=1024px){.banner-shrink-desktop[data-v-697d5bea] img{max-height:48svh}.banner-shrink-desktop[data-v-697d5bea] .relative.mx-auto.w-full.max-w-6xl>div:last-child>div.relative{max-width:460px}}
|
||||
1
dist/assets/HomePage-CvQwUlGw.js
vendored
Normal file
1
dist/assets/HomePage-CvQwUlGw.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
||||
import{B as e,C as t,G as n,M as r,T as i,c as a,j as o,l as s,lt as c,m as l,o as u,r as d,s as f,u as p}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{r as m}from"./runtime-dom.esm-bundler-CcSFQHoC.js";import{n as h,t as g}from"./Icon-BCRRMV3J.js";import{t as _}from"./i18n-DrTQks20.js";import{t as v}from"./SectionShell-BEISUYi8.js";var y={class:`mb-5 flex items-center gap-3 flex-wrap`},b={class:`relative inline-flex items-center`},x={class:`absolute left-3 text-muted pointer-events-none`},S=[`placeholder`],C={class:`text-[12px] text-muted`},w={key:0,class:`text-[14px] text-muted`},T={class:`eyebrow mb-4`},E={class:`grid grid-cols-[repeat(auto-fill,minmax(120px,1fr))] gap-3`},D=[`onClick`],O={class:`w-10 h-10 rounded-sm bg-cream text-brand flex items-center justify-center`},k={class:`font-mono text-[11px] text-muted group-hover:text-brand transition-colors`},A={class:`eyebrow mb-5`},j={class:`grid md:grid-cols-3 gap-4`},M={class:`rounded-md border border-line bg-paper text-brand p-8 flex items-center justify-center gap-6`},N={class:`rounded-md border border-line bg-cream text-brand p-8 flex items-center justify-center gap-6`},P={class:`rounded-md bg-brand text-accent p-8 flex items-center justify-center gap-6`},F={class:`eyebrow mb-5`},I={class:`rounded-md border border-line bg-paper p-8 flex items-end gap-8 text-brand`},L={class:`flex flex-col items-center gap-3`},R={class:`flex flex-col items-center gap-3`},z={class:`font-mono text-[11px] text-muted`},B={class:`flex flex-col items-center gap-3`},V={class:`flex flex-col items-center gap-3`},H={class:`flex flex-col items-center gap-3`},U={class:`eyebrow mb-5`},W={__name:`IconsSection`,setup(W){let{t:G}=_(),K=u(()=>[{title:G(`ds.icons.group.commerce`),names:[`cart`,`bag`,`heart`,`user`,`search`]},{title:G(`ds.icons.group.navigation`),names:[`menu`,`close`,`chevron-left`,`chevron-right`,`chevron-down`,`chevron-up`,`arrow-left`,`arrow-right`]},{title:G(`ds.icons.group.actions`),names:[`plus`,`minus`,`check`]},{title:G(`ds.icons.group.contact`),names:[`mail`,`phone`,`map-pin`,`external-link`]},{title:G(`ds.icons.group.feedback`),names:[`info`,`star`]},{title:G(`ds.icons.group.devices`),names:[`mobile`,`tablet`,`desktop`]}]),q=e(``),J=u(()=>{let e=q.value.trim().toLowerCase();return e?K.value.map(t=>({...t,names:t.names.filter(t=>t.includes(e)||(h[t]?.label||``).toLowerCase().includes(e))})).filter(e=>e.names.length>0):K.value}),Y=e(``);async function X(e){let t=`<Icon name="${e}" />`;try{await navigator.clipboard.writeText(t),Y.value=e,setTimeout(()=>{Y.value===e&&(Y.value=``)},1200)}catch{}}return(e,u)=>(t(),a(v,{eyebrow:n(G)(`ds.eyebrow.components`),title:n(G)(`ds.icons.title`),description:n(G)(`ds.icons.description`)},{default:o(()=>[f(`section`,null,[f(`div`,y,[f(`label`,b,[f(`span`,x,[l(g,{name:`search`,size:16})]),r(f(`input`,{"onUpdate:modelValue":u[0]||=e=>q.value=e,type:`search`,placeholder:n(G)(`ds.icons.search`),class:`pl-9 pr-4 py-2 rounded-pill border border-line bg-paper text-[14px] text-ink placeholder:text-muted focus:outline-none focus:border-brand w-[260px]`},null,8,S),[[m,q.value]])]),f(`span`,C,c(n(G)(`ds.icons.copyHint`)),1)]),J.value.length===0?(t(),p(`div`,w,c(n(G)(`ds.icons.noMatch`))+` "`+c(q.value)+`". `,1)):s(``,!0),(t(!0),p(d,null,i(J.value,e=>(t(),p(`div`,{key:e.title,class:`mb-10 last:mb-0`},[f(`h2`,T,c(e.title),1),f(`div`,E,[(t(!0),p(d,null,i(e.names,e=>(t(),p(`button`,{key:e,type:`button`,class:`group flex flex-col items-center justify-center gap-2 p-4 rounded-md border border-line bg-paper text-ink hover:border-brand-soft hover:-translate-y-0.5 hover:shadow-sm transition-all duration-base ease-out`,onClick:t=>X(e)},[f(`span`,O,[l(g,{name:e,size:22},null,8,[`name`])]),f(`span`,k,c(Y.value===e?n(G)(`ds.icons.copied`):e),1)],8,D))),128))])]))),128))]),f(`section`,null,[f(`h2`,A,c(n(G)(`ds.heading.onDifferentSurfaces`)),1),f(`div`,j,[f(`div`,M,[l(g,{name:`cart`,size:28}),l(g,{name:`heart`,size:28}),l(g,{name:`user`,size:28})]),f(`div`,N,[l(g,{name:`cart`,size:28}),l(g,{name:`heart`,size:28}),l(g,{name:`user`,size:28})]),f(`div`,P,[l(g,{name:`cart`,size:28}),l(g,{name:`heart`,size:28}),l(g,{name:`user`,size:28})])])]),f(`section`,null,[f(`h2`,F,c(n(G)(`ds.heading.sizes`)),1),f(`div`,I,[f(`div`,L,[l(g,{name:`cart`,size:16}),u[1]||=f(`code`,{class:`font-mono text-[11px] text-muted`},`16`,-1)]),f(`div`,R,[l(g,{name:`cart`,size:20}),f(`code`,z,c(n(G)(`ds.icons.sizeDefault`)),1)]),f(`div`,B,[l(g,{name:`cart`,size:24}),u[2]||=f(`code`,{class:`font-mono text-[11px] text-muted`},`24`,-1)]),f(`div`,V,[l(g,{name:`cart`,size:32}),u[3]||=f(`code`,{class:`font-mono text-[11px] text-muted`},`32`,-1)]),f(`div`,H,[l(g,{name:`cart`,size:48}),u[4]||=f(`code`,{class:`font-mono text-[11px] text-muted`},`48`,-1)])])]),f(`section`,null,[f(`h2`,U,c(n(G)(`ds.heading.usage`)),1),u[5]||=f(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[f(`pre`,{class:`whitespace-pre-wrap`},`<Icon name="cart" :size="20" />
|
||||
import{B as e,C as t,G as n,M as r,T as i,c as a,j as o,l as s,lt as c,m as l,o as u,r as d,s as f,u as p}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{r as m}from"./runtime-dom.esm-bundler-CcSFQHoC.js";import{n as h,t as g}from"./Icon-BCRRMV3J.js";import{t as _}from"./i18n-CJQl3WLC.js";import{t as v}from"./SectionShell-Cd_Fu3uI.js";var y={class:`mb-5 flex items-center gap-3 flex-wrap`},b={class:`relative inline-flex items-center`},x={class:`absolute left-3 text-muted pointer-events-none`},S=[`placeholder`],C={class:`text-[12px] text-muted`},w={key:0,class:`text-[14px] text-muted`},T={class:`eyebrow mb-4`},E={class:`grid grid-cols-[repeat(auto-fill,minmax(120px,1fr))] gap-3`},D=[`onClick`],O={class:`w-10 h-10 rounded-sm bg-cream text-brand flex items-center justify-center`},k={class:`font-mono text-[11px] text-muted group-hover:text-brand transition-colors`},A={class:`eyebrow mb-5`},j={class:`grid md:grid-cols-3 gap-4`},M={class:`rounded-md border border-line bg-paper text-brand p-8 flex items-center justify-center gap-6`},N={class:`rounded-md border border-line bg-cream text-brand p-8 flex items-center justify-center gap-6`},P={class:`rounded-md bg-brand text-accent p-8 flex items-center justify-center gap-6`},F={class:`eyebrow mb-5`},I={class:`rounded-md border border-line bg-paper p-8 flex items-end gap-8 text-brand`},L={class:`flex flex-col items-center gap-3`},R={class:`flex flex-col items-center gap-3`},z={class:`font-mono text-[11px] text-muted`},B={class:`flex flex-col items-center gap-3`},V={class:`flex flex-col items-center gap-3`},H={class:`flex flex-col items-center gap-3`},U={class:`eyebrow mb-5`},W={__name:`IconsSection`,setup(W){let{t:G}=_(),K=u(()=>[{title:G(`ds.icons.group.commerce`),names:[`cart`,`bag`,`heart`,`user`,`search`]},{title:G(`ds.icons.group.navigation`),names:[`menu`,`close`,`chevron-left`,`chevron-right`,`chevron-down`,`chevron-up`,`arrow-left`,`arrow-right`]},{title:G(`ds.icons.group.actions`),names:[`plus`,`minus`,`check`]},{title:G(`ds.icons.group.contact`),names:[`mail`,`phone`,`map-pin`,`external-link`]},{title:G(`ds.icons.group.feedback`),names:[`info`,`star`]},{title:G(`ds.icons.group.devices`),names:[`mobile`,`tablet`,`desktop`]}]),q=e(``),J=u(()=>{let e=q.value.trim().toLowerCase();return e?K.value.map(t=>({...t,names:t.names.filter(t=>t.includes(e)||(h[t]?.label||``).toLowerCase().includes(e))})).filter(e=>e.names.length>0):K.value}),Y=e(``);async function X(e){let t=`<Icon name="${e}" />`;try{await navigator.clipboard.writeText(t),Y.value=e,setTimeout(()=>{Y.value===e&&(Y.value=``)},1200)}catch{}}return(e,u)=>(t(),a(v,{eyebrow:n(G)(`ds.eyebrow.components`),title:n(G)(`ds.icons.title`),description:n(G)(`ds.icons.description`)},{default:o(()=>[f(`section`,null,[f(`div`,y,[f(`label`,b,[f(`span`,x,[l(g,{name:`search`,size:16})]),r(f(`input`,{"onUpdate:modelValue":u[0]||=e=>q.value=e,type:`search`,placeholder:n(G)(`ds.icons.search`),class:`pl-9 pr-4 py-2 rounded-pill border border-line bg-paper text-[14px] text-ink placeholder:text-muted focus:outline-none focus:border-brand w-[260px]`},null,8,S),[[m,q.value]])]),f(`span`,C,c(n(G)(`ds.icons.copyHint`)),1)]),J.value.length===0?(t(),p(`div`,w,c(n(G)(`ds.icons.noMatch`))+` "`+c(q.value)+`". `,1)):s(``,!0),(t(!0),p(d,null,i(J.value,e=>(t(),p(`div`,{key:e.title,class:`mb-10 last:mb-0`},[f(`h2`,T,c(e.title),1),f(`div`,E,[(t(!0),p(d,null,i(e.names,e=>(t(),p(`button`,{key:e,type:`button`,class:`group flex flex-col items-center justify-center gap-2 p-4 rounded-md border border-line bg-paper text-ink hover:border-brand-soft hover:-translate-y-0.5 hover:shadow-sm transition-all duration-base ease-out`,onClick:t=>X(e)},[f(`span`,O,[l(g,{name:e,size:22},null,8,[`name`])]),f(`span`,k,c(Y.value===e?n(G)(`ds.icons.copied`):e),1)],8,D))),128))])]))),128))]),f(`section`,null,[f(`h2`,A,c(n(G)(`ds.heading.onDifferentSurfaces`)),1),f(`div`,j,[f(`div`,M,[l(g,{name:`cart`,size:28}),l(g,{name:`heart`,size:28}),l(g,{name:`user`,size:28})]),f(`div`,N,[l(g,{name:`cart`,size:28}),l(g,{name:`heart`,size:28}),l(g,{name:`user`,size:28})]),f(`div`,P,[l(g,{name:`cart`,size:28}),l(g,{name:`heart`,size:28}),l(g,{name:`user`,size:28})])])]),f(`section`,null,[f(`h2`,F,c(n(G)(`ds.heading.sizes`)),1),f(`div`,I,[f(`div`,L,[l(g,{name:`cart`,size:16}),u[1]||=f(`code`,{class:`font-mono text-[11px] text-muted`},`16`,-1)]),f(`div`,R,[l(g,{name:`cart`,size:20}),f(`code`,z,c(n(G)(`ds.icons.sizeDefault`)),1)]),f(`div`,B,[l(g,{name:`cart`,size:24}),u[2]||=f(`code`,{class:`font-mono text-[11px] text-muted`},`24`,-1)]),f(`div`,V,[l(g,{name:`cart`,size:32}),u[3]||=f(`code`,{class:`font-mono text-[11px] text-muted`},`32`,-1)]),f(`div`,H,[l(g,{name:`cart`,size:48}),u[4]||=f(`code`,{class:`font-mono text-[11px] text-muted`},`48`,-1)])])]),f(`section`,null,[f(`h2`,U,c(n(G)(`ds.heading.usage`)),1),u[5]||=f(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[f(`pre`,{class:`whitespace-pre-wrap`},`<Icon name="cart" :size="20" />
|
||||
<Icon name="arrow-right" :size="16" label="Next slide" />`)],-1)])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{W as default};
|
||||
@@ -1 +1 @@
|
||||
import{B as e,C as t,G as n,c as r,j as i,k as a,l as o,lt as s,m as c,o as l,p as u,s as d,st as f,u as p}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as m}from"./i18n-DrTQks20.js";import{t as h}from"./SectionShell-BEISUYi8.js";import{t as g}from"./Card-DM27vc3f.js";var _={class:`flex flex-col gap-2`},v=[`for`],y={key:0,class:`text-danger`},b=[`id`,`type`,`value`,`placeholder`,`disabled`,`required`,`aria-invalid`,`aria-describedby`],x=[`id`],S=[`id`],C={__name:`Input`,props:{modelValue:{type:[String,Number],default:``},label:{type:String,default:``},hint:{type:String,default:``},error:{type:String,default:``},type:{type:String,default:`text`},placeholder:{type:String,default:``},disabled:{type:Boolean,default:!1},required:{type:Boolean,default:!1}},emits:[`update:modelValue`],setup(e){let n=e,r=a(),i=l(()=>`in-${r}`),c=l(()=>n.hint?`hint-${r}`:void 0),m=l(()=>n.error?`err-${r}`:void 0),h=l(()=>[c.value,m.value].filter(Boolean).join(` `)||void 0);return(n,r)=>(t(),p(`div`,_,[e.label?(t(),p(`label`,{key:0,for:i.value,class:`text-[11px] font-bold uppercase tracking-eyebrow text-muted`},[u(s(e.label),1),e.required?(t(),p(`span`,y,` *`)):o(``,!0)],8,v)):o(``,!0),d(`input`,{id:i.value,type:e.type,value:e.modelValue,placeholder:e.placeholder,disabled:e.disabled,required:e.required,"aria-invalid":!!e.error,"aria-describedby":h.value,class:f([`w-full rounded-sm border bg-paper px-4 py-3 text-[15px] text-ink placeholder:text-ink-placeholder transition-colors duration-base focus:outline-none focus:border-brand disabled:opacity-50 disabled:cursor-not-allowed`,e.error?`border-danger`:`border-line`]),onInput:r[0]||=e=>n.$emit(`update:modelValue`,e.target.value)},null,42,b),e.hint&&!e.error?(t(),p(`p`,{key:1,id:c.value,class:`text-[13px] text-muted`},s(e.hint),9,x)):o(``,!0),e.error?(t(),p(`p`,{key:2,id:m.value,class:`text-[13px] text-danger`},s(e.error),9,S)):o(``,!0)]))}},w={class:`eyebrow mb-5`},T={class:`grid md:grid-cols-2 gap-6 max-w-3xl`},E={class:`eyebrow mb-5`},D={class:`grid md:grid-cols-2 gap-6 max-w-3xl`},O={__name:`InputsSection`,setup(a){let{t:o}=m(),l=e(``),u=e(``),f=e(``);return(e,a)=>(t(),r(h,{eyebrow:n(o)(`ds.eyebrow.components`),title:n(o)(`ds.inputs.title`),description:n(o)(`ds.inputs.description`)},{default:i(()=>[d(`section`,null,[d(`h2`,w,s(n(o)(`ds.heading.default`)),1),c(g,{tone:`paper`},{default:i(()=>[d(`div`,T,[c(C,{modelValue:l.value,"onUpdate:modelValue":a[0]||=e=>l.value=e,label:n(o)(`ds.inputs.email`),type:`email`,placeholder:`you@example.com`,hint:n(o)(`ds.inputs.emailHint`)},null,8,[`modelValue`,`label`,`hint`]),c(C,{modelValue:u.value,"onUpdate:modelValue":a[1]||=e=>u.value=e,label:n(o)(`ds.inputs.password`),type:`password`,placeholder:`••••••••`},null,8,[`modelValue`,`label`])])]),_:1})]),d(`section`,null,[d(`h2`,E,s(n(o)(`ds.heading.states`)),1),c(g,{tone:`paper`},{default:i(()=>[d(`div`,D,[c(C,{modelValue:f.value,"onUpdate:modelValue":a[2]||=e=>f.value=e,label:n(o)(`ds.inputs.required`),required:``,error:n(o)(`ds.inputs.requiredError`)},null,8,[`modelValue`,`label`,`error`]),c(C,{label:n(o)(`ds.inputs.disabled`),placeholder:n(o)(`ds.inputs.disabledPlaceholder`),disabled:``},null,8,[`label`,`placeholder`])])]),_:1})])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{O as default};
|
||||
import{B as e,C as t,G as n,c as r,j as i,k as a,l as o,lt as s,m as c,o as l,p as u,s as d,st as f,u as p}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as m}from"./i18n-CJQl3WLC.js";import{t as h}from"./SectionShell-Cd_Fu3uI.js";import{t as g}from"./Card-pgd8VnYH.js";var _={class:`flex flex-col gap-2`},v=[`for`],y={key:0,class:`text-danger`},b=[`id`,`type`,`value`,`placeholder`,`disabled`,`required`,`aria-invalid`,`aria-describedby`],x=[`id`],S=[`id`],C={__name:`Input`,props:{modelValue:{type:[String,Number],default:``},label:{type:String,default:``},hint:{type:String,default:``},error:{type:String,default:``},type:{type:String,default:`text`},placeholder:{type:String,default:``},disabled:{type:Boolean,default:!1},required:{type:Boolean,default:!1}},emits:[`update:modelValue`],setup(e){let n=e,r=a(),i=l(()=>`in-${r}`),c=l(()=>n.hint?`hint-${r}`:void 0),m=l(()=>n.error?`err-${r}`:void 0),h=l(()=>[c.value,m.value].filter(Boolean).join(` `)||void 0);return(n,r)=>(t(),p(`div`,_,[e.label?(t(),p(`label`,{key:0,for:i.value,class:`text-[11px] font-bold uppercase tracking-eyebrow text-muted`},[u(s(e.label),1),e.required?(t(),p(`span`,y,` *`)):o(``,!0)],8,v)):o(``,!0),d(`input`,{id:i.value,type:e.type,value:e.modelValue,placeholder:e.placeholder,disabled:e.disabled,required:e.required,"aria-invalid":!!e.error,"aria-describedby":h.value,class:f([`w-full rounded-sm border bg-paper px-4 py-3 text-[15px] text-ink placeholder:text-ink-placeholder transition-colors duration-base focus:outline-none focus:border-brand disabled:opacity-50 disabled:cursor-not-allowed`,e.error?`border-danger`:`border-line`]),onInput:r[0]||=e=>n.$emit(`update:modelValue`,e.target.value)},null,42,b),e.hint&&!e.error?(t(),p(`p`,{key:1,id:c.value,class:`text-[13px] text-muted`},s(e.hint),9,x)):o(``,!0),e.error?(t(),p(`p`,{key:2,id:m.value,class:`text-[13px] text-danger`},s(e.error),9,S)):o(``,!0)]))}},w={class:`eyebrow mb-5`},T={class:`grid md:grid-cols-2 gap-6 max-w-3xl`},E={class:`eyebrow mb-5`},D={class:`grid md:grid-cols-2 gap-6 max-w-3xl`},O={__name:`InputsSection`,setup(a){let{t:o}=m(),l=e(``),u=e(``),f=e(``);return(e,a)=>(t(),r(h,{eyebrow:n(o)(`ds.eyebrow.components`),title:n(o)(`ds.inputs.title`),description:n(o)(`ds.inputs.description`)},{default:i(()=>[d(`section`,null,[d(`h2`,w,s(n(o)(`ds.heading.default`)),1),c(g,{tone:`paper`},{default:i(()=>[d(`div`,T,[c(C,{modelValue:l.value,"onUpdate:modelValue":a[0]||=e=>l.value=e,label:n(o)(`ds.inputs.email`),type:`email`,placeholder:`you@example.com`,hint:n(o)(`ds.inputs.emailHint`)},null,8,[`modelValue`,`label`,`hint`]),c(C,{modelValue:u.value,"onUpdate:modelValue":a[1]||=e=>u.value=e,label:n(o)(`ds.inputs.password`),type:`password`,placeholder:`••••••••`},null,8,[`modelValue`,`label`])])]),_:1})]),d(`section`,null,[d(`h2`,E,s(n(o)(`ds.heading.states`)),1),c(g,{tone:`paper`},{default:i(()=>[d(`div`,D,[c(C,{modelValue:f.value,"onUpdate:modelValue":a[2]||=e=>f.value=e,label:n(o)(`ds.inputs.required`),required:``,error:n(o)(`ds.inputs.requiredError`)},null,8,[`modelValue`,`label`,`error`]),c(C,{label:n(o)(`ds.inputs.disabled`),placeholder:n(o)(`ds.inputs.disabledPlaceholder`),disabled:``},null,8,[`label`,`placeholder`])])]),_:1})])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{O as default};
|
||||
@@ -1 +1 @@
|
||||
import{C as e,G as t,T as n,lt as r,o as i,r as a,st as o,u as s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as c}from"./i18n-DrTQks20.js";var l=[`aria-label`,`aria-pressed`,`onClick`],u={__name:`LanguageSwitcher`,props:{floating:{type:Boolean,default:!1},tone:{type:String,default:`paper`,validator:e=>[`paper`,`cream`,`brand`].includes(e)}},setup(u){let d=u,{locale:f,setLocale:p,availableLocales:m}=c(),h={paper:{container:`border border-line bg-paper`,active:`bg-brand text-accent`,inactive:`text-muted hover:text-brand`},cream:{container:`border border-line-strong bg-paper`,active:`bg-brand text-accent`,inactive:`text-muted hover:text-brand`},brand:{container:`border border-cream-line bg-cream-wash`,active:`bg-accent text-brand`,inactive:`text-cream hover:text-accent`}},g=i(()=>h[d.tone]);return(i,c)=>(e(),s(`div`,{role:`group`,"aria-label":`Language`,class:o([`inline-flex items-center h-10 px-2 gap-0.5 rounded-pill font-sans`,g.value.container,u.floating?`fixed top-6 right-6 z-[60] shadow-sm`:``])},[(e(!0),s(a,null,n(t(m),n=>(e(),s(`button`,{key:n.code,type:`button`,"aria-label":n.name,"aria-pressed":t(f)===n.code,class:o([`px-2.5 py-1 text-[11px] font-bold tracking-eyebrow rounded-pill transition-colors duration-base`,t(f)===n.code?g.value.active:g.value.inactive]),onClick:e=>t(p)(n.code)},r(n.label),11,l))),128))],2))}};export{u as t};
|
||||
import{C as e,G as t,T as n,lt as r,o as i,r as a,st as o,u as s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as c}from"./i18n-CJQl3WLC.js";var l=[`aria-label`,`aria-pressed`,`onClick`],u={__name:`LanguageSwitcher`,props:{floating:{type:Boolean,default:!1},tone:{type:String,default:`paper`,validator:e=>[`paper`,`cream`,`brand`].includes(e)}},setup(u){let d=u,{locale:f,setLocale:p,availableLocales:m}=c(),h={paper:{container:`border border-line bg-paper`,active:`bg-brand text-accent`,inactive:`text-muted hover:text-brand`},cream:{container:`border border-line-strong bg-paper`,active:`bg-brand text-accent`,inactive:`text-muted hover:text-brand`},brand:{container:`border border-cream-line bg-cream-wash`,active:`bg-accent text-brand`,inactive:`text-cream hover:text-accent`}},g=i(()=>h[d.tone]);return(i,c)=>(e(),s(`div`,{role:`group`,"aria-label":`Language`,class:o([`inline-flex items-center h-10 px-2 gap-0.5 rounded-pill font-sans`,g.value.container,u.floating?`fixed top-6 right-6 z-[60] shadow-sm`:``])},[(e(!0),s(a,null,n(t(m),n=>(e(),s(`button`,{key:n.code,type:`button`,"aria-label":n.name,"aria-pressed":t(f)===n.code,class:o([`px-2.5 py-1 text-[11px] font-bold tracking-eyebrow rounded-pill transition-colors duration-base`,t(f)===n.code?g.value.active:g.value.inactive]),onClick:e=>t(p)(n.code)},r(n.label),11,l))),128))],2))}};export{u as t};
|
||||
@@ -1,3 +1,3 @@
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,s as o}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as s}from"./i18n-DrTQks20.js";import{t as c}from"./LanguageSwitcher-sWIzrbUO.js";import{t as l}from"./SectionShell-BEISUYi8.js";import{t as u}from"./Card-DM27vc3f.js";var d={class:`eyebrow mb-5`},f={class:`grid md:grid-cols-3 gap-4`},p={class:`eyebrow mb-4`},m={class:`text-[13px] text-muted mt-4 leading-relaxed`},h={class:`eyebrow mb-4`},g={class:`text-[13px] text-muted mt-4 leading-relaxed`},_={class:`eyebrow mb-4`},v={class:`text-[13px] opacity-80 mt-4 leading-relaxed`},y={class:`eyebrow mb-5`},b={class:`text-[13px] text-muted max-w-2xl leading-relaxed`},x={class:`eyebrow mb-5`},S={__name:`LanguageSwitcherSection`,setup(S){let{t:C}=s();return(s,S)=>(e(),n(l,{eyebrow:t(C)(`ds.eyebrow.components`),title:t(C)(`ds.language.title`),description:t(C)(`ds.language.description`)},{default:r(()=>[o(`section`,null,[o(`h2`,d,i(t(C)(`ds.heading.onDifferentSurfaces`)),1),o(`div`,f,[a(u,{tone:`paper`},{default:r(()=>[o(`p`,p,i(t(C)(`ds.cards.paper`)),1),a(c,{tone:`paper`}),o(`p`,m,i(t(C)(`ds.language.paperNote`)),1)]),_:1}),a(u,{tone:`cream`},{default:r(()=>[o(`p`,h,i(t(C)(`ds.cards.cream`)),1),a(c,{tone:`cream`}),o(`p`,g,i(t(C)(`ds.language.creamNote`)),1)]),_:1}),a(u,{tone:`brand`},{default:r(()=>[o(`p`,_,i(t(C)(`ds.cards.brand`)),1),a(c,{tone:`brand`}),o(`p`,v,i(t(C)(`ds.language.brandNote`)),1)]),_:1})])]),o(`section`,null,[o(`h2`,y,i(t(C)(`ds.language.floating`)),1),a(u,{tone:`paper`},{default:r(()=>[o(`p`,b,i(t(C)(`ds.language.floatingNote`)),1)]),_:1})]),o(`section`,null,[o(`h2`,x,i(t(C)(`ds.heading.usage`)),1),S[0]||=o(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[o(`pre`,{class:`whitespace-pre-wrap`},`<LanguageSwitcher />
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,s as o}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as s}from"./i18n-CJQl3WLC.js";import{t as c}from"./LanguageSwitcher-D0mrMmyq.js";import{t as l}from"./SectionShell-Cd_Fu3uI.js";import{t as u}from"./Card-pgd8VnYH.js";var d={class:`eyebrow mb-5`},f={class:`grid md:grid-cols-3 gap-4`},p={class:`eyebrow mb-4`},m={class:`text-[13px] text-muted mt-4 leading-relaxed`},h={class:`eyebrow mb-4`},g={class:`text-[13px] text-muted mt-4 leading-relaxed`},_={class:`eyebrow mb-4`},v={class:`text-[13px] opacity-80 mt-4 leading-relaxed`},y={class:`eyebrow mb-5`},b={class:`text-[13px] text-muted max-w-2xl leading-relaxed`},x={class:`eyebrow mb-5`},S={__name:`LanguageSwitcherSection`,setup(S){let{t:C}=s();return(s,S)=>(e(),n(l,{eyebrow:t(C)(`ds.eyebrow.components`),title:t(C)(`ds.language.title`),description:t(C)(`ds.language.description`)},{default:r(()=>[o(`section`,null,[o(`h2`,d,i(t(C)(`ds.heading.onDifferentSurfaces`)),1),o(`div`,f,[a(u,{tone:`paper`},{default:r(()=>[o(`p`,p,i(t(C)(`ds.cards.paper`)),1),a(c,{tone:`paper`}),o(`p`,m,i(t(C)(`ds.language.paperNote`)),1)]),_:1}),a(u,{tone:`cream`},{default:r(()=>[o(`p`,h,i(t(C)(`ds.cards.cream`)),1),a(c,{tone:`cream`}),o(`p`,g,i(t(C)(`ds.language.creamNote`)),1)]),_:1}),a(u,{tone:`brand`},{default:r(()=>[o(`p`,_,i(t(C)(`ds.cards.brand`)),1),a(c,{tone:`brand`}),o(`p`,v,i(t(C)(`ds.language.brandNote`)),1)]),_:1})])]),o(`section`,null,[o(`h2`,y,i(t(C)(`ds.language.floating`)),1),a(u,{tone:`paper`},{default:r(()=>[o(`p`,b,i(t(C)(`ds.language.floatingNote`)),1)]),_:1})]),o(`section`,null,[o(`h2`,x,i(t(C)(`ds.heading.usage`)),1),S[0]||=o(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[o(`pre`,{class:`whitespace-pre-wrap`},`<LanguageSwitcher />
|
||||
<LanguageSwitcher tone="brand" />
|
||||
<LanguageSwitcher floating />`)],-1)])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{S as default};
|
||||
@@ -1 +1 @@
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,s as o}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as s}from"./Logo-FFBeOKwm.js";import{t as c}from"./i18n-DrTQks20.js";import{t as l}from"./SectionShell-BEISUYi8.js";var u={class:`eyebrow mb-5`},d={class:`grid md:grid-cols-3 gap-4`},f={class:`rounded-md border border-line bg-paper p-10 flex flex-col items-center gap-4`},p={class:`font-mono text-[11px] text-muted`},m={class:`rounded-md border border-line bg-cream p-10 flex flex-col items-center gap-4`},h={class:`font-mono text-[11px] text-muted`},g={class:`rounded-md bg-brand p-10 flex flex-col items-center gap-4`},_={class:`font-mono text-[11px] text-cream opacity-70`},v={class:`eyebrow mb-5`},y={class:`rounded-md border border-line bg-paper p-10 flex items-end gap-10 flex-wrap`},b={class:`flex flex-col items-center gap-3`},x={class:`flex flex-col items-center gap-3`},S={class:`flex flex-col items-center gap-3`},C={class:`eyebrow mb-5`},w={class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},T={class:`mb-2 text-muted`},E={__name:`LogoSection`,setup(E){let{t:D}=c();return(c,E)=>(e(),n(l,{eyebrow:t(D)(`ds.eyebrow.brand`),title:t(D)(`ds.logo.title`),description:t(D)(`ds.logo.description`)},{default:r(()=>[o(`section`,null,[o(`h2`,u,i(t(D)(`ds.heading.onDifferentSurfaces`)),1),o(`div`,d,[o(`div`,f,[a(s,{class:`w-40 h-auto text-brand`}),o(`code`,p,i(t(D)(`ds.cards.paper`)),1)]),o(`div`,m,[a(s,{class:`w-40 h-auto text-brand`}),o(`code`,h,i(t(D)(`ds.cards.cream`)),1)]),o(`div`,g,[a(s,{class:`w-40 h-auto text-paper`}),o(`code`,_,i(t(D)(`ds.cards.brand`)),1)])])]),o(`section`,null,[o(`h2`,v,i(t(D)(`ds.heading.sizes`)),1),o(`div`,y,[o(`div`,b,[a(s,{class:`w-16 h-auto text-brand`}),E[0]||=o(`code`,{class:`font-mono text-[11px] text-muted`},`w-16`,-1)]),o(`div`,x,[a(s,{class:`w-32 h-auto text-brand`}),E[1]||=o(`code`,{class:`font-mono text-[11px] text-muted`},`w-32`,-1)]),o(`div`,S,[a(s,{class:`w-60 h-auto text-brand`}),E[2]||=o(`code`,{class:`font-mono text-[11px] text-muted`},`w-60`,-1)])])]),o(`section`,null,[o(`h2`,C,i(t(D)(`ds.heading.usage`)),1),o(`div`,w,[o(`p`,T,i(t(D)(`ds.logo.usageIntro`)),1),E[3]||=o(`pre`,{class:`whitespace-pre-wrap`},`<Logo class="w-60 h-auto text-brand" />`,-1)])])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{E as default};
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,s as o}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as s}from"./Logo-FFBeOKwm.js";import{t as c}from"./i18n-CJQl3WLC.js";import{t as l}from"./SectionShell-Cd_Fu3uI.js";var u={class:`eyebrow mb-5`},d={class:`grid md:grid-cols-3 gap-4`},f={class:`rounded-md border border-line bg-paper p-10 flex flex-col items-center gap-4`},p={class:`font-mono text-[11px] text-muted`},m={class:`rounded-md border border-line bg-cream p-10 flex flex-col items-center gap-4`},h={class:`font-mono text-[11px] text-muted`},g={class:`rounded-md bg-brand p-10 flex flex-col items-center gap-4`},_={class:`font-mono text-[11px] text-cream opacity-70`},v={class:`eyebrow mb-5`},y={class:`rounded-md border border-line bg-paper p-10 flex items-end gap-10 flex-wrap`},b={class:`flex flex-col items-center gap-3`},x={class:`flex flex-col items-center gap-3`},S={class:`flex flex-col items-center gap-3`},C={class:`eyebrow mb-5`},w={class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},T={class:`mb-2 text-muted`},E={__name:`LogoSection`,setup(E){let{t:D}=c();return(c,E)=>(e(),n(l,{eyebrow:t(D)(`ds.eyebrow.brand`),title:t(D)(`ds.logo.title`),description:t(D)(`ds.logo.description`)},{default:r(()=>[o(`section`,null,[o(`h2`,u,i(t(D)(`ds.heading.onDifferentSurfaces`)),1),o(`div`,d,[o(`div`,f,[a(s,{class:`w-40 h-auto text-brand`}),o(`code`,p,i(t(D)(`ds.cards.paper`)),1)]),o(`div`,m,[a(s,{class:`w-40 h-auto text-brand`}),o(`code`,h,i(t(D)(`ds.cards.cream`)),1)]),o(`div`,g,[a(s,{class:`w-40 h-auto text-paper`}),o(`code`,_,i(t(D)(`ds.cards.brand`)),1)])])]),o(`section`,null,[o(`h2`,v,i(t(D)(`ds.heading.sizes`)),1),o(`div`,y,[o(`div`,b,[a(s,{class:`w-16 h-auto text-brand`}),E[0]||=o(`code`,{class:`font-mono text-[11px] text-muted`},`w-16`,-1)]),o(`div`,x,[a(s,{class:`w-32 h-auto text-brand`}),E[1]||=o(`code`,{class:`font-mono text-[11px] text-muted`},`w-32`,-1)]),o(`div`,S,[a(s,{class:`w-60 h-auto text-brand`}),E[2]||=o(`code`,{class:`font-mono text-[11px] text-muted`},`w-60`,-1)])])]),o(`section`,null,[o(`h2`,C,i(t(D)(`ds.heading.usage`)),1),o(`div`,w,[o(`p`,T,i(t(D)(`ds.logo.usageIntro`)),1),E[3]||=o(`pre`,{class:`whitespace-pre-wrap`},`<Logo class="w-60 h-auto text-brand" />`,-1)])])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{E as default};
|
||||
File diff suppressed because one or more lines are too long
1
dist/assets/Navbar-DRsVuXxb.js
vendored
Normal file
1
dist/assets/Navbar-DRsVuXxb.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/assets/Navbar-DTKm8Xku.js
vendored
1
dist/assets/Navbar-DTKm8Xku.js
vendored
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{C as e,T as t,ct as n,m as r,o as i,r as a,s as o,u as s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{a as c}from"./vue-router-QRVDVSxc.js";import{t as l}from"./Navbar-DTKm8Xku.js";var u={class:`min-h-screen bg-surface`},d={class:`max-w-5xl mx-auto px-6 py-16 space-y-6`},f={__name:`NavbarPreview`,setup(f){let p=c(),m=i(()=>{let e=p.query.variant;return[`paper`,`cream`,`brand`].includes(e)?e:`paper`}),h=i(()=>p.query.layout===`floating`?`floating`:`standard`);return(i,c)=>(e(),s(`div`,u,[r(l,{variant:m.value,layout:h.value,"cart-count":2},null,8,[`variant`,`layout`]),o(`div`,d,[(e(),s(a,null,t([40,28,40,32,40,28,36,40],e=>o(`div`,{key:e,class:`rounded-md border border-line bg-paper`,style:n({height:e*4+`px`})},null,4)),64))])]))}};export{f as default};
|
||||
import{C as e,T as t,ct as n,m as r,o as i,r as a,s as o,u as s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{a as c}from"./vue-router-QRVDVSxc.js";import{t as l}from"./Navbar-DRsVuXxb.js";var u={class:`min-h-screen bg-surface`},d={class:`max-w-5xl mx-auto px-6 py-16 space-y-6`},f={__name:`NavbarPreview`,setup(f){let p=c(),m=i(()=>{let e=p.query.variant;return[`paper`,`cream`,`brand`].includes(e)?e:`paper`}),h=i(()=>p.query.layout===`floating`?`floating`:`standard`);return(i,c)=>(e(),s(`div`,u,[r(l,{variant:m.value,layout:h.value,"cart-count":2},null,8,[`variant`,`layout`]),o(`div`,d,[(e(),s(a,null,t([40,28,40,32,40,28,36,40],e=>o(`div`,{key:e,class:`rounded-md border border-line bg-paper`,style:n({height:e*4+`px`})},null,4)),64))])]))}};export{f as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{B as e,C as t,G as n,T as r,c as i,ct as a,j as o,lt as s,m as c,o as l,p as u,r as d,s as f,st as p,u as m}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as h}from"./i18n-DrTQks20.js";import{t as g}from"./SectionShell-BEISUYi8.js";import{t as _}from"./DevicePreview-DvIWByfU.js";var v=[`aria-label`],y=[`aria-selected`,`onClick`],b=[`aria-label`],x=[`aria-selected`,`onClick`],S={class:`eyebrow mb-5`},C={__name:`NavbarSection`,setup(C){let{t:w}=h(),T=l(()=>[{id:`paper`,label:w(`ds.navbar.tone.paper`),swatch:`#ffffff`},{id:`cream`,label:w(`ds.navbar.tone.cream`),swatch:`var(--color-cream)`},{id:`brand`,label:w(`ds.navbar.tone.brand`),swatch:`var(--color-brand)`}]),E=l(()=>[{id:`standard`,label:w(`ds.navbar.layout.standard`)},{id:`floating`,label:w(`ds.navbar.layout.floating`)}]),D=e(`paper`),O=e(`standard`),k=l(()=>`/design/preview/navbar?variant=${D.value}&layout=${O.value}`);return(e,l)=>(t(),i(g,{eyebrow:n(w)(`ds.eyebrow.components`),title:n(w)(`ds.navbar.title`),description:n(w)(`ds.navbar.description`),wide:``},{default:o(()=>[f(`section`,null,[c(_,{src:k.value,initial:`mobile`,height:720},{controls:o(()=>[f(`div`,{role:`tablist`,"aria-label":n(w)(`ds.navbar.layout`),class:`inline-flex items-center p-1 gap-0.5 rounded-pill border border-line bg-paper`},[(t(!0),m(d,null,r(E.value,e=>(t(),m(`button`,{key:e.id,type:`button`,role:`tab`,"aria-selected":O.value===e.id,class:p([`px-3 py-1.5 text-[12px] font-semibold tracking-label rounded-pill transition-colors duration-base`,O.value===e.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:t=>O.value=e.id},s(e.label),11,y))),128))],8,v),f(`div`,{role:`tablist`,"aria-label":n(w)(`ds.navbar.tone`),class:`inline-flex items-center p-1 gap-0.5 rounded-pill border border-line bg-paper`},[(t(!0),m(d,null,r(T.value,e=>(t(),m(`button`,{key:e.id,type:`button`,role:`tab`,"aria-selected":D.value===e.id,class:p([`inline-flex items-center gap-2 px-3 py-1.5 text-[12px] font-semibold tracking-label rounded-pill transition-colors duration-base`,D.value===e.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:t=>D.value=e.id},[f(`span`,{class:`w-2.5 h-2.5 rounded-full border border-line-strong`,style:a({backgroundColor:e.swatch})},null,4),u(` `+s(e.label),1)],10,x))),128))],8,b)]),_:1},8,[`src`])]),f(`section`,null,[f(`h2`,S,s(n(w)(`ds.heading.usage`)),1),l[0]||=f(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[f(`pre`,{class:`whitespace-pre-wrap`},`<Navbar
|
||||
import{B as e,C as t,G as n,T as r,c as i,ct as a,j as o,lt as s,m as c,o as l,p as u,r as d,s as f,st as p,u as m}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as h}from"./i18n-CJQl3WLC.js";import{t as g}from"./SectionShell-Cd_Fu3uI.js";import{t as _}from"./DevicePreview-Dx8DzWeH.js";var v=[`aria-label`],y=[`aria-selected`,`onClick`],b=[`aria-label`],x=[`aria-selected`,`onClick`],S={class:`eyebrow mb-5`},C={__name:`NavbarSection`,setup(C){let{t:w}=h(),T=l(()=>[{id:`paper`,label:w(`ds.navbar.tone.paper`),swatch:`#ffffff`},{id:`cream`,label:w(`ds.navbar.tone.cream`),swatch:`var(--color-cream)`},{id:`brand`,label:w(`ds.navbar.tone.brand`),swatch:`var(--color-brand)`}]),E=l(()=>[{id:`standard`,label:w(`ds.navbar.layout.standard`)},{id:`floating`,label:w(`ds.navbar.layout.floating`)}]),D=e(`paper`),O=e(`standard`),k=l(()=>`/design/preview/navbar?variant=${D.value}&layout=${O.value}`);return(e,l)=>(t(),i(g,{eyebrow:n(w)(`ds.eyebrow.components`),title:n(w)(`ds.navbar.title`),description:n(w)(`ds.navbar.description`),wide:``},{default:o(()=>[f(`section`,null,[c(_,{src:k.value,initial:`mobile`,height:720},{controls:o(()=>[f(`div`,{role:`tablist`,"aria-label":n(w)(`ds.navbar.layout`),class:`inline-flex items-center p-1 gap-0.5 rounded-pill border border-line bg-paper`},[(t(!0),m(d,null,r(E.value,e=>(t(),m(`button`,{key:e.id,type:`button`,role:`tab`,"aria-selected":O.value===e.id,class:p([`px-3 py-1.5 text-[12px] font-semibold tracking-label rounded-pill transition-colors duration-base`,O.value===e.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:t=>O.value=e.id},s(e.label),11,y))),128))],8,v),f(`div`,{role:`tablist`,"aria-label":n(w)(`ds.navbar.tone`),class:`inline-flex items-center p-1 gap-0.5 rounded-pill border border-line bg-paper`},[(t(!0),m(d,null,r(T.value,e=>(t(),m(`button`,{key:e.id,type:`button`,role:`tab`,"aria-selected":D.value===e.id,class:p([`inline-flex items-center gap-2 px-3 py-1.5 text-[12px] font-semibold tracking-label rounded-pill transition-colors duration-base`,D.value===e.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:t=>D.value=e.id},[f(`span`,{class:`w-2.5 h-2.5 rounded-full border border-line-strong`,style:a({backgroundColor:e.swatch})},null,4),u(` `+s(e.label),1)],10,x))),128))],8,b)]),_:1},8,[`src`])]),f(`section`,null,[f(`h2`,S,s(n(w)(`ds.heading.usage`)),1),l[0]||=f(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[f(`pre`,{class:`whitespace-pre-wrap`},`<Navbar
|
||||
variant="paper"
|
||||
layout="floating"
|
||||
:items="[{ key: 'nav.shop', href: '/shop' }]"
|
||||
1
dist/assets/ProductCard-Cxy5I4vQ.js
vendored
Normal file
1
dist/assets/ProductCard-Cxy5I4vQ.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{C as e,G as t,O as n,c as r,j as i,l as a,lt as o,m as s,o as c,p as l,s as u,st as d,u as f}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as p}from"./Icon-BCRRMV3J.js";import{t as m}from"./i18n-CJQl3WLC.js";import{t as h}from"./Badge-DcvgVKep.js";import{t as g}from"./Button-DkdaDkuf.js";var _=[`src`,`alt`],v={class:`flex flex-col gap-3 p-6`},y={class:`flex flex-col gap-1`},b={key:0,class:`text-sm text-muted tracking-label`},x={class:`mt-auto flex items-center justify-between gap-3 pt-2`},S={class:`font-display text-2xl font-normal text-brand`},C={key:0,class:`text-xs font-semibold tracking-label uppercase text-danger`},w={__name:`ProductCard`,props:{title:{type:String,required:!0},size:{type:String,default:``},price:{type:[String,Number],required:!0},currency:{type:String,default:`€`},image:{type:String,required:!0},imageAlt:{type:String,default:``},badge:{type:String,default:``},badgeVariant:{type:String,default:`accent`,validator:e=>[`neutral`,`brand`,`accent`,`subtle`,`success`,`warning`,`danger`].includes(e)},tone:{type:String,default:`paper`,validator:e=>[`paper`,`cream`].includes(e)},inStock:{type:Boolean,default:!0},href:{type:String,default:``}},emits:[`add`],setup(w){let T=w,{t:E}=m(),D={paper:{surface:`bg-paper`,media:`bg-cream`,border:`border-line`},cream:{surface:`bg-cream`,media:`bg-paper`,border:`border-line`}},O=c(()=>D[T.tone]),k=c(()=>typeof T.price==`number`?`${T.currency} ${T.price.toFixed(2).replace(`.`,`,`)}`:`${T.currency} ${T.price}`);return(c,m)=>(e(),f(`article`,{class:d([`group flex flex-col overflow-hidden rounded-md border transition-all duration-base ease-out`,O.value.surface,O.value.border,`hover:-translate-y-1 hover:shadow-md hover:border-brand-soft`])},[(e(),r(n(w.href?`a`:`div`),{href:w.href||null,class:d([`relative block aspect-[4/5] overflow-hidden`,O.value.media])},{default:i(()=>[w.badge?(e(),r(h,{key:0,variant:w.badgeVariant,class:`absolute top-4 left-4 z-[1]`},{default:i(()=>[l(o(w.badge),1)]),_:1},8,[`variant`])):a(``,!0),u(`img`,{src:w.image,alt:w.imageAlt||w.title,loading:`lazy`,decoding:`async`,class:`absolute inset-0 w-full h-full object-contain p-8 transition-transform duration-slow ease-out group-hover:scale-105`},null,8,_)]),_:1},8,[`href`,`class`])),u(`div`,v,[u(`div`,y,[(e(),r(n(w.href?`a`:`h3`),{href:w.href||null,class:d([`font-display text-xl font-normal leading-tight text-ink`,w.href?`hover:text-brand transition-colors duration-base`:``])},{default:i(()=>[l(o(w.title),1)]),_:1},8,[`href`,`class`])),w.size?(e(),f(`p`,b,o(w.size),1)):a(``,!0)]),u(`div`,x,[u(`span`,S,o(k.value),1),w.inStock?a(``,!0):(e(),f(`span`,C,o(t(E)(`ds.product.outOfStock`)),1))]),s(g,{variant:`primary`,size:`md`,block:``,disabled:!w.inStock,onClick:m[0]||=e=>c.$emit(`add`)},{before:i(()=>[s(p,{name:`plus`,size:16})]),default:i(()=>[l(` `+o(t(E)(`ds.buttons.addToCart`)),1)]),_:1},8,[`disabled`])])],2))}};export{w as t};
|
||||
11
dist/assets/ProductsSection-DstmW8dO.js
vendored
11
dist/assets/ProductsSection-DstmW8dO.js
vendored
@@ -1,11 +0,0 @@
|
||||
import{B as e,C as t,G as n,O as r,c as i,j as a,l as o,lt as s,m as c,o as l,p as u,s as d,st as f,u as p}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as m}from"./Icon-BCRRMV3J.js";import{t as h}from"./i18n-DrTQks20.js";import{t as g}from"./Badge-DcvgVKep.js";import{t as _}from"./Button-DkdaDkuf.js";import{t as v}from"./SectionShell-BEISUYi8.js";var y=[`src`,`alt`],b={class:`flex flex-col gap-3 p-6`},x={class:`flex flex-col gap-1`},S={key:0,class:`text-sm text-muted tracking-label`},C={class:`mt-auto flex items-center justify-between gap-3 pt-2`},w={class:`font-display text-2xl font-normal text-brand`},T={key:0,class:`text-xs font-semibold tracking-label uppercase text-danger`},E={__name:`ProductCard`,props:{title:{type:String,required:!0},size:{type:String,default:``},price:{type:[String,Number],required:!0},currency:{type:String,default:`€`},image:{type:String,required:!0},imageAlt:{type:String,default:``},badge:{type:String,default:``},badgeVariant:{type:String,default:`accent`,validator:e=>[`neutral`,`brand`,`accent`,`subtle`,`success`,`warning`,`danger`].includes(e)},tone:{type:String,default:`paper`,validator:e=>[`paper`,`cream`].includes(e)},inStock:{type:Boolean,default:!0},href:{type:String,default:``}},emits:[`add`],setup(e){let v=e,{t:E}=h(),D={paper:{surface:`bg-paper`,media:`bg-cream`,border:`border-line`},cream:{surface:`bg-cream`,media:`bg-paper`,border:`border-line`}},O=l(()=>D[v.tone]),k=l(()=>typeof v.price==`number`?`${v.currency} ${v.price.toFixed(2).replace(`.`,`,`)}`:`${v.currency} ${v.price}`);return(l,h)=>(t(),p(`article`,{class:f([`group flex flex-col overflow-hidden rounded-md border transition-all duration-base ease-out`,O.value.surface,O.value.border,`hover:-translate-y-1 hover:shadow-md hover:border-brand-soft`])},[(t(),i(r(e.href?`a`:`div`),{href:e.href||null,class:f([`relative block aspect-[4/5] overflow-hidden`,O.value.media])},{default:a(()=>[e.badge?(t(),i(g,{key:0,variant:e.badgeVariant,class:`absolute top-4 left-4 z-[1]`},{default:a(()=>[u(s(e.badge),1)]),_:1},8,[`variant`])):o(``,!0),d(`img`,{src:e.image,alt:e.imageAlt||e.title,loading:`lazy`,decoding:`async`,class:`absolute inset-0 w-full h-full object-contain p-8 transition-transform duration-slow ease-out group-hover:scale-105`},null,8,y)]),_:1},8,[`href`,`class`])),d(`div`,b,[d(`div`,x,[(t(),i(r(e.href?`a`:`h3`),{href:e.href||null,class:f([`font-display text-xl font-normal leading-tight text-ink`,e.href?`hover:text-brand transition-colors duration-base`:``])},{default:a(()=>[u(s(e.title),1)]),_:1},8,[`href`,`class`])),e.size?(t(),p(`p`,S,s(e.size),1)):o(``,!0)]),d(`div`,C,[d(`span`,w,s(k.value),1),e.inStock?o(``,!0):(t(),p(`span`,T,s(n(E)(`ds.product.outOfStock`)),1))]),c(_,{variant:`primary`,size:`md`,block:``,disabled:!e.inStock,onClick:h[0]||=e=>l.$emit(`add`)},{before:a(()=>[c(m,{name:`plus`,size:16})]),default:a(()=>[u(` `+s(n(E)(`ds.buttons.addToCart`)),1)]),_:1},8,[`disabled`])])],2))}},D={class:`eyebrow mb-5`},O={class:`grid sm:grid-cols-2 lg:grid-cols-3 gap-6`},k={key:0,class:`mt-5 text-sm text-muted`},A={class:`font-mono text-[12px]`},j={class:`eyebrow mb-5`},M={class:`grid sm:grid-cols-2 lg:grid-cols-3 gap-6`},N={class:`eyebrow mb-5`},P=`/products/cutouts/kaiser-natron-pulver-250-g-grosspackung-removebg-preview-1.png`,F={__name:`ProductsSection`,setup(r){let{t:l}=h(),f=e(``);function m(e){f.value=e,setTimeout(()=>{f.value===e&&(f.value=``)},2e3)}return(e,r)=>(t(),i(v,{eyebrow:n(l)(`ds.eyebrow.components`),title:n(l)(`ds.product.title`),description:n(l)(`ds.product.description`)},{default:a(()=>[d(`section`,null,[d(`h2`,D,s(n(l)(`ds.heading.default`)),1),d(`div`,O,[c(E,{title:`Kaiser-Natron® Pulver`,size:`250 g Großpackung`,price:4.49,image:P,"image-alt":`Kaiser-Natron Pulver 250 g Großpackung`,href:`#`,onAdd:r[0]||=e=>m(`pulver-250`)}),c(E,{title:`Kaiser-Natron® Pulver`,size:`250 g Großpackung`,price:4.49,image:P,badge:n(l)(`ds.badges.featured`),"badge-variant":`accent`,href:`#`,onAdd:r[1]||=e=>m(`pulver-250-featured`)},null,8,[`badge`]),c(E,{title:`Kaiser-Natron® Pulver`,size:`250 g Großpackung`,price:4.49,image:P,tone:`cream`,href:`#`,onAdd:r[2]||=e=>m(`pulver-250-cream`)})]),f.value?(t(),p(`p`,k,[u(s(n(l)(`ds.product.added`))+`: `,1),d(`code`,A,s(f.value),1)])):o(``,!0)]),d(`section`,null,[d(`h2`,j,s(n(l)(`ds.heading.states`)),1),d(`div`,M,[c(E,{title:`Kaiser-Natron® Pulver`,size:`250 g Großpackung`,price:4.49,image:P,"in-stock":!1}),c(E,{title:`Kaiser-Natron® Pulver`,size:`250 g Großpackung`,price:4.49,image:P,badge:n(l)(`ds.badges.newRelease`),"badge-variant":`brand`,href:`#`},null,8,[`badge`])])]),d(`section`,null,[d(`h2`,N,s(n(l)(`ds.heading.usage`)),1),r[3]||=d(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[d(`pre`,{class:`whitespace-pre-wrap`},`<ProductCard
|
||||
title="Kaiser-Natron® Pulver"
|
||||
size="250 g Großpackung"
|
||||
:price="4.49"
|
||||
image="/products/cutouts/…-removebg-preview.png"
|
||||
badge="Bestseller"
|
||||
badge-variant="accent"
|
||||
tone="paper"
|
||||
href="/kaiser-natron-pulver-250-g-grosspackung"
|
||||
@add="addToCart(sku)"
|
||||
/>`)],-1)])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{F as default};
|
||||
11
dist/assets/ProductsSection-qRzVWVuD.js
vendored
Normal file
11
dist/assets/ProductsSection-qRzVWVuD.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import{B as e,C as t,G as n,c as r,j as i,l as a,lt as o,m as s,p as c,s as l,u}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as d}from"./i18n-CJQl3WLC.js";import{t as f}from"./ProductCard-Cxy5I4vQ.js";import{t as p}from"./SectionShell-Cd_Fu3uI.js";var m={class:`eyebrow mb-5`},h={class:`grid sm:grid-cols-2 lg:grid-cols-3 gap-6`},g={key:0,class:`mt-5 text-sm text-muted`},_={class:`font-mono text-[12px]`},v={class:`eyebrow mb-5`},y={class:`grid sm:grid-cols-2 lg:grid-cols-3 gap-6`},b={class:`eyebrow mb-5`},x=`/products/cutouts/kaiser-natron-pulver-250-g-grosspackung-removebg-preview-1.png`,S={__name:`ProductsSection`,setup(S){let{t:C}=d(),w=e(``);function T(e){w.value=e,setTimeout(()=>{w.value===e&&(w.value=``)},2e3)}return(e,d)=>(t(),r(p,{eyebrow:n(C)(`ds.eyebrow.components`),title:n(C)(`ds.product.title`),description:n(C)(`ds.product.description`)},{default:i(()=>[l(`section`,null,[l(`h2`,m,o(n(C)(`ds.heading.default`)),1),l(`div`,h,[s(f,{title:`Kaiser-Natron® Pulver`,size:`250 g Großpackung`,price:4.49,image:x,"image-alt":`Kaiser-Natron Pulver 250 g Großpackung`,href:`#`,onAdd:d[0]||=e=>T(`pulver-250`)}),s(f,{title:`Kaiser-Natron® Pulver`,size:`250 g Großpackung`,price:4.49,image:x,badge:n(C)(`ds.badges.featured`),"badge-variant":`accent`,href:`#`,onAdd:d[1]||=e=>T(`pulver-250-featured`)},null,8,[`badge`]),s(f,{title:`Kaiser-Natron® Pulver`,size:`250 g Großpackung`,price:4.49,image:x,tone:`cream`,href:`#`,onAdd:d[2]||=e=>T(`pulver-250-cream`)})]),w.value?(t(),u(`p`,g,[c(o(n(C)(`ds.product.added`))+`: `,1),l(`code`,_,o(w.value),1)])):a(``,!0)]),l(`section`,null,[l(`h2`,v,o(n(C)(`ds.heading.states`)),1),l(`div`,y,[s(f,{title:`Kaiser-Natron® Pulver`,size:`250 g Großpackung`,price:4.49,image:x,"in-stock":!1}),s(f,{title:`Kaiser-Natron® Pulver`,size:`250 g Großpackung`,price:4.49,image:x,badge:n(C)(`ds.badges.newRelease`),"badge-variant":`brand`,href:`#`},null,8,[`badge`])])]),l(`section`,null,[l(`h2`,b,o(n(C)(`ds.heading.usage`)),1),d[3]||=l(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[l(`pre`,{class:`whitespace-pre-wrap`},`<ProductCard
|
||||
title="Kaiser-Natron® Pulver"
|
||||
size="250 g Großpackung"
|
||||
:price="4.49"
|
||||
image="/products/cutouts/…-removebg-preview.png"
|
||||
badge="Bestseller"
|
||||
badge-variant="accent"
|
||||
tone="paper"
|
||||
href="/kaiser-natron-pulver-250-g-grosspackung"
|
||||
@add="addToCart(sku)"
|
||||
/>`)],-1)])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{S as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{B as e,C as t,G as n,c as r,j as i,lt as a,m as o,s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as c}from"./i18n-DrTQks20.js";import{t as l}from"./QuantityStepper-Bjh3X3wE.js";import{t as u}from"./SectionShell-BEISUYi8.js";var d={class:`eyebrow mb-5`},f={class:`flex flex-wrap items-center gap-6`},p={class:`eyebrow mb-5`},m={class:`flex flex-wrap items-center gap-6`},h={class:`flex flex-col gap-2`},g={class:`eyebrow`},_={class:`flex flex-col gap-2`},v={class:`eyebrow`},y={class:`flex flex-col gap-2`},b={class:`eyebrow`},x={class:`eyebrow mb-5`},S={__name:`QuantityStepperSection`,setup(S){let{t:C}=c(),w=e(1),T=e(3),E=e(5),D=e(2);return(e,c)=>(t(),r(u,{eyebrow:n(C)(`ds.eyebrow.components`),title:n(C)(`ds.qtyStepper.title`),description:n(C)(`ds.qtyStepper.description`)},{default:i(()=>[s(`section`,null,[s(`h2`,d,a(n(C)(`ds.heading.sizes`)),1),s(`div`,f,[o(l,{modelValue:w.value,"onUpdate:modelValue":c[0]||=e=>w.value=e,size:`sm`,"decrease-label":n(C)(`cart.qty.decrease`),"increase-label":n(C)(`cart.qty.increase`)},null,8,[`modelValue`,`decrease-label`,`increase-label`]),o(l,{modelValue:T.value,"onUpdate:modelValue":c[1]||=e=>T.value=e,size:`md`,"decrease-label":n(C)(`cart.qty.decrease`),"increase-label":n(C)(`cart.qty.increase`)},null,8,[`modelValue`,`decrease-label`,`increase-label`])])]),s(`section`,null,[s(`h2`,p,a(n(C)(`ds.heading.states`)),1),s(`div`,m,[s(`div`,h,[s(`span`,g,a(n(C)(`ds.qtyStepper.minBoundary`)),1),o(l,{"model-value":0,min:0,"decrease-label":n(C)(`cart.qty.decrease`),"increase-label":n(C)(`cart.qty.increase`)},null,8,[`decrease-label`,`increase-label`])]),s(`div`,_,[s(`span`,v,a(n(C)(`ds.qtyStepper.maxBoundary`)),1),o(l,{modelValue:E.value,"onUpdate:modelValue":c[2]||=e=>E.value=e,max:5,"decrease-label":n(C)(`cart.qty.decrease`),"increase-label":n(C)(`cart.qty.increase`)},null,8,[`modelValue`,`decrease-label`,`increase-label`])]),s(`div`,y,[s(`span`,b,a(n(C)(`ds.buttons.disabled`)),1),o(l,{modelValue:D.value,"onUpdate:modelValue":c[3]||=e=>D.value=e,disabled:``,"decrease-label":n(C)(`cart.qty.decrease`),"increase-label":n(C)(`cart.qty.increase`)},null,8,[`modelValue`,`decrease-label`,`increase-label`])])])]),s(`section`,null,[s(`h2`,x,a(n(C)(`ds.heading.usage`)),1),c[4]||=s(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[s(`pre`,{class:`whitespace-pre-wrap`},`<QuantityStepper
|
||||
import{B as e,C as t,G as n,c as r,j as i,lt as a,m as o,s}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as c}from"./i18n-CJQl3WLC.js";import{t as l}from"./QuantityStepper-Bjh3X3wE.js";import{t as u}from"./SectionShell-Cd_Fu3uI.js";var d={class:`eyebrow mb-5`},f={class:`flex flex-wrap items-center gap-6`},p={class:`eyebrow mb-5`},m={class:`flex flex-wrap items-center gap-6`},h={class:`flex flex-col gap-2`},g={class:`eyebrow`},_={class:`flex flex-col gap-2`},v={class:`eyebrow`},y={class:`flex flex-col gap-2`},b={class:`eyebrow`},x={class:`eyebrow mb-5`},S={__name:`QuantityStepperSection`,setup(S){let{t:C}=c(),w=e(1),T=e(3),E=e(5),D=e(2);return(e,c)=>(t(),r(u,{eyebrow:n(C)(`ds.eyebrow.components`),title:n(C)(`ds.qtyStepper.title`),description:n(C)(`ds.qtyStepper.description`)},{default:i(()=>[s(`section`,null,[s(`h2`,d,a(n(C)(`ds.heading.sizes`)),1),s(`div`,f,[o(l,{modelValue:w.value,"onUpdate:modelValue":c[0]||=e=>w.value=e,size:`sm`,"decrease-label":n(C)(`cart.qty.decrease`),"increase-label":n(C)(`cart.qty.increase`)},null,8,[`modelValue`,`decrease-label`,`increase-label`]),o(l,{modelValue:T.value,"onUpdate:modelValue":c[1]||=e=>T.value=e,size:`md`,"decrease-label":n(C)(`cart.qty.decrease`),"increase-label":n(C)(`cart.qty.increase`)},null,8,[`modelValue`,`decrease-label`,`increase-label`])])]),s(`section`,null,[s(`h2`,p,a(n(C)(`ds.heading.states`)),1),s(`div`,m,[s(`div`,h,[s(`span`,g,a(n(C)(`ds.qtyStepper.minBoundary`)),1),o(l,{"model-value":0,min:0,"decrease-label":n(C)(`cart.qty.decrease`),"increase-label":n(C)(`cart.qty.increase`)},null,8,[`decrease-label`,`increase-label`])]),s(`div`,_,[s(`span`,v,a(n(C)(`ds.qtyStepper.maxBoundary`)),1),o(l,{modelValue:E.value,"onUpdate:modelValue":c[2]||=e=>E.value=e,max:5,"decrease-label":n(C)(`cart.qty.decrease`),"increase-label":n(C)(`cart.qty.increase`)},null,8,[`modelValue`,`decrease-label`,`increase-label`])]),s(`div`,y,[s(`span`,b,a(n(C)(`ds.buttons.disabled`)),1),o(l,{modelValue:D.value,"onUpdate:modelValue":c[3]||=e=>D.value=e,disabled:``,"decrease-label":n(C)(`cart.qty.decrease`),"increase-label":n(C)(`cart.qty.increase`)},null,8,[`modelValue`,`decrease-label`,`increase-label`])])])]),s(`section`,null,[s(`h2`,x,a(n(C)(`ds.heading.usage`)),1),c[4]||=s(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[s(`pre`,{class:`whitespace-pre-wrap`},`<QuantityStepper
|
||||
v-model="quantity"
|
||||
:min="0"
|
||||
:max="10"
|
||||
@@ -1 +1 @@
|
||||
import{C as e,G as t,T as n,c as r,ct as i,j as a,lt as o,r as s,s as c,u as l}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as u}from"./i18n-DrTQks20.js";import{t as d}from"./SectionShell-BEISUYi8.js";var f={class:`grid grid-cols-2 sm:grid-cols-3 gap-6`},p={class:`font-mono text-[12px] text-ink block`},m={class:`text-[12px] text-muted mt-1`},h={__name:`RadiiSection`,setup(h){let{t:g}=u(),_=[{name:`xs`,value:`6px`},{name:`sm`,value:`10px`},{name:`md`,value:`16px`},{name:`lg`,value:`20px`},{name:`xl`,value:`28px`},{name:`pill`,value:`100px`}];return(u,h)=>(e(),r(d,{eyebrow:t(g)(`ds.eyebrow.tokens`),title:t(g)(`ds.radii.title`),description:t(g)(`ds.radii.description`)},{default:a(()=>[c(`div`,f,[(e(),l(s,null,n(_,e=>c(`div`,{key:e.name,class:`flex flex-col items-center`},[c(`div`,{class:`h-32 w-full bg-paper border border-line mb-4 shadow-sm`,style:i({borderRadius:`var(--radius-${e.name})`})},null,4),c(`code`,p,`--radius-`+o(e.name),1),c(`span`,m,o(e.value),1)])),64))])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{h as default};
|
||||
import{C as e,G as t,T as n,c as r,ct as i,j as a,lt as o,r as s,s as c,u as l}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as u}from"./i18n-CJQl3WLC.js";import{t as d}from"./SectionShell-Cd_Fu3uI.js";var f={class:`grid grid-cols-2 sm:grid-cols-3 gap-6`},p={class:`font-mono text-[12px] text-ink block`},m={class:`text-[12px] text-muted mt-1`},h={__name:`RadiiSection`,setup(h){let{t:g}=u(),_=[{name:`xs`,value:`6px`},{name:`sm`,value:`10px`},{name:`md`,value:`16px`},{name:`lg`,value:`20px`},{name:`xl`,value:`28px`},{name:`pill`,value:`100px`}];return(u,h)=>(e(),r(d,{eyebrow:t(g)(`ds.eyebrow.tokens`),title:t(g)(`ds.radii.title`),description:t(g)(`ds.radii.description`)},{default:a(()=>[c(`div`,f,[(e(),l(s,null,n(_,e=>c(`div`,{key:e.name,class:`flex flex-col items-center`},[c(`div`,{class:`h-32 w-full bg-paper border border-line mb-4 shadow-sm`,style:i({borderRadius:`var(--radius-${e.name})`})},null,4),c(`code`,p,`--radius-`+o(e.name),1),c(`span`,m,o(e.value),1)])),64))])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{h as default};
|
||||
1
dist/assets/Revitalization-BT7qlXRm.css
vendored
Normal file
1
dist/assets/Revitalization-BT7qlXRm.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.rv-orbit[data-v-04135cd6]{width:var(--size-orbit);height:var(--size-orbit);justify-content:center;align-items:center;display:inline-flex;position:relative}.rv-orbit-ring[data-v-04135cd6]{border:1px solid color-mix(in oklab, var(--color-accent) 60%, transparent);background:color-mix(in oklab, var(--color-accent) 6%, transparent);animation:var(--animate-orbit);border-radius:9999px;position:absolute;inset:0}.rv-orbit-dot[data-v-04135cd6]{background:var(--color-accent);width:6px;height:6px;box-shadow:0 0 8px color-mix(in oklab, var(--color-accent) 55%, transparent);border-radius:9999px;margin-left:-3px;position:absolute;top:-3px;left:50%}.rv-orbit-center[data-v-04135cd6]{filter:drop-shadow(0 1px 2px #00000040);font-size:22px;line-height:1}
|
||||
1
dist/assets/Revitalization-D6Ehuu8K.js
vendored
Normal file
1
dist/assets/Revitalization-D6Ehuu8K.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{C as e,T as t,c as n,ct as r,j as i,l as a,lt as o,m as s,p as c,r as l,s as u,u as d}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as f}from"./_plugin-vue_export-helper-BOai-rQB.js";import{t as p}from"./Badge-DcvgVKep.js";import{t as m}from"./Button-DkdaDkuf.js";var h={id:`revitalize`,class:`bg-brand text-cream`},g={class:`mx-auto w-full max-w-6xl px-6 py-16 sm:px-8 sm:py-20 md:px-12 md:py-24 lg:px-16 lg:py-28`},_={class:`flex flex-col items-center text-center gap-6 max-w-3xl mx-auto`},v={key:1,class:`font-display font-normal leading-[1.04] tracking-tight text-headline-lg`},y={key:0,class:`italic font-light text-accent-soft`},b={key:2,class:`text-lg leading-relaxed text-cream/80 max-w-2xl`},x={key:0,class:`mt-10 md:mt-14 grid gap-6 sm:grid-cols-3 sm:gap-8 max-w-4xl mx-auto`},S={"aria-hidden":`true`,class:`rv-orbit`},C={key:0,class:`rv-orbit-center`},w={class:`font-sans text-base font-semibold text-cream leading-snug`},T={key:1,class:`mt-10 md:mt-14 flex justify-center`},E=f({__name:`Revitalization`,props:{eyebrow:{type:String,default:``},headline:{type:String,default:``},headlineEm:{type:String,default:``},sub:{type:String,default:``},features:{type:Array,default:()=>[],validator:e=>e.every(e=>typeof e==`string`||e&&typeof e==`object`&&typeof e.title==`string`)},notifyCta:{type:String,default:``}},emits:[`notify`],setup(f){return(E,D)=>(e(),d(`section`,h,[u(`div`,g,[u(`div`,_,[f.eyebrow?(e(),n(p,{key:0,variant:`accent`},{default:i(()=>[c(o(f.eyebrow),1)]),_:1})):a(``,!0),f.headline||f.headlineEm?(e(),d(`h2`,v,[c(o(f.headline)+` `,1),f.headlineEm?(e(),d(`em`,y,o(f.headlineEm),1)):a(``,!0)])):a(``,!0),f.sub?(e(),d(`p`,b,o(f.sub),1)):a(``,!0)]),f.features.length?(e(),d(`ul`,x,[(e(!0),d(l,null,t(f.features.slice(0,3),(t,n)=>(e(),d(`li`,{key:typeof t==`string`?t:t.title,class:`flex flex-col items-center gap-4 text-center`},[u(`span`,S,[u(`span`,{class:`rv-orbit-ring`,style:r({animationDelay:`${n*-5}s`})},[...D[1]||=[u(`span`,{class:`rv-orbit-dot`},null,-1)]],4),typeof t==`object`&&t.icon?(e(),d(`span`,C,o(t.icon),1)):a(``,!0)]),u(`span`,w,o(typeof t==`string`?t:t.title),1)]))),128))])):a(``,!0),f.notifyCta?(e(),d(`div`,T,[s(m,{variant:`accent`,size:`lg`,onClick:D[0]||=e=>E.$emit(`notify`)},{default:i(()=>[c(o(f.notifyCta),1)]),_:1})])):a(``,!0)])]))}},[[`__scopeId`,`data-v-04135cd6`]]);export{E as t};
|
||||
1
dist/assets/Revitalization-Dbf9J8TA.js
vendored
1
dist/assets/Revitalization-Dbf9J8TA.js
vendored
@@ -1 +0,0 @@
|
||||
import{C as e,T as t,c as n,ct as r,j as i,l as a,lt as o,m as s,p as c,r as l,s as u,u as d}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as f}from"./_plugin-vue_export-helper-BOai-rQB.js";import{t as p}from"./Badge-DcvgVKep.js";import{t as m}from"./Button-DkdaDkuf.js";var h={id:`revitalize`,class:`bg-brand text-cream`},g={class:`mx-auto w-full max-w-6xl px-6 py-16 sm:px-8 sm:py-20 md:px-12 md:py-24 lg:px-16 lg:py-28`},_={class:`flex flex-col items-center text-center gap-6 max-w-3xl mx-auto`},v={key:1,class:`font-display font-normal leading-[1.04] tracking-tight`,style:{"font-size":`clamp(2.25rem, 5vw, 3.75rem)`}},y={key:0,class:`italic font-light text-accent-soft`},b={key:2,class:`text-lg leading-relaxed text-cream/80 max-w-2xl`},x={key:0,class:`mt-10 md:mt-14 grid gap-6 sm:grid-cols-3 sm:gap-8 max-w-4xl mx-auto`},S={"aria-hidden":`true`,class:`rv-orbit`},C={key:0,class:`rv-orbit-center`},w={class:`font-sans text-base font-semibold text-cream leading-snug`},T={key:1,class:`mt-10 md:mt-14 flex justify-center`},E=f({__name:`Revitalization`,props:{eyebrow:{type:String,default:``},headline:{type:String,default:``},headlineEm:{type:String,default:``},sub:{type:String,default:``},features:{type:Array,default:()=>[],validator:e=>e.every(e=>typeof e==`string`||e&&typeof e==`object`&&typeof e.title==`string`)},notifyCta:{type:String,default:``}},emits:[`notify`],setup(f){return(E,D)=>(e(),d(`section`,h,[u(`div`,g,[u(`div`,_,[f.eyebrow?(e(),n(p,{key:0,variant:`accent`},{default:i(()=>[c(o(f.eyebrow),1)]),_:1})):a(``,!0),f.headline||f.headlineEm?(e(),d(`h2`,v,[c(o(f.headline)+` `,1),f.headlineEm?(e(),d(`em`,y,o(f.headlineEm),1)):a(``,!0)])):a(``,!0),f.sub?(e(),d(`p`,b,o(f.sub),1)):a(``,!0)]),f.features.length?(e(),d(`ul`,x,[(e(!0),d(l,null,t(f.features.slice(0,3),(t,n)=>(e(),d(`li`,{key:typeof t==`string`?t:t.title,class:`flex flex-col items-center gap-4 text-center`},[u(`span`,S,[u(`span`,{class:`rv-orbit-ring`,style:r({animationDelay:`${n*-5}s`})},[...D[1]||=[u(`span`,{class:`rv-orbit-dot`},null,-1)]],4),typeof t==`object`&&t.icon?(e(),d(`span`,C,o(t.icon),1)):a(``,!0)]),u(`span`,w,o(typeof t==`string`?t:t.title),1)]))),128))])):a(``,!0),f.notifyCta?(e(),d(`div`,T,[s(m,{variant:`accent`,size:`lg`,onClick:D[0]||=e=>E.$emit(`notify`)},{default:i(()=>[c(o(f.notifyCta),1)]),_:1})])):a(``,!0)])]))}},[[`__scopeId`,`data-v-ec4233b0`]]);export{E as t};
|
||||
1
dist/assets/Revitalization-DnKrmED6.css
vendored
1
dist/assets/Revitalization-DnKrmED6.css
vendored
@@ -1 +0,0 @@
|
||||
.rv-orbit[data-v-ec4233b0]{justify-content:center;align-items:center;width:72px;height:72px;display:inline-flex;position:relative}.rv-orbit-ring[data-v-ec4233b0]{border:1px solid color-mix(in oklab, var(--color-accent) 60%, transparent);background:color-mix(in oklab, var(--color-accent) 6%, transparent);animation:var(--animate-orbit);border-radius:9999px;position:absolute;inset:0}.rv-orbit-dot[data-v-ec4233b0]{background:var(--color-accent);width:6px;height:6px;box-shadow:0 0 8px color-mix(in oklab, var(--color-accent) 55%, transparent);border-radius:9999px;margin-left:-3px;position:absolute;top:-3px;left:50%}.rv-orbit-center[data-v-ec4233b0]{filter:drop-shadow(0 1px 2px #00000040);font-size:22px;line-height:1}
|
||||
@@ -1 +1 @@
|
||||
import{C as e,G as t,m as n,o as r,u as i}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as a}from"./i18n-DrTQks20.js";import{t as o}from"./Revitalization-Dbf9J8TA.js";var s={class:`min-h-screen bg-brand`},c={__name:`RevitalizationPreview`,setup(c){let{t:l}=a(),u=r(()=>[{title:l(`revit.feature.1.title`),icon:`⚗️`},{title:l(`revit.feature.2.title`),icon:`💊`},{title:l(`revit.feature.3.title`),icon:`🌿`}]);return(r,a)=>(e(),i(`div`,s,[n(o,{eyebrow:t(l)(`revit.eyebrow`),headline:t(l)(`revit.headline.a`),"headline-em":t(l)(`revit.headline.em`),sub:t(l)(`revit.sub`),features:u.value,"notify-cta":t(l)(`revit.notifyCta`)},null,8,[`eyebrow`,`headline`,`headline-em`,`sub`,`features`,`notify-cta`])]))}};export{c as default};
|
||||
import{C as e,G as t,m as n,o as r,u as i}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as a}from"./i18n-CJQl3WLC.js";import{t as o}from"./Revitalization-D6Ehuu8K.js";var s={class:`min-h-screen bg-brand`},c={__name:`RevitalizationPreview`,setup(c){let{t:l}=a(),u=r(()=>[{title:l(`revit.feature.1.title`),icon:`⚗️`},{title:l(`revit.feature.2.title`),icon:`💊`},{title:l(`revit.feature.3.title`),icon:`🌿`}]);return(r,a)=>(e(),i(`div`,s,[n(o,{eyebrow:t(l)(`revit.eyebrow`),headline:t(l)(`revit.headline.a`),"headline-em":t(l)(`revit.headline.em`),sub:t(l)(`revit.sub`),features:u.value,"notify-cta":t(l)(`revit.notifyCta`)},null,8,[`eyebrow`,`headline`,`headline-em`,`sub`,`features`,`notify-cta`])]))}};export{c as default};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,s as o}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as s}from"./i18n-DrTQks20.js";import{t as c}from"./SectionShell-BEISUYi8.js";import{t as l}from"./DevicePreview-DvIWByfU.js";var u={class:`eyebrow mb-5`},d=`/design/preview/revitalization`,f={__name:`RevitalizationSection`,setup(f){let{t:p}=s();return(s,f)=>(e(),n(c,{eyebrow:t(p)(`ds.eyebrow.components`),title:t(p)(`ds.revitalization.title`),description:t(p)(`ds.revitalization.description`),wide:``},{default:r(()=>[o(`section`,null,[a(l,{src:d,initial:`desktop`,height:720})]),o(`section`,null,[o(`h2`,u,i(t(p)(`ds.heading.usage`)),1),f[0]||=o(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[o(`pre`,{class:`whitespace-pre-wrap`},`<Revitalization
|
||||
import{C as e,G as t,c as n,j as r,lt as i,m as a,s as o}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as s}from"./i18n-CJQl3WLC.js";import{t as c}from"./SectionShell-Cd_Fu3uI.js";import{t as l}from"./DevicePreview-Dx8DzWeH.js";var u={class:`eyebrow mb-5`},d=`/design/preview/revitalization`,f={__name:`RevitalizationSection`,setup(f){let{t:p}=s();return(s,f)=>(e(),n(c,{eyebrow:t(p)(`ds.eyebrow.components`),title:t(p)(`ds.revitalization.title`),description:t(p)(`ds.revitalization.description`),wide:``},{default:r(()=>[o(`section`,null,[a(l,{src:d,initial:`desktop`,height:720})]),o(`section`,null,[o(`h2`,u,i(t(p)(`ds.heading.usage`)),1),f[0]||=o(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[o(`pre`,{class:`whitespace-pre-wrap`},`<Revitalization
|
||||
:eyebrow="t('revit.eyebrow')"
|
||||
:headline="t('revit.headline.a')"
|
||||
:headline-em="t('revit.headline.em')"
|
||||
1
dist/assets/Search-5Gw6O_vh.js
vendored
1
dist/assets/Search-5Gw6O_vh.js
vendored
File diff suppressed because one or more lines are too long
1
dist/assets/Search-BYh1LNrJ.js
vendored
Normal file
1
dist/assets/Search-BYh1LNrJ.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/assets/Search-CnDOJpVS.css
vendored
1
dist/assets/Search-CnDOJpVS.css
vendored
@@ -1 +0,0 @@
|
||||
.search-input[data-v-3782d7e2]::-webkit-search-cancel-button{appearance:none}.search-input[data-v-3782d7e2]::-webkit-search-decoration{appearance:none}
|
||||
1
dist/assets/Search-dtR7osTa.css
vendored
Normal file
1
dist/assets/Search-dtR7osTa.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.search-input[data-v-5b95e6b1]::-webkit-search-cancel-button{appearance:none}.search-input[data-v-5b95e6b1]::-webkit-search-decoration{appearance:none}
|
||||
@@ -1,4 +1,4 @@
|
||||
import{B as e,C as t,G as n,T as r,c as i,j as a,lt as o,m as s,p as c,r as l,s as u,u as d}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as f}from"./Icon-BCRRMV3J.js";import{t as p}from"./i18n-DrTQks20.js";import{t as m}from"./Search-5Gw6O_vh.js";import{n as h,r as g}from"./products-GEWPSJSp.js";import{t as _}from"./Button-DkdaDkuf.js";import{t as v}from"./SectionShell-BEISUYi8.js";var y={class:`eyebrow mb-5`},b={class:`rounded-md border border-line bg-paper p-6 flex flex-col sm:flex-row sm:items-center gap-4`},x={class:`text-[13px] text-muted`},S={class:`eyebrow mb-5`},C={class:`rounded-md border border-line bg-paper divide-y divide-line overflow-hidden`},w=[`src`,`alt`],T={class:`min-w-0 flex-1`},E={class:`text-[14px] font-semibold text-ink truncate`},D={class:`text-[12px] text-muted truncate`},O={class:`shrink-0 text-[13px] font-semibold text-brand`},k={class:`eyebrow mb-5`},A=`natron pulver`,j={__name:`SearchSection`,setup(j){let{t:M}=p(),N=e(!1),P=g(A,h,4);return(e,p)=>(t(),i(v,{eyebrow:n(M)(`ds.eyebrow.components`),title:n(M)(`ds.search.title`),description:n(M)(`ds.search.description`)},{default:a(()=>[u(`section`,null,[u(`h2`,y,o(n(M)(`ds.heading.default`)),1),u(`div`,b,[s(_,{variant:`primary`,onClick:p[0]||=e=>N.value=!0},{before:a(()=>[s(f,{name:`search`,size:18})]),default:a(()=>[c(` `+o(n(M)(`ds.search.demo.label`)),1)]),_:1}),u(`p`,x,o(n(M)(`ds.search.demo.hint`)),1)])]),u(`section`,null,[u(`h2`,S,o(n(M)(`ds.heading.variants`))+` — "`+o(A)+`"`,1),u(`ul`,C,[(t(!0),d(l,null,r(n(P),e=>(t(),d(`li`,{key:e.id,class:`flex items-center gap-4 px-4 py-3`},[u(`img`,{src:e.image,alt:e.title,loading:`lazy`,decoding:`async`,class:`shrink-0 w-12 h-12 rounded-sm object-cover bg-cream`},null,8,w),u(`div`,T,[u(`p`,E,o(e.title),1),u(`p`,D,o(e.size)+` · `+o(e.category),1)]),u(`span`,O,`€ `+o(e.price.toFixed(2).replace(`.`,`,`)),1)]))),128))])]),u(`section`,null,[u(`h2`,k,o(n(M)(`ds.heading.usage`)),1),p[2]||=u(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[u(`pre`,{class:`whitespace-pre-wrap`},`import { products } from '@/api/products.js'
|
||||
import{B as e,C as t,G as n,T as r,c as i,j as a,lt as o,m as s,p as c,r as l,s as u,u as d}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as f}from"./Icon-BCRRMV3J.js";import{t as p}from"./i18n-CJQl3WLC.js";import{t as m}from"./Search-BYh1LNrJ.js";import{a as h,r as g}from"./products-Dhgp5EjC.js";import{t as _}from"./Button-DkdaDkuf.js";import{t as v}from"./SectionShell-Cd_Fu3uI.js";var y={class:`eyebrow mb-5`},b={class:`rounded-md border border-line bg-paper p-6 flex flex-col sm:flex-row sm:items-center gap-4`},x={class:`text-[13px] text-muted`},S={class:`eyebrow mb-5`},C={class:`rounded-md border border-line bg-paper divide-y divide-line overflow-hidden`},w=[`src`,`alt`],T={class:`min-w-0 flex-1`},E={class:`text-[14px] font-semibold text-ink truncate`},D={class:`text-[12px] text-muted truncate`},O={class:`shrink-0 text-[13px] font-semibold text-brand`},k={class:`eyebrow mb-5`},A=`natron pulver`,j={__name:`SearchSection`,setup(j){let{t:M}=p(),N=e(!1),P=h(A,g,4);return(e,p)=>(t(),i(v,{eyebrow:n(M)(`ds.eyebrow.components`),title:n(M)(`ds.search.title`),description:n(M)(`ds.search.description`)},{default:a(()=>[u(`section`,null,[u(`h2`,y,o(n(M)(`ds.heading.default`)),1),u(`div`,b,[s(_,{variant:`primary`,onClick:p[0]||=e=>N.value=!0},{before:a(()=>[s(f,{name:`search`,size:18})]),default:a(()=>[c(` `+o(n(M)(`ds.search.demo.label`)),1)]),_:1}),u(`p`,x,o(n(M)(`ds.search.demo.hint`)),1)])]),u(`section`,null,[u(`h2`,S,o(n(M)(`ds.heading.variants`))+` — "`+o(A)+`"`,1),u(`ul`,C,[(t(!0),d(l,null,r(n(P),e=>(t(),d(`li`,{key:e.id,class:`flex items-center gap-4 px-4 py-3`},[u(`img`,{src:e.image,alt:e.title,loading:`lazy`,decoding:`async`,class:`shrink-0 w-12 h-12 rounded-sm object-cover bg-cream`},null,8,w),u(`div`,T,[u(`p`,E,o(e.title),1),u(`p`,D,o(e.size)+` · `+o(e.category),1)]),u(`span`,O,`€ `+o(e.price.toFixed(2).replace(`.`,`,`)),1)]))),128))])]),u(`section`,null,[u(`h2`,k,o(n(M)(`ds.heading.usage`)),1),p[2]||=u(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[u(`pre`,{class:`whitespace-pre-wrap`},`import { products } from '@/api/products.js'
|
||||
import Search from '@/design-system/components/Search.vue'
|
||||
|
||||
const open = ref(false)
|
||||
@@ -8,4 +8,4 @@ const open = ref(false)
|
||||
// Navbar already renders its own Search overlay, so most callers
|
||||
// just pass the catalogue in:
|
||||
|
||||
<Navbar :products="products" />`)],-1)]),s(m,{open:N.value,"onUpdate:open":p[1]||=e=>N.value=e,products:n(h)},null,8,[`open`,`products`])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{j as default};
|
||||
<Navbar :products="products" />`)],-1)]),s(m,{open:N.value,"onUpdate:open":p[1]||=e=>N.value=e,products:n(g)},null,8,[`open`,`products`])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{j as default};
|
||||
@@ -1 +1 @@
|
||||
import{C as e,G as t,T as n,c as r,ct as i,j as a,lt as o,o as s,r as c,s as l,u}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as d}from"./i18n-DrTQks20.js";import{t as f}from"./SectionShell-BEISUYi8.js";var p={class:`grid sm:grid-cols-3 gap-8`},m={class:`font-mono text-[12px] text-ink block`},h={class:`text-[13px] text-muted mt-1`},g={__name:`ShadowsSection`,setup(g){let{t:_}=d(),v=s(()=>[{name:`sm`,css:`var(--shadow-sm)`,note:_(`ds.shadows.sm.note`)},{name:`md`,css:`var(--shadow-md)`,note:_(`ds.shadows.md.note`)},{name:`lg`,css:`var(--shadow-lg)`,note:_(`ds.shadows.lg.note`)}]);return(s,d)=>(e(),r(f,{eyebrow:t(_)(`ds.eyebrow.tokens`),title:t(_)(`ds.shadows.title`),description:t(_)(`ds.shadows.description`)},{default:a(()=>[l(`div`,p,[(e(!0),u(c,null,n(v.value,t=>(e(),u(`div`,{key:t.name,class:`space-y-4`},[l(`div`,{class:`h-36 rounded-md bg-paper`,style:i({boxShadow:t.css})},null,4),l(`div`,null,[l(`code`,m,`--shadow-`+o(t.name),1),l(`p`,h,o(t.note),1)])]))),128))])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{g as default};
|
||||
import{C as e,G as t,T as n,c as r,ct as i,j as a,lt as o,o as s,r as c,s as l,u}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as d}from"./i18n-CJQl3WLC.js";import{t as f}from"./SectionShell-Cd_Fu3uI.js";var p={class:`grid sm:grid-cols-3 gap-8`},m={class:`font-mono text-[12px] text-ink block`},h={class:`text-[13px] text-muted mt-1`},g={__name:`ShadowsSection`,setup(g){let{t:_}=d(),v=s(()=>[{name:`sm`,css:`var(--shadow-sm)`,note:_(`ds.shadows.sm.note`)},{name:`md`,css:`var(--shadow-md)`,note:_(`ds.shadows.md.note`)},{name:`lg`,css:`var(--shadow-lg)`,note:_(`ds.shadows.lg.note`)}]);return(s,d)=>(e(),r(f,{eyebrow:t(_)(`ds.eyebrow.tokens`),title:t(_)(`ds.shadows.title`),description:t(_)(`ds.shadows.description`)},{default:a(()=>[l(`div`,p,[(e(!0),u(c,null,n(v.value,t=>(e(),u(`div`,{key:t.name,class:`space-y-4`},[l(`div`,{class:`h-36 rounded-md bg-paper`,style:i({boxShadow:t.css})},null,4),l(`div`,null,[l(`code`,m,`--shadow-`+o(t.name),1),l(`p`,h,o(t.note),1)])]))),128))])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{g as default};
|
||||
1
dist/assets/ShopPage-BDztc4FL.js
vendored
Normal file
1
dist/assets/ShopPage-BDztc4FL.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{C as e,G as t,T as n,c as r,j as i,lt as a,m as o,r as s,s as c,st as l,u}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as d}from"./i18n-DrTQks20.js";import{t as f}from"./SectionShell-BEISUYi8.js";import{t as p}from"./Card-DM27vc3f.js";var m={class:`grid md:grid-cols-2 gap-6`},h={class:`eyebrow mb-3`},g={class:`text-[14px] text-muted leading-relaxed`},_={class:`eyebrow mb-3`},v={class:`text-[14px] text-muted leading-relaxed`},y={class:`eyebrow mb-6`},b={class:`divide-y divide-line rounded-md border border-line bg-paper px-6`},x={class:`font-mono text-[11px] text-muted w-24 shrink-0`},S={__name:`TypographySection`,setup(S){let{t:C}=d(),w=[`xs`,`sm`,`base`,`lg`,`xl`,`2xl`,`3xl`,`4xl`,`5xl`];return(d,S)=>(e(),r(f,{eyebrow:t(C)(`ds.eyebrow.tokens`),title:t(C)(`ds.typography.title`),description:t(C)(`ds.typography.description`)},{default:i(()=>[c(`section`,m,[o(p,{tone:`paper`},{default:i(()=>[c(`p`,h,a(t(C)(`ds.heading.display`)),1),S[0]||=c(`p`,{class:`font-display text-5xl font-normal leading-[1.05] mb-3`},`Fraunces`,-1),c(`p`,g,a(t(C)(`ds.typography.serifDesc`)),1),S[1]||=c(`code`,{class:`font-mono text-[11px] text-muted block mt-5`},`var(--font-serif)`,-1)]),_:1}),o(p,{tone:`paper`},{default:i(()=>[c(`p`,_,a(t(C)(`ds.heading.body`)),1),S[2]||=c(`p`,{class:`font-sans text-5xl font-medium leading-[1.05] mb-3`},`DM Sans`,-1),c(`p`,v,a(t(C)(`ds.typography.sansDesc`)),1),S[3]||=c(`code`,{class:`font-mono text-[11px] text-muted block mt-5`},`var(--font-sans)`,-1)]),_:1})]),c(`section`,null,[c(`h2`,y,a(t(C)(`ds.heading.scale`)),1),c(`div`,b,[(e(),u(s,null,n(w,e=>c(`div`,{key:e,class:`flex items-baseline gap-8 py-4`},[c(`code`,x,`text-`+a(e),1),c(`span`,{class:l(`text-${e}`)},a(t(C)(`ds.typography.sample`)),3)])),64))])])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{S as default};
|
||||
import{C as e,G as t,T as n,c as r,j as i,lt as a,m as o,r as s,s as c,st as l,u}from"./runtime-core.esm-bundler-BD0e4RlP.js";import{t as d}from"./i18n-CJQl3WLC.js";import{t as f}from"./SectionShell-Cd_Fu3uI.js";import{t as p}from"./Card-pgd8VnYH.js";var m={class:`grid md:grid-cols-2 gap-6`},h={class:`eyebrow mb-3`},g={class:`text-[14px] text-muted leading-relaxed`},_={class:`eyebrow mb-3`},v={class:`text-[14px] text-muted leading-relaxed`},y={class:`eyebrow mb-6`},b={class:`divide-y divide-line rounded-md border border-line bg-paper px-6`},x={class:`font-mono text-[11px] text-muted w-24 shrink-0`},S={__name:`TypographySection`,setup(S){let{t:C}=d(),w=[`xs`,`sm`,`base`,`lg`,`xl`,`2xl`,`3xl`,`4xl`,`5xl`];return(d,S)=>(e(),r(f,{eyebrow:t(C)(`ds.eyebrow.tokens`),title:t(C)(`ds.typography.title`),description:t(C)(`ds.typography.description`)},{default:i(()=>[c(`section`,m,[o(p,{tone:`paper`},{default:i(()=>[c(`p`,h,a(t(C)(`ds.heading.display`)),1),S[0]||=c(`p`,{class:`font-display text-5xl font-normal leading-[1.05] mb-3`},`Fraunces`,-1),c(`p`,g,a(t(C)(`ds.typography.serifDesc`)),1),S[1]||=c(`code`,{class:`font-mono text-[11px] text-muted block mt-5`},`var(--font-serif)`,-1)]),_:1}),o(p,{tone:`paper`},{default:i(()=>[c(`p`,_,a(t(C)(`ds.heading.body`)),1),S[2]||=c(`p`,{class:`font-sans text-5xl font-medium leading-[1.05] mb-3`},`DM Sans`,-1),c(`p`,v,a(t(C)(`ds.typography.sansDesc`)),1),S[3]||=c(`code`,{class:`font-mono text-[11px] text-muted block mt-5`},`var(--font-sans)`,-1)]),_:1})]),c(`section`,null,[c(`h2`,y,a(t(C)(`ds.heading.scale`)),1),c(`div`,b,[(e(),u(s,null,n(w,e=>c(`div`,{key:e,class:`flex items-baseline gap-8 py-4`},[c(`code`,x,`text-`+a(e),1),c(`span`,{class:l(`text-${e}`)},a(t(C)(`ds.typography.sample`)),3)])),64))])])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{S as default};
|
||||
@@ -1 +1 @@
|
||||
import{n as e}from"./pinia-DQoUg3qR.js";import{n as t}from"./products-GEWPSJSp.js";var n=`kn-cart-v1`;function r(){if(typeof localStorage>`u`)return[];try{let e=localStorage.getItem(n);if(!e)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>e&&typeof e.productId==`string`&&Number.isInteger(e.quantity)&&e.quantity>0):[]}catch{return[]}}function i(e){if(!(typeof localStorage>`u`))try{localStorage.setItem(n,JSON.stringify(e))}catch{}}function a(e){let n=t.find(t=>t.id===e.productId);return n?{productId:e.productId,quantity:e.quantity,unitPrice:n.price,lineTotal:+(n.price*e.quantity).toFixed(2),product:{id:n.id,title:n.title,brand:n.brand,size:n.size,image:n.image,href:n.href}}:null}var o=e(`cart`,{state:()=>({lines:r()}),getters:{items:e=>e.lines.map(a).filter(Boolean),count:e=>e.lines.reduce((e,t)=>e+t.quantity,0),subtotal(){return+this.items.reduce((e,t)=>e+t.lineTotal,0).toFixed(2)},isEmpty:e=>e.lines.length===0},actions:{add(e,t=1){let n=this.lines.find(t=>t.productId===e);n?n.quantity+=t:this.lines.push({productId:e,quantity:t}),i(this.lines)},update(e,t){if(Number.isInteger(t)){if(t<=0)this.lines=this.lines.filter(t=>t.productId!==e);else{let n=this.lines.find(t=>t.productId===e);n&&(n.quantity=t)}i(this.lines)}},remove(e){this.lines=this.lines.filter(t=>t.productId!==e),i(this.lines)},clear(){this.lines=[],i(this.lines)}}});function s(e){return{items:e.items,count:e.count,subtotal:e.subtotal,updatedAt:new Date().toISOString()}}async function c(){return s(o())}async function l(e,t=1){if(typeof e!=`string`||!e)throw Error(`cart.productIdRequired`);let n=Number.isInteger(t)?t:1;if(n<1)throw Error(`cart.quantityInvalid`);let r=o();return r.add(e,n),s(r)}async function u(e,t){let n=o();return n.update(e,Number.isInteger(t)?t:0),s(n)}async function d(e){let t=o();return t.remove(e),s(t)}async function f(){let e=o();return e.clear(),s(e)}export{u as a,d as i,f as n,o,c as r,l as t};
|
||||
import{n as e}from"./pinia-DQoUg3qR.js";import{r as t}from"./products-Dhgp5EjC.js";var n=`kn-cart-v1`;function r(){if(typeof localStorage>`u`)return[];try{let e=localStorage.getItem(n);if(!e)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>e&&typeof e.productId==`string`&&Number.isInteger(e.quantity)&&e.quantity>0):[]}catch{return[]}}function i(e){if(!(typeof localStorage>`u`))try{localStorage.setItem(n,JSON.stringify(e))}catch{}}function a(e){let n=t.find(t=>t.id===e.productId);return n?{productId:e.productId,quantity:e.quantity,unitPrice:n.price,lineTotal:+(n.price*e.quantity).toFixed(2),product:{id:n.id,title:n.title,brand:n.brand,size:n.size,image:n.image,href:n.href}}:null}var o=e(`cart`,{state:()=>({lines:r()}),getters:{items:e=>e.lines.map(a).filter(Boolean),count:e=>e.lines.reduce((e,t)=>e+t.quantity,0),subtotal(){return+this.items.reduce((e,t)=>e+t.lineTotal,0).toFixed(2)},isEmpty:e=>e.lines.length===0},actions:{add(e,t=1){let n=this.lines.find(t=>t.productId===e);n?n.quantity+=t:this.lines.push({productId:e,quantity:t}),i(this.lines)},update(e,t){if(Number.isInteger(t)){if(t<=0)this.lines=this.lines.filter(t=>t.productId!==e);else{let n=this.lines.find(t=>t.productId===e);n&&(n.quantity=t)}i(this.lines)}},remove(e){this.lines=this.lines.filter(t=>t.productId!==e),i(this.lines)},clear(){this.lines=[],i(this.lines)}}});function s(e){return{items:e.items,count:e.count,subtotal:e.subtotal,updatedAt:new Date().toISOString()}}async function c(){return s(o())}async function l(e,t=1){if(typeof e!=`string`||!e)throw Error(`cart.productIdRequired`);let n=Number.isInteger(t)?t:1;if(n<1)throw Error(`cart.quantityInvalid`);let r=o();return r.add(e,n),s(r)}async function u(e,t){let n=o();return n.update(e,Number.isInteger(t)?t:0),s(n)}async function d(e){let t=o();return t.remove(e),s(t)}async function f(){let e=o();return e.clear(),s(e)}export{u as a,d as i,f as n,o,c as r,l as t};
|
||||
1
dist/assets/i18n-CJQl3WLC.js
vendored
Normal file
1
dist/assets/i18n-CJQl3WLC.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/assets/i18n-DrTQks20.js
vendored
1
dist/assets/i18n-DrTQks20.js
vendored
File diff suppressed because one or more lines are too long
2
dist/assets/index-D8xPTD_C.js
vendored
2
dist/assets/index-D8xPTD_C.js
vendored
File diff suppressed because one or more lines are too long
1
dist/assets/index-Dqiix-Zn.css
vendored
1
dist/assets/index-Dqiix-Zn.css
vendored
File diff suppressed because one or more lines are too long
2
dist/assets/index-GHK8PbUQ.js
vendored
Normal file
2
dist/assets/index-GHK8PbUQ.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/assets/index-j7lHVelw.css
vendored
Normal file
1
dist/assets/index-j7lHVelw.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
dist/index.html
vendored
4
dist/index.html
vendored
@@ -12,13 +12,13 @@
|
||||
href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,200;0,9..144,400;0,9..144,600;0,9..144,700;1,9..144,200;1,9..144,400;1,9..144,600&family=DM+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script type="module" crossorigin src="/assets/index-D8xPTD_C.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-GHK8PbUQ.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-BOai-rQB.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/runtime-core.esm-bundler-BD0e4RlP.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/runtime-dom.esm-bundler-CcSFQHoC.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/pinia-DQoUg3qR.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-router-QRVDVSxc.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-Dqiix-Zn.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-j7lHVelw.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
14
src/App.vue
14
src/App.vue
@@ -1,11 +1,9 @@
|
||||
<script setup>
|
||||
import { computed, ref, defineAsyncComponent } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import DefaultLayout from './layouts/DefaultLayout.vue'
|
||||
import SplashIntro from './components/SplashIntro.vue'
|
||||
|
||||
const route = useRoute()
|
||||
const useDefaultLayout = computed(() => route.meta.layout !== 'none')
|
||||
const isPreview = computed(() => route.meta.preview === true)
|
||||
const isDesignRoute = computed(() => route.path.startsWith('/design'))
|
||||
const inIframe = typeof window !== 'undefined' && window.self !== window.top
|
||||
@@ -31,9 +29,13 @@ const A11yToolbar = isDev
|
||||
|
||||
<template>
|
||||
<SplashIntro v-if="showSplash" @finished="onSplashFinished" />
|
||||
<DefaultLayout v-if="useDefaultLayout">
|
||||
<router-view />
|
||||
</DefaultLayout>
|
||||
<router-view v-else />
|
||||
<!-- Single router outlet. Each page (Home, Shop, /design/*) owns its
|
||||
own layout chrome — no app-level wrapper, so there's no frame
|
||||
where an intermediate layout can flash before the route
|
||||
resolves. (Previously a conditional DefaultLayout was rendered
|
||||
whenever `route.meta.layout !== 'none'`, but during initial
|
||||
load `route.meta` is `{}`, so the condition was truthy and the
|
||||
dev sidebar showed under every page for one frame.) -->
|
||||
<router-view />
|
||||
<A11yToolbar v-if="isDev && isDesignRoute && !isPreview && !inIframe" />
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
// Barrel for the API boundary. Swap these imports for real backend calls
|
||||
// when the PHP / MySQL side lands — callers keep the same import path.
|
||||
|
||||
export { products, searchProducts, formatPrice } from './products.js'
|
||||
export {
|
||||
products,
|
||||
searchProducts,
|
||||
formatPrice,
|
||||
USE_CASES,
|
||||
useCaseFor,
|
||||
productsByUseCase,
|
||||
} from './products.js'
|
||||
export {
|
||||
fetchCart,
|
||||
addToCart,
|
||||
|
||||
@@ -338,3 +338,38 @@ export function formatPrice(amount, currency = '€') {
|
||||
if (!Number.isFinite(num)) return ''
|
||||
return `${currency} ${num.toFixed(2).replace('.', ',')}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Shop use-cases — the three top-level bands on the Shop page and in
|
||||
* the desktop nav (Cook / Clean / Care). Product-level `category`
|
||||
* strings are fine-grained (Pulver, Reinigung, Wäsche, Körperpflege,
|
||||
* Sport, Tabletten); this table rolls them up into the three shop-
|
||||
* facing groups so the mapping is declared in one place.
|
||||
*
|
||||
* cook — kitchen & digestion (baking, gastro)
|
||||
* clean — household cleaning & laundry
|
||||
* care — bath, body and sport
|
||||
*/
|
||||
export const USE_CASES = ['cook', 'clean', 'care']
|
||||
const USE_CASE_BY_CATEGORY = {
|
||||
Pulver: 'cook',
|
||||
Tabletten: 'cook',
|
||||
Reinigung: 'clean',
|
||||
Wäsche: 'clean',
|
||||
Körperpflege: 'care',
|
||||
Sport: 'care',
|
||||
}
|
||||
|
||||
export function useCaseFor(product) {
|
||||
return USE_CASE_BY_CATEGORY[product.category] || 'clean'
|
||||
}
|
||||
|
||||
export function productsByUseCase(list = products) {
|
||||
return list.reduce(
|
||||
(acc, p) => {
|
||||
acc[useCaseFor(p)].push(p)
|
||||
return acc
|
||||
},
|
||||
{ cook: [], clean: [], care: [] },
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,13 @@
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
font-size: 17px;
|
||||
/* Runtime-measured navbar height. Default matches the standard
|
||||
Navbar variant at lg (py-5 + logo + border) so the home-page
|
||||
first-fold wrapper can use `calc(100svh - var(--nav-h))` from
|
||||
first paint. HomePage still refines this at mount via a
|
||||
ResizeObserver for pixel-exact fit, but the default prevents a
|
||||
~nav-height layout shift between first paint and hydration. */
|
||||
--nav-h: 68px;
|
||||
}
|
||||
|
||||
body {
|
||||
|
||||
@@ -71,6 +71,11 @@ const props = defineProps({
|
||||
// fill finishes at 2.70s). We give it a 100ms breath then start the
|
||||
// fade so the splash doesn't linger past its own climax.
|
||||
duration: { type: Number, default: 2800 },
|
||||
// Portrait/mobile animation is tightened to ~1.0s total: slides
|
||||
// resolve at ~670ms, wordmark + mound land at ~1.0s. Dismiss at
|
||||
// 1150ms gives a ~150ms breath past the climax — matches the snap
|
||||
// of the desktop dismiss (desktop climax 2.70s → dismiss 2.80s).
|
||||
durationPortrait: { type: Number, default: 1150 },
|
||||
dismissOnTap: { type: Boolean, default: true },
|
||||
respectReducedMotion: { type: Boolean, default: true },
|
||||
portraitQuery: { type: String, default: '(max-width: 768px), (orientation: portrait) and (max-width: 900px)' }
|
||||
@@ -97,7 +102,9 @@ onMounted(() => {
|
||||
props.respectReducedMotion &&
|
||||
typeof window !== 'undefined' &&
|
||||
window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
||||
const totalMs = reduced ? 1200 : props.duration
|
||||
const totalMs = reduced
|
||||
? 1200
|
||||
: (isPortrait.value ? props.durationPortrait : props.duration)
|
||||
timer = window.setTimeout(() => { visible.value = false }, totalMs)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
@@ -164,24 +171,34 @@ const dPortMound = `M 501.491 1116.015 C 501.156 1116.557, 499.810 1117, 498.50
|
||||
transition-delay: 1.30s; }
|
||||
.splash-root.go .wordmark { opacity: 1; }
|
||||
|
||||
/* Mobile slide-ins */
|
||||
.left-m { fill: #b5d8b6; opacity: 0; transform: translateX(-14%); transition-delay: 260ms; }
|
||||
.right-m { fill: #b5d8b6; opacity: 0; transform: translateX( 14%); transition-delay: 260ms; }
|
||||
/* Mobile slide-ins — tightened to ~550ms so the whole portrait
|
||||
choreography lands in ~1.1s total (was ~1.6s). Uses the same
|
||||
cubic-bezier as the default .layer rule but overrides the
|
||||
duration/delay so the .layer 900ms/260ms transition doesn't
|
||||
slow things down. */
|
||||
.left-m { fill: #b5d8b6; opacity: 0; transform: translateX(-14%);
|
||||
transition: transform 550ms cubic-bezier(.22,.61,.36,1) 120ms,
|
||||
opacity 450ms ease 120ms; }
|
||||
.right-m { fill: #b5d8b6; opacity: 0; transform: translateX( 14%);
|
||||
transition: transform 550ms cubic-bezier(.22,.61,.36,1) 120ms,
|
||||
opacity 450ms ease 120ms; }
|
||||
.splash-root.go .left-m,
|
||||
.splash-root.go .right-m { opacity: 1; transform: none; }
|
||||
|
||||
/* Mobile wordmark — slides from top + fades in (no stroke draw) */
|
||||
/* Mobile wordmark — slides from top + fades in (no stroke draw).
|
||||
Starts as the slides are landing (~500ms) and resolves by ~1.0s
|
||||
so the splash can auto-dismiss shortly after. */
|
||||
.top-m { fill: #ffffff; opacity: 0; transform: translateY(-14%);
|
||||
transition-property: opacity, transform;
|
||||
transition-duration: 700ms;
|
||||
transition-duration: 500ms;
|
||||
transition-timing-function: ease;
|
||||
transition-delay: 900ms; }
|
||||
transition-delay: 500ms; }
|
||||
.splash-root.go .top-m { opacity: 1; transform: none; }
|
||||
|
||||
/* Mobile handful-of-natron — matches the wordmark fade timing */
|
||||
.mound-m { fill: #ffffff; opacity: 0;
|
||||
transition: opacity 700ms ease;
|
||||
transition-delay: 900ms; }
|
||||
transition: opacity 500ms ease;
|
||||
transition-delay: 500ms; }
|
||||
.splash-root.go .mound-m { opacity: 1; }
|
||||
|
||||
/* Desktop climax: natron droplets */
|
||||
|
||||
@@ -77,8 +77,7 @@ const CARD_TONES = [
|
||||
|
||||
<h2
|
||||
v-if="headline"
|
||||
class="font-display font-normal leading-[1.05] tracking-tight text-ink"
|
||||
style="font-size: clamp(2.25rem, 5vw, 3.75rem);"
|
||||
class="font-display font-normal leading-[1.05] tracking-tight text-ink text-headline-lg"
|
||||
>{{ headline }}</h2>
|
||||
|
||||
<p v-if="sub" class="text-lg leading-relaxed text-muted max-w-2xl">
|
||||
@@ -117,14 +116,19 @@ const CARD_TONES = [
|
||||
<li
|
||||
v-for="(milestone, i) in milestones.slice(0, 3)"
|
||||
:key="milestone.year + milestone.title"
|
||||
class="timeline-item flex flex-col"
|
||||
class="timeline-item flex flex-col md:h-full"
|
||||
>
|
||||
<div class="timeline-mobile-marker">
|
||||
<span :class="['timeline-pill', CARD_TONES[i].pill]">{{ milestone.year }}</span>
|
||||
</div>
|
||||
<!-- md:flex-1 + md:h-full: the `<li>` stretches to the row's
|
||||
natural tallest height via CSS-grid's default
|
||||
align-items: stretch; the card then fills that li so
|
||||
every card in the row reads as the same height on
|
||||
desktop. Mobile stays auto-height (no grid row). -->
|
||||
<div
|
||||
:class="[
|
||||
'flex flex-col gap-3 rounded-md border p-6 md:p-7',
|
||||
'flex flex-col gap-3 rounded-md border p-6 md:p-7 md:flex-1 md:h-full',
|
||||
CARD_TONES[i].card,
|
||||
]"
|
||||
>
|
||||
|
||||
@@ -4,6 +4,8 @@ import Button from './Button.vue'
|
||||
import Icon from './Icon.vue'
|
||||
import IconButton from './IconButton.vue'
|
||||
import BundleCard from './BundleCard.vue'
|
||||
import BundlesHeader from './internal/BundlesHeader.vue'
|
||||
import BundlesBenefits from './internal/BundlesBenefits.vue'
|
||||
import { useI18n } from '@/i18n/index.js'
|
||||
|
||||
/**
|
||||
@@ -15,6 +17,19 @@ import { useI18n } from '@/i18n/index.js'
|
||||
* can be overridden per-instance via the *Label / *A11y props.
|
||||
*/
|
||||
const props = defineProps({
|
||||
// Layout variant.
|
||||
// - 'sidebar' (default): left column holds headline/sub/benefits/CTA,
|
||||
// right column holds a one-at-a-time scroll-snap carousel.
|
||||
// - 'stacked': desktop puts the sidebar content in a full-width row
|
||||
// on top, then renders the bundles as a 3-up grid below — no
|
||||
// carousel, no pagination (since all three fit in view).
|
||||
// Mobile (<md) is identical for both: a vertical stack of cards.
|
||||
layout: {
|
||||
type: String,
|
||||
default: 'sidebar',
|
||||
validator: (v) => ['sidebar', 'stacked'].includes(v),
|
||||
},
|
||||
|
||||
// Section headline. `headline` renders in the display serif; `headlineEm`
|
||||
// is the italicised highlight, styled consistently with Hero.
|
||||
headline: { type: String, default: '' },
|
||||
@@ -124,37 +139,48 @@ onBeforeUnmount(() => {
|
||||
<!-- Matches the Hero banner container — same max-w-6xl so the section
|
||||
aligns with the banner above rather than breaking full-bleed. -->
|
||||
<div
|
||||
class="mx-auto w-full max-w-6xl px-6 py-16 sm:px-8 sm:py-20 md:px-12 md:py-20 lg:px-16 lg:py-24"
|
||||
class="mx-auto w-full max-w-6xl px-6 py-16 sm:px-8 sm:py-20 md:px-12 md:py-24 lg:px-16 lg:py-28"
|
||||
>
|
||||
<div class="grid gap-10 md:gap-12 lg:gap-16 lg:grid-cols-[340px_1fr] lg:items-center">
|
||||
<!-- Sidebar: heading + sub + up-to-3 benefits + CTA. -->
|
||||
<aside class="flex flex-col gap-8">
|
||||
<div v-if="headline || sub" class="flex flex-col gap-4">
|
||||
<h2
|
||||
v-if="headline || headlineEm"
|
||||
class="font-display font-normal leading-[1.05] tracking-tight text-ink"
|
||||
style="font-size: clamp(2rem, 4vw, 3rem);"
|
||||
>
|
||||
{{ headline }}
|
||||
<em
|
||||
v-if="headlineEm"
|
||||
class="italic font-light text-brand"
|
||||
>{{ headlineEm }}</em>
|
||||
</h2>
|
||||
<p v-if="sub" class="text-base leading-relaxed text-muted max-w-md">
|
||||
{{ sub }}
|
||||
</p>
|
||||
</div>
|
||||
<!-- STACKED layout (option 2).
|
||||
Row 1: headline + sub (single column, full width).
|
||||
Row 2: benefits as a horizontal chip row inside a paper
|
||||
container — sits between the pitch and the products
|
||||
as a "why join" summary strip.
|
||||
Row 3: mobile stack / md+ 3-up grid of bundle cards.
|
||||
Row 4: "become a member" CTA centred below the products. -->
|
||||
<div v-if="layout === 'stacked'" class="flex flex-col gap-10 md:gap-12 lg:gap-14">
|
||||
<!-- Row 1: headline + sub. Full width so the pitch reads as a
|
||||
section opener rather than a split banner. -->
|
||||
<BundlesHeader
|
||||
:headline="headline"
|
||||
:headline-em="headlineEm"
|
||||
:sub="sub"
|
||||
sub-max-width="max-w-2xl"
|
||||
/>
|
||||
|
||||
<ul v-if="benefits.length" class="flex flex-col gap-4">
|
||||
<!-- Row 2: benefits strip. Cream-on-surface container, the
|
||||
cream-surface analogue of the LanguageSwitcher's `brand`
|
||||
tone (cream-wash-on-brand). The warm fill + strong line
|
||||
border lifts the chips off the section's surface ground
|
||||
without competing with the bundle cards below.
|
||||
`rounded-md` reads as "card" at this larger scale —
|
||||
reserving the pill shape for true chip rows (nav, tabs,
|
||||
language switcher) where the container is the control.
|
||||
Flex-wrap lets long benefit copy reflow to two lines on
|
||||
narrow viewports instead of overflowing horizontally. -->
|
||||
<div
|
||||
v-if="benefits.length"
|
||||
class="rounded-md border border-cream-dark bg-cream px-5 py-4 sm:px-6 sm:py-5"
|
||||
>
|
||||
<ul class="flex flex-col gap-4 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between sm:gap-x-8 sm:gap-y-3">
|
||||
<li
|
||||
v-for="benefit in benefits.slice(0, 3)"
|
||||
:key="benefit"
|
||||
class="flex items-start gap-3"
|
||||
class="flex items-center gap-3"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="mt-0.5 inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-brand-wash text-brand"
|
||||
class="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-brand-wash text-brand"
|
||||
>
|
||||
<Icon name="check" :size="14" :stroke-width="2.2" />
|
||||
</span>
|
||||
@@ -163,20 +189,89 @@ onBeforeUnmount(() => {
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Products row. Mobile: vertical stack (same as sidebar
|
||||
layout). md+: 3-up grid, vertical cards. -->
|
||||
<div class="min-w-0">
|
||||
<div class="md:hidden grid gap-5">
|
||||
<BundleCard
|
||||
v-for="bundle in bundles"
|
||||
:key="bundle.id"
|
||||
layout="vertical"
|
||||
:name="bundle.name"
|
||||
:items="bundle.items"
|
||||
:price="bundle.price"
|
||||
:member-price="bundle.memberPrice"
|
||||
:usage="bundle.usage"
|
||||
:image="bundle.image"
|
||||
:image-alt="bundle.imageAlt"
|
||||
:badge="bundle.badge"
|
||||
:badge-variant="bundle.badgeVariant || 'accent'"
|
||||
tone="paper"
|
||||
@add="$emit('add', bundle.id)"
|
||||
/>
|
||||
</div>
|
||||
<div class="hidden md:grid md:gap-6 md:grid-cols-3">
|
||||
<BundleCard
|
||||
v-for="bundle in bundles.slice(0, 3)"
|
||||
:key="bundle.id"
|
||||
layout="vertical"
|
||||
:name="bundle.name"
|
||||
:items="bundle.items"
|
||||
:price="bundle.price"
|
||||
:member-price="bundle.memberPrice"
|
||||
:usage="bundle.usage"
|
||||
:image="bundle.image"
|
||||
:image-alt="bundle.imageAlt"
|
||||
:badge="bundle.badge"
|
||||
:badge-variant="bundle.badgeVariant || 'accent'"
|
||||
tone="paper"
|
||||
@add="$emit('add', bundle.id)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bottom CTA — centred below the products so the eye lands
|
||||
on it last, after the member pitch has been made above
|
||||
and the products have been scanned. -->
|
||||
<div v-if="joinCta" class="flex justify-center">
|
||||
<Button
|
||||
variant="primary"
|
||||
size="lg"
|
||||
@click="$emit('join')"
|
||||
>{{ joinCta }}</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SIDEBAR layout (option 1, original).
|
||||
Left aside + right carousel on lg+. -->
|
||||
<div
|
||||
v-else
|
||||
class="grid gap-10 md:gap-12 lg:gap-16 lg:grid-cols-[340px_1fr] lg:items-center"
|
||||
>
|
||||
<aside class="flex flex-col gap-8">
|
||||
<BundlesHeader
|
||||
:headline="headline"
|
||||
:headline-em="headlineEm"
|
||||
:sub="sub"
|
||||
sub-max-width="max-w-md"
|
||||
/>
|
||||
<BundlesBenefits :benefits="benefits" />
|
||||
<Button
|
||||
v-if="joinCta"
|
||||
variant="primary"
|
||||
size="md"
|
||||
class="self-start"
|
||||
@click="$emit('join')"
|
||||
>{{ joinCta }}</Button>
|
||||
</aside>
|
||||
|
||||
<!-- Bundles. `min-w-0` is load-bearing: a grid `1fr` column
|
||||
defaults to `min-width: auto`, letting its children's
|
||||
intrinsic width push the column past its allocation.
|
||||
Without this, the carousel's fixed-width slides drag the
|
||||
right column past the section's max-width during resizes. -->
|
||||
<!-- `min-w-0` is load-bearing: a grid `1fr` column defaults to
|
||||
`min-width: auto`, letting children push the column past
|
||||
its allocation. Without this, the carousel's fixed-width
|
||||
slides drag the right column past the section's max-width
|
||||
during resizes. -->
|
||||
<div class="min-w-0">
|
||||
<!-- Mobile: vertical stack. -->
|
||||
<div class="md:hidden grid gap-5">
|
||||
@@ -198,9 +293,7 @@ onBeforeUnmount(() => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- md+ : one-at-a-time scroll-snap carousel with horizontal cards.
|
||||
Swipe, keyboard arrow keys, and the prev/next buttons all
|
||||
drive the same scrollLeft — no animation state needed. -->
|
||||
<!-- md+ : one-at-a-time scroll-snap carousel. -->
|
||||
<div class="hidden md:flex md:flex-col md:gap-6 relative">
|
||||
<!-- Padding + matching negative margins reserve room inside the
|
||||
scroll container for the hover lift and shadow-md without
|
||||
|
||||
@@ -34,6 +34,12 @@ const props = defineProps({
|
||||
* and copy on the right from `lg` up. Mobile order is unchanged (image
|
||||
* on top, copy below) to preserve reading order. */
|
||||
reverse: { type: Boolean, default: false },
|
||||
/** Compact hero: smaller image cap + narrower media column from `lg` up.
|
||||
* Used for secondary/supporting heroes (e.g. the cream "hundert
|
||||
* Anwendungen" second-fold banner) so they read as companion content
|
||||
* to the primary first-fold hero rather than a second centre-stage
|
||||
* block. Mobile sizing is unchanged. */
|
||||
compact: { type: Boolean, default: false },
|
||||
})
|
||||
|
||||
defineEmits(['cta', 'secondary'])
|
||||
@@ -73,7 +79,7 @@ const layout = computed(() => {
|
||||
copy: 'max-w-2xl mx-auto items-center text-center',
|
||||
actions: 'justify-center',
|
||||
media: 'mt-4 md:mt-6',
|
||||
mediaSize: 'w-[287px] sm:w-[354px] md:w-[442px] lg:w-[530px]',
|
||||
mediaSize: 'w-full max-w-[287px] sm:max-w-[354px] md:max-w-[442px] lg:max-w-[530px]',
|
||||
}
|
||||
}
|
||||
// Split: image on top on mobile/tablet, text-left/image-right on desktop.
|
||||
@@ -82,37 +88,97 @@ const layout = computed(() => {
|
||||
// the copy column so its headline/CTA block sits at the image's vertical midpoint.
|
||||
// `reverse` swaps the desktop columns so the image sits on the left.
|
||||
return {
|
||||
// `grid-cols-1` is load-bearing at mobile. Without it, the grid
|
||||
// has no column template below `lg`, so `grid-auto-columns: auto`
|
||||
// sizes the implicit column to max-content of its widest child —
|
||||
// which is the image column's declared width. That max-content
|
||||
// column then forces the copy column to the same width, overflowing
|
||||
// narrow viewports and clipping the headline against the section
|
||||
// edge. `grid-cols-1` emits `minmax(0, 1fr)`, constraining the
|
||||
// column to available width and letting children actually shrink.
|
||||
root: props.reverse
|
||||
? 'grid gap-10 md:gap-14 lg:grid-cols-[1fr_1.05fr]'
|
||||
: 'grid gap-10 md:gap-14 lg:grid-cols-[1.05fr_1fr]',
|
||||
? 'grid grid-cols-1 gap-10 md:gap-14 lg:grid-cols-[1fr_1.05fr]'
|
||||
: 'grid grid-cols-1 gap-10 md:gap-14 lg:grid-cols-[1.05fr_1fr]',
|
||||
copy: [
|
||||
'order-2 max-w-xl mx-auto lg:mx-0 items-center text-center lg:justify-center',
|
||||
props.reverse ? 'lg:order-2 lg:items-start lg:text-left' : 'lg:order-1 lg:items-start lg:text-left',
|
||||
].join(' '),
|
||||
actions: 'justify-center lg:justify-start',
|
||||
media: props.reverse ? 'order-1 lg:order-1' : 'order-1 lg:order-2',
|
||||
mediaSize: 'w-[373px] sm:w-[489px] md:w-[603px] lg:w-full lg:max-w-[748px]',
|
||||
// Media cell: use max-width rather than fixed width below `lg` so
|
||||
// the column can shrink below the image's preferred size on narrow
|
||||
// phones. A fixed `w-[373px]` forced the single-column mobile grid
|
||||
// to 373px, which overflowed a 375px viewport minus section padding
|
||||
// and pushed the headline text past the section edge (clipped).
|
||||
// Compact heroes cap the desktop media width tighter so the image
|
||||
// doesn't dominate; mobile/tablet sizing is identical.
|
||||
mediaSize: props.compact
|
||||
? 'w-full max-w-[373px] sm:max-w-[489px] md:max-w-[603px] lg:max-w-[460px] mx-auto'
|
||||
: 'w-full max-w-[373px] sm:max-w-[489px] md:max-w-[603px] lg:max-w-[748px] mx-auto',
|
||||
}
|
||||
})
|
||||
|
||||
// Max image height per viewport step. Compact drops the desktop cap
|
||||
// from 78svh → 48svh so the secondary hero reads as a companion,
|
||||
// not a second main stage. Mobile/tablet caps are shared because
|
||||
// phone screens shouldn't scale content down below its legible size.
|
||||
// Image max-height steps. At lg the default cap is deliberately
|
||||
// conservative (52svh) because anything larger makes the Hero
|
||||
// exceed the home page's `min-h-[calc(100svh - var(--nav-h))] +
|
||||
// pb-[var(--nav-h)]` content box on typical laptop viewports
|
||||
// (svh ≈ 800–900), which forces the wrapper to grow and pins the
|
||||
// Hero to the top — losing vertical centering. 52svh keeps the
|
||||
// total Hero height below the content box at svh ≥ 700 so
|
||||
// centering holds across all common desktop breakpoints. Compact
|
||||
// variant is lower still for the secondary banner.
|
||||
const imageHeightClass = computed(() =>
|
||||
props.compact
|
||||
? 'max-h-[44svh] md:max-h-[61svh] lg:max-h-[48svh]'
|
||||
: 'max-h-[44svh] md:max-h-[61svh] lg:max-h-[52svh]',
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- overflow-clip (not overflow-hidden) contains the media halo/disc
|
||||
decor WITHOUT establishing a new scrollport — so the headline's
|
||||
italic-overhang can't be clipped against the section edge at
|
||||
narrow widths. Historically this was `overflow-hidden`, which
|
||||
made the section a scrolling ancestor and sheared the last
|
||||
italic letter off the hero h1 at phone-sim widths.
|
||||
The `hero-section` scoped class carries the overflow-clip-margin
|
||||
value — up to 1rem of content (including italic overhang) is
|
||||
allowed past the section edge before clipping kicks in. -->
|
||||
<section
|
||||
:class="[
|
||||
'relative overflow-hidden',
|
||||
'hero-section relative overflow-clip',
|
||||
'px-6 py-10 sm:px-8 sm:py-12 md:px-12 md:py-16 lg:px-16 lg:py-20',
|
||||
tone.surface,
|
||||
tone.text,
|
||||
]"
|
||||
>
|
||||
<div :class="['relative mx-auto w-full max-w-6xl', layout.root]">
|
||||
<!-- Copy -->
|
||||
<div :class="['relative z-[1] flex flex-col gap-6', layout.copy]">
|
||||
<!-- Copy.
|
||||
`min-w-0` is load-bearing: the copy column is a flex/grid
|
||||
child whose default `min-width: auto` resolves to its
|
||||
longest word's intrinsic width, which lets the headline
|
||||
push the column wider than the viewport. Overriding to 0
|
||||
lets the headline actually respect its own max width so
|
||||
the font-size clamp and wrapping can take effect. -->
|
||||
<div :class="['relative z-[1] flex flex-col gap-6 min-w-0', layout.copy]">
|
||||
<p v-if="eyebrow" class="eyebrow">{{ eyebrow }}</p>
|
||||
|
||||
<!-- Headline sizing uses responsive Tailwind arbitrary values
|
||||
so each breakpoint compiles to a plain media-query
|
||||
`font-size` rule — no scoped-CSS hash, no HMR edge
|
||||
cases. Italic Fraunces at ≥2.25rem overhangs the
|
||||
line-box at ≤400px and gets clipped by the section's
|
||||
`overflow-hidden` (needed for the halo/disc decor);
|
||||
capping at 1.625rem on phones keeps the whole phrase
|
||||
inside the content width. `break-words` + the inline
|
||||
`overflow-wrap` is belt-and-braces for any long word
|
||||
(e.g. German compounds) that still can't fit. -->
|
||||
<h1
|
||||
class="font-display font-normal leading-[1.04] tracking-tight"
|
||||
style="font-size: clamp(2.5rem, 6vw, 4.5rem);"
|
||||
class="hero-headline font-display font-normal leading-[1.04] tracking-tight hyphens-auto break-words text-[1.625rem] sm:text-[2.25rem] lg:text-[3rem] xl:text-[3.75rem] 2xl:text-[4.5rem]"
|
||||
>
|
||||
<slot name="headline">{{ headline }}</slot>
|
||||
</h1>
|
||||
@@ -207,11 +273,42 @@ const layout = computed(() => {
|
||||
:alt="imageAlt || headline"
|
||||
loading="eager"
|
||||
decoding="async"
|
||||
class="relative mx-auto w-auto max-w-full max-h-[44svh] md:max-h-[61svh] lg:max-h-[78svh] object-contain drop-shadow-[0_20px_40px_rgba(28,58,40,0.18)]"
|
||||
:class="[
|
||||
'relative mx-auto w-auto max-w-full object-contain drop-shadow-[0_20px_40px_rgba(28,58,40,0.18)]',
|
||||
imageHeightClass,
|
||||
]"
|
||||
/>
|
||||
</slot>
|
||||
<!-- Page-level extension point for mobile category shortcuts
|
||||
etc. Sits under the image within the media column so it
|
||||
tracks the hero's vertical rhythm. Empty by default. -->
|
||||
<slot name="afterMedia" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* overflow-clip (vs overflow-hidden) contains the decorative halo and
|
||||
disc behind the product image WITHOUT establishing a new scrollport.
|
||||
The margin lets up to 1rem of content — including Fraunces italic
|
||||
overhang — extend past the section edge before being clipped. No
|
||||
Tailwind utility covers this pair, so it lives here rather than as
|
||||
inline CSS on every call site. */
|
||||
.hero-section {
|
||||
overflow-clip-margin: 1rem;
|
||||
}
|
||||
|
||||
/* Headline wrap rules. `overflow-wrap: anywhere` is stronger than
|
||||
`break-words` — the latter only breaks between words, the former
|
||||
will break inside a word if it can't otherwise fit the line-box.
|
||||
Paired with `word-break: normal` so regular CJK / soft-hyphen
|
||||
behaviour isn't altered. Together these guarantee a long German
|
||||
compound can never overflow the column. */
|
||||
.hero-headline {
|
||||
overflow-wrap: anywhere;
|
||||
word-break: normal;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -24,6 +24,11 @@ const props = defineProps({
|
||||
default: 'standard',
|
||||
validator: (v) => ['standard', 'floating'].includes(v),
|
||||
},
|
||||
/**
|
||||
* Primary nav items — render in the left cluster, next to the logo.
|
||||
* On the shop/home these are the top-level shop destinations
|
||||
* (Shop, Cook, Clean, Care).
|
||||
*/
|
||||
items: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
@@ -33,6 +38,18 @@ const props = defineProps({
|
||||
{ key: 'nav.contact', href: '#' },
|
||||
],
|
||||
},
|
||||
/**
|
||||
* Secondary nav items — render in the right cluster, immediately to
|
||||
* the LEFT of the search trigger. Intended for supporting pages
|
||||
* (Bundles, Revitalisation, About) that sit above the purchasing
|
||||
* flow but below the category browse in importance. Empty by
|
||||
* default so callers that don't use the split leave the right
|
||||
* cluster unchanged.
|
||||
*/
|
||||
secondaryItems: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
cartCount: { type: Number, default: 0 },
|
||||
floatOnMobile: { type: Boolean, default: true },
|
||||
/**
|
||||
@@ -133,8 +150,24 @@ onBeforeUnmount(() => {
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Right: search + language + cart (desktop only) -->
|
||||
<!-- Right: secondary nav + search + language + cart (desktop only) -->
|
||||
<div class="hidden md:flex items-center gap-4">
|
||||
<!-- Secondary nav — supporting pages tucked to the left of
|
||||
search so the primary category nav on the left stays the
|
||||
focal point. Shares the same visual treatment as the
|
||||
primary items for consistency. -->
|
||||
<nav
|
||||
v-if="secondaryItems.length"
|
||||
class="flex items-center gap-6 mr-2"
|
||||
>
|
||||
<a
|
||||
v-for="item in secondaryItems"
|
||||
:key="item.key || item.label"
|
||||
:href="item.href || '#'"
|
||||
:class="[tone.link, 'text-[14px] font-medium tracking-label transition-colors duration-base']"
|
||||
@click="$emit('nav', item)"
|
||||
>{{ itemLabel(item) }}</a>
|
||||
</nav>
|
||||
<button
|
||||
type="button"
|
||||
:class="[
|
||||
@@ -223,9 +256,13 @@ onBeforeUnmount(() => {
|
||||
<Logo class="w-12 h-auto text-cream" />
|
||||
</div>
|
||||
|
||||
<!-- Mobile menu shows primary + secondary nav as one stack.
|
||||
Desktop splits them left/right of the search; on mobile
|
||||
the menu is the only nav surface so they read as one
|
||||
list, primary first. -->
|
||||
<nav class="flex-1 flex flex-col justify-center px-8 gap-3 overflow-y-auto">
|
||||
<a
|
||||
v-for="item in items"
|
||||
v-for="item in [...items, ...secondaryItems]"
|
||||
:key="item.key || item.label"
|
||||
:href="item.href || '#'"
|
||||
class="font-serif font-normal text-[clamp(2.25rem,9vw,3.5rem)] tracking-tight leading-[1.05] text-cream hover:text-accent transition-colors duration-base"
|
||||
|
||||
@@ -46,8 +46,7 @@ defineEmits(['notify'])
|
||||
|
||||
<h2
|
||||
v-if="headline || headlineEm"
|
||||
class="font-display font-normal leading-[1.04] tracking-tight"
|
||||
style="font-size: clamp(2.25rem, 5vw, 3.75rem);"
|
||||
class="font-display font-normal leading-[1.04] tracking-tight text-headline-lg"
|
||||
>
|
||||
{{ headline }}
|
||||
<em
|
||||
@@ -106,8 +105,8 @@ defineEmits(['notify'])
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
width: var(--size-orbit);
|
||||
height: var(--size-orbit);
|
||||
}
|
||||
.rv-orbit-ring {
|
||||
position: absolute;
|
||||
|
||||
@@ -215,9 +215,20 @@ function priceLabel(p) {
|
||||
return p.price ? `€ ${p.price}` : ''
|
||||
}
|
||||
|
||||
// Real anchors still navigate; prevent the '#' fallback from hash-jumping.
|
||||
// Always suppress the browser's native anchor navigation. The row's
|
||||
// `href` is retained so middle-click / right-click "open in new tab"
|
||||
// keeps working semantically, but a primary-click is a *selection*:
|
||||
// we emit `select` and let the parent decide what happens (add to
|
||||
// cart, route to the PDP, close a drawer, etc.). Previously an
|
||||
// unprevented primary-click also followed the href, which on the
|
||||
// homepage caused a full-page navigation to `/shop/<slug>` — a
|
||||
// route that doesn't exist — leaving the SPA in an inconsistent
|
||||
// state behind the intended "add to cart" flow.
|
||||
function onRowClick(i, item, e) {
|
||||
if (!item.href) e.preventDefault()
|
||||
// Respect modifier-click intent (open in new tab / window): let the
|
||||
// browser handle those natively without also firing `select`.
|
||||
if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) return
|
||||
e.preventDefault()
|
||||
selectAt(i)
|
||||
}
|
||||
</script>
|
||||
|
||||
73
src/design-system/components/WaveDivider.vue
Normal file
73
src/design-system/components/WaveDivider.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<script setup>
|
||||
/**
|
||||
* WaveDivider — the home page's signature soft-wave transition
|
||||
* between two full-bleed coloured sections. Extracted from
|
||||
* HomePage.vue so the shop page (and any future sections page) can
|
||||
* reuse the same visual grammar instead of duplicating the SVG.
|
||||
*
|
||||
* The SVG is fully opaque by design: a `to` rect fills the whole
|
||||
* viewBox so the bottom row is solid destination colour (matches
|
||||
* the section below → no seam), and a `from` path paints the wavy
|
||||
* top portion (matches the section above → no seam). Leaving the
|
||||
* top half transparent caused browsers to anti-alias the path's
|
||||
* top/bottom edges against the parent and produce hairline
|
||||
* artefacts.
|
||||
*
|
||||
* Tone names (`brand`, `cream`, `surface`, `paper`) mirror the
|
||||
* surface tokens used across Hero / About / Bundles etc. so calls
|
||||
* read as "from X to Y" without the caller knowing the underlying
|
||||
* CSS-variable names.
|
||||
*/
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
/** Colour of the section above the wave — painted on the wavy top. */
|
||||
from: {
|
||||
type: String,
|
||||
default: 'brand',
|
||||
validator: (v) => ['brand', 'cream', 'surface', 'paper'].includes(v),
|
||||
},
|
||||
/** Colour of the section below the wave — fills the solid bottom. */
|
||||
to: {
|
||||
type: String,
|
||||
default: 'cream',
|
||||
validator: (v) => ['brand', 'cream', 'surface', 'paper'].includes(v),
|
||||
},
|
||||
})
|
||||
|
||||
const toneVar = {
|
||||
brand: 'var(--color-brand)',
|
||||
cream: 'var(--color-cream)',
|
||||
surface: 'var(--color-surface)',
|
||||
paper: 'var(--color-paper)',
|
||||
}
|
||||
const toneBg = {
|
||||
brand: 'bg-brand',
|
||||
cream: 'bg-cream',
|
||||
surface: 'bg-surface',
|
||||
paper: 'bg-paper',
|
||||
}
|
||||
|
||||
// The wrapping bg-* class paints any 1-device-pixel gap that could
|
||||
// otherwise show up between the SVG's bottom and the next section
|
||||
// during subpixel rounding — matches the `from` tone so the wave
|
||||
// rests flush on the section above.
|
||||
const wrapperClass = computed(() => toneBg[props.from])
|
||||
const fromFill = computed(() => toneVar[props.from])
|
||||
const toFill = computed(() => toneVar[props.to])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
:class="['block w-full h-12 md:h-16 shrink-0 -mb-px', wrapperClass]"
|
||||
viewBox="0 0 1440 64"
|
||||
preserveAspectRatio="none"
|
||||
>
|
||||
<rect width="1440" height="64" :fill="toFill" />
|
||||
<path
|
||||
d="M0,0 L0,40 C320,4 520,60 720,32 C920,4 1120,60 1440,24 L1440,0 Z"
|
||||
:fill="fromFill"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
44
src/design-system/components/internal/BundlesBenefits.vue
Normal file
44
src/design-system/components/internal/BundlesBenefits.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<script setup>
|
||||
/**
|
||||
* BundlesBenefits — the checklist rendered alongside both Bundles
|
||||
* layouts. Accepts a positioning hint so the caller can align the
|
||||
* list flush-left in a grid cell (stacked layout) without the
|
||||
* subcomponent needing to know anything about grid context.
|
||||
*/
|
||||
import Icon from '../Icon.vue'
|
||||
|
||||
defineProps({
|
||||
benefits: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr.every((v) => typeof v === 'string'),
|
||||
},
|
||||
/** Applied to the root `<ul>`. Stacked layout uses
|
||||
* `lg:justify-self-start lg:max-w-sm` so the list sits at the
|
||||
* left of its grid column; sidebar layout passes nothing. */
|
||||
listClass: { type: String, default: '' },
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ul
|
||||
v-if="benefits.length"
|
||||
:class="['flex flex-col gap-4', listClass]"
|
||||
>
|
||||
<li
|
||||
v-for="benefit in benefits.slice(0, 3)"
|
||||
:key="benefit"
|
||||
class="flex items-start gap-3"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="mt-0.5 inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-brand-wash text-brand"
|
||||
>
|
||||
<Icon name="check" :size="14" :stroke-width="2.2" />
|
||||
</span>
|
||||
<span class="font-sans text-sm font-semibold text-ink leading-snug">
|
||||
{{ benefit }}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
39
src/design-system/components/internal/BundlesHeader.vue
Normal file
39
src/design-system/components/internal/BundlesHeader.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<script setup>
|
||||
/**
|
||||
* BundlesHeader — shared headline + sub block rendered by both
|
||||
* Bundles layouts (sidebar and stacked). Kept local to
|
||||
* `design-system/components/internal/` so the top-level index stays
|
||||
* focused on publicly-composed primitives (Bundles, BundleCard, etc.)
|
||||
* and this stays plainly "an implementation detail of Bundles".
|
||||
*/
|
||||
defineProps({
|
||||
headline: { type: String, default: '' },
|
||||
headlineEm: { type: String, default: '' },
|
||||
sub: { type: String, default: '' },
|
||||
/** Tailwind max-width utility applied to the sub paragraph. Callers
|
||||
* pass whichever fits their column rhythm — `max-w-md` for the
|
||||
* narrow sidebar, `max-w-2xl` for a full-width banner, etc. Kept
|
||||
* as a string rather than an enum so we don't have to maintain an
|
||||
* allow-list in two places. */
|
||||
subMaxWidth: { type: String, default: 'max-w-md' },
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="headline || headlineEm || sub" class="flex flex-col gap-4">
|
||||
<h2
|
||||
v-if="headline || headlineEm"
|
||||
class="font-display font-normal leading-[1.05] tracking-tight text-ink text-headline-md"
|
||||
>
|
||||
{{ headline }}
|
||||
<em
|
||||
v-if="headlineEm"
|
||||
class="italic font-light text-brand"
|
||||
>{{ headlineEm }}</em>
|
||||
</h2>
|
||||
<p
|
||||
v-if="sub"
|
||||
:class="['text-base leading-relaxed text-muted', subMaxWidth]"
|
||||
>{{ sub }}</p>
|
||||
</div>
|
||||
</template>
|
||||
@@ -29,6 +29,12 @@
|
||||
--color-line: color-mix(in srgb, var(--color-brand) 11%, transparent);
|
||||
--color-line-strong: color-mix(in srgb, var(--color-brand) 22%, transparent);
|
||||
--color-cream: #f4efe4;
|
||||
/* Darker cream — brand-tinted so it stays in the warm-green palette
|
||||
rather than drifting toward muddy taupe. Used as a visible border
|
||||
or rule where plain `--color-cream` would disappear against the
|
||||
surface ground, and `--color-line-strong` (brand-tinted hairline)
|
||||
would read as "technical line" rather than "paper edge". */
|
||||
--color-cream-dark: color-mix(in oklab, var(--color-cream), var(--color-brand) 18%);
|
||||
--color-surface: #faf7f1;
|
||||
--color-paper: #ffffff;
|
||||
|
||||
@@ -61,13 +67,31 @@
|
||||
--text-3xl: 1.875rem;
|
||||
--text-4xl: 2.25rem;
|
||||
--text-5xl: 3rem;
|
||||
|
||||
/* Section-headline scale — fluid clamps shared by full-bleed
|
||||
sections (Hero, About, Revitalization, Bundles). Centralised so
|
||||
the home page reads as one typographic rhythm rather than a set
|
||||
of individually-tuned clamps. `display` is the first-fold hero
|
||||
statement; `headline-lg` is the standard second-tier section
|
||||
heading; `headline-md` is a quieter band (Bundles). Tailwind v4
|
||||
auto-generates `text-display` / `text-headline-lg` / `text-
|
||||
headline-md` utilities from these custom properties. */
|
||||
--text-display: clamp(3.25rem, 5.2vw, 5.125rem);
|
||||
--text-headline-lg: clamp(2.25rem, 5vw, 3.75rem);
|
||||
--text-headline-md: clamp(2rem, 4vw, 3rem);
|
||||
|
||||
--tracking-eyebrow: 0.08em;
|
||||
--tracking-label: 0.04em;
|
||||
--tracking-wide: 0.12em;
|
||||
--tracking-tight: -0.025em;
|
||||
|
||||
/* ——— Iconography sizing —————————————————————————————————— */
|
||||
/* Orbit is the decorative dot-on-a-ring glyph used in
|
||||
Revitalization's feature cluster. Kept as a token so any
|
||||
future "pillar / feature / science-beat" block can match
|
||||
without re-deriving the geometry. */
|
||||
--size-orbit: 72px;
|
||||
|
||||
/* ——— Radius ———————————————————————————————————————————————— */
|
||||
--radius-xs: 6px;
|
||||
--radius-sm: 10px;
|
||||
|
||||
@@ -5,11 +5,32 @@
|
||||
const de = {
|
||||
// Navbar (also used by the Navbar preview)
|
||||
'nav.shop': 'Shop',
|
||||
'nav.cook': 'Kochen',
|
||||
'nav.clean': 'Reinigen',
|
||||
'nav.care': 'Pflege',
|
||||
'nav.applications': 'Anwendungen',
|
||||
'nav.bundles': 'Bundles',
|
||||
'nav.revitalization': 'Revitalisierung',
|
||||
'nav.about': 'Über uns',
|
||||
'nav.contact': 'Kontakt',
|
||||
// Shop page — section headlines for the three use-case groups.
|
||||
'shop.eyebrow': 'Unser Sortiment',
|
||||
'shop.headline': 'Kaiser-Natron',
|
||||
'shop.headline.em': 'für jeden Bereich',
|
||||
'shop.sub': 'Vom Kochen über das Reinigen bis zur Pflege: drei Sammlungen, ein Rohstoff.',
|
||||
'shop.section.cook.headline': 'Backen, kochen,',
|
||||
'shop.section.cook.headline.em': 'gesund verdauen.',
|
||||
'shop.section.cook.sub': 'Pulver und Tabletten — die Basis für Teig, Gerichte und guten Geschmack.',
|
||||
'shop.section.clean.headline': 'Schrubben, waschen,',
|
||||
'shop.section.clean.headline.em': 'alles sauber.',
|
||||
'shop.section.clean.sub': 'Natron-basierte Reiniger und Waschhelfer, die auch bei hartnäckigem Schmutz überzeugen.',
|
||||
'shop.section.care.headline': 'Baden, pflegen,',
|
||||
'shop.section.care.headline.em': 'durchatmen.',
|
||||
'shop.section.care.sub': 'Bade- und Pflegeprodukte, abgestimmt auf den Alltag und den Sport.',
|
||||
'shop.feature.cook': 'Für die Küche',
|
||||
'shop.feature.clean': 'Für den Haushalt',
|
||||
'shop.feature.care': 'Für Körper & Pflege',
|
||||
'shop.feature.cta': 'Zur Kategorie',
|
||||
'cart.open': 'Warenkorb öffnen',
|
||||
'cart.label': 'Warenkorb',
|
||||
'cart.subtotal': 'Zwischensumme',
|
||||
@@ -272,6 +293,11 @@ const de = {
|
||||
'home.banner.headline.b': 'im Haushalt.',
|
||||
'home.banner.sub': 'Vom Kuchen über das Bad bis zur Wäsche – Kaiser-Natron leistet überall still und zuverlässig seine Arbeit.',
|
||||
|
||||
// Home page – mobile-only hero category shortcuts (Clean / Cook / Care).
|
||||
'home.categories.clean': 'Putzen',
|
||||
'home.categories.cook': 'Kochen',
|
||||
'home.categories.care': 'Pflege',
|
||||
|
||||
// Bundles section — copy for the sidebar, card chrome, and carousel.
|
||||
'bundles.headline.a': 'Bundles &',
|
||||
'bundles.headline.em': 'Vorteile',
|
||||
@@ -392,11 +418,32 @@ const atOverrides = {
|
||||
|
||||
const en = {
|
||||
'nav.shop': 'Shop',
|
||||
'nav.cook': 'Cook',
|
||||
'nav.clean': 'Clean',
|
||||
'nav.care': 'Care',
|
||||
'nav.applications': 'Uses',
|
||||
'nav.bundles': 'Bundles',
|
||||
'nav.revitalization': 'Revitalisation',
|
||||
'nav.about': 'About',
|
||||
'nav.contact': 'Contact',
|
||||
// Shop page — section headlines for the three use-case groups.
|
||||
'shop.eyebrow': 'Our range',
|
||||
'shop.headline': 'Kaiser Natron',
|
||||
'shop.headline.em': 'for every corner',
|
||||
'shop.sub': 'From cooking to cleaning to care — three collections, one ingredient.',
|
||||
'shop.section.cook.headline': 'Bake, cook,',
|
||||
'shop.section.cook.headline.em': 'digest well.',
|
||||
'shop.section.cook.sub': 'Powders and tablets — the quiet foundation under bread, cakes and good digestion.',
|
||||
'shop.section.clean.headline': 'Scrub, wash,',
|
||||
'shop.section.clean.headline.em': 'all clean.',
|
||||
'shop.section.clean.sub': 'Natron-based cleaners and laundry helpers that hold up against stubborn grime.',
|
||||
'shop.section.care.headline': 'Bathe, soften,',
|
||||
'shop.section.care.headline.em': 'breathe easy.',
|
||||
'shop.section.care.sub': 'Bath and care products tuned for daily life and sport.',
|
||||
'shop.feature.cook': 'For the kitchen',
|
||||
'shop.feature.clean': 'For the home',
|
||||
'shop.feature.care': 'For body & care',
|
||||
'shop.feature.cta': 'Shop category',
|
||||
'cart.open': 'Open cart',
|
||||
'cart.label': 'Cart',
|
||||
'cart.subtotal': 'Subtotal',
|
||||
@@ -643,6 +690,11 @@ const en = {
|
||||
'home.banner.headline.b': 'around the home.',
|
||||
'home.banner.sub': 'From baking to bathing to laundry — Kaiser Natron quietly does its work wherever you need it.',
|
||||
|
||||
// Home page – mobile-only hero category shortcuts.
|
||||
'home.categories.clean': 'Clean',
|
||||
'home.categories.cook': 'Cook',
|
||||
'home.categories.care': 'Care',
|
||||
|
||||
// Bundles section
|
||||
'bundles.headline.a': 'Bundles &',
|
||||
'bundles.headline.em': 'Benefits',
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { RouterLink, useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const isDesign = computed(() => route.name === 'design')
|
||||
|
||||
const designSections = [
|
||||
{ id: 'colors', label: 'Colors' },
|
||||
{ id: 'typography', label: 'Typography' },
|
||||
{ id: 'radii', label: 'Radii' },
|
||||
{ id: 'shadows', label: 'Shadows' },
|
||||
{ id: 'buttons', label: 'Buttons' },
|
||||
{ id: 'badges', label: 'Badges' },
|
||||
{ id: 'inputs', label: 'Inputs' },
|
||||
{ id: 'cards', label: 'Cards' },
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-screen flex">
|
||||
<!-- Sidebar -->
|
||||
<aside
|
||||
class="fixed inset-y-0 left-0 w-[260px] border-r border-[var(--color-line)] bg-[var(--color-surface)] flex flex-col z-40"
|
||||
>
|
||||
<!-- Logo -->
|
||||
<div class="h-[78px] shrink-0 flex items-center px-6 border-b border-[var(--color-line)]">
|
||||
<RouterLink
|
||||
to="/"
|
||||
class="font-display text-[20px] font-normal tracking-[-0.01em] text-[var(--color-ink)]"
|
||||
>
|
||||
Kaiser<span class="italic font-light text-[var(--color-brand-soft)]"> Natron</span>
|
||||
</RouterLink>
|
||||
</div>
|
||||
|
||||
<!-- Primary nav -->
|
||||
<nav class="flex-1 overflow-y-auto p-4 space-y-1">
|
||||
<RouterLink
|
||||
to="/"
|
||||
class="flex items-center gap-3 px-3 py-2 rounded-[var(--radius-sm)] text-[14px] font-medium text-[var(--color-muted)] hover:text-[var(--color-brand)] hover:bg-[rgba(28,58,40,0.06)] transition-colors"
|
||||
active-class="!text-[var(--color-brand)] !bg-[rgba(28,58,40,0.08)]"
|
||||
>
|
||||
<span class="inline-block w-1.5 h-1.5 rounded-full bg-current opacity-60" />
|
||||
Home
|
||||
</RouterLink>
|
||||
|
||||
<div>
|
||||
<RouterLink
|
||||
to="/design"
|
||||
class="flex items-center gap-3 px-3 py-2 rounded-[var(--radius-sm)] text-[14px] font-medium text-[var(--color-muted)] hover:text-[var(--color-brand)] hover:bg-[rgba(28,58,40,0.06)] transition-colors"
|
||||
active-class="!text-[var(--color-brand)] !bg-[rgba(28,58,40,0.08)]"
|
||||
>
|
||||
<span class="inline-block w-1.5 h-1.5 rounded-full bg-current opacity-60" />
|
||||
Design system
|
||||
</RouterLink>
|
||||
|
||||
<!-- Nested sub-sections, visible only on /design -->
|
||||
<div
|
||||
v-if="isDesign"
|
||||
class="mt-1 ml-[18px] pl-3 border-l border-[var(--color-line)] flex flex-col"
|
||||
>
|
||||
<a
|
||||
v-for="s in designSections"
|
||||
:key="s.id"
|
||||
:href="`#${s.id}`"
|
||||
class="px-3 py-1.5 rounded-[var(--radius-sm)] text-[13px] font-medium text-[var(--color-muted)] hover:text-[var(--color-brand)] hover:bg-[rgba(28,58,40,0.05)] transition-colors"
|
||||
>
|
||||
{{ s.label }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Sidebar footer -->
|
||||
<div class="shrink-0 p-4 border-t border-[var(--color-line)]">
|
||||
<p class="text-[11px] font-bold uppercase tracking-[var(--tracking-eyebrow)] text-[var(--color-muted)]">
|
||||
Kaiser Natron · v0.1
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main content (offset by sidebar width) -->
|
||||
<main class="flex-1 ml-[260px] min-w-0">
|
||||
<slot />
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
@@ -32,13 +32,35 @@ const bannerProductId = 'kaiser-natron-pulver-250-g-grosspackung'
|
||||
// Homepage top-level nav items — overrides the Navbar default so the
|
||||
// homepage reads as the shop entry point (Shop / Bundles / Revitalisierung
|
||||
// / Über uns) instead of the generic catalogue chrome.
|
||||
// Primary nav — the top-level shop destinations, rendered on the left
|
||||
// of the Navbar. Cook / Clean / Care deep-link into the Shop page's
|
||||
// use-case sections so users land on the right band immediately.
|
||||
const navItems = [
|
||||
{ key: 'nav.shop', href: '#' },
|
||||
{ key: 'nav.shop', href: '/shop' },
|
||||
{ key: 'nav.cook', href: '/shop#cook' },
|
||||
{ key: 'nav.clean', href: '/shop#clean' },
|
||||
{ key: 'nav.care', href: '/shop#care' },
|
||||
]
|
||||
|
||||
// Secondary nav — supporting pages. Rendered on the right, tucked to
|
||||
// the left of the search trigger. Same visual treatment as primary so
|
||||
// the split reads as "categories | pages" rather than two navs.
|
||||
const navSecondaryItems = [
|
||||
{ key: 'nav.bundles', href: '#bundles' },
|
||||
{ key: 'nav.revitalization', href: '#revitalize' },
|
||||
{ key: 'nav.about', href: '#about' },
|
||||
]
|
||||
|
||||
// Mobile-only category shortcuts rendered under the hero image. Three
|
||||
// pills that point at the shop's top-level use-cases. Labels are
|
||||
// translated through the page i18n so the German/English splits stay
|
||||
// in sync with the rest of the site copy.
|
||||
const heroCategories = computed(() => [
|
||||
{ label: t('home.categories.clean'), href: '#clean' },
|
||||
{ label: t('home.categories.cook'), href: '#cook' },
|
||||
{ label: t('home.categories.care'), href: '#care' },
|
||||
])
|
||||
|
||||
// Bundles sidebar copy resolves through the page's own i18n namespace so
|
||||
// component internals stay decoupled from any particular key tree.
|
||||
const bundlesCopy = computed(() => ({
|
||||
@@ -92,8 +114,7 @@ const bundles = [
|
||||
],
|
||||
price: 24.9,
|
||||
memberPrice: 21.17,
|
||||
image:
|
||||
'/products/cutouts/kaiser-natron-pulver-250-g-grosspackung-removebg-preview-1.png',
|
||||
image: '/products/ai/kaiser-natron-pulver-250-g-grosspackung.png',
|
||||
imageAlt: 'Haushalts-Bundle mit Kaiser-Natron',
|
||||
badge: 'Bestseller',
|
||||
badgeVariant: 'accent',
|
||||
@@ -105,7 +126,7 @@ const bundles = [
|
||||
items: ['1× Holste Wasch-Soda 500 g', '1× Gazelle Wäschestärke 1 l', '1× Linda Fleckenweg 200 ml'],
|
||||
price: 22.9,
|
||||
memberPrice: 19.47,
|
||||
image: '/products/cutouts/holste-wasch-soda-500-g-beutel-Photoroom.png',
|
||||
image: '/products/ai/kaiser-natron-pulver-250-g-grosspackung.png',
|
||||
imageAlt: 'Wäsche & Pflege Bundle',
|
||||
badge: '',
|
||||
badgeVariant: 'accent',
|
||||
@@ -117,8 +138,7 @@ const bundles = [
|
||||
items: ['1× Kaiser-Natron Tabletten 100 g', '1× Kaiser-Natron Bad 500 g', '1× Kaiser-Natron Fußbad 500 g'],
|
||||
price: 29.9,
|
||||
memberPrice: 25.42,
|
||||
image:
|
||||
'/products/cutouts/kaiser-natron-pulver-250-g-grosspackung-removebg-preview-3.png',
|
||||
image: '/products/ai/kaiser-natron-bad-500-g.png',
|
||||
imageAlt: 'Wohlfühl-Bundle mit Kaiser-Natron Bad',
|
||||
badge: '',
|
||||
badgeVariant: 'accent',
|
||||
@@ -179,45 +199,27 @@ async function onSearchSelect(product) {
|
||||
cartOpen.value = true
|
||||
}
|
||||
|
||||
// Hydrate from the API on mount — today this reads the local store, later
|
||||
// it will hit `GET /api/cart`. Either way the drawer has data to show.
|
||||
// First-fold vertical centering: the sticky navbar sits above the green
|
||||
// hero container and occupies layout space. If the green container is a
|
||||
// full 100svh tall, the hero centers inside that block, which sits *below*
|
||||
// the navbar — so the hero's visual center ends up ~navH/2 below the
|
||||
// viewport's visual center (between nav bottom and viewport bottom).
|
||||
// First-fold vertical centering. The sticky navbar takes flow space
|
||||
// above the green wrapper; if the wrapper is a full 100svh tall, the
|
||||
// hero centers inside that block (which starts BELOW the nav) and
|
||||
// its visual center lands ~navH/2 below the viewport's true center.
|
||||
//
|
||||
// Fix: set the green container's min-height to `100svh - navH`, so the
|
||||
// flex-centering wrapper inside centers the hero exactly within the
|
||||
// available viewport area below the sticky nav.
|
||||
// The wrapper's height is driven by CSS: `100svh - var(--nav-h)`,
|
||||
// with `--nav-h` defaulted in global styles so first paint is correct.
|
||||
// This ResizeObserver refines `--nav-h` at runtime so the wrapper
|
||||
// tracks real Navbar height changes (logo swaps, language changes,
|
||||
// responsive breakpoints) without a layout shift.
|
||||
const navRef = ref(null)
|
||||
const navHeight = ref(0)
|
||||
const isMdUp = ref(false)
|
||||
let navResizeObserver = null
|
||||
let mdQuery = null
|
||||
function syncNavHeight() {
|
||||
const el = navRef.value
|
||||
const node = el && (el.$el || el)
|
||||
if (!node || typeof window === 'undefined') return
|
||||
navHeight.value = Math.round(node.getBoundingClientRect().height)
|
||||
document.documentElement.style.setProperty('--nav-h', `${navHeight.value}px`)
|
||||
const h = Math.round(node.getBoundingClientRect().height)
|
||||
document.documentElement.style.setProperty('--nav-h', `${h}px`)
|
||||
}
|
||||
const heroFoldStyle = computed(() => {
|
||||
const h = navHeight.value
|
||||
if (!h || !isMdUp.value) return {}
|
||||
// Override Tailwind's `md:min-h-svh` with a nav-aware value. Inline
|
||||
// styles win over classes, so this reliably shrinks the centering
|
||||
// block to the viewport area actually visible below the sticky nav.
|
||||
return { minHeight: `calc(100svh - ${h}px)` }
|
||||
})
|
||||
onMounted(() => {
|
||||
fetchCart()
|
||||
// Match Tailwind's `md` breakpoint (768px).
|
||||
if (typeof window !== 'undefined' && window.matchMedia) {
|
||||
mdQuery = window.matchMedia('(min-width: 768px)')
|
||||
isMdUp.value = mdQuery.matches
|
||||
mdQuery.addEventListener('change', onMdChange)
|
||||
}
|
||||
syncNavHeight()
|
||||
if (typeof ResizeObserver !== 'undefined' && navRef.value) {
|
||||
const node = navRef.value.$el || navRef.value
|
||||
@@ -226,12 +228,8 @@ onMounted(() => {
|
||||
}
|
||||
window.addEventListener('resize', syncNavHeight)
|
||||
})
|
||||
function onMdChange(e) {
|
||||
isMdUp.value = e.matches
|
||||
}
|
||||
onBeforeUnmount(() => {
|
||||
if (navResizeObserver) navResizeObserver.disconnect()
|
||||
if (mdQuery) mdQuery.removeEventListener('change', onMdChange)
|
||||
if (typeof window !== 'undefined') window.removeEventListener('resize', syncNavHeight)
|
||||
})
|
||||
</script>
|
||||
@@ -250,67 +248,90 @@ onBeforeUnmount(() => {
|
||||
variant="brand"
|
||||
layout="standard"
|
||||
:items="navItems"
|
||||
:secondary-items="navSecondaryItems"
|
||||
:cart-count="cart.count"
|
||||
:products="products"
|
||||
@cart="cartOpen = true"
|
||||
@search="onSearchSelect"
|
||||
/>
|
||||
<!-- First-fold wrapper — full viewport height, pulled up under the
|
||||
sticky nav via a negative margin equal to `--nav-h`. The nav
|
||||
and the wrapper share the brand green, so the overlap reads as
|
||||
a single continuous surface, and the hero centers at the TRUE
|
||||
viewport vertical midpoint (50svh) rather than the midpoint of
|
||||
the nav-offset space below it. The wave divider sits OUTSIDE
|
||||
this wrapper so it never eats vertical space from the centering
|
||||
calculation. `--nav-h` is defaulted in global CSS so first
|
||||
paint is correct; a ResizeObserver refines it on mount. -->
|
||||
<div
|
||||
class="flex flex-col bg-brand md:min-h-svh"
|
||||
:style="heroFoldStyle"
|
||||
class="flex flex-col bg-brand md:min-h-[calc(100svh-var(--nav-h))] md:justify-center"
|
||||
>
|
||||
<div class="md:flex-1 md:flex md:items-center">
|
||||
<Hero
|
||||
class="w-full"
|
||||
variant="split"
|
||||
tone="brand"
|
||||
:eyebrow="t('ds.hero.eyebrow')"
|
||||
:subheadline="t('ds.hero.sub')"
|
||||
:image="imgPulver250"
|
||||
image-alt="Kaiser-Natron Pulver 250 g Großpackung"
|
||||
:cta-label="t('ds.buttons.addToCart')"
|
||||
:secondary-label="t('ds.buttons.learnMore')"
|
||||
secondary-href="/anwendungen"
|
||||
@cta="onHeroAdd"
|
||||
>
|
||||
<template #headline>
|
||||
{{ t('ds.hero.headline.a') }}
|
||||
<em class="italic font-light text-accent-soft">{{ t('ds.hero.headline.em') }}</em>
|
||||
{{ t('ds.hero.headline.b') }}
|
||||
</template>
|
||||
</Hero>
|
||||
</div>
|
||||
|
||||
<!-- Wave divider from brand-green → cream. The SVG is fully opaque:
|
||||
a cream rect fills the whole viewBox so the SVG's bottom row is
|
||||
solid cream (matches the banner below → no seam), and a green
|
||||
path paints the top portion (matches the bg-brand parent above
|
||||
→ no seam). The earlier version left the top half transparent,
|
||||
which caused browsers to anti-alias the path's top/bottom
|
||||
edges against the parent and produce hairline artifacts. -->
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="block w-full h-12 md:h-16 shrink-0 -mb-px"
|
||||
viewBox="0 0 1440 64"
|
||||
preserveAspectRatio="none"
|
||||
<Hero
|
||||
class="w-full"
|
||||
variant="split"
|
||||
tone="brand"
|
||||
:eyebrow="t('ds.hero.eyebrow')"
|
||||
:subheadline="t('ds.hero.sub')"
|
||||
:image="imgPulver250"
|
||||
image-alt="Kaiser-Natron Pulver 250 g Großpackung"
|
||||
:cta-label="t('ds.buttons.addToCart')"
|
||||
:secondary-label="t('ds.buttons.learnMore')"
|
||||
secondary-href="/anwendungen"
|
||||
@cta="onHeroAdd"
|
||||
>
|
||||
<rect width="1440" height="64" fill="var(--color-cream)" />
|
||||
<path
|
||||
d="M0,0 L0,40 C320,4 520,60 720,32 C920,4 1120,60 1440,24 L1440,0 Z"
|
||||
fill="var(--color-brand)"
|
||||
/>
|
||||
</svg>
|
||||
<template #headline>
|
||||
{{ t('ds.hero.headline.a') }}
|
||||
<em class="italic font-light text-accent-soft">{{ t('ds.hero.headline.em') }}</em>
|
||||
{{ t('ds.hero.headline.b') }}
|
||||
</template>
|
||||
<!-- Mobile-only category shortcuts. Three pills sit directly
|
||||
under the hero jar so the phone user can jump straight to
|
||||
a use-case context without scrolling past the whole fold.
|
||||
Hidden on md+ because desktop already has full nav chrome. -->
|
||||
<template #afterMedia>
|
||||
<div class="md:hidden mt-6 flex items-center justify-center gap-2">
|
||||
<a
|
||||
v-for="cat in heroCategories"
|
||||
:key="cat.href"
|
||||
:href="cat.href"
|
||||
class="inline-flex items-center justify-center rounded-pill border border-cream/50 px-5 py-2.5 text-sm font-semibold tracking-label text-cream transition-colors duration-base hover:border-cream hover:bg-cream-wash-strong"
|
||||
>{{ cat.label }}</a>
|
||||
</div>
|
||||
</template>
|
||||
</Hero>
|
||||
</div>
|
||||
|
||||
<!-- Wave divider from brand-green → cream. Sits OUTSIDE the fold
|
||||
wrapper so it doesn't steal vertical space from the hero's
|
||||
centering. The SVG is fully opaque: a cream rect fills the
|
||||
whole viewBox so the SVG's bottom row is solid cream (matches
|
||||
the banner below → no seam), and a green path paints the top
|
||||
portion (matches the bg-brand fold above → no seam). -->
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="block w-full h-12 md:h-16 shrink-0 -mb-px bg-brand"
|
||||
viewBox="0 0 1440 64"
|
||||
preserveAspectRatio="none"
|
||||
>
|
||||
<rect width="1440" height="64" fill="var(--color-cream)" />
|
||||
<path
|
||||
d="M0,0 L0,40 C320,4 520,60 720,32 C920,4 1120,60 1440,24 L1440,0 Z"
|
||||
fill="var(--color-brand)"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<!-- Second-fold product banner — same Hero component, cream surface,
|
||||
split layout reversed so the product sits on the left. The -mt-px
|
||||
pairs with the wave's -mb-px to overlap the two sections by 1 CSS
|
||||
split layout reversed so the product sits on the left. `compact`
|
||||
tightens the desktop media sizing so this section reads as a
|
||||
companion band, not a second full hero stage. The -mt-px pairs
|
||||
with the wave's -mb-px to overlap the two sections by 1 CSS
|
||||
pixel and hide any device-pixel seam. -->
|
||||
<Hero
|
||||
class="banner-shrink-desktop -mt-px"
|
||||
class="-mt-px"
|
||||
variant="split"
|
||||
tone="cream"
|
||||
reverse
|
||||
compact
|
||||
:eyebrow="t('home.banner.eyebrow')"
|
||||
:subheadline="t('home.banner.sub')"
|
||||
:image="imgBanner"
|
||||
@@ -351,6 +372,7 @@ onBeforeUnmount(() => {
|
||||
md+ flips to a one-at-a-time scroll-snap carousel. -->
|
||||
<Bundles
|
||||
class="-mt-px"
|
||||
layout="stacked"
|
||||
:bundles="bundles"
|
||||
:headline="bundlesCopy.headline"
|
||||
:headline-em="bundlesCopy.headlineEm"
|
||||
@@ -435,18 +457,3 @@ onBeforeUnmount(() => {
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Banner (second-fold Hero) desktop sizing override.
|
||||
Hero was globally scaled +30%. On desktop we want the banner to read
|
||||
~20% smaller than ORIGINAL size (0.8 × 575px ≈ 460px max width, and
|
||||
0.8 × 60svh = 48svh max height). Mobile/tablet keep the enlarged
|
||||
sizing from Hero.vue. */
|
||||
@media (min-width: 1024px) {
|
||||
.banner-shrink-desktop :deep(img) {
|
||||
max-height: 48svh;
|
||||
}
|
||||
.banner-shrink-desktop :deep(.relative.mx-auto.w-full.max-w-6xl > div:last-child > div.relative) {
|
||||
max-width: 460px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
252
src/pages/ShopPage.vue
Normal file
252
src/pages/ShopPage.vue
Normal file
@@ -0,0 +1,252 @@
|
||||
<script setup>
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import Navbar from '@/design-system/components/Navbar.vue'
|
||||
import ProductCard from '@/design-system/components/ProductCard.vue'
|
||||
import WaveDivider from '@/design-system/components/WaveDivider.vue'
|
||||
import CartDrawer from '@/design-system/components/CartDrawer.vue'
|
||||
import {
|
||||
products,
|
||||
productsByUseCase,
|
||||
USE_CASES,
|
||||
fetchCart,
|
||||
addToCart,
|
||||
updateCartItem,
|
||||
removeFromCart,
|
||||
} from '@/api/index.js'
|
||||
import { useCartStore } from '@/stores/cart.js'
|
||||
import { useI18n } from '@/i18n/index.js'
|
||||
|
||||
const { t } = useI18n()
|
||||
const cart = useCartStore()
|
||||
const cartOpen = ref(false)
|
||||
|
||||
// Site-wide nav split mirrors HomePage so the header reads as one
|
||||
// piece of chrome across both routes. On /shop the category links
|
||||
// point at in-page anchors (`#cook`, `#clean`, `#care`) so they
|
||||
// scroll within the page rather than re-route.
|
||||
const navItems = [
|
||||
{ key: 'nav.shop', href: '/shop' },
|
||||
{ key: 'nav.cook', href: '#cook' },
|
||||
{ key: 'nav.clean', href: '#clean' },
|
||||
{ key: 'nav.care', href: '#care' },
|
||||
]
|
||||
const navSecondaryItems = [
|
||||
{ key: 'nav.bundles', href: '/#bundles' },
|
||||
{ key: 'nav.revitalization', href: '/#revitalize' },
|
||||
{ key: 'nav.about', href: '/#about' },
|
||||
]
|
||||
|
||||
// Group products by use-case once; iterate a stable config below.
|
||||
// The featured tiles in the top banner each pick the FIRST product
|
||||
// in their group — a representative face for that band. The
|
||||
// sections themselves display every product in the group.
|
||||
const grouped = computed(() => productsByUseCase(products))
|
||||
const featuredTiles = computed(() =>
|
||||
USE_CASES.map((id) => ({
|
||||
id,
|
||||
label: t(`shop.feature.${id}`),
|
||||
product: grouped.value[id][0],
|
||||
})),
|
||||
)
|
||||
const sections = computed(() =>
|
||||
USE_CASES.map((id, i) => ({
|
||||
id,
|
||||
headline: t(`shop.section.${id}.headline`),
|
||||
headlineEm: t(`shop.section.${id}.headline.em`),
|
||||
sub: t(`shop.section.${id}.sub`),
|
||||
products: grouped.value[id],
|
||||
// Alternate tones so neighbouring sections read as distinct
|
||||
// surfaces without a hard rule. Cook/Care land on cream;
|
||||
// Clean sits on surface between them for contrast.
|
||||
tone: i % 2 === 0 ? 'cream' : 'surface',
|
||||
})),
|
||||
)
|
||||
|
||||
async function onAdd(product) {
|
||||
await addToCart(product.id, 1)
|
||||
cartOpen.value = true
|
||||
}
|
||||
async function onSearchSelect(product) {
|
||||
await addToCart(product.id, 1)
|
||||
cartOpen.value = true
|
||||
}
|
||||
async function onQty({ productId, quantity }) {
|
||||
await updateCartItem(productId, quantity)
|
||||
}
|
||||
async function onRemove(productId) {
|
||||
await removeFromCart(productId)
|
||||
}
|
||||
|
||||
// `--nav-h` is defaulted in global styles; this ResizeObserver refines
|
||||
// it so deep-link anchor targets (e.g. `/shop#care`) land just below
|
||||
// the sticky nav via each section's `scroll-mt` offset.
|
||||
const navRef = ref(null)
|
||||
let navResizeObserver = null
|
||||
function syncNavHeight() {
|
||||
const el = navRef.value
|
||||
const node = el && (el.$el || el)
|
||||
if (!node || typeof window === 'undefined') return
|
||||
const h = Math.round(node.getBoundingClientRect().height)
|
||||
document.documentElement.style.setProperty('--nav-h', `${h}px`)
|
||||
}
|
||||
onMounted(() => {
|
||||
fetchCart()
|
||||
syncNavHeight()
|
||||
if (typeof ResizeObserver !== 'undefined' && navRef.value) {
|
||||
const node = navRef.value.$el || navRef.value
|
||||
navResizeObserver = new ResizeObserver(syncNavHeight)
|
||||
navResizeObserver.observe(node)
|
||||
}
|
||||
window.addEventListener('resize', syncNavHeight)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
if (navResizeObserver) navResizeObserver.disconnect()
|
||||
if (typeof window !== 'undefined') window.removeEventListener('resize', syncNavHeight)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Navbar
|
||||
ref="navRef"
|
||||
variant="brand"
|
||||
layout="standard"
|
||||
:items="navItems"
|
||||
:secondary-items="navSecondaryItems"
|
||||
:cart-count="cart.count"
|
||||
:products="products"
|
||||
@cart="cartOpen = true"
|
||||
@search="onSearchSelect"
|
||||
/>
|
||||
|
||||
<!-- First-fold green banner — full viewport height, pulled up under
|
||||
the sticky nav so the hero content centers at the TRUE viewport
|
||||
midpoint (matches the home page's first fold). The content is a
|
||||
page-title band + three featured product tiles, one per use-case
|
||||
section, with anchor links into the sections below. -->
|
||||
<div
|
||||
class="flex flex-col bg-brand text-cream md:min-h-[calc(100svh-var(--nav-h))] md:justify-center"
|
||||
>
|
||||
<div class="mx-auto w-full max-w-6xl px-6 py-12 sm:px-8 sm:py-16 md:px-12 md:py-12 lg:px-16 lg:py-16">
|
||||
<!-- Title band. Mixed-font banner treatment (Hero-style): normal
|
||||
display weight + italic light for the emphasis phrase. -->
|
||||
<div class="flex flex-col items-center text-center gap-4 max-w-3xl mx-auto">
|
||||
<h1 class="font-display font-normal leading-[1.05] tracking-tight text-cream text-headline-lg">
|
||||
{{ t('shop.headline') }}
|
||||
<em class="italic font-light text-accent-soft">{{ t('shop.headline.em') }}</em>
|
||||
</h1>
|
||||
<p class="text-base md:text-lg leading-relaxed text-cream/80 max-w-2xl">
|
||||
{{ t('shop.sub') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Three featured tiles — rule of 3. One representative product
|
||||
per use-case, each tile is an anchor into its section. Uses
|
||||
the cream-wash-on-brand container pattern from the
|
||||
LanguageSwitcher's `brand` tone so tiles read as lifted off
|
||||
the green ground without another heavy surface.
|
||||
Image uses aspect-[4/3] (not aspect-square) with a svh-
|
||||
relative height cap so the whole fold — title + sub + three
|
||||
tiles + padding — stays inside 100svh at desktop heights
|
||||
from ~720px up. Mobile stacks the tiles; the fold can
|
||||
overflow below there because phones scroll naturally. -->
|
||||
<ul class="mt-8 md:mt-10 grid gap-4 sm:gap-5 md:gap-6 grid-cols-1 sm:grid-cols-3">
|
||||
<li v-for="tile in featuredTiles" :key="tile.id">
|
||||
<a
|
||||
:href="`#${tile.id}`"
|
||||
class="group flex h-full flex-col items-center gap-4 p-4 md:p-5 rounded-md border border-cream-line bg-cream-wash hover:bg-cream-wash-strong transition-colors duration-base"
|
||||
>
|
||||
<div class="w-full aspect-[4/3] max-h-[30svh] md:max-h-[26svh] lg:max-h-[28svh] rounded-md bg-cream overflow-hidden flex items-center justify-center">
|
||||
<img
|
||||
:src="tile.product.image"
|
||||
:alt="tile.product.title"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
class="w-full h-full object-contain p-4 md:p-5"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col items-center text-center gap-1">
|
||||
<p class="eyebrow text-accent">{{ tile.label }}</p>
|
||||
<h3 class="font-display text-lg md:text-xl font-normal leading-tight text-cream">
|
||||
{{ tile.product.title }}
|
||||
</h3>
|
||||
</div>
|
||||
<span
|
||||
class="mt-auto inline-flex items-center gap-1.5 text-sm font-semibold tracking-label text-cream/80 group-hover:text-accent transition-colors duration-base"
|
||||
>
|
||||
{{ t('shop.feature.cta') }}
|
||||
<span aria-hidden="true" class="transition-transform duration-base group-hover:translate-x-1">→</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Three use-case sections. Each has its own banner-style mixed-font
|
||||
heading (no eyebrow pill), a 3-up product grid capped at the
|
||||
rule of 3 per row, and wave dividers on either side so the
|
||||
page reads with the same rhythm as the home page. -->
|
||||
<template v-for="(section, i) in sections" :key="section.id">
|
||||
<!-- Wave into the section. Previous surface is `brand` for the
|
||||
first divider (coming out of the green fold), then alternates
|
||||
between cream/surface to match the previous section's tone. -->
|
||||
<WaveDivider :from="i === 0 ? 'brand' : sections[i - 1].tone" :to="section.tone" />
|
||||
|
||||
<section
|
||||
:id="section.id"
|
||||
:class="[
|
||||
'-mt-px scroll-mt-[calc(var(--nav-h)+1rem)]',
|
||||
section.tone === 'cream' ? 'bg-cream text-ink' : 'bg-surface text-ink',
|
||||
]"
|
||||
>
|
||||
<div class="mx-auto w-full max-w-6xl px-6 py-16 sm:px-8 sm:py-20 md:px-12 md:py-24 lg:px-16 lg:py-28">
|
||||
<div class="flex flex-col gap-4 max-w-3xl">
|
||||
<h2 class="font-display font-normal leading-[1.05] tracking-tight text-ink text-headline-lg">
|
||||
{{ section.headline }}
|
||||
<em class="italic font-light text-brand">{{ section.headlineEm }}</em>
|
||||
</h2>
|
||||
<p class="text-lg leading-relaxed text-muted max-w-2xl">
|
||||
{{ section.sub }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="section.products.length"
|
||||
class="mt-12 md:mt-14 grid gap-5 md:gap-7 grid-cols-1 sm:grid-cols-2 md:grid-cols-3"
|
||||
>
|
||||
<ProductCard
|
||||
v-for="product in section.products"
|
||||
:key="product.id"
|
||||
:title="product.title"
|
||||
:size="product.size"
|
||||
:price="product.price"
|
||||
:image="product.image"
|
||||
:image-alt="product.title"
|
||||
:href="product.href"
|
||||
:tone="section.tone === 'cream' ? 'paper' : 'cream'"
|
||||
:in-stock="product.inStock"
|
||||
@add="onAdd(product)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<!-- Bottom clearance for the mobile floating cluster (search / cart /
|
||||
menu), same pattern as HomePage so both pages align visually. -->
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="md:hidden"
|
||||
style="height: calc(100px + env(safe-area-inset-bottom));"
|
||||
/>
|
||||
|
||||
<CartDrawer
|
||||
v-model="cartOpen"
|
||||
:items="cart.items"
|
||||
:subtotal="cart.subtotal"
|
||||
:count="cart.count"
|
||||
@update-quantity="onQty"
|
||||
@remove="onRemove"
|
||||
@checkout="cartOpen = false"
|
||||
/>
|
||||
</template>
|
||||
@@ -1,4 +1,5 @@
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import SectionShell from './SectionShell.vue'
|
||||
import DevicePreview from '@/design-system/components/DevicePreview.vue'
|
||||
import { useI18n } from '@/i18n/index.js'
|
||||
@@ -9,7 +10,17 @@ const { t } = useI18n()
|
||||
// md up — iframe it through DevicePreview so we can demo mobile / tablet /
|
||||
// desktop breakpoints side by side rather than squeezing into the docs
|
||||
// column at a single width.
|
||||
const src = '/design/preview/bundles'
|
||||
//
|
||||
// Layout variant travels to the preview route via `?layout=` so the
|
||||
// iframe can re-render in the selected shape. Index-based labelling
|
||||
// ('Option 1', 'Option 2', …) keeps the UI generic so the same
|
||||
// switcher pattern works for any future component variant set.
|
||||
const variants = [
|
||||
{ id: 'sidebar', label: 'Option 1' },
|
||||
{ id: 'stacked', label: 'Option 2' },
|
||||
]
|
||||
const variant = ref('sidebar')
|
||||
const src = computed(() => `/design/preview/bundles?layout=${variant.value}`)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -20,7 +31,31 @@ const src = '/design/preview/bundles'
|
||||
wide
|
||||
>
|
||||
<section>
|
||||
<DevicePreview :src="src" initial="desktop" :height="1080" />
|
||||
<DevicePreview :src="src" initial="desktop" :height="1080">
|
||||
<template #controls>
|
||||
<!-- Variant switcher. Same pill treatment as the device
|
||||
switcher on the right, aligned left so the two sit at
|
||||
opposite ends of the preview's control bar. -->
|
||||
<div
|
||||
role="tablist"
|
||||
aria-label="Layout variant"
|
||||
class="inline-flex items-center p-1 gap-0.5 rounded-pill border border-line bg-paper"
|
||||
>
|
||||
<button
|
||||
v-for="v in variants"
|
||||
:key="v.id"
|
||||
type="button"
|
||||
role="tab"
|
||||
:aria-selected="variant === v.id"
|
||||
:class="[
|
||||
'inline-flex items-center gap-2 px-3 py-1.5 text-[12px] font-semibold tracking-label rounded-pill transition-colors duration-base',
|
||||
variant === v.id ? 'bg-brand text-accent' : 'text-muted hover:text-brand',
|
||||
]"
|
||||
@click="variant = v.id"
|
||||
>{{ v.label }}</button>
|
||||
</div>
|
||||
</template>
|
||||
</DevicePreview>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import Bundles from '@/design-system/components/Bundles.vue'
|
||||
import { useI18n } from '@/i18n/index.js'
|
||||
|
||||
const { t } = useI18n()
|
||||
const route = useRoute()
|
||||
|
||||
// Variant selection travels in as a URL query param so the section
|
||||
// page's iframe can switch layouts without reloading the component
|
||||
// registry. Falls back to the default 'sidebar' layout if the param
|
||||
// is missing or not one of the component's recognised variants.
|
||||
const layout = computed(() => {
|
||||
const q = route.query.layout
|
||||
return q === 'stacked' ? 'stacked' : 'sidebar'
|
||||
})
|
||||
|
||||
// Demo fixtures — mirrors HomePage's real content so the preview is
|
||||
// representative rather than lorem-ipsum. Kept inline because preview
|
||||
@@ -66,6 +77,7 @@ const benefits = computed(() => [
|
||||
<template>
|
||||
<div class="min-h-screen bg-surface">
|
||||
<Bundles
|
||||
:layout="layout"
|
||||
:bundles="bundles"
|
||||
:headline="t('bundles.headline.a')"
|
||||
:headline-em="t('bundles.headline.em')"
|
||||
|
||||
@@ -7,6 +7,12 @@ const routes = [
|
||||
component: () => import('@/pages/HomePage.vue'),
|
||||
meta: { layout: 'none' },
|
||||
},
|
||||
{
|
||||
path: '/shop',
|
||||
name: 'shop',
|
||||
component: () => import('@/pages/ShopPage.vue'),
|
||||
meta: { layout: 'none' },
|
||||
},
|
||||
{
|
||||
path: '/design/preview/navbar',
|
||||
name: 'ds-preview-navbar',
|
||||
@@ -72,7 +78,15 @@ const routes = [
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
scrollBehavior: () => ({ top: 0 }),
|
||||
// Anchor-aware scroll: navigating to `/shop#care` scrolls to the
|
||||
// #care section rather than resetting to top. `el: ...` lets the
|
||||
// router run the browser's own findElementBySelector, so the
|
||||
// ShopPage sections' `scroll-mt-[calc(var(--nav-h)+1rem)]` offset
|
||||
// handles the sticky-nav clearance declaratively.
|
||||
scrollBehavior(to) {
|
||||
if (to.hash) return { el: to.hash, behavior: 'smooth' }
|
||||
return { top: 0 }
|
||||
},
|
||||
})
|
||||
|
||||
export default router
|
||||
|
||||
Reference in New Issue
Block a user