build: skip container npm, ship prebuilt dist for portainer showcase

The Portainer host keeps failing on `npm ci` inside the build stage
(both Alpine+libc6-compat and Debian slim exited 1 without ever surfacing
the real error to us). For a dev showcase this isn't worth chasing —
the dev machine is the source of truth for the built output anyway.

- Dockerfile: drop the Node build stage. Image is just nginx:1.27.3-alpine
  with /dist copied in. No npm inside the container.
- docker-compose.yml: drop the production hardening (read_only, tmpfs,
  security_opt, resource caps) and the container_name. Dev-only, don't
  inhibit things.
- .gitignore / .dockerignore: stop ignoring dist/ — it's committed now.
- README: document the `npm run build && commit && push` release flow
  and note what to reinstate when this graduates to real production.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-04-21 11:52:01 +01:00
parent 9b4eaafd99
commit 80f1c8db08
63 changed files with 127 additions and 58 deletions

View File

@@ -6,7 +6,7 @@
# Local development artefacts
node_modules
dist
# dist/ is intentionally shipped — the container serves it directly.
dist-ssr
.vite
coverage

View File

@@ -1,35 +1,21 @@
# syntax=docker/dockerfile:1.7
# Multi-stage build: Node builds the Vite SPA, Nginx serves the static output.
# Pinned tags only — no :latest, no floating minors.
# Dev-showcase image for the Portainer stack. No container-side build —
# the `dist/` directory is built locally (`npm run build`) and committed,
# then copied straight into nginx. This sidesteps the Node/native-binding
# fights that kept breaking `npm ci` on the Portainer host.
#
# Not how the site should ship to real production, but fine for a showcase
# stack where the dev machine is the source of truth for the built output.
# ── 1. Build ───────────────────────────────────────────────────────────────
# Debian slim (glibc) for the build stage. Alpine/musl works in theory with
# libc6-compat, but Tailwind v4 oxide + lightningcss + rolldown prebuilt
# .node bindings keep finding new ways to fail there. Debian slim is the
# known-good path and the build stage is thrown away after COPY --from.
FROM node:24.15.0-bookworm-slim AS build
WORKDIR /app
FROM nginx:1.27.3-alpine
# Copy lockfile first so `npm ci` layer caches when only source changes.
COPY package.json package-lock.json ./
RUN npm ci --no-audit --no-fund
COPY . .
RUN npm run build
# ── 2. Serve ───────────────────────────────────────────────────────────────
FROM nginx:1.27.3-alpine AS serve
# Strip the default site; our config owns /etc/nginx/conf.d/default.conf.
# Our site config owns the default server block.
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Drop the built SPA into the document root.
COPY --from=build /app/dist /usr/share/nginx/html
# Prebuilt Vite output.
COPY dist /usr/share/nginx/html
EXPOSE 80
# Alpine ships busybox wget — avoids pulling curl just for healthchecks.
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD wget -q -O- http://127.0.0.1/health || exit 1

View File

@@ -27,13 +27,18 @@ Browse the full system at `/design` when running `npm run dev`. This is the sing
All dep versions are pinned exactly (no `^`/`~`). Use `npm ci` (not `npm install`) in CI and before builds. Run `npm audit` before adding any new dep.
## Deployment (Portainer stack)
## Deployment (Portainer dev-showcase stack)
Portainer builds the image from the `Dockerfile` at the repo root each time the stack is pulled & redeployed — no registry needed.
This is the showcase path, not real production — the dev machine is the source of truth for the built output. The container has **no** build step: it just copies a prebuilt `dist/` into nginx.
1. Portainer → **Stacks****Add stack**
2. Either paste `docker-compose.yml` in the web editor or point Portainer at this repo (build path `/`)
3. Deploy. The site comes up on host port **5555** (internal container port 80).
4. Health: `GET /health` returns `200 ok`.
Release flow:
Pinned images: `node:24.15.0-bookworm-slim` (build stage, glibc — Alpine/musl fights with Tailwind v4's native bindings), `nginx:1.27.3-alpine` (serve stage). Bump explicitly when you want to upgrade — no floating tags.
```
npm run build # produces /dist
git add dist && git commit -m "build: <what changed>"
git push
```
Then in Portainer → **Stacks****Pull and redeploy**. The site comes up on host port **5555** (`/health` returns `200 ok`).
Base image: `nginx:1.27.3-alpine` (pinned). When this graduates to real production, reintroduce the multi-stage Node build + the hardening (`read_only`, `security_opt`, resource caps) that lived in earlier revisions of this file.

1
dist/assets/Badge-BPajj5yh.js vendored Normal file
View File

@@ -0,0 +1 @@
import{$ as e,o as t,u as n,w as r,x as i}from"./runtime-core.esm-bundler-CjdnoyKJ.js";var a={__name:`Badge`,props:{variant:{type:String,default:`neutral`,validator:e=>[`neutral`,`brand`,`accent`,`subtle`,`success`,`warning`,`danger`].includes(e)},uppercase:{type:Boolean,default:!0}},setup(a){let o=a,s={neutral:`bg-cream text-muted border border-line`,brand:`bg-brand text-accent`,accent:`bg-accent text-accent-ink`,subtle:`bg-brand-soft-wash text-brand-soft`,success:`bg-success-wash text-success`,warning:`bg-warning-wash text-warning`,danger:`bg-danger-wash text-danger`},c=t(()=>[`inline-flex items-center gap-1 px-[11px] py-[5px] rounded-pill text-[11px] font-bold tracking-eyebrow`,o.uppercase?`uppercase`:``,s[o.variant]]);return(t,a)=>(i(),n(`span`,{class:e(c.value)},[r(t.$slots,`default`)],2))}};export{a as t};

1
dist/assets/BadgesSection-BaVzz_Mt.js vendored Normal file
View File

@@ -0,0 +1 @@
import{L as e,c as t,k as n,m as r,p as i,s as a,tt as o,x as s}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as c}from"./i18n-Dy4LSDvO.js";import{t as l}from"./SectionShell-CRUwhFt3.js";import{t as u}from"./Badge-BPajj5yh.js";import{t as d}from"./Card-BKj8EzNc.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)=>(s(),t(l,{eyebrow:e(_)(`ds.eyebrow.components`),title:e(_)(`ds.badges.title`),description:e(_)(`ds.badges.description`)},{default:n(()=>[a(`section`,null,[a(`h2`,f,o(e(_)(`ds.heading.variants`)),1),r(d,{tone:`paper`},{default:n(()=>[a(`div`,p,[r(u,{variant:`neutral`},{default:n(()=>[i(o(e(_)(`ds.badges.neutral`)),1)]),_:1}),r(u,{variant:`brand`},{default:n(()=>[i(o(e(_)(`ds.badges.brand`)),1)]),_:1}),r(u,{variant:`accent`},{default:n(()=>[i(o(e(_)(`ds.badges.accent`)),1)]),_:1}),r(u,{variant:`subtle`},{default:n(()=>[i(o(e(_)(`ds.badges.subtle`)),1)]),_:1}),r(u,{variant:`success`},{default:n(()=>[i(o(e(_)(`ds.badges.success`)),1)]),_:1}),r(u,{variant:`warning`},{default:n(()=>[i(o(e(_)(`ds.badges.warning`)),1)]),_:1}),r(u,{variant:`danger`},{default:n(()=>[i(o(e(_)(`ds.badges.danger`)),1)]),_:1})])]),_:1})]),a(`section`,null,[a(`h2`,m,o(e(_)(`ds.heading.nonUppercase`)),1),r(d,{tone:`paper`},{default:n(()=>[a(`div`,h,[r(u,{variant:`brand`,uppercase:!1},{default:n(()=>[i(o(e(_)(`ds.badges.newRelease`)),1)]),_:1}),r(u,{variant:`accent`,uppercase:!1},{default:n(()=>[i(o(e(_)(`ds.badges.featured`)),1)]),_:1}),r(u,{variant:`subtle`,uppercase:!1},{default:n(()=>[...g[0]||=[i(`v2.1.0`,-1)]]),_:1})])]),_:1})])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{g as default};

1
dist/assets/Button-Wjj-Z6Tb.js vendored Normal file
View File

@@ -0,0 +1 @@
import{$ as e,l as t,o as n,u as r,w as i,x as a}from"./runtime-core.esm-bundler-CjdnoyKJ.js";var o=[`type`,`disabled`],s={key:0,class:`inline-block h-3 w-3 rounded-full border-2 border-current border-t-transparent animate-spin`},c=`inline-flex items-center justify-center gap-2 font-sans font-semibold rounded-pill border transition-all duration-base ease-out disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none disabled:shadow-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand`,l={__name:`Button`,props:{variant:{type:String,default:`primary`,validator:e=>[`primary`,`accent`,`secondary`,`ghost`,`danger`].includes(e)},size:{type:String,default:`md`,validator:e=>[`sm`,`md`,`lg`].includes(e)},type:{type:String,default:`button`},disabled:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},block:{type:Boolean,default:!1}},emits:[`click`],setup(l){let u=l,d={primary:`bg-brand text-accent border-brand hover:bg-brand-hover hover:-translate-y-0.5 hover:shadow-md`,accent:`bg-accent text-brand border-accent hover:bg-accent-soft hover:-translate-y-0.5 hover:shadow-md`,secondary:`bg-transparent text-brand border-brand hover:bg-brand hover:text-accent`,ghost:`bg-transparent text-brand border-transparent hover:bg-brand-wash`,danger:`bg-danger text-white border-danger hover:opacity-90 hover:-translate-y-0.5 hover:shadow-md`},f={sm:`text-[13px] px-[18px] py-[9px] tracking-label`,md:`text-[15px] px-[26px] py-[13px] tracking-label`,lg:`text-[16px] px-[34px] py-[17px] tracking-label`},p=n(()=>[c,d[u.variant],f[u.size],u.block?`w-full`:``]);return(n,c)=>(a(),r(`button`,{type:l.type,disabled:l.disabled||l.loading,class:e(p.value),onClick:c[0]||=e=>n.$emit(`click`,e)},[l.loading?(a(),r(`span`,s)):t(``,!0),i(n.$slots,`before`),i(n.$slots,`default`),i(n.$slots,`after`)],10,o))}};export{l as t};

