explicit smooth-scroll handlers on Navbar links

Vue Router's scrollBehavior doesn't fire when RouterLink resolves to
the current URL (logo while on /, /#bundles while already at #bundles),
so the smooth scroll never happened. Added onNavClick + onLogoClick
handlers that intercept the click when the destination is the same
route and call scrollIntoView / window.scrollTo with behavior:'smooth'
directly. Cross-route nav still goes through Vue Router's scrollBehavior
unchanged (savedPosition restore + same-route smooth + cross-route
instant).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-05-03 16:17:47 +01:00
parent eefaa06995
commit 7cad9d27c8
14 changed files with 50 additions and 16 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{C as e,G as t,ft as n,j as r,m as i,o as a,p as o,r as s,s as c,u as l,ut as u}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{a as d}from"./vue-router-Cyqru1db.js";import{t as f}from"./i18n-DhVF3Pwg.js";import{t as p}from"./Navbar-1LFtbeJc.js";import{t as m}from"./Hero-Bag8c3o2.js";var h={class:`italic font-light text-brand-soft`},g={class:`italic font-light text-brand-soft`},_=`/products/kaiser-natron-pulver-250-g-grosspackung.webp`,v=`/products/kaiser-natron-bad-500-g.webp`,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(),l(`div`,{class:u([`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:r(()=>[w.value?(e(),l(s,{key:0},[o(n(t(x)(`home.banner.headline.a`))+` `,1),c(`em`,h,n(t(x)(`home.banner.headline.em`)),1),o(` `+n(t(x)(`home.banner.headline.b`)),1)],64)):(e(),l(s,{key:1},[o(n(t(x)(`ds.hero.headline.a`))+` `,1),c(`em`,g,n(t(x)(`ds.hero.headline.em`)),1),o(` `+n(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,ft as n,j as r,m as i,o as a,p as o,r as s,s as c,u as l,ut as u}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{a as d}from"./vue-router-Cyqru1db.js";import{t as f}from"./i18n-DhVF3Pwg.js";import{t as p}from"./Navbar-BZK-fooS.js";import{t as m}from"./Hero-Bag8c3o2.js";var h={class:`italic font-light text-brand-soft`},g={class:`italic font-light text-brand-soft`},_=`/products/kaiser-natron-pulver-250-g-grosspackung.webp`,v=`/products/kaiser-natron-bad-500-g.webp`,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(),l(`div`,{class:u([`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:r(()=>[w.value?(e(),l(s,{key:0},[o(n(t(x)(`home.banner.headline.a`))+` `,1),c(`em`,h,n(t(x)(`home.banner.headline.em`)),1),o(` `+n(t(x)(`home.banner.headline.b`)),1)],64)):(e(),l(s,{key:1},[o(n(t(x)(`ds.hero.headline.a`))+` `,1),c(`em`,g,n(t(x)(`ds.hero.headline.em`)),1),o(` `+n(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};

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{B as e,C as t,G as n,S as r,T as i,ft as a,l as o,m as s,o as c,r as l,s as u,u as d,x as f}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{o as p}from"./vue-router-Cyqru1db.js";import{t as m}from"./i18n-DhVF3Pwg.js";import{r as h}from"./products-BqW5PUnm.js";import{c as g,d as _,f as v,p as y,u as b}from"./api-DlB23x7f.js";import{t as x}from"./Navbar-1LFtbeJc.js";import{t as S}from"./Footer-DX-ml2dd.js";import{t as C}from"./CartDrawer-f57jysS_.js";var w={class:`bg-cream text-ink min-h-svh`},T={class:`mx-auto w-full max-w-3xl px-6 py-14 sm:px-8 sm:py-16 md:px-12 md:py-20 lg:px-16 lg:py-24`},E={class:`flex flex-col gap-3 mb-10 md:mb-14`},D={class:`eyebrow`},O={class:`font-display font-normal leading-[1.05] tracking-tight text-ink text-headline-md`},k={key:0,class:`text-[12px] text-muted`},A={class:`flex flex-col gap-10`},j=[`id`],M={class:`font-display text-xl md:text-2xl font-normal text-brand leading-tight`},N={class:`text-[15px] leading-relaxed text-ink whitespace-pre-line`},P={__name:`LegalPage`,props:{kind:{type:String,required:!0,validator:e=>[`impressum`,`datenschutz`].includes(e)}},setup(P){let F=P,{t:I}=m(),L=y(),R=p(),z=e(!1);function B(){z.value=!1,R.push(`/checkout`)}let V=[{key:`nav.shop`,href:`/shop`},{key:`nav.bundles`,href:`/#bundles`},{key:`nav.revitalization`,href:`/#revitalize`},{key:`nav.about`,href:`/#about`}],H={impressum:[`operator`,`contact`,`register`,`vat`,`authority`,`liability`,`copyright`],datenschutz:[`controller`,`scope`,`legalBasis`,`data`,`cookies`,`analytics`,`payments`,`rights`,`retention`,`contact`]},U=c(()=>H[F.kind].map(e=>({id:e,heading:I(`legal.${F.kind}.section.${e}.heading`),body:I(`legal.${F.kind}.section.${e}.body`)}))),W=c(()=>I(`legal.${F.kind}.updated`));async function G(e){await g(e.id,1),z.value=!0}async function K({productId:e,quantity:t}){await v(e,t)}async function q(e){await _(e)}let J=e(null),Y=null;function X(){let e=J.value,t=e&&(e.$el||e);if(!t||typeof window>`u`)return;let n=Math.round(t.getBoundingClientRect().height);document.documentElement.style.setProperty(`--nav-h`,`${n}px`)}return r(()=>{if(b(),X(),typeof ResizeObserver<`u`&&J.value){let e=J.value.$el||J.value;Y=new ResizeObserver(X),Y.observe(e)}window.addEventListener(`resize`,X)}),f(()=>{Y&&Y.disconnect(),typeof window<`u`&&window.removeEventListener(`resize`,X)}),(e,r)=>(t(),d(l,null,[s(x,{ref_key:`navRef`,ref:J,variant:`cream`,layout:`standard`,items:V,"cart-count":n(L).count,products:n(h),onCart:r[0]||=e=>z.value=!0,onSearch:G},null,8,[`cart-count`,`products`]),u(`main`,w,[u(`div`,T,[u(`header`,E,[u(`p`,D,a(n(I)(`legal.${P.kind}.eyebrow`)),1),u(`h1`,O,a(n(I)(`legal.${P.kind}.title`)),1),W.value?(t(),d(`p`,k,a(W.value),1)):o(``,!0)]),u(`article`,A,[(t(!0),d(l,null,i(U.value,e=>(t(),d(`section`,{id:e.id,key:e.id,class:`flex flex-col gap-3`},[u(`h2`,M,a(e.heading),1),u(`p`,N,a(e.body),1)],8,j))),128))])])]),s(S),r[2]||=u(`div`,{"aria-hidden":`true`,class:`md:hidden`,style:{height:`calc(64px + env(safe-area-inset-bottom))`}},null,-1),s(C,{modelValue:z.value,"onUpdate:modelValue":r[1]||=e=>z.value=e,items:n(L).items,subtotal:n(L).subtotal,count:n(L).count,onUpdateQuantity:K,onRemove:q,onCheckout:B},null,8,[`modelValue`,`items`,`subtotal`,`count`])],64))}};export{P as default};
import{B as e,C as t,G as n,S as r,T as i,ft as a,l as o,m as s,o as c,r as l,s as u,u as d,x as f}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{o as p}from"./vue-router-Cyqru1db.js";import{t as m}from"./i18n-DhVF3Pwg.js";import{r as h}from"./products-BqW5PUnm.js";import{c as g,d as _,f as v,p as y,u as b}from"./api-DlB23x7f.js";import{t as x}from"./Navbar-BZK-fooS.js";import{t as S}from"./Footer-DX-ml2dd.js";import{t as C}from"./CartDrawer-f57jysS_.js";var w={class:`bg-cream text-ink min-h-svh`},T={class:`mx-auto w-full max-w-3xl px-6 py-14 sm:px-8 sm:py-16 md:px-12 md:py-20 lg:px-16 lg:py-24`},E={class:`flex flex-col gap-3 mb-10 md:mb-14`},D={class:`eyebrow`},O={class:`font-display font-normal leading-[1.05] tracking-tight text-ink text-headline-md`},k={key:0,class:`text-[12px] text-muted`},A={class:`flex flex-col gap-10`},j=[`id`],M={class:`font-display text-xl md:text-2xl font-normal text-brand leading-tight`},N={class:`text-[15px] leading-relaxed text-ink whitespace-pre-line`},P={__name:`LegalPage`,props:{kind:{type:String,required:!0,validator:e=>[`impressum`,`datenschutz`].includes(e)}},setup(P){let F=P,{t:I}=m(),L=y(),R=p(),z=e(!1);function B(){z.value=!1,R.push(`/checkout`)}let V=[{key:`nav.shop`,href:`/shop`},{key:`nav.bundles`,href:`/#bundles`},{key:`nav.revitalization`,href:`/#revitalize`},{key:`nav.about`,href:`/#about`}],H={impressum:[`operator`,`contact`,`register`,`vat`,`authority`,`liability`,`copyright`],datenschutz:[`controller`,`scope`,`legalBasis`,`data`,`cookies`,`analytics`,`payments`,`rights`,`retention`,`contact`]},U=c(()=>H[F.kind].map(e=>({id:e,heading:I(`legal.${F.kind}.section.${e}.heading`),body:I(`legal.${F.kind}.section.${e}.body`)}))),W=c(()=>I(`legal.${F.kind}.updated`));async function G(e){await g(e.id,1),z.value=!0}async function K({productId:e,quantity:t}){await v(e,t)}async function q(e){await _(e)}let J=e(null),Y=null;function X(){let e=J.value,t=e&&(e.$el||e);if(!t||typeof window>`u`)return;let n=Math.round(t.getBoundingClientRect().height);document.documentElement.style.setProperty(`--nav-h`,`${n}px`)}return r(()=>{if(b(),X(),typeof ResizeObserver<`u`&&J.value){let e=J.value.$el||J.value;Y=new ResizeObserver(X),Y.observe(e)}window.addEventListener(`resize`,X)}),f(()=>{Y&&Y.disconnect(),typeof window<`u`&&window.removeEventListener(`resize`,X)}),(e,r)=>(t(),d(l,null,[s(x,{ref_key:`navRef`,ref:J,variant:`cream`,layout:`standard`,items:V,"cart-count":n(L).count,products:n(h),onCart:r[0]||=e=>z.value=!0,onSearch:G},null,8,[`cart-count`,`products`]),u(`main`,w,[u(`div`,T,[u(`header`,E,[u(`p`,D,a(n(I)(`legal.${P.kind}.eyebrow`)),1),u(`h1`,O,a(n(I)(`legal.${P.kind}.title`)),1),W.value?(t(),d(`p`,k,a(W.value),1)):o(``,!0)]),u(`article`,A,[(t(!0),d(l,null,i(U.value,e=>(t(),d(`section`,{id:e.id,key:e.id,class:`flex flex-col gap-3`},[u(`h2`,M,a(e.heading),1),u(`p`,N,a(e.body),1)],8,j))),128))])])]),s(S),r[2]||=u(`div`,{"aria-hidden":`true`,class:`md:hidden`,style:{height:`calc(64px + env(safe-area-inset-bottom))`}},null,-1),s(C,{modelValue:z.value,"onUpdate:modelValue":r[1]||=e=>z.value=e,items:n(L).items,subtotal:n(L).subtotal,count:n(L).count,onUpdateQuantity:K,onRemove:q,onCheckout:B},null,8,[`modelValue`,`items`,`subtotal`,`count`])],64))}};export{P as default};

View File

@@ -1 +1 @@
import{B as e,C as t,G as n,S as r,c as i,ft as a,j as o,l as s,m as c,o as l,p as u,r as d,s as f,u as p,x as m}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{s as h}from"./runtime-dom.esm-bundler-BrsyFPJA.js";import{a as g,o as _,t as v}from"./vue-router-Cyqru1db.js";import{t as ee}from"./i18n-DhVF3Pwg.js";import{r as y}from"./products-BqW5PUnm.js";import{i as b,p as x,r as S}from"./api-DlB23x7f.js";import{t as C}from"./Navbar-1LFtbeJc.js";import{t as w}from"./Button-D1Rp2Xe1.js";import{t as T}from"./Footer-DX-ml2dd.js";import{t as E}from"./Input-os2-AnNh.js";var D={class:`bg-cream text-ink min-h-svh`},O={class:`mx-auto w-full max-w-md px-6 py-14 sm:px-8 sm:py-20 md:py-24`},k={class:`flex flex-col gap-3 mb-8 text-center`},A={class:`eyebrow`},j={class:`font-display font-normal leading-[1.05] tracking-tight text-ink text-headline-md`},M={class:`text-[14px] text-muted`},N={key:1,class:`text-sm text-danger`,role:`alert`,"aria-live":`polite`},P={key:1,class:`rounded-md border border-line bg-paper p-6 md:p-8 flex flex-col gap-3 text-center`},F={class:`font-display text-xl text-brand`},I={class:`text-[14px] text-muted`},L={class:`mt-8 text-center text-[14px] text-muted`},te={__name:`LoginPage`,setup(te){let{t:R}=ee(),z=x(),B=g(),V=_(),H=[{key:`nav.shop`,href:`/shop`},{key:`nav.bundles`,href:`/#bundles`},{key:`nav.revitalization`,href:`/#revitalize`},{key:`nav.about`,href:`/#about`}],U=e(``),W=e(``),G=e(!1),K=e(``),q=e(!1),J=e(!1),Y=l(()=>U.value?q.value?!1:W.value.length<8:!0);async function X(){K.value=``,G.value=!0;try{if(q.value){await S({email:U.value}),J.value=!0;return}await b({email:U.value,password:W.value});let e=String(B.query.next||`/`);V.push(e)}catch(e){K.value=e?.message||R(`checkout.error.generic`)}finally{G.value=!1}}let Z=e(null),Q=null;function $(){let e=Z.value,t=e&&(e.$el||e);if(!t||typeof window>`u`)return;let n=Math.round(t.getBoundingClientRect().height);document.documentElement.style.setProperty(`--nav-h`,`${n}px`)}return r(()=>{if($(),typeof ResizeObserver<`u`&&Z.value){let e=Z.value.$el||Z.value;Q=new ResizeObserver($),Q.observe(e)}window.addEventListener(`resize`,$)}),m(()=>{Q&&Q.disconnect(),typeof window<`u`&&window.removeEventListener(`resize`,$)}),(e,r)=>(t(),p(d,null,[c(C,{ref_key:`navRef`,ref:Z,variant:`cream`,layout:`standard`,items:H,"cart-count":n(z).count,products:n(y)},null,8,[`cart-count`,`products`]),f(`main`,D,[f(`div`,O,[f(`header`,k,[f(`p`,A,a(n(R)(`auth.login.eyebrow`)),1),f(`h1`,j,a(q.value?n(R)(`auth.reset.title`):n(R)(`auth.login.title`)),1),f(`p`,M,a(q.value?n(R)(`auth.reset.sub`):n(R)(`auth.login.sub`)),1)]),J.value?(t(),p(`div`,P,[f(`h2`,F,a(n(R)(`auth.reset.sent.title`)),1),f(`p`,I,a(n(R)(`auth.reset.sent.body`)),1),f(`button`,{type:`button`,class:`text-[13px] text-brand hover:underline self-center mt-2`,onClick:r[3]||=e=>{q.value=!1,J.value=!1}},a(n(R)(`auth.reset.back`)),1)])):(t(),p(`form`,{key:0,class:`flex flex-col gap-5 rounded-md border border-line bg-paper p-6 md:p-8`,novalidate:``,onSubmit:h(X,[`prevent`])},[c(E,{modelValue:U.value,"onUpdate:modelValue":r[0]||=e=>U.value=e,label:n(R)(`checkout.field.email`),type:`email`,required:``,placeholder:n(R)(`checkout.placeholder.email`)},null,8,[`modelValue`,`label`,`placeholder`]),q.value?s(``,!0):(t(),i(E,{key:0,modelValue:W.value,"onUpdate:modelValue":r[1]||=e=>W.value=e,label:n(R)(`checkout.field.password`),type:`password`,required:``},null,8,[`modelValue`,`label`])),K.value?(t(),p(`p`,N,a(K.value),1)):s(``,!0),c(w,{type:`submit`,variant:`primary`,size:`lg`,block:``,loading:G.value,disabled:Y.value},{default:o(()=>[u(a(q.value?n(R)(`auth.reset.cta`):n(R)(`auth.login.cta`)),1)]),_:1},8,[`loading`,`disabled`]),f(`button`,{type:`button`,class:`text-[13px] text-brand hover:underline self-start`,onClick:r[2]||=e=>q.value=!q.value},a(q.value?n(R)(`auth.reset.back`):n(R)(`auth.login.forgot`)),1)],32)),f(`p`,L,[u(a(n(R)(`auth.login.newCustomer`))+` `,1),c(n(v),{to:`/register`,class:`text-brand hover:underline`},{default:o(()=>[u(a(n(R)(`auth.login.cta.register`)),1)]),_:1})])])]),c(T)],64))}};export{te as default};
import{B as e,C as t,G as n,S as r,c as i,ft as a,j as o,l as s,m as c,o as l,p as u,r as d,s as f,u as p,x as m}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{s as h}from"./runtime-dom.esm-bundler-BrsyFPJA.js";import{a as g,o as _,t as v}from"./vue-router-Cyqru1db.js";import{t as ee}from"./i18n-DhVF3Pwg.js";import{r as y}from"./products-BqW5PUnm.js";import{i as b,p as x,r as S}from"./api-DlB23x7f.js";import{t as C}from"./Navbar-BZK-fooS.js";import{t as w}from"./Button-D1Rp2Xe1.js";import{t as T}from"./Footer-DX-ml2dd.js";import{t as E}from"./Input-os2-AnNh.js";var D={class:`bg-cream text-ink min-h-svh`},O={class:`mx-auto w-full max-w-md px-6 py-14 sm:px-8 sm:py-20 md:py-24`},k={class:`flex flex-col gap-3 mb-8 text-center`},A={class:`eyebrow`},j={class:`font-display font-normal leading-[1.05] tracking-tight text-ink text-headline-md`},M={class:`text-[14px] text-muted`},N={key:1,class:`text-sm text-danger`,role:`alert`,"aria-live":`polite`},P={key:1,class:`rounded-md border border-line bg-paper p-6 md:p-8 flex flex-col gap-3 text-center`},F={class:`font-display text-xl text-brand`},I={class:`text-[14px] text-muted`},L={class:`mt-8 text-center text-[14px] text-muted`},te={__name:`LoginPage`,setup(te){let{t:R}=ee(),z=x(),B=g(),V=_(),H=[{key:`nav.shop`,href:`/shop`},{key:`nav.bundles`,href:`/#bundles`},{key:`nav.revitalization`,href:`/#revitalize`},{key:`nav.about`,href:`/#about`}],U=e(``),W=e(``),G=e(!1),K=e(``),q=e(!1),J=e(!1),Y=l(()=>U.value?q.value?!1:W.value.length<8:!0);async function X(){K.value=``,G.value=!0;try{if(q.value){await S({email:U.value}),J.value=!0;return}await b({email:U.value,password:W.value});let e=String(B.query.next||`/`);V.push(e)}catch(e){K.value=e?.message||R(`checkout.error.generic`)}finally{G.value=!1}}let Z=e(null),Q=null;function $(){let e=Z.value,t=e&&(e.$el||e);if(!t||typeof window>`u`)return;let n=Math.round(t.getBoundingClientRect().height);document.documentElement.style.setProperty(`--nav-h`,`${n}px`)}return r(()=>{if($(),typeof ResizeObserver<`u`&&Z.value){let e=Z.value.$el||Z.value;Q=new ResizeObserver($),Q.observe(e)}window.addEventListener(`resize`,$)}),m(()=>{Q&&Q.disconnect(),typeof window<`u`&&window.removeEventListener(`resize`,$)}),(e,r)=>(t(),p(d,null,[c(C,{ref_key:`navRef`,ref:Z,variant:`cream`,layout:`standard`,items:H,"cart-count":n(z).count,products:n(y)},null,8,[`cart-count`,`products`]),f(`main`,D,[f(`div`,O,[f(`header`,k,[f(`p`,A,a(n(R)(`auth.login.eyebrow`)),1),f(`h1`,j,a(q.value?n(R)(`auth.reset.title`):n(R)(`auth.login.title`)),1),f(`p`,M,a(q.value?n(R)(`auth.reset.sub`):n(R)(`auth.login.sub`)),1)]),J.value?(t(),p(`div`,P,[f(`h2`,F,a(n(R)(`auth.reset.sent.title`)),1),f(`p`,I,a(n(R)(`auth.reset.sent.body`)),1),f(`button`,{type:`button`,class:`text-[13px] text-brand hover:underline self-center mt-2`,onClick:r[3]||=e=>{q.value=!1,J.value=!1}},a(n(R)(`auth.reset.back`)),1)])):(t(),p(`form`,{key:0,class:`flex flex-col gap-5 rounded-md border border-line bg-paper p-6 md:p-8`,novalidate:``,onSubmit:h(X,[`prevent`])},[c(E,{modelValue:U.value,"onUpdate:modelValue":r[0]||=e=>U.value=e,label:n(R)(`checkout.field.email`),type:`email`,required:``,placeholder:n(R)(`checkout.placeholder.email`)},null,8,[`modelValue`,`label`,`placeholder`]),q.value?s(``,!0):(t(),i(E,{key:0,modelValue:W.value,"onUpdate:modelValue":r[1]||=e=>W.value=e,label:n(R)(`checkout.field.password`),type:`password`,required:``},null,8,[`modelValue`,`label`])),K.value?(t(),p(`p`,N,a(K.value),1)):s(``,!0),c(w,{type:`submit`,variant:`primary`,size:`lg`,block:``,loading:G.value,disabled:Y.value},{default:o(()=>[u(a(q.value?n(R)(`auth.reset.cta`):n(R)(`auth.login.cta`)),1)]),_:1},8,[`loading`,`disabled`]),f(`button`,{type:`button`,class:`text-[13px] text-brand hover:underline self-start`,onClick:r[2]||=e=>q.value=!q.value},a(q.value?n(R)(`auth.reset.back`):n(R)(`auth.login.forgot`)),1)],32)),f(`p`,L,[u(a(n(R)(`auth.login.newCustomer`))+` `,1),c(n(v),{to:`/register`,class:`text-brand hover:underline`},{default:o(()=>[u(a(n(R)(`auth.login.cta.register`)),1)]),_:1})])])]),c(T)],64))}};export{te as default};

File diff suppressed because one or more lines are too long

1
dist/assets/Navbar-BZK-fooS.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{C as e,T as t,dt as n,m as r,o as i,r as a,s as o,u as s}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{a as c}from"./vue-router-Cyqru1db.js";import{t as l}from"./Navbar-1LFtbeJc.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,dt as n,m as r,o as i,r as a,s as o,u as s}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{a as c}from"./vue-router-Cyqru1db.js";import{t as l}from"./Navbar-BZK-fooS.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};

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{B as e,C as t,G as n,M as r,S as i,ft as a,j as o,l as s,m as c,o as l,p as u,r as ee,s as d,u as f,x as p}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{r as m,s as h}from"./runtime-dom.esm-bundler-BrsyFPJA.js";import{a as g,o as _,t as v}from"./vue-router-Cyqru1db.js";import{t as y}from"./i18n-DhVF3Pwg.js";import{r as te}from"./products-BqW5PUnm.js";import{n as ne,p as b}from"./api-DlB23x7f.js";import{t as x}from"./Navbar-1LFtbeJc.js";import{t as S}from"./Button-D1Rp2Xe1.js";import{t as C}from"./Footer-DX-ml2dd.js";import{t as w}from"./Input-os2-AnNh.js";var T={class:`bg-cream text-ink min-h-svh`},E={class:`mx-auto w-full max-w-md px-6 py-14 sm:px-8 sm:py-20 md:py-24`},D={class:`flex flex-col gap-3 mb-8 text-center`},O={class:`eyebrow`},k={class:`font-display font-normal leading-[1.05] tracking-tight text-ink text-headline-md`},A={class:`text-[14px] text-muted`},j={class:`grid gap-5 md:grid-cols-2`},M={class:`inline-flex items-center gap-3 cursor-pointer select-none`},N={class:`text-sm text-ink`},P={key:0,class:`text-sm text-danger`,role:`alert`,"aria-live":`polite`},F={class:`mt-8 text-center text-[14px] text-muted`},I={__name:`RegisterPage`,setup(I){let{t:L}=y(),R=b(),re=g(),z=_(),B=[{key:`nav.shop`,href:`/shop`},{key:`nav.bundles`,href:`/#bundles`},{key:`nav.revitalization`,href:`/#revitalize`},{key:`nav.about`,href:`/#about`}],V=e(``),H=e(``),U=e(``),W=e(``),G=e(``),K=e(!1),q=e(!1),J=e(``),Y=l(()=>W.value===G.value),X=l(()=>!U.value||W.value.length<8||!Y.value);async function ie(){J.value=``,q.value=!0;try{await ne({email:U.value,password:W.value,firstName:V.value,lastName:H.value,acceptsMarketing:K.value});let e=String(re.query.next||`/`);z.push(e)}catch(e){J.value=e?.message||L(`checkout.error.generic`)}finally{q.value=!1}}let Z=e(null),Q=null;function $(){let e=Z.value,t=e&&(e.$el||e);if(!t||typeof window>`u`)return;let n=Math.round(t.getBoundingClientRect().height);document.documentElement.style.setProperty(`--nav-h`,`${n}px`)}return i(()=>{if($(),typeof ResizeObserver<`u`&&Z.value){let e=Z.value.$el||Z.value;Q=new ResizeObserver($),Q.observe(e)}window.addEventListener(`resize`,$)}),p(()=>{Q&&Q.disconnect(),typeof window<`u`&&window.removeEventListener(`resize`,$)}),(e,i)=>(t(),f(ee,null,[c(x,{ref_key:`navRef`,ref:Z,variant:`cream`,layout:`standard`,items:B,"cart-count":n(R).count,products:n(te)},null,8,[`cart-count`,`products`]),d(`main`,T,[d(`div`,E,[d(`header`,D,[d(`p`,O,a(n(L)(`auth.register.eyebrow`)),1),d(`h1`,k,a(n(L)(`auth.register.title`)),1),d(`p`,A,a(n(L)(`auth.register.sub`)),1)]),d(`form`,{class:`flex flex-col gap-5 rounded-md border border-line bg-paper p-6 md:p-8`,novalidate:``,onSubmit:h(ie,[`prevent`])},[d(`div`,j,[c(w,{modelValue:V.value,"onUpdate:modelValue":i[0]||=e=>V.value=e,label:n(L)(`checkout.field.firstName`)},null,8,[`modelValue`,`label`]),c(w,{modelValue:H.value,"onUpdate:modelValue":i[1]||=e=>H.value=e,label:n(L)(`checkout.field.lastName`)},null,8,[`modelValue`,`label`])]),c(w,{modelValue:U.value,"onUpdate:modelValue":i[2]||=e=>U.value=e,label:n(L)(`checkout.field.email`),type:`email`,required:``,placeholder:n(L)(`checkout.placeholder.email`)},null,8,[`modelValue`,`label`,`placeholder`]),c(w,{modelValue:W.value,"onUpdate:modelValue":i[3]||=e=>W.value=e,label:n(L)(`checkout.field.password`),type:`password`,required:``,hint:n(L)(`checkout.hint.password`)},null,8,[`modelValue`,`label`,`hint`]),c(w,{modelValue:G.value,"onUpdate:modelValue":i[4]||=e=>G.value=e,label:n(L)(`checkout.field.passwordConfirm`),type:`password`,required:``,error:G.value&&!Y.value?n(L)(`checkout.error.passwordMismatch`):``},null,8,[`modelValue`,`label`,`error`]),d(`label`,M,[r(d(`input`,{"onUpdate:modelValue":i[5]||=e=>K.value=e,type:`checkbox`,class:`w-5 h-5 rounded-xs border border-line accent-brand`},null,512),[[m,K.value]]),d(`span`,N,a(n(L)(`checkout.field.marketing`)),1)]),J.value?(t(),f(`p`,P,a(J.value),1)):s(``,!0),c(S,{type:`submit`,variant:`primary`,size:`lg`,block:``,loading:q.value,disabled:X.value},{default:o(()=>[u(a(n(L)(`auth.register.cta`)),1)]),_:1},8,[`loading`,`disabled`])],32),d(`p`,F,[u(a(n(L)(`auth.register.haveAccount`))+` `,1),c(n(v),{to:`/login`,class:`text-brand hover:underline`},{default:o(()=>[u(a(n(L)(`auth.register.cta.signIn`)),1)]),_:1})])])]),c(C)],64))}};export{I as default};
import{B as e,C as t,G as n,M as r,S as i,ft as a,j as o,l as s,m as c,o as l,p as u,r as ee,s as d,u as f,x as p}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{r as m,s as h}from"./runtime-dom.esm-bundler-BrsyFPJA.js";import{a as g,o as _,t as v}from"./vue-router-Cyqru1db.js";import{t as y}from"./i18n-DhVF3Pwg.js";import{r as te}from"./products-BqW5PUnm.js";import{n as ne,p as b}from"./api-DlB23x7f.js";import{t as x}from"./Navbar-BZK-fooS.js";import{t as S}from"./Button-D1Rp2Xe1.js";import{t as C}from"./Footer-DX-ml2dd.js";import{t as w}from"./Input-os2-AnNh.js";var T={class:`bg-cream text-ink min-h-svh`},E={class:`mx-auto w-full max-w-md px-6 py-14 sm:px-8 sm:py-20 md:py-24`},D={class:`flex flex-col gap-3 mb-8 text-center`},O={class:`eyebrow`},k={class:`font-display font-normal leading-[1.05] tracking-tight text-ink text-headline-md`},A={class:`text-[14px] text-muted`},j={class:`grid gap-5 md:grid-cols-2`},M={class:`inline-flex items-center gap-3 cursor-pointer select-none`},N={class:`text-sm text-ink`},P={key:0,class:`text-sm text-danger`,role:`alert`,"aria-live":`polite`},F={class:`mt-8 text-center text-[14px] text-muted`},I={__name:`RegisterPage`,setup(I){let{t:L}=y(),R=b(),re=g(),z=_(),B=[{key:`nav.shop`,href:`/shop`},{key:`nav.bundles`,href:`/#bundles`},{key:`nav.revitalization`,href:`/#revitalize`},{key:`nav.about`,href:`/#about`}],V=e(``),H=e(``),U=e(``),W=e(``),G=e(``),K=e(!1),q=e(!1),J=e(``),Y=l(()=>W.value===G.value),X=l(()=>!U.value||W.value.length<8||!Y.value);async function ie(){J.value=``,q.value=!0;try{await ne({email:U.value,password:W.value,firstName:V.value,lastName:H.value,acceptsMarketing:K.value});let e=String(re.query.next||`/`);z.push(e)}catch(e){J.value=e?.message||L(`checkout.error.generic`)}finally{q.value=!1}}let Z=e(null),Q=null;function $(){let e=Z.value,t=e&&(e.$el||e);if(!t||typeof window>`u`)return;let n=Math.round(t.getBoundingClientRect().height);document.documentElement.style.setProperty(`--nav-h`,`${n}px`)}return i(()=>{if($(),typeof ResizeObserver<`u`&&Z.value){let e=Z.value.$el||Z.value;Q=new ResizeObserver($),Q.observe(e)}window.addEventListener(`resize`,$)}),p(()=>{Q&&Q.disconnect(),typeof window<`u`&&window.removeEventListener(`resize`,$)}),(e,i)=>(t(),f(ee,null,[c(x,{ref_key:`navRef`,ref:Z,variant:`cream`,layout:`standard`,items:B,"cart-count":n(R).count,products:n(te)},null,8,[`cart-count`,`products`]),d(`main`,T,[d(`div`,E,[d(`header`,D,[d(`p`,O,a(n(L)(`auth.register.eyebrow`)),1),d(`h1`,k,a(n(L)(`auth.register.title`)),1),d(`p`,A,a(n(L)(`auth.register.sub`)),1)]),d(`form`,{class:`flex flex-col gap-5 rounded-md border border-line bg-paper p-6 md:p-8`,novalidate:``,onSubmit:h(ie,[`prevent`])},[d(`div`,j,[c(w,{modelValue:V.value,"onUpdate:modelValue":i[0]||=e=>V.value=e,label:n(L)(`checkout.field.firstName`)},null,8,[`modelValue`,`label`]),c(w,{modelValue:H.value,"onUpdate:modelValue":i[1]||=e=>H.value=e,label:n(L)(`checkout.field.lastName`)},null,8,[`modelValue`,`label`])]),c(w,{modelValue:U.value,"onUpdate:modelValue":i[2]||=e=>U.value=e,label:n(L)(`checkout.field.email`),type:`email`,required:``,placeholder:n(L)(`checkout.placeholder.email`)},null,8,[`modelValue`,`label`,`placeholder`]),c(w,{modelValue:W.value,"onUpdate:modelValue":i[3]||=e=>W.value=e,label:n(L)(`checkout.field.password`),type:`password`,required:``,hint:n(L)(`checkout.hint.password`)},null,8,[`modelValue`,`label`,`hint`]),c(w,{modelValue:G.value,"onUpdate:modelValue":i[4]||=e=>G.value=e,label:n(L)(`checkout.field.passwordConfirm`),type:`password`,required:``,error:G.value&&!Y.value?n(L)(`checkout.error.passwordMismatch`):``},null,8,[`modelValue`,`label`,`error`]),d(`label`,M,[r(d(`input`,{"onUpdate:modelValue":i[5]||=e=>K.value=e,type:`checkbox`,class:`w-5 h-5 rounded-xs border border-line accent-brand`},null,512),[[m,K.value]]),d(`span`,N,a(n(L)(`checkout.field.marketing`)),1)]),J.value?(t(),f(`p`,P,a(J.value),1)):s(``,!0),c(S,{type:`submit`,variant:`primary`,size:`lg`,block:``,loading:q.value,disabled:X.value},{default:o(()=>[u(a(n(L)(`auth.register.cta`)),1)]),_:1},8,[`loading`,`disabled`])],32),d(`p`,F,[u(a(n(L)(`auth.register.haveAccount`))+` `,1),c(n(v),{to:`/login`,class:`text-brand hover:underline`},{default:o(()=>[u(a(n(L)(`auth.register.cta.signIn`)),1)]),_:1})])])]),c(C)],64))}};export{I as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/index.html vendored
View File

@@ -12,7 +12,7 @@
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-CC1r8WJK.js"></script>
<script type="module" crossorigin src="/assets/index-BR1OPvkc.js"></script>
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-BOai-rQB.js">
<link rel="modulepreload" crossorigin href="/assets/preload-helper-DzyYoeor.js">
<link rel="modulepreload" crossorigin href="/assets/runtime-core.esm-bundler-DTXUv7Wx.js">

View File

@@ -148,6 +148,39 @@ function isActive(href) {
return href === hereHash
}
// RouterLink doesn't fire a navigation when the destination resolves
// to the current URL, so Vue Router's scrollBehavior never runs for
// "logo while on /" or "/#bundles while on /#bundles". We handle the
// scroll manually here so those clicks always animate.
function onNavClick(item, event) {
if (!item || !item.href) return
const [path, hash] = item.href.split('#')
const targetPath = path || '/'
const onSameRoute = targetPath === route.path
if (!onSameRoute) return
if (hash) {
const el = document.getElementById(hash)
if (el) {
event?.preventDefault?.()
el.scrollIntoView({ behavior: 'smooth', block: 'start' })
try {
history.replaceState(history.state, '', `#${hash}`)
} catch {}
}
return
}
// Same path, no hash (logo click on home) → smooth-scroll to top.
event?.preventDefault?.()
window.scrollTo({ top: 0, behavior: 'smooth' })
}
function onLogoClick(event) {
if (route.path === '/') {
event?.preventDefault?.()
window.scrollTo({ top: 0, behavior: 'smooth' })
}
}
watch(menuOpen, (open) => {
if (typeof document === 'undefined') return
document.documentElement.style.overflow = open ? 'hidden' : ''
@@ -167,6 +200,7 @@ onBeforeUnmount(() => {
to="/"
:class="['block shrink-0 py-1', tone.logo]"
aria-label="Kaiser Natron home"
@click="onLogoClick"
>
<Logo :class="logoClasses" />
</RouterLink>
@@ -179,7 +213,7 @@ onBeforeUnmount(() => {
isActive(item.href) ? 'text-accent' : tone.link,
'text-[14px] font-medium tracking-label transition-colors duration-base',
]"
@click="$emit('nav', item)"
@click="onNavClick(item, $event); $emit('nav', item)"
>{{ itemLabel(item) }}</RouterLink>
</nav>
</div>
@@ -202,7 +236,7 @@ onBeforeUnmount(() => {
isActive(item.href) ? 'text-accent' : tone.link,
'text-[14px] font-medium tracking-label transition-colors duration-base',
]"
@click="$emit('nav', item)"
@click="onNavClick(item, $event); $emit('nav', item)"
>{{ itemLabel(item) }}</RouterLink>
</nav>
<button
@@ -310,7 +344,7 @@ onBeforeUnmount(() => {
? 'text-accent'
: 'text-cream hover:text-accent',
]"
@click="menuOpen = false; $emit('nav', item)"
@click="onNavClick(item, $event); menuOpen = false; $emit('nav', item)"
>{{ itemLabel(item) }}</RouterLink>
</nav>