View File

@@ -0,0 +1,4 @@
import{L as e,c as t,k as n,m as r,p as i,s as a,tt as o,x as s}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as c}from"./Icon-DUE2bXq6.js";import{t as l}from"./i18n-Dy4LSDvO.js";import{t as u}from"./Button-Wjj-Z6Tb.js";import{t as d}from"./SectionShell-CRUwhFt3.js";import{t as f}from"./Card-BKj8EzNc.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)=>(s(),t(d,{eyebrow:e(F)(`ds.eyebrow.components`),title:e(F)(`ds.buttons.title`),description:e(F)(`ds.buttons.description`)},{default:n(()=>[a(`section`,null,[a(`h2`,p,o(e(F)(`ds.heading.variants`)),1),r(f,{tone:`paper`},{default:n(()=>[a(`div`,m,[r(u,{variant:`primary`},{default:n(()=>[i(o(e(F)(`ds.buttons.primary`)),1)]),_:1}),r(u,{variant:`accent`},{default:n(()=>[i(o(e(F)(`ds.buttons.accent`)),1)]),_:1}),r(u,{variant:`secondary`},{default:n(()=>[i(o(e(F)(`ds.buttons.secondary`)),1)]),_:1}),r(u,{variant:`ghost`},{default:n(()=>[i(o(e(F)(`ds.buttons.ghost`)),1)]),_:1}),r(u,{variant:`danger`},{default:n(()=>[i(o(e(F)(`ds.buttons.danger`)),1)]),_:1})])]),_:1})]),a(`section`,null,[a(`h2`,h,o(e(F)(`ds.heading.onDifferentSurfaces`)),1),a(`div`,g,[r(f,{tone:`paper`},{default:n(()=>[a(`p`,_,o(e(F)(`ds.cards.paper`)),1),a(`div`,v,[r(u,{variant:`primary`},{before:n(()=>[r(c,{name:`cart`,size:18})]),default:n(()=>[i(` `+o(e(F)(`ds.buttons.addToCart`)),1)]),_:1}),r(u,{variant:`ghost`},{default:n(()=>[i(o(e(F)(`ds.buttons.learnMore`)),1)]),_:1})])]),_:1}),r(f,{tone:`cream`},{default:n(()=>[a(`p`,y,o(e(F)(`ds.cards.cream`)),1),a(`div`,b,[r(u,{variant:`primary`},{before:n(()=>[r(c,{name:`cart`,size:18})]),default:n(()=>[i(` `+o(e(F)(`ds.buttons.addToCart`)),1)]),_:1}),r(u,{variant:`ghost`},{default:n(()=>[i(o(e(F)(`ds.buttons.learnMore`)),1)]),_:1})])]),_:1}),r(f,{tone:`brand`},{default:n(()=>[a(`p`,x,o(e(F)(`ds.cards.brand`)),1),a(`div`,S,[r(u,{variant:`accent`},{before:n(()=>[r(c,{name:`cart`,size:18})]),default:n(()=>[i(` `+o(e(F)(`ds.buttons.addToCart`)),1)]),_:1}),r(u,{variant:`ghost`,class:`!text-cream hover:!bg-cream-wash`},{default:n(()=>[i(o(e(F)(`ds.buttons.learnMore`)),1)]),_:1})])]),_:1})])]),a(`section`,null,[a(`h2`,C,o(e(F)(`ds.heading.sizes`)),1),r(f,{tone:`paper`},{default:n(()=>[a(`div`,w,[r(u,{size:`sm`},{default:n(()=>[i(o(e(F)(`ds.buttons.small`)),1)]),_:1}),r(u,{size:`md`},{default:n(()=>[i(o(e(F)(`ds.buttons.medium`)),1)]),_:1}),r(u,{size:`lg`},{default:n(()=>[i(o(e(F)(`ds.buttons.large`)),1)]),_:1})])]),_:1})]),a(`section`,null,[a(`h2`,T,o(e(F)(`ds.heading.withIcons`)),1),r(f,{tone:`paper`},{default:n(()=>[a(`div`,E,[r(u,{variant:`primary`},{before:n(()=>[r(c,{name:`cart`,size:18})]),default:n(()=>[i(` `+o(e(F)(`ds.buttons.addToCart`)),1)]),_:1}),r(u,{variant:`secondary`},{after:n(()=>[r(c,{name:`arrow-right`,size:18})]),default:n(()=>[i(o(e(F)(`ds.buttons.learnMore`))+` `,1)]),_:1}),r(u,{variant:`ghost`},{before:n(()=>[r(c,{name:`heart`,size:18})]),default:n(()=>[i(` `+o(e(F)(`ds.buttons.save`)),1)]),_:1}),r(u,{variant:`accent`,size:`sm`},{before:n(()=>[r(c,{name:`check`,size:16})]),default:n(()=>[i(` `+o(e(F)(`ds.buttons.confirm`)),1)]),_:1})])]),_:1})]),a(`section`,null,[a(`h2`,D,o(e(F)(`ds.heading.states`)),1),r(f,{tone:`paper`},{default:n(()=>[a(`div`,O,[r(u,null,{default:n(()=>[i(o(e(F)(`ds.heading.default`)),1)]),_:1}),r(u,{disabled:``},{default:n(()=>[i(o(e(F)(`ds.buttons.disabled`)),1)]),_:1}),r(u,{loading:``},{default:n(()=>[i(o(e(F)(`ds.buttons.loading`)),1)]),_:1})])]),_:1})]),a(`section`,null,[a(`h2`,k,o(e(F)(`ds.heading.block`)),1),r(f,{tone:`paper`},{default:n(()=>[a(`div`,A,[r(u,{block:``,variant:`primary`},{before:n(()=>[r(c,{name:`cart`,size:18})]),default:n(()=>[i(` `+o(e(F)(`ds.buttons.addToCart`)),1)]),_:1}),r(u,{block:``,variant:`secondary`},{default:n(()=>[i(o(e(F)(`ds.buttons.continueShopping`)),1)]),_:1})])]),_:1})]),a(`section`,null,[a(`h2`,j,o(e(F)(`ds.heading.usage`)),1),a(`div`,M,[a(`pre`,N,`<Button variant="primary" size="md">
<template #before><Icon name="cart" :size="18" /></template>
`+o(e(F)(`ds.buttons.addToCart`))+`
</Button>`,1)])])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{P as default};

1
dist/assets/Card-BKj8EzNc.js vendored Normal file
View File

@@ -0,0 +1 @@
import{$ as e,u as t,w as n,x as r}from"./runtime-core.esm-bundler-CjdnoyKJ.js";var i={__name:`Card`,props:{padded:{type:Boolean,default:!0},interactive:{type:Boolean,default:!1},tone:{type:String,default:`paper`,validator:e=>[`paper`,`cream`,`brand`].includes(e)}},setup(i){let a={paper:`bg-paper text-ink border-line`,cream:`bg-cream text-ink border-line`,brand:`bg-brand text-accent border-transparent`};return(o,s)=>(r(),t(`div`,{class:e([`rounded-md border`,[a[i.tone],i.padded?`p-7`:``,i.interactive?`transition-all duration-base ease-out hover:-translate-y-1 hover:shadow-md hover:border-brand-soft cursor-pointer`:``]])},[n(o.$slots,`default`)],2))}};export{i as t};

1
dist/assets/CardsSection-BKD5xxAT.js vendored Normal file
View File

@@ -0,0 +1 @@
import{L as e,c as t,k as n,m as r,p as i,s as a,tt as o,x as s}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as c}from"./i18n-Dy4LSDvO.js";import{t as l}from"./SectionShell-CRUwhFt3.js";import{t as u}from"./Badge-BPajj5yh.js";import{t as d}from"./Card-BKj8EzNc.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)=>(s(),t(l,{eyebrow:e(j)(`ds.eyebrow.components`),title:e(j)(`ds.cards.title`),description:e(j)(`ds.cards.description`)},{default:n(()=>[a(`section`,null,[a(`h2`,f,o(e(j)(`ds.heading.tones`)),1),a(`div`,p,[r(d,{tone:`paper`},{default:n(()=>[r(u,{variant:`subtle`,class:`mb-4`},{default:n(()=>[i(o(e(j)(`ds.cards.paper`)),1)]),_:1}),a(`h3`,m,o(e(j)(`ds.cards.paperTitle`)),1),a(`p`,h,o(e(j)(`ds.cards.paperBody`)),1)]),_:1}),r(d,{tone:`cream`},{default:n(()=>[r(u,{variant:`subtle`,class:`mb-4`},{default:n(()=>[i(o(e(j)(`ds.cards.cream`)),1)]),_:1}),a(`h3`,g,o(e(j)(`ds.cards.creamTitle`)),1),a(`p`,_,o(e(j)(`ds.cards.creamBody`)),1)]),_:1}),r(d,{tone:`brand`},{default:n(()=>[r(u,{variant:`accent`,class:`mb-4`},{default:n(()=>[i(o(e(j)(`ds.cards.brand`)),1)]),_:1}),a(`h3`,v,o(e(j)(`ds.cards.brandTitle`)),1),a(`p`,y,o(e(j)(`ds.cards.brandBody`)),1)]),_:1})])]),a(`section`,null,[a(`h2`,b,o(e(j)(`ds.heading.interactive`)),1),a(`div`,x,[r(d,{tone:`paper`,interactive:``},{default:n(()=>[a(`h3`,S,o(e(j)(`ds.cards.hoverMe`)),1),a(`p`,C,o(e(j)(`ds.cards.hoverBody`)),1)]),_:1}),r(d,{tone:`cream`,interactive:``},{default:n(()=>[a(`h3`,w,o(e(j)(`ds.cards.hoverMeToo`)),1),a(`p`,T,o(e(j)(`ds.cards.hoverBodyAlt`)),1)]),_:1})])]),a(`section`,null,[a(`h2`,E,o(e(j)(`ds.heading.withoutPadding`)),1),r(d,{tone:`paper`,padded:!1},{default:n(()=>[A[2]||=a(`div`,{class:`h-40 bg-cream rounded-t-md`},null,-1),a(`div`,D,[a(`h3`,O,o(e(j)(`ds.cards.mediaTitle`)),1),a(`p`,k,[i(o(e(j)(`ds.cards.mediaBody`))+` `,1),A[0]||=a(`code`,{class:`font-mono text-[12px]`},`:padded="false"`,-1),A[1]||=i(`. `,-1)])])]),_:1})])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{A as default};

1
dist/assets/ColorsSection-B9zfVnIF.js vendored Normal file
View File

@@ -0,0 +1 @@
import{C as e,L as t,c as n,et as r,k as i,o as a,r as o,s,tt as c,u as l,x as u}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as d}from"./i18n-Dy4LSDvO.js";import{t as f}from"./SectionShell-CRUwhFt3.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=a(()=>[{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(a,d)=>(u(),n(f,{eyebrow:t(v)(`ds.eyebrow.tokens`),title:t(v)(`ds.colors.title`),description:t(v)(`ds.colors.description`)},{default:i(()=>[(u(!0),l(o,null,e(y.value,t=>(u(),l(`section`,{key:t.title},[s(`h2`,p,c(t.title),1),s(`div`,m,[(u(!0),l(o,null,e(t.names,e=>(u(),l(`div`,{key:e,class:`rounded-md border border-line overflow-hidden bg-paper`},[s(`div`,{class:`h-28 border-b border-line`,style:r({background:`var(--color-${e})`})},null,4),s(`div`,h,[s(`code`,g,`--color-`+c(e),1)])]))),128))])]))),128))]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{_ as default};

1
dist/assets/DesignLayout-CLtySxRW.js vendored Normal file
View File

@@ -0,0 +1 @@
import{C as e,L as t,c as n,k as r,m as i,o as a,p as o,r as s,s as c,tt as l,u,x as d}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{n as f,t as p}from"./vue-router-BrNWkU63.js";import{t as m}from"./Logo-XIYt07ns.js";import{t as h}from"./i18n-Dy4LSDvO.js";import{t as g}from"./LanguageSwitcher-SSHEwswt.js";var _={class:`h-screen flex bg-surface text-ink overflow-hidden`},v={class:`w-[260px] shrink-0 border-r border-line bg-paper flex flex-col`},y={class:`px-6 py-6 border-b border-line`},b={class:`eyebrow mt-3`},x={class:`flex-1 overflow-y-auto px-3 py-5 space-y-6`},S={class:`eyebrow px-3 mb-2`},C={class:`flex flex-col gap-0.5`},w={class:`px-6 py-4 border-t border-line`},T={class:`flex-1 overflow-y-auto`},E={__name:`DesignLayout`,setup(E){let{t:D}=h(),O=a(()=>[{title:D(`ds.sidebar.brand`),items:[{name:`ds-logo`,label:D(`ds.nav.logo`)}]},{title:D(`ds.sidebar.tokens`),items:[{name:`ds-colors`,label:D(`ds.nav.colors`)},{name:`ds-typography`,label:D(`ds.nav.typography`)},{name:`ds-radii`,label:D(`ds.nav.radii`)},{name:`ds-shadows`,label:D(`ds.nav.shadows`)}]},{title:D(`ds.sidebar.components`),items:[{name:`ds-icons`,label:D(`ds.nav.icons`)},{name:`ds-buttons`,label:D(`ds.nav.buttons`)},{name:`ds-badges`,label:D(`ds.nav.badges`)},{name:`ds-inputs`,label:D(`ds.nav.inputs`)},{name:`ds-cards`,label:D(`ds.nav.cards`)},{name:`ds-products`,label:D(`ds.nav.products`)},{name:`ds-hero`,label:D(`ds.nav.hero`)},{name:`ds-navbar`,label:D(`ds.nav.navbar`)},{name:`ds-language`,label:D(`ds.nav.language`)}]}]);return(a,h)=>(d(),u(`div`,_,[c(`aside`,v,[c(`div`,y,[i(t(p),{to:`/`,class:`block text-brand`,"aria-label":`Kaiser Natron home`},{default:r(()=>[i(m,{class:`w-16 h-auto`})]),_:1}),c(`p`,b,l(t(D)(`ds.eyebrow.designSystem`)),1)]),c(`nav`,x,[(d(!0),u(s,null,e(O.value,i=>(d(),u(`div`,{key:i.title},[c(`p`,S,l(i.title),1),c(`div`,C,[(d(!0),u(s,null,e(i.items,e=>(d(),n(t(p),{key:e.name,to:{name:e.name},class:`px-3 py-2 rounded-sm text-[14px] font-medium text-muted hover:text-brand hover:bg-brand-wash transition-colors`,"active-class":`!text-brand !bg-brand-soft-wash`},{default:r(()=>[o(l(e.label),1)]),_:2},1032,[`to`]))),128))])]))),128))]),c(`div`,w,[i(t(p),{to:`/`,class:`text-[13px] text-muted hover:text-brand transition-colors`},{default:r(()=>[o(l(t(D)(`ds.sidebar.back`)),1)]),_:1})])]),c(`main`,T,[i(t(f))]),i(g,{floating:``})]))}};export{E as default};

1
dist/assets/DevicePreview-BLtCZL_d.js vendored Normal file
View File

@@ -0,0 +1 @@
import{$ as e,C as t,P as n,et as r,m as i,o as a,p as o,r as s,s as c,tt as l,u,w as d,x as f}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as p}from"./Icon-DUE2bXq6.js";var m={class:`flex items-center gap-3 mb-4 flex-wrap`},h={role:`tablist`,"aria-label":`Preview viewport`,class:`inline-flex items-center p-1 gap-0.5 rounded-pill border border-line bg-paper ml-auto`},g=[`aria-selected`,`onClick`],_={class:`rounded-md border border-line bg-surface p-6 overflow-x-auto`},v=[`src`,`title`],y={class:`mt-2 text-center font-mono text-[11px] text-muted`},b={__name:`DevicePreview`,props:{src:{type:String,required:!0},initial:{type:String,default:`desktop`,validator:e=>[`mobile`,`tablet`,`desktop`].includes(e)},height:{type:Number,default:560}},setup(b){let x=b,S=[{id:`mobile`,label:`Mobile`,width:390},{id:`tablet`,label:`Tablet`,width:820},{id:`desktop`,label:`Desktop`,width:1280}],C=n(x.initial),w=a(()=>S.find(e=>e.id===C.value));return(n,a)=>(f(),u(`div`,null,[c(`div`,m,[d(n.$slots,`controls`),c(`div`,h,[(f(),u(s,null,t(S,t=>c(`button`,{key:t.id,type:`button`,role:`tab`,"aria-selected":C.value===t.id,class:e([`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===t.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:e=>C.value=t.id},[i(p,{name:t.id,size:14},null,8,[`name`]),o(` `+l(t.label),1)],10,g)),64))])]),c(`div`,_,[c(`div`,{class:`mx-auto transition-[width] duration-base ease-out`,style:r({width:w.value.width+`px`})},[c(`iframe`,{src:b.src,title:`${w.value.label} preview`,style:r({height:b.height+`px`}),class:`w-full block rounded-sm border border-line bg-paper`,loading:`lazy`},null,12,v),c(`p`,y,l(w.value.width)+`px `,1)],4)])]))}};export{b as t};

1
dist/assets/HeroPreview-DxWKyYcb.js vendored Normal file

File diff suppressed because one or more lines are too long

14
dist/assets/HeroSection-C6abwGao.js vendored Normal file
View File

@@ -0,0 +1,14 @@
import{$ as e,C as t,L as n,P as r,c as i,et as a,k as o,m as s,o as c,p as l,r as u,s as d,tt as f,u as p,x as m}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as h}from"./i18n-Dy4LSDvO.js";import{t as g}from"./SectionShell-CRUwhFt3.js";import{t as _}from"./DevicePreview-BLtCZL_d.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=c(()=>[{id:`split`,label:w(`ds.hero.variant.split`)},{id:`centered`,label:w(`ds.hero.variant.centered`)}]),E=c(()=>[{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=r(`split`),O=r(`cream`),k=c(()=>`/design/preview/hero?variant=${D.value}&tone=${O.value}`);return(r,c)=>(m(),i(g,{eyebrow:n(w)(`ds.eyebrow.components`),title:n(w)(`ds.hero.title`),description:n(w)(`ds.hero.description`),wide:``},{default:o(()=>[d(`section`,null,[s(_,{src:k.value,initial:`desktop`,height:760},{controls:o(()=>[d(`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`},[(m(!0),p(u,null,t(T.value,t=>(m(),p(`button`,{key:t.id,type:`button`,role:`tab`,"aria-selected":D.value===t.id,class:e([`px-3 py-1.5 text-[12px] font-semibold tracking-label rounded-pill transition-colors duration-base`,D.value===t.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:e=>D.value=t.id},f(t.label),11,y))),128))],8,v),d(`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`},[(m(!0),p(u,null,t(E.value,t=>(m(),p(`button`,{key:t.id,type:`button`,role:`tab`,"aria-selected":O.value===t.id,class:e([`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===t.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:e=>O.value=t.id},[d(`span`,{class:`w-2.5 h-2.5 rounded-full border border-line-strong`,style:a({backgroundColor:t.swatch})},null,4),l(` `+f(t.label),1)],10,x))),128))],8,b)]),_:1},8,[`src`])]),d(`section`,null,[d(`h2`,S,f(n(w)(`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`},`<Hero
variant="split"
tone="cream"
eyebrow="Neu"
headline="Kaiser-Natron Pulver"
subheadline="Reinigt. Backt. Neutralisiert."
image="/products/cutouts/…-removebg-preview.png"
image-alt="Kaiser-Natron Pulver 250 g"
badge="Bestseller"
cta-label="In den Warenkorb"
secondary-label="Mehr erfahren"
@cta="addToCart(sku)"
@secondary="router.push('/anwendungen')"
/>`)],-1)])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{C as default};

1
dist/assets/HomePage-KhgwXZe3.js vendored Normal file
View File

@@ -0,0 +1 @@
import{L as e,f as t,k as n,m as r,p as i,s as a,u as o,x as s}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as c}from"./vue-router-BrNWkU63.js";import{t as l}from"./Navbar-CC9dNfRJ.js";import{t as u}from"./Button-Wjj-Z6Tb.js";var d={class:`min-h-screen bg-surface`},f={class:`mx-auto max-w-4xl px-6 py-28 text-center`},p={__name:`HomePage`,setup(p){return(p,m)=>(s(),o(`div`,d,[r(l,{variant:`brand`,layout:`standard`,"cart-count":0}),a(`section`,f,[m[1]||=t(`<p class="eyebrow mb-4">Scaffolding</p><h1 class="font-display font-normal tracking-[var(--tracking-tight)] leading-[1.05]" style="font-size:clamp(3rem, 5vw, 4.5rem);"> Design system <em class="italic font-light text-brand-soft">first</em>. </h1><p class="mt-5 text-muted max-w-xl mx-auto"> Tokens, primitives, and patterns live in <code class="font-mono text-sm">/src/design-system</code>. Browse the live reference and iterate. </p>`,3),r(e(c),{to:`/design`,class:`inline-block mt-10`},{default:n(()=>[r(u,{size:`lg`},{default:n(()=>[...m[0]||=[i(`Open design system`,-1)]]),_:1})]),_:1})])]))}};export{p as default};

1
dist/assets/Icon-DUE2bXq6.js vendored Normal file
View File

@@ -0,0 +1 @@
import{l as e,o as t,u as n,x as r}from"./runtime-core.esm-bundler-CjdnoyKJ.js";var i={cart:{path:`<path d="M6 7h12l-1.2 10.3a2 2 0 0 1-2 1.7H9.2a2 2 0 0 1-2-1.7L6 7Z" /><path d="M9 10V6a3 3 0 1 1 6 0v4" />`,label:`Warenkorb`},bag:{path:`<path d="M5 7h14v12a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V7Z" /><path d="M9 7V5a3 3 0 1 1 6 0v2" />`,label:`Tasche`},heart:{path:`<path d="M12 20s-7-4.35-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.65-7 10-7 10Z" />`,label:`Favorit`},user:{path:`<circle cx="12" cy="8" r="3.5" /><path d="M5 20c0-3.5 3-6 7-6s7 2.5 7 6" />`,label:`Konto`},search:{path:`<circle cx="11" cy="11" r="6.5" /><path d="m20 20-3.5-3.5" />`,label:`Suche`},menu:{path:`<path d="M5 7h14M5 12h14M5 17h14" />`,label:`Menü`},close:{path:`<path d="M6 6l12 12M18 6L6 18" />`,label:`Schließen`},"chevron-left":{path:`<path d="M14 6l-6 6 6 6" />`,label:`Zurück`},"chevron-right":{path:`<path d="M10 6l6 6-6 6" />`,label:`Weiter`},"chevron-down":{path:`<path d="M6 10l6 6 6-6" />`,label:`Öffnen`},"chevron-up":{path:`<path d="M6 14l6-6 6 6" />`,label:`Schließen`},"arrow-right":{path:`<path d="M5 12h14M13 6l6 6-6 6" />`,label:`Pfeil rechts`},"arrow-left":{path:`<path d="M19 12H5M11 6l-6 6 6 6" />`,label:`Pfeil links`},plus:{path:`<path d="M12 5v14M5 12h14" />`,label:`Hinzufügen`},minus:{path:`<path d="M5 12h14" />`,label:`Entfernen`},check:{path:`<path d="m5 12 5 5L20 7" />`,label:`Bestätigt`},mail:{path:`<rect x="3" y="5" width="18" height="14" rx="2" /><path d="m3 7 9 6 9-6" />`,label:`E-Mail`},phone:{path:`<path d="M21 16.5v3a2 2 0 0 1-2.2 2 19 19 0 0 1-8.3-3 19 19 0 0 1-6-6A19 19 0 0 1 1.5 4.2 2 2 0 0 1 3.5 2h3a2 2 0 0 1 2 1.7c.1.9.3 1.8.6 2.6a2 2 0 0 1-.5 2L7.3 9.6a16 16 0 0 0 6 6l1.3-1.3a2 2 0 0 1 2-.5c.8.3 1.7.5 2.6.6a2 2 0 0 1 1.7 2Z" />`,label:`Telefon`},"map-pin":{path:`<path d="M12 21s7-6 7-11a7 7 0 1 0-14 0c0 5 7 11 7 11Z" /><circle cx="12" cy="10" r="2.5" />`,label:`Standort`},"external-link":{path:`<path d="M14 5h5v5" /><path d="M19 5l-9 9" /><path d="M19 14v5H5V5h5" />`,label:`Externer Link`},info:{path:`<circle cx="12" cy="12" r="9" /><path d="M12 11v5" /><circle cx="12" cy="8" r="0.6" fill="currentColor" stroke="none" />`,label:`Info`},star:{path:`<path d="m12 3 2.7 5.7 6.3.9-4.6 4.4 1.1 6.2L12 17.3 6.5 20.2l1.1-6.2L3 9.6l6.3-.9Z" />`,label:`Stern`},mobile:{path:`<rect x="7" y="3" width="10" height="18" rx="2" /><path d="M11 18h2" />`,label:`Mobile`},tablet:{path:`<rect x="4" y="3" width="16" height="18" rx="2" /><path d="M11 18h2" />`,label:`Tablet`},desktop:{path:`<rect x="3" y="4" width="18" height="12" rx="2" /><path d="M8 20h8M12 16v4" />`,label:`Desktop`}},a=[`width`,`height`,`stroke-width`,`role`,`aria-label`,`aria-hidden`,`innerHTML`],o={__name:`Icon`,props:{name:{type:String,required:!0},size:{type:[String,Number],default:20},strokeWidth:{type:[String,Number],default:1.8},label:{type:String,default:null}},setup(o){let s=o,c=t(()=>i[s.name]),l=t(()=>s.label??null);return(t,i)=>c.value?(r(),n(`svg`,{key:0,xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 24 24`,width:o.size,height:o.size,fill:`none`,stroke:`currentColor`,"stroke-width":o.strokeWidth,"stroke-linecap":`round`,"stroke-linejoin":`round`,role:l.value?`img`:`presentation`,"aria-label":l.value,"aria-hidden":l.value?null:`true`,innerHTML:c.value.path},null,8,a)):e(``,!0)}};export{i as n,o as t};

2
dist/assets/IconsSection-5_Y3SRTU.js vendored Normal file
View File

@@ -0,0 +1,2 @@
import{A as e,C as t,L as n,P as r,c as i,k as a,l as o,m as s,o as c,r as l,s as u,tt as d,u as f,x as p}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{r as m}from"./runtime-dom.esm-bundler-DWTDSpp2.js";import{n as h,t as g}from"./Icon-DUE2bXq6.js";import{t as _}from"./i18n-Dy4LSDvO.js";import{t as v}from"./SectionShell-CRUwhFt3.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=c(()=>[{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=r(``),J=c(()=>{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=r(``);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(r,c)=>(p(),i(v,{eyebrow:n(G)(`ds.eyebrow.components`),title:n(G)(`ds.icons.title`),description:n(G)(`ds.icons.description`)},{default:a(()=>[u(`section`,null,[u(`div`,y,[u(`label`,b,[u(`span`,x,[s(g,{name:`search`,size:16})]),e(u(`input`,{"onUpdate:modelValue":c[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]])]),u(`span`,C,d(n(G)(`ds.icons.copyHint`)),1)]),J.value.length===0?(p(),f(`div`,w,d(n(G)(`ds.icons.noMatch`))+` "`+d(q.value)+`". `,1)):o(``,!0),(p(!0),f(l,null,t(J.value,e=>(p(),f(`div`,{key:e.title,class:`mb-10 last:mb-0`},[u(`h2`,T,d(e.title),1),u(`div`,E,[(p(!0),f(l,null,t(e.names,e=>(p(),f(`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)},[u(`span`,O,[s(g,{name:e,size:22},null,8,[`name`])]),u(`span`,k,d(Y.value===e?n(G)(`ds.icons.copied`):e),1)],8,D))),128))])]))),128))]),u(`section`,null,[u(`h2`,A,d(n(G)(`ds.heading.onDifferentSurfaces`)),1),u(`div`,j,[u(`div`,M,[s(g,{name:`cart`,size:28}),s(g,{name:`heart`,size:28}),s(g,{name:`user`,size:28})]),u(`div`,N,[s(g,{name:`cart`,size:28}),s(g,{name:`heart`,size:28}),s(g,{name:`user`,size:28})]),u(`div`,P,[s(g,{name:`cart`,size:28}),s(g,{name:`heart`,size:28}),s(g,{name:`user`,size:28})])])]),u(`section`,null,[u(`h2`,F,d(n(G)(`ds.heading.sizes`)),1),u(`div`,I,[u(`div`,L,[s(g,{name:`cart`,size:16}),c[1]||=u(`code`,{class:`font-mono text-[11px] text-muted`},`16`,-1)]),u(`div`,R,[s(g,{name:`cart`,size:20}),u(`code`,z,d(n(G)(`ds.icons.sizeDefault`)),1)]),u(`div`,B,[s(g,{name:`cart`,size:24}),c[2]||=u(`code`,{class:`font-mono text-[11px] text-muted`},`24`,-1)]),u(`div`,V,[s(g,{name:`cart`,size:32}),c[3]||=u(`code`,{class:`font-mono text-[11px] text-muted`},`32`,-1)]),u(`div`,H,[s(g,{name:`cart`,size:48}),c[4]||=u(`code`,{class:`font-mono text-[11px] text-muted`},`48`,-1)])])]),u(`section`,null,[u(`h2`,U,d(n(G)(`ds.heading.usage`)),1),c[5]||=u(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[u(`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
dist/assets/InputsSection-pE5zXWou.js vendored Normal file
View File

@@ -0,0 +1 @@
import{$ as e,D as t,L as n,P as r,c as i,k as a,l as o,m as s,o as c,p as l,s as u,tt as d,u as f,x as p}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as m}from"./i18n-Dy4LSDvO.js";import{t as h}from"./SectionShell-CRUwhFt3.js";import{t as g}from"./Card-BKj8EzNc.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(n){let r=n,i=t(),a=c(()=>`in-${i}`),s=c(()=>r.hint?`hint-${i}`:void 0),m=c(()=>r.error?`err-${i}`:void 0),h=c(()=>[s.value,m.value].filter(Boolean).join(` `)||void 0);return(t,r)=>(p(),f(`div`,_,[n.label?(p(),f(`label`,{key:0,for:a.value,class:`text-[11px] font-bold uppercase tracking-eyebrow text-muted`},[l(d(n.label),1),n.required?(p(),f(`span`,y,` *`)):o(``,!0)],8,v)):o(``,!0),u(`input`,{id:a.value,type:n.type,value:n.modelValue,placeholder:n.placeholder,disabled:n.disabled,required:n.required,"aria-invalid":!!n.error,"aria-describedby":h.value,class:e([`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`,n.error?`border-danger`:`border-line`]),onInput:r[0]||=e=>t.$emit(`update:modelValue`,e.target.value)},null,42,b),n.hint&&!n.error?(p(),f(`p`,{key:1,id:s.value,class:`text-[13px] text-muted`},d(n.hint),9,x)):o(``,!0),n.error?(p(),f(`p`,{key:2,id:m.value,class:`text-[13px] text-danger`},d(n.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(e){let{t}=m(),o=r(``),c=r(``),l=r(``);return(e,r)=>(p(),i(h,{eyebrow:n(t)(`ds.eyebrow.components`),title:n(t)(`ds.inputs.title`),description:n(t)(`ds.inputs.description`)},{default:a(()=>[u(`section`,null,[u(`h2`,w,d(n(t)(`ds.heading.default`)),1),s(g,{tone:`paper`},{default:a(()=>[u(`div`,T,[s(C,{modelValue:o.value,"onUpdate:modelValue":r[0]||=e=>o.value=e,label:n(t)(`ds.inputs.email`),type:`email`,placeholder:`you@example.com`,hint:n(t)(`ds.inputs.emailHint`)},null,8,[`modelValue`,`label`,`hint`]),s(C,{modelValue:c.value,"onUpdate:modelValue":r[1]||=e=>c.value=e,label:n(t)(`ds.inputs.password`),type:`password`,placeholder:`••••••••`},null,8,[`modelValue`,`label`])])]),_:1})]),u(`section`,null,[u(`h2`,E,d(n(t)(`ds.heading.states`)),1),s(g,{tone:`paper`},{default:a(()=>[u(`div`,D,[s(C,{modelValue:l.value,"onUpdate:modelValue":r[2]||=e=>l.value=e,label:n(t)(`ds.inputs.required`),required:``,error:n(t)(`ds.inputs.requiredError`)},null,8,[`modelValue`,`label`,`error`]),s(C,{label:n(t)(`ds.inputs.disabled`),placeholder:n(t)(`ds.inputs.disabledPlaceholder`),disabled:``},null,8,[`label`,`placeholder`])])]),_:1})])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{O as default};

View File

@@ -0,0 +1 @@
import{$ as e,C as t,L as n,o as r,r as i,tt as a,u as o,x as s}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as c}from"./i18n-Dy4LSDvO.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=r(()=>h[d.tone]);return(r,c)=>(s(),o(`div`,{role:`group`,"aria-label":`Language`,class:e([`inline-flex items-center p-1 gap-0.5 rounded-pill font-sans`,g.value.container,u.floating?`fixed top-6 right-6 z-[60] shadow-sm`:``])},[(s(!0),o(i,null,t(n(m),t=>(s(),o(`button`,{key:t.code,type:`button`,"aria-label":t.name,"aria-pressed":n(f)===t.code,class:e([`px-2.5 py-1 text-[11px] font-bold tracking-eyebrow rounded-pill transition-colors duration-base`,n(f)===t.code?g.value.active:g.value.inactive]),onClick:e=>n(p)(t.code)},a(t.label),11,l))),128))],2))}};export{u as t};

View File

@@ -0,0 +1,3 @@
import{L as e,c as t,k as n,m as r,s as i,tt as a,x as o}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as s}from"./i18n-Dy4LSDvO.js";import{t as c}from"./LanguageSwitcher-SSHEwswt.js";import{t as l}from"./SectionShell-CRUwhFt3.js";import{t as u}from"./Card-BKj8EzNc.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)=>(o(),t(l,{eyebrow:e(C)(`ds.eyebrow.components`),title:e(C)(`ds.language.title`),description:e(C)(`ds.language.description`)},{default:n(()=>[i(`section`,null,[i(`h2`,d,a(e(C)(`ds.heading.onDifferentSurfaces`)),1),i(`div`,f,[r(u,{tone:`paper`},{default:n(()=>[i(`p`,p,a(e(C)(`ds.cards.paper`)),1),r(c,{tone:`paper`}),i(`p`,m,a(e(C)(`ds.language.paperNote`)),1)]),_:1}),r(u,{tone:`cream`},{default:n(()=>[i(`p`,h,a(e(C)(`ds.cards.cream`)),1),r(c,{tone:`cream`}),i(`p`,g,a(e(C)(`ds.language.creamNote`)),1)]),_:1}),r(u,{tone:`brand`},{default:n(()=>[i(`p`,_,a(e(C)(`ds.cards.brand`)),1),r(c,{tone:`brand`}),i(`p`,v,a(e(C)(`ds.language.brandNote`)),1)]),_:1})])]),i(`section`,null,[i(`h2`,y,a(e(C)(`ds.language.floating`)),1),r(u,{tone:`paper`},{default:n(()=>[i(`p`,b,a(e(C)(`ds.language.floatingNote`)),1)]),_:1})]),i(`section`,null,[i(`h2`,x,a(e(C)(`ds.heading.usage`)),1),S[0]||=i(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[i(`pre`,{class:`whitespace-pre-wrap`},`<LanguageSwitcher />
<LanguageSwitcher tone="brand" />
<LanguageSwitcher floating />`)],-1)])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{S as default};

1
dist/assets/Logo-XIYt07ns.js vendored Normal file
View File

@@ -0,0 +1 @@
import{f as e,s as t,tt as n,u as r,x as i}from"./runtime-core.esm-bundler-CjdnoyKJ.js";var a=[`aria-label`],o={__name:`Logo`,props:{title:{type:String,default:`Kaiser Natron`}},setup(o){return(s,c)=>(i(),r(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 121.9 76.9`,role:`img`,"aria-label":o.title,fill:`currentColor`},[t(`title`,null,n(o.title),1),c[0]||=e(`<g><polygon points="13.8,15.6 6.7,28.7 6.7,17.5 0,19.3 0,46.4 6.8,44.6 6.7,38.4 9.8,33.3 15.3,42.4 22.4,40.4 14.1,25.9 21.3,13.6"></polygon><path d="M33.1,32c0.6-0.2,1.1-0.4,1.6-0.9l0-7.3c-0.7-0.1-1.3,0-2.1,0.2c-3.1,0.8-3.9,3.2-3.2,5.7 C29.9,31.8,31.2,32.5,33.1,32 M36.3,35.3c-1.1,1.5-2.6,2.6-4.5,3.1c-3.7,1-7.3-0.6-8.8-5.9c-1.7-6.3,1.1-12,7.5-13.7 c2.3-0.6,4.4-0.5,6.1,0.2l1-1.7l3.5-0.9l0,19.1l-3.6,1L36.3,35.3z"></path><path d="M44.9,15.4l6.4-1.7l0,19.1l-6.4,1.7L44.9,15.4z M44.7,5.9l6.6-1.8l0,6.6l-6.7,1.8L44.7,5.9z"></path><path d="M55.6,29.9l-1.3-6.1c2.6,1.1,5.3,1.7,7.2,1.2c0.8-0.2,1.1-0.7,1-1.3c-0.1-0.5-0.6-0.7-2.2-1.1l-0.4-0.1 c-2.9-0.6-4.5-1.8-5.1-4.1c-0.9-3.3,1.1-6.7,5.4-7.8c2.4-0.6,4.9-0.6,6.9,0l0.2,5.6c-1.7-0.7-3.9-0.9-5.1-0.6 c-1,0.3-1.4,0.8-1.2,1.5c0.1,0.4,0.5,0.7,2,1l0.5,0.1c3,0.7,4.3,1.7,4.9,3.8c1,3.6-1.4,6.7-5.6,7.9C60,30.8,57.6,30.8,55.6,29.9"></path><path d="M76.4,14.7l5.4-1.4c-0.6-1.8-1.7-2.5-3-2.1C77.4,11.5,76.5,12.8,76.4,14.7 M80.5,25.3 c-4.5,1.2-8.6,0.2-10.1-5.4c-1.8-6.5,1.7-12.3,7.2-13.8c4.8-1.3,7.8,1.1,9.1,6.1c0.2,0.7,0.4,1.6,0.4,2.4l-10.4,2.8 c0.8,2.3,2.4,2.5,4.5,1.9c1.8-0.5,3.6-1.5,4.8-2.6l-0.8,5.9C83.9,24,82.4,24.7,80.5,25.3"></path><path d="M96,10l0,10.7l-6.4,1.7l0-19.1l4.7-1.3L95.8,4c1.5-2.5,3.2-3.5,4.9-4l0,7.9C99.1,8.4,97.5,9.1,96,10"></path><polygon points="104.5,6.3 112.6,4.1 112.6,7.1 104.5,9.2"></polygon><polygon points="15.5,45.6 15.5,59.7 4.6,48.5 0,49.7 0,76.9 6.6,75.1 6.7,60.7 17.6,72.1 22.1,70.9 22.1,43.8"></polygon><path d="M35.8,61.6c0.6-0.2,1.1-0.4,1.6-0.9l0-7.3c-0.7-0.1-1.3,0-2.1,0.2c-3.1,0.8-3.9,3.2-3.2,5.7 C32.7,61.5,33.9,62.1,35.8,61.6 M39.1,64.9c-1.1,1.5-2.6,2.6-4.5,3.1c-3.7,1-7.3-0.6-8.8-5.9c-1.7-6.3,1.1-12,7.5-13.7 c2.3-0.6,4.4-0.5,6.1,0.2l1-1.7l3.5-0.9l0,19.1l-3.6,1L39.1,64.9z"></path><path d="M54.8,62.5c-3,0.8-5.4,0.3-6.4-3.4C48.2,58,48,56.5,48,54.6l0-4l-1.6,0.4l0-5.7l1.6-0.4l0-5.4l6.4-1.7 l0,5.4l3.1-0.8l0,5.7l-3.1,0.8l0,5.1c0,0.4,0,0.6,0.1,0.9c0.2,0.8,0.8,1,1.8,0.7c0.4-0.1,0.8-0.3,1.3-0.5l-0.5,6.4 C56.4,62,55.6,62.3,54.8,62.5"></path><path d="M67.3,48.1l0,10.7l-6.4,1.7l0-19.1l4.7-1.3l1.5,1.8c1.5-2.5,3.2-3.5,4.9-4l0,7.9 C70.3,46.5,68.8,47.2,67.3,48.1"></path><path d="M86,43.3c-0.5-1.9-1.7-2.7-3.4-2.3c-2.2,0.6-3.2,3-2.4,5.7c0.6,2.1,1.9,2.8,3.4,2.4 C85.8,48.5,86.7,46,86,43.3 M73.9,49.2c-1.6-5.9,1.3-12,8.1-13.9c5.5-1.5,9.1,0.9,10.3,5.4c1.5,5.6-0.9,12-8,13.9 C78.9,56.2,75.2,54.1,73.9,49.2"></path><path d="M101.8,37l0,12.6l-6.4,1.7l0-19.1l3.7-1l2,1.9c1.1-2.3,2.8-3.6,4.6-4.1c2.9-0.8,5.3,0.5,6.3,4.1 c0.3,1.3,0.6,3.3,0.6,5.6l0,7.9l-6.4,1.7l0-8.3c0-1.1,0-2.1-0.2-2.9c-0.3-1.3-1.1-1.5-2.2-1.2C103.2,36.1,102.6,36.4,101.8,37"></path><path d="M117.2,30.5v-2h0.6c0.7,0,1,0.4,1,1c0,0.6-0.4,1-1,1H117.2z M117.2,31.1h0.7c0.1,0,0.2,0,0.3,0l0.7,1.2h0.9 l-1-1.6c0.4-0.3,0.6-0.8,0.6-1.3c0-1-0.7-1.6-1.7-1.6h-1.4v4.5h0.8V31.1z M117.9,33.5c-1.9,0-3.2-1.1-3.2-3.4 c0-2.1,1.4-3.3,3.2-3.3c1.9,0,3.2,1.2,3.2,3.4C121.1,32.3,119.8,33.5,117.9,33.5 M117.8,34.2c2.4,0,4-1.5,4-4.1 c0-2.5-1.6-4.1-4-4.1c-2.3,0-4,1.6-4,4.1C113.8,32.7,115.4,34.2,117.8,34.2"></path></g>`,1)],8,a))}};export{o as t};

1
dist/assets/LogoSection-CWQzivtR.js vendored Normal file
View File

@@ -0,0 +1 @@
import{L as e,c as t,k as n,m as r,s as i,tt as a,x as o}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as s}from"./Logo-XIYt07ns.js";import{t as c}from"./i18n-Dy4LSDvO.js";import{t as l}from"./SectionShell-CRUwhFt3.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)=>(o(),t(l,{eyebrow:e(D)(`ds.eyebrow.brand`),title:e(D)(`ds.logo.title`),description:e(D)(`ds.logo.description`)},{default:n(()=>[i(`section`,null,[i(`h2`,u,a(e(D)(`ds.heading.onDifferentSurfaces`)),1),i(`div`,d,[i(`div`,f,[r(s,{class:`w-40 h-auto text-brand`}),i(`code`,p,a(e(D)(`ds.cards.paper`)),1)]),i(`div`,m,[r(s,{class:`w-40 h-auto text-brand`}),i(`code`,h,a(e(D)(`ds.cards.cream`)),1)]),i(`div`,g,[r(s,{class:`w-40 h-auto text-paper`}),i(`code`,_,a(e(D)(`ds.cards.brand`)),1)])])]),i(`section`,null,[i(`h2`,v,a(e(D)(`ds.heading.sizes`)),1),i(`div`,y,[i(`div`,b,[r(s,{class:`w-16 h-auto text-brand`}),E[0]||=i(`code`,{class:`font-mono text-[11px] text-muted`},`w-16`,-1)]),i(`div`,x,[r(s,{class:`w-32 h-auto text-brand`}),E[1]||=i(`code`,{class:`font-mono text-[11px] text-muted`},`w-32`,-1)]),i(`div`,S,[r(s,{class:`w-60 h-auto text-brand`}),E[2]||=i(`code`,{class:`font-mono text-[11px] text-muted`},`w-60`,-1)])])]),i(`section`,null,[i(`h2`,C,a(e(D)(`ds.heading.usage`)),1),i(`div`,w,[i(`p`,T,a(e(D)(`ds.logo.usageIntro`)),1),E[3]||=i(`pre`,{class:`whitespace-pre-wrap`},`<Logo class="w-60 h-auto text-brand" />`,-1)])])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{E as default};

1
dist/assets/Navbar-CC9dNfRJ.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/assets/NavbarPreview-CP-QQfL8.js vendored Normal file
View File

@@ -0,0 +1 @@
import{C as e,et as t,m as n,o as r,r as i,s as a,u as o,x as s}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{a as c}from"./vue-router-BrNWkU63.js";import{t as l}from"./Navbar-CC9dNfRJ.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=r(()=>{let e=p.query.variant;return[`paper`,`cream`,`brand`].includes(e)?e:`paper`}),h=r(()=>p.query.layout===`floating`?`floating`:`standard`);return(r,c)=>(s(),o(`div`,u,[n(l,{variant:m.value,layout:h.value,"cart-count":2},null,8,[`variant`,`layout`]),a(`div`,d,[(s(),o(i,null,e([40,28,40,32,40,28,36,40],e=>a(`div`,{key:e,class:`rounded-md border border-line bg-paper`,style:t({height:e*4+`px`})},null,4)),64))])]))}};export{f as default};

8
dist/assets/NavbarSection-CHIc7oGa.js vendored Normal file
View File

@@ -0,0 +1,8 @@
import{$ as e,C as t,L as n,P as r,c as i,et as a,k as o,m as s,o as c,p as l,r as u,s as d,tt as f,u as p,x as m}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as h}from"./i18n-Dy4LSDvO.js";import{t as g}from"./SectionShell-CRUwhFt3.js";import{t as _}from"./DevicePreview-BLtCZL_d.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=c(()=>[{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=c(()=>[{id:`standard`,label:w(`ds.navbar.layout.standard`)},{id:`floating`,label:w(`ds.navbar.layout.floating`)}]),D=r(`paper`),O=r(`standard`),k=c(()=>`/design/preview/navbar?variant=${D.value}&layout=${O.value}`);return(r,c)=>(m(),i(g,{eyebrow:n(w)(`ds.eyebrow.components`),title:n(w)(`ds.navbar.title`),description:n(w)(`ds.navbar.description`),wide:``},{default:o(()=>[d(`section`,null,[s(_,{src:k.value,initial:`mobile`,height:720},{controls:o(()=>[d(`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`},[(m(!0),p(u,null,t(E.value,t=>(m(),p(`button`,{key:t.id,type:`button`,role:`tab`,"aria-selected":O.value===t.id,class:e([`px-3 py-1.5 text-[12px] font-semibold tracking-label rounded-pill transition-colors duration-base`,O.value===t.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:e=>O.value=t.id},f(t.label),11,y))),128))],8,v),d(`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`},[(m(!0),p(u,null,t(T.value,t=>(m(),p(`button`,{key:t.id,type:`button`,role:`tab`,"aria-selected":D.value===t.id,class:e([`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===t.id?`bg-brand text-accent`:`text-muted hover:text-brand`]),onClick:e=>D.value=t.id},[d(`span`,{class:`w-2.5 h-2.5 rounded-full border border-line-strong`,style:a({backgroundColor:t.swatch})},null,4),l(` `+f(t.label),1)],10,x))),128))],8,b)]),_:1},8,[`src`])]),d(`section`,null,[d(`h2`,S,f(n(w)(`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`},`<Navbar
variant="paper"
layout="floating"
:items="[{ key: 'nav.shop', href: '/shop' }]"
:cart-count="2"
@cart="openCart"
@nav="onNav"
/>`)],-1)])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{C as default};

11
dist/assets/ProductsSection-t-6g-88A.js vendored Normal file
View File

@@ -0,0 +1,11 @@
import{$ as e,E as t,L as n,P as r,c as i,k as a,l as o,m as s,o as c,p as l,s as u,tt as d,u as f,x as p}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as m}from"./Icon-DUE2bXq6.js";import{t as h}from"./i18n-Dy4LSDvO.js";import{t as g}from"./Button-Wjj-Z6Tb.js";import{t as _}from"./SectionShell-CRUwhFt3.js";import{t as v}from"./Badge-BPajj5yh.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(r){let _=r,{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=c(()=>D[_.tone]),k=c(()=>typeof _.price==`number`?`${_.currency} ${_.price.toFixed(2).replace(`.`,`,`)}`:`${_.currency} ${_.price}`);return(c,h)=>(p(),f(`article`,{class:e([`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`])},[(p(),i(t(r.href?`a`:`div`),{href:r.href||null,class:e([`relative block aspect-[4/5] overflow-hidden`,O.value.media])},{default:a(()=>[r.badge?(p(),i(v,{key:0,variant:r.badgeVariant,class:`absolute top-4 left-4 z-[1]`},{default:a(()=>[l(d(r.badge),1)]),_:1},8,[`variant`])):o(``,!0),u(`img`,{src:r.image,alt:r.imageAlt||r.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`])),u(`div`,b,[u(`div`,x,[(p(),i(t(r.href?`a`:`h3`),{href:r.href||null,class:e([`font-display text-xl font-normal leading-tight text-ink`,r.href?`hover:text-brand transition-colors duration-base`:``])},{default:a(()=>[l(d(r.title),1)]),_:1},8,[`href`,`class`])),r.size?(p(),f(`p`,S,d(r.size),1)):o(``,!0)]),u(`div`,C,[u(`span`,w,d(k.value),1),r.inStock?o(``,!0):(p(),f(`span`,T,d(n(E)(`ds.product.outOfStock`)),1))]),s(g,{variant:`primary`,size:`md`,block:``,disabled:!r.inStock,onClick:h[0]||=e=>c.$emit(`add`)},{before:a(()=>[s(m,{name:`plus`,size:16})]),default:a(()=>[l(` `+d(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-gro%C3%9Fpackung-removebg-preview.png`,F={__name:`ProductsSection`,setup(e){let{t}=h(),c=r(``);function m(e){c.value=e,setTimeout(()=>{c.value===e&&(c.value=``)},2e3)}return(e,r)=>(p(),i(_,{eyebrow:n(t)(`ds.eyebrow.components`),title:n(t)(`ds.product.title`),description:n(t)(`ds.product.description`)},{default:a(()=>[u(`section`,null,[u(`h2`,D,d(n(t)(`ds.heading.default`)),1),u(`div`,O,[s(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`)}),s(E,{title:`Kaiser-Natron® Pulver`,size:`250 g Großpackung`,price:4.49,image:P,badge:n(t)(`ds.badges.featured`),"badge-variant":`accent`,href:`#`,onAdd:r[1]||=e=>m(`pulver-250-featured`)},null,8,[`badge`]),s(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`)})]),c.value?(p(),f(`p`,k,[l(d(n(t)(`ds.product.added`))+`: `,1),u(`code`,A,d(c.value),1)])):o(``,!0)]),u(`section`,null,[u(`h2`,j,d(n(t)(`ds.heading.states`)),1),u(`div`,M,[s(E,{title:`Kaiser-Natron® Pulver`,size:`250 g Großpackung`,price:4.49,image:P,"in-stock":!1}),s(E,{title:`Kaiser-Natron® Pulver`,size:`250 g Großpackung`,price:4.49,image:P,badge:n(t)(`ds.badges.newRelease`),"badge-variant":`brand`,href:`#`},null,8,[`badge`])])]),u(`section`,null,[u(`h2`,N,d(n(t)(`ds.heading.usage`)),1),r[3]||=u(`div`,{class:`rounded-md border border-line bg-paper p-6 font-mono text-[12px] text-ink`},[u(`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};

1
dist/assets/RadiiSection-D3n7M71B.js vendored Normal file
View File

@@ -0,0 +1 @@
import{C as e,L as t,c as n,et as r,k as i,r as a,s as o,tt as s,u as c,x as l}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as u}from"./i18n-Dy4LSDvO.js";import{t as d}from"./SectionShell-CRUwhFt3.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)=>(l(),n(d,{eyebrow:t(g)(`ds.eyebrow.tokens`),title:t(g)(`ds.radii.title`),description:t(g)(`ds.radii.description`)},{default:i(()=>[o(`div`,f,[(l(),c(a,null,e(_,e=>o(`div`,{key:e.name,class:`flex flex-col items-center`},[o(`div`,{class:`h-32 w-full bg-paper border border-line mb-4 shadow-sm`,style:r({borderRadius:`var(--radius-${e.name})`})},null,4),o(`code`,p,`--radius-`+s(e.name),1),o(`span`,m,s(e.value),1)])),64))])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{h as default};

1
dist/assets/SectionShell-CRUwhFt3.js vendored Normal file
View File

@@ -0,0 +1 @@
import{$ as e,l as t,s as n,tt as r,u as i,w as a,x as o}from"./runtime-core.esm-bundler-CjdnoyKJ.js";var s={class:`mb-14 max-w-2xl`},c={class:`eyebrow mb-3`},l={class:`font-display text-5xl font-normal tracking-tight leading-[1.05] text-ink`},u={key:0,class:`mt-5 text-[17px] text-muted leading-relaxed`},d={class:`space-y-16`},f={__name:`SectionShell`,props:{eyebrow:{type:String,default:`Design system`},title:{type:String,required:!0},description:{type:String,default:``},wide:{type:Boolean,default:!1}},setup(f){return(p,m)=>(o(),i(`div`,{class:e([`mx-auto py-16`,f.wide?`max-w-none px-6 lg:px-8`:`max-w-5xl px-10 lg:px-16`])},[n(`header`,s,[n(`p`,c,r(f.eyebrow),1),n(`h1`,l,r(f.title),1),f.description?(o(),i(`p`,u,r(f.description),1)):t(``,!0)]),n(`div`,d,[a(p.$slots,`default`)])],2))}};export{f as t};

View File

@@ -0,0 +1 @@
import{C as e,L as t,c as n,et as r,k as i,o as a,r as o,s,tt as c,u as l,x as u}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as d}from"./i18n-Dy4LSDvO.js";import{t as f}from"./SectionShell-CRUwhFt3.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=a(()=>[{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(a,d)=>(u(),n(f,{eyebrow:t(_)(`ds.eyebrow.tokens`),title:t(_)(`ds.shadows.title`),description:t(_)(`ds.shadows.description`)},{default:i(()=>[s(`div`,p,[(u(!0),l(o,null,e(v.value,e=>(u(),l(`div`,{key:e.name,class:`space-y-4`},[s(`div`,{class:`h-36 rounded-md bg-paper`,style:r({boxShadow:e.css})},null,4),s(`div`,null,[s(`code`,m,`--shadow-`+c(e.name),1),s(`p`,h,c(e.note),1)])]))),128))])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{g as default};

View File

@@ -0,0 +1 @@
import{$ as e,C as t,L as n,c as r,k as i,m as a,r as o,s,tt as c,u as l,x as u}from"./runtime-core.esm-bundler-CjdnoyKJ.js";import{t as d}from"./i18n-Dy4LSDvO.js";import{t as f}from"./SectionShell-CRUwhFt3.js";import{t as p}from"./Card-BKj8EzNc.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)=>(u(),r(f,{eyebrow:n(C)(`ds.eyebrow.tokens`),title:n(C)(`ds.typography.title`),description:n(C)(`ds.typography.description`)},{default:i(()=>[s(`section`,m,[a(p,{tone:`paper`},{default:i(()=>[s(`p`,h,c(n(C)(`ds.heading.display`)),1),S[0]||=s(`p`,{class:`font-display text-5xl font-normal leading-[1.05] mb-3`},`Fraunces`,-1),s(`p`,g,c(n(C)(`ds.typography.serifDesc`)),1),S[1]||=s(`code`,{class:`font-mono text-[11px] text-muted block mt-5`},`var(--font-serif)`,-1)]),_:1}),a(p,{tone:`paper`},{default:i(()=>[s(`p`,_,c(n(C)(`ds.heading.body`)),1),S[2]||=s(`p`,{class:`font-sans text-5xl font-medium leading-[1.05] mb-3`},`DM Sans`,-1),s(`p`,v,c(n(C)(`ds.typography.sansDesc`)),1),S[3]||=s(`code`,{class:`font-mono text-[11px] text-muted block mt-5`},`var(--font-sans)`,-1)]),_:1})]),s(`section`,null,[s(`h2`,y,c(n(C)(`ds.heading.scale`)),1),s(`div`,b,[(u(),l(o,null,t(w,t=>s(`div`,{key:t,class:`flex items-baseline gap-8 py-4`},[s(`code`,x,`text-`+c(t),1),s(`span`,{class:e(`text-${t}`)},c(n(C)(`ds.typography.sample`)),3)])),64))])])]),_:1},8,[`eyebrow`,`title`,`description`]))}};export{S as default};

1
dist/assets/i18n-Dy4LSDvO.js vendored Normal file

File diff suppressed because one or more lines are too long

2
dist/assets/index-BOeKBKy1.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/assets/index-BRTnN62I.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

File diff suppressed because one or more lines are too long

1
dist/assets/vue-router-BrNWkU63.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/favicon.svg vendored Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" rx="6" fill="#1c3a28"/><text x="16" y="22" font-family="'DM Sans', system-ui, sans-serif" font-size="20" font-weight="700" fill="#ffffff" text-anchor="middle">K</text></svg>

After

Width:  |  Height:  |  Size: 263 B

24
dist/index.html vendored Normal file
View File

@@ -0,0 +1,24 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#faf7f1" />
<title>Kaiser Natron</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
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-BOeKBKy1.js"></script>
<link rel="modulepreload" crossorigin href="/assets/runtime-core.esm-bundler-CjdnoyKJ.js">
<link rel="modulepreload" crossorigin href="/assets/runtime-dom.esm-bundler-DWTDSpp2.js">
<link rel="modulepreload" crossorigin href="/assets/vue-router-BrNWkU63.js">
<link rel="stylesheet" crossorigin href="/assets/index-BRTnN62I.css">
</head>
<body>
<div id="app"></div>
</body>
</html>

1
dist/logo/logo-kaisernatron.svg vendored Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 121.9 76.9" style="enable-background:new 0 0 121.9 76.9;" xml:space="preserve"> <style type="text/css"> .st0{fill:#FFFFFF;} </style> <g id="Claim"> </g> <g id="Kaiser_Natron"> <g> <g> <g> <polygon class="st0" points="13.8,15.6 6.7,28.7 6.7,17.5 0,19.3 0,46.4 6.8,44.6 6.7,38.4 9.8,33.3 15.3,42.4 22.4,40.4 14.1,25.9 21.3,13.6 "></polygon> <path class="st0" d="M33.1,32c0.6-0.2,1.1-0.4,1.6-0.9l0-7.3c-0.7-0.1-1.3,0-2.1,0.2c-3.1,0.8-3.9,3.2-3.2,5.7 C29.9,31.8,31.2,32.5,33.1,32 M36.3,35.3c-1.1,1.5-2.6,2.6-4.5,3.1c-3.7,1-7.3-0.6-8.8-5.9c-1.7-6.3,1.1-12,7.5-13.7 c2.3-0.6,4.4-0.5,6.1,0.2l1-1.7l3.5-0.9l0,19.1l-3.6,1L36.3,35.3z"></path> <path class="st0" d="M44.9,15.4l6.4-1.7l0,19.1l-6.4,1.7L44.9,15.4z M44.7,5.9l6.6-1.8l0,6.6l-6.7,1.8L44.7,5.9z"></path> <path class="st0" d="M55.6,29.9l-1.3-6.1c2.6,1.1,5.3,1.7,7.2,1.2c0.8-0.2,1.1-0.7,1-1.3c-0.1-0.5-0.6-0.7-2.2-1.1l-0.4-0.1 c-2.9-0.6-4.5-1.8-5.1-4.1c-0.9-3.3,1.1-6.7,5.4-7.8c2.4-0.6,4.9-0.6,6.9,0l0.2,5.6c-1.7-0.7-3.9-0.9-5.1-0.6 c-1,0.3-1.4,0.8-1.2,1.5c0.1,0.4,0.5,0.7,2,1l0.5,0.1c3,0.7,4.3,1.7,4.9,3.8c1,3.6-1.4,6.7-5.6,7.9C60,30.8,57.6,30.8,55.6,29.9 "></path> <path class="st0" d="M76.4,14.7l5.4-1.4c-0.6-1.8-1.7-2.5-3-2.1C77.4,11.5,76.5,12.8,76.4,14.7 M80.5,25.3 c-4.5,1.2-8.6,0.2-10.1-5.4c-1.8-6.5,1.7-12.3,7.2-13.8c4.8-1.3,7.8,1.1,9.1,6.1c0.2,0.7,0.4,1.6,0.4,2.4l-10.4,2.8 c0.8,2.3,2.4,2.5,4.5,1.9c1.8-0.5,3.6-1.5,4.8-2.6l-0.8,5.9C83.9,24,82.4,24.7,80.5,25.3"></path> <path class="st0" d="M96,10l0,10.7l-6.4,1.7l0-19.1l4.7-1.3L95.8,4c1.5-2.5,3.2-3.5,4.9-4l0,7.9C99.1,8.4,97.5,9.1,96,10"></path> <polygon class="st0" points="104.5,6.3 112.6,4.1 112.6,7.1 104.5,9.2 "></polygon> <polygon class="st0" points="15.5,45.6 15.5,59.7 4.6,48.5 0,49.7 0,76.9 6.6,75.1 6.7,60.7 17.6,72.1 22.1,70.9 22.1,43.8 "></polygon> <path class="st0" d="M35.8,61.6c0.6-0.2,1.1-0.4,1.6-0.9l0-7.3c-0.7-0.1-1.3,0-2.1,0.2c-3.1,0.8-3.9,3.2-3.2,5.7 C32.7,61.5,33.9,62.1,35.8,61.6 M39.1,64.9c-1.1,1.5-2.6,2.6-4.5,3.1c-3.7,1-7.3-0.6-8.8-5.9c-1.7-6.3,1.1-12,7.5-13.7 c2.3-0.6,4.4-0.5,6.1,0.2l1-1.7l3.5-0.9l0,19.1l-3.6,1L39.1,64.9z"></path> <path class="st0" d="M54.8,62.5c-3,0.8-5.4,0.3-6.4-3.4C48.2,58,48,56.5,48,54.6l0-4l-1.6,0.4l0-5.7l1.6-0.4l0-5.4l6.4-1.7 l0,5.4l3.1-0.8l0,5.7l-3.1,0.8l0,5.1c0,0.4,0,0.6,0.1,0.9c0.2,0.8,0.8,1,1.8,0.7c0.4-0.1,0.8-0.3,1.3-0.5l-0.5,6.4 C56.4,62,55.6,62.3,54.8,62.5"></path> <path class="st0" d="M67.3,48.1l0,10.7l-6.4,1.7l0-19.1l4.7-1.3l1.5,1.8c1.5-2.5,3.2-3.5,4.9-4l0,7.9 C70.3,46.5,68.8,47.2,67.3,48.1"></path> <path class="st0" d="M86,43.3c-0.5-1.9-1.7-2.7-3.4-2.3c-2.2,0.6-3.2,3-2.4,5.7c0.6,2.1,1.9,2.8,3.4,2.4 C85.8,48.5,86.7,46,86,43.3 M73.9,49.2c-1.6-5.9,1.3-12,8.1-13.9c5.5-1.5,9.1,0.9,10.3,5.4c1.5,5.6-0.9,12-8,13.9 C78.9,56.2,75.2,54.1,73.9,49.2"></path> <path class="st0" d="M101.8,37l0,12.6l-6.4,1.7l0-19.1l3.7-1l2,1.9c1.1-2.3,2.8-3.6,4.6-4.1c2.9-0.8,5.3,0.5,6.3,4.1 c0.3,1.3,0.6,3.3,0.6,5.6l0,7.9l-6.4,1.7l0-8.3c0-1.1,0-2.1-0.2-2.9c-0.3-1.3-1.1-1.5-2.2-1.2C103.2,36.1,102.6,36.4,101.8,37"></path> </g> </g> <path class="st0" d="M117.2,30.5v-2h0.6c0.7,0,1,0.4,1,1c0,0.6-0.4,1-1,1H117.2z M117.2,31.1h0.7c0.1,0,0.2,0,0.3,0l0.7,1.2h0.9 l-1-1.6c0.4-0.3,0.6-0.8,0.6-1.3c0-1-0.7-1.6-1.7-1.6h-1.4v4.5h0.8V31.1z M117.9,33.5c-1.9,0-3.2-1.1-3.2-3.4 c0-2.1,1.4-3.3,3.2-3.3c1.9,0,3.2,1.2,3.2,3.4C121.1,32.3,119.8,33.5,117.9,33.5 M117.8,34.2c2.4,0,4-1.5,4-4.1 c0-2.5-1.6-4.1-4-4.1c-2.3,0-4,1.6-4,4.1C113.8,32.7,115.4,34.2,117.8,34.2"></path> </g> </g> </svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@@ -1,11 +1,12 @@
# Portainer stack — Kaiser Natron static frontend.
# Portainer stack — Kaiser Natron dev showcase.
#
# Deploy:
# Portainer → Stacks → Add stack → Repository (point at this repo)
# or Web editor (paste this file).
# Flow:
# 1. Developer runs `npm run build` locally and commits the updated dist/.
# 2. Portainer → Stacks → Pull and redeploy.
# 3. The image is a tiny nginx with the prebuilt dist copied in.
#
# Portainer will build the image from the Dockerfile at the repo root on first
# deploy and on each "Pull and redeploy".
# This is deliberately simple for a showcase box — no container-side npm,
# no hardening, no resource ceilings. Tighten when it graduates to prod.
services:
web:
@@ -13,11 +14,8 @@ services:
context: .
dockerfile: Dockerfile
image: kaiser-natron:portainer
container_name: kaiser-natron-web
restart: unless-stopped
ports:
# Host 5555 → container 80. Change the host side if you put a reverse
# proxy in front later; the container always listens on 80 internally.
- "5555:80"
healthcheck:
test: ["CMD", "wget", "-q", "-O-", "http://127.0.0.1/health"]
@@ -25,19 +23,3 @@ services:
timeout: 5s
retries: 3
start_period: 10s
# Hardening: the Vite output + nginx don't need a writable root. The tmp
# paths nginx uses are carved out as tmpfs so the main FS can be read-only.
read_only: true
tmpfs:
- /var/cache/nginx
- /var/run
- /tmp
security_opt:
- no-new-privileges:true
# Resource ceiling — a static site doesn't need much, and this prevents
# a runaway from starving other stacks on the same host.
deploy:
resources:
limits:
cpus: "0.50"
memory: 128M