chore: serve dev-doc + review-doc as static pages (/dev-doc, /review-doc)
Move the HTML dev-doc render to public/dev-doc/index.html and add the brand-review status page at public/review-doc/index.html. nginx's try_files $uri $uri/ serves them at /dev-doc and /review-doc ahead of the SPA fallback; CSP already permits the inline styles. Unlisted (URL-only). dist/ rebuilt so Portainer bakes them in. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
425
dist/review-doc/index.html
vendored
Normal file
425
dist/review-doc/index.html
vendored
Normal file
@@ -0,0 +1,425 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Kaiser-Natron® — Brand Review Status</title>
|
||||
<style>
|
||||
:root {
|
||||
--brand: #006548;
|
||||
--brand-soft: #4a9079;
|
||||
--crimson: #cc0230;
|
||||
--mint: #6eceb2;
|
||||
--gold: #e9c84b;
|
||||
--ink: #0a2c20;
|
||||
--muted: #5c7a6f;
|
||||
--paper: #ffffff;
|
||||
--cream: #f4f7f4;
|
||||
--line: #d9e4df;
|
||||
--kitchen: #c6d47d;
|
||||
--clean: #eb5a61;
|
||||
--wash: #c15a7e;
|
||||
--care: #f1864c;
|
||||
--done: #006548;
|
||||
--partial: #d98a1f;
|
||||
--open: #cc0230;
|
||||
--review: #6b7f8c;
|
||||
--serif: 'Zeitung', 'Iowan Old Style', 'Palatino', Georgia, serif;
|
||||
--sans: 'Zeitung', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
html { -webkit-font-smoothing: antialiased; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--sans);
|
||||
color: var(--ink);
|
||||
background: var(--cream);
|
||||
line-height: 1.55;
|
||||
}
|
||||
.wrap { max-width: 920px; margin: 0 auto; padding: 0 24px 80px; }
|
||||
|
||||
/* ---- Header ---- */
|
||||
header.hero {
|
||||
background: var(--brand);
|
||||
color: #fff;
|
||||
padding: 56px 24px 64px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
header.hero::after {
|
||||
/* angled divider — echoes the Soulmates angular CI, not waves */
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0; right: 0; bottom: -1px;
|
||||
height: 64px;
|
||||
background: var(--cream);
|
||||
clip-path: polygon(0 100%, 100% 100%, 100% 38%);
|
||||
}
|
||||
.hero-inner { max-width: 920px; margin: 0 auto; position: relative; z-index: 1; }
|
||||
.eyebrow {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .22em;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--mint);
|
||||
margin: 0 0 14px;
|
||||
}
|
||||
h1 {
|
||||
font-family: var(--serif);
|
||||
font-weight: 600;
|
||||
font-size: clamp(30px, 5vw, 46px);
|
||||
line-height: 1.05;
|
||||
margin: 0 0 14px;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
h1 em { font-style: italic; font-weight: 300; color: var(--mint); }
|
||||
.hero p { max-width: 60ch; color: rgba(255,255,255,.85); margin: 0; font-size: 16px; }
|
||||
.meta { margin-top: 22px; font-size: 13px; color: rgba(255,255,255,.7); }
|
||||
|
||||
/* ---- Summary chips ---- */
|
||||
.summary {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 12px;
|
||||
margin: -34px 0 38px;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.stat {
|
||||
background: var(--paper);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 12px;
|
||||
padding: 16px 14px;
|
||||
text-align: center;
|
||||
box-shadow: 0 10px 30px rgba(0,101,72,.07);
|
||||
}
|
||||
.stat .n { font-family: var(--serif); font-size: 30px; line-height: 1; font-weight: 600; }
|
||||
.stat .l { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin-top: 7px; }
|
||||
.stat.done .n { color: var(--done); }
|
||||
.stat.review .n { color: var(--review); }
|
||||
.stat.partial .n { color: var(--partial); }
|
||||
.stat.open .n { color: var(--open); }
|
||||
.stat.note .n { color: var(--brand-soft); }
|
||||
|
||||
/* ---- Legend ---- */
|
||||
.legend { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 0 0 34px; font-size: 13px; color: var(--muted); }
|
||||
.legend span { display: inline-flex; align-items: center; gap: 7px; }
|
||||
.dot { width: 11px; height: 11px; border-radius: 50%; display: inline-block; }
|
||||
.dot.done { background: var(--done); }
|
||||
.dot.review { background: var(--review); }
|
||||
.dot.partial { background: var(--partial); }
|
||||
.dot.open { background: var(--open); }
|
||||
.dot.note { background: var(--brand-soft); }
|
||||
|
||||
/* ---- Section ---- */
|
||||
section.group { margin-bottom: 40px; }
|
||||
.group > h2 {
|
||||
font-family: var(--serif);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 4px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid var(--brand);
|
||||
display: flex; align-items: baseline; gap: 12px;
|
||||
}
|
||||
.group > h2 .count { font-family: var(--sans); font-size: 13px; font-weight: 500; color: var(--muted); }
|
||||
|
||||
/* ---- Item card ---- */
|
||||
.item {
|
||||
background: var(--paper);
|
||||
border: 1px solid var(--line);
|
||||
border-left-width: 5px;
|
||||
border-radius: 10px;
|
||||
padding: 16px 18px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.item.done { border-left-color: var(--done); }
|
||||
.item.review { border-left-color: var(--review); }
|
||||
.item.partial { border-left-color: var(--partial); }
|
||||
.item.open { border-left-color: var(--open); }
|
||||
.item.note { border-left-color: var(--brand-soft); }
|
||||
|
||||
.item-head { display: flex; align-items: flex-start; gap: 12px; }
|
||||
.badge {
|
||||
flex: none;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .05em;
|
||||
padding: 4px 10px;
|
||||
border-radius: 999px;
|
||||
white-space: nowrap;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.badge.done { background: rgba(0,101,72,.10); color: var(--done); }
|
||||
.badge.review { background: rgba(107,127,140,.14); color: var(--review); }
|
||||
.badge.partial { background: rgba(217,138,31,.14); color: var(--partial); }
|
||||
.badge.open { background: rgba(204,2,48,.10); color: var(--open); }
|
||||
.badge.note { background: rgba(74,144,121,.14); color: var(--brand-soft); }
|
||||
|
||||
.quote { margin: 0; font-size: 15px; color: var(--ink); }
|
||||
.note {
|
||||
margin: 10px 0 0;
|
||||
font-size: 14px;
|
||||
color: var(--muted);
|
||||
padding-left: 14px;
|
||||
border-left: 2px solid var(--line);
|
||||
}
|
||||
.note strong { color: var(--brand); font-weight: 600; }
|
||||
|
||||
/* category swatch row */
|
||||
.swatches { display: inline-flex; gap: 5px; margin-left: 4px; vertical-align: middle; }
|
||||
.sw { width: 13px; height: 13px; border-radius: 3px; display: inline-block; border: 1px solid rgba(0,0,0,.06); }
|
||||
|
||||
/* opinion block */
|
||||
.opinion {
|
||||
background: var(--paper);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 12px;
|
||||
padding: 22px 24px;
|
||||
margin-top: 12px;
|
||||
font-size: 14.5px;
|
||||
color: var(--ink);
|
||||
}
|
||||
.opinion p { margin: 0 0 12px; }
|
||||
.opinion p:last-child { margin-bottom: 0; }
|
||||
|
||||
footer.foot {
|
||||
margin-top: 48px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid var(--line);
|
||||
font-size: 12.5px;
|
||||
color: var(--muted);
|
||||
display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.summary { grid-template-columns: repeat(2, 1fr); }
|
||||
}
|
||||
@media print {
|
||||
body { background: #fff; }
|
||||
.stat, .item, .opinion { box-shadow: none; }
|
||||
header.hero { padding-bottom: 48px; }
|
||||
.item { break-inside: avoid; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="hero">
|
||||
<div class="hero-inner">
|
||||
<p class="eyebrow">Brand Review · Implementation Status</p>
|
||||
<h1>Kaiser-Natron<sup>®</sup> website review —<br><em>what's done, what's next</em></h1>
|
||||
<p>Every point from the brand-owner review, tracked against the current build. Each item carries its real status and a short note on what was changed or what's still needed.</p>
|
||||
<p class="meta">Prepared 24 June 2026 · Branch <code>feat/shop-category-sections</code> · 28 review points</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
<div class="summary">
|
||||
<div class="stat done"><div class="n">18</div><div class="l">Done</div></div>
|
||||
<div class="stat review"><div class="n">2</div><div class="l">Reviewed / kept</div></div>
|
||||
<div class="stat partial"><div class="n">2</div><div class="l">In progress</div></div>
|
||||
<div class="stat open"><div class="n">6</div><div class="l">Needs your input</div></div>
|
||||
</div>
|
||||
|
||||
<div class="legend">
|
||||
<span><i class="dot done"></i> Done — implemented & on the branch</span>
|
||||
<span><i class="dot review"></i> Reviewed — kept as-is by your decision / verified</span>
|
||||
<span><i class="dot partial"></i> In progress — partially done</span>
|
||||
<span><i class="dot open"></i> Needs your input — legal text, content or a decision</span>
|
||||
</div>
|
||||
|
||||
<!-- ===================== LAYOUT ===================== -->
|
||||
<section class="group">
|
||||
<h2>Layout <span class="count">15 points</span></h2>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The overall layout is not consistent with the Kaiser-Natron® brand identity (CI).</p></div>
|
||||
<p class="note"><strong>Aligned to CI:</strong> official brand palette, the Zeitung typeface, angled (Soulmates) dividers and the official artwork are all in place. Holistic consistency continues as a guiding rule for every change.</p>
|
||||
</div>
|
||||
|
||||
<div class="item review">
|
||||
<div class="item-head"><span class="badge review">Reviewed</span>
|
||||
<p class="quote">The Kaiser-Natron® logo on the homepage is far too small and not prominent enough.</p></div>
|
||||
<p class="note"><strong>Kept at current size</strong> by your call this session — revisit anytime if you'd like it enlarged.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The spring/source has been distorted (mountains, Hebe's hair, the “mountain” by her head, the stream). All illustrations should match the original Kaiser-Natron® design.</p></div>
|
||||
<p class="note"><strong>Brand-hero rebuilt</strong> with the official Hebe + waterfall artwork, replacing the distorted composition.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">Incorrect font and incorrect colour palette.</p></div>
|
||||
<p class="note"><strong>Corrected:</strong> self-hosted Zeitung typeface and the official brand palette (green <code>#006548</code>, crimson, mint, gold) throughout.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The Soulmates angled concept is lost; wave-shaped elements do not fit the structure.</p></div>
|
||||
<p class="note"><strong>Waves removed.</strong> All section dividers are now angled/diagonal, echoing the logo's geometry and rebuilding brand recognition.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The 250 g package image: background colour and product image are not visually aligned.</p></div>
|
||||
<p class="note"><strong>Resolved:</strong> the 250 g box artwork was recoloured to the brand green so product and background sit together.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">“…for everything that should shine. Cleans, bakes and neutralizes…” does not fit the tone of voice.</p></div>
|
||||
<p class="note"><strong>Rewritten</strong> toward versatility — “Kaiser-Natron® für fast alles im Alltag” / “…for almost anything at home”, sourced from the live brand voice.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">Under “Bundles & Benefits”: AI-generated images must be marked as AI content with an icon, beginning in August.</p></div>
|
||||
<p class="note"><strong>Disclosed:</strong> a discreet “AI Edited” caption now sits on each AI-composed bundle image. It switches off automatically once real photos replace them.</p>
|
||||
</div>
|
||||
|
||||
<div class="item partial">
|
||||
<div class="item-head"><span class="badge partial">In progress</span>
|
||||
<p class="quote">The product depictions inside the AI images are inaccurate; as a manufacturer I'd avoid AI imagery altogether.</p></div>
|
||||
<p class="note"><strong>Disclosed for now</strong> with the AI-Edited badge. Full removal is wired and ready — it just needs your <strong>real product photography</strong> to drop in.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">“One powder, a hundred applications…” does not match the bath image shown above it; the powder product should be shown.</p></div>
|
||||
<p class="note"><strong>Fixed this session:</strong> the banner now shows the powder (the bulk bucket), and its “add to cart” / “learn more” point to that powder product.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The “Personal Care”, “Household” and “Kitchen” categories are disrupted, and “Kitchen” is effectively lost.</p></div>
|
||||
<p class="note"><strong>Restored:</strong> the shop is rebuilt into four clear category sections — Kitchen, Cleaning, Laundry, Care — and Kitchen now has its own section and standalone page.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The colour-coding concept of the product groups has been lost.
|
||||
<span class="swatches"><i class="sw" style="background:var(--kitchen)"></i><i class="sw" style="background:var(--clean)"></i><i class="sw" style="background:var(--wash)"></i><i class="sw" style="background:var(--care)"></i></span></p></div>
|
||||
<p class="note"><strong>Re-established</strong> from the brand's own group colours — Kitchen (lime), Cleaning (grapefruit), Laundry (plum), Care (orange) — as full-width banners and dividers.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The icons and name of the “Revitalization Center” do not fit the brand identity.</p></div>
|
||||
<p class="note"><strong>Section removed</strong> from the site for now, so neither the off-brand icons nor the name appear. The component is kept in reserve and can return with the correct naming whenever you want it.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The ® symbol is missing in several places and spelling should be reviewed.</p></div>
|
||||
<p class="note"><strong>Audited:</strong> ® added to every visible mention and the name hyphenated consistently as “Kaiser-Natron®”.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The Kaiser-Natron® logo should be white.</p></div>
|
||||
<p class="note"><strong>Confirmed fine:</strong> the logo renders white on green/dark surfaces and brand-green on light ones — the right behaviour in each context. Signed off as-is.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===================== UI ===================== -->
|
||||
<section class="group">
|
||||
<h2>User Interface <span class="count">6 points</span></h2>
|
||||
|
||||
<div class="item review">
|
||||
<div class="item-head"><span class="badge review">Verified</span>
|
||||
<p class="quote">Missing navigation menu in the mobile view.</p></div>
|
||||
<p class="note"><strong>Navigation is present</strong> on mobile (checked on the current build). If a specific device hid it for you, send a screenshot and we'll chase it.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The animation of Hebe is not successful, in my opinion.</p></div>
|
||||
<p class="note"><strong>Updated:</strong> the intro was reworked around the official Hebe + waterfall artwork, addressing the motion concern.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">“Bundles & Benefits”: “As a member…” — member of what? No information on how to become one or what it costs.</p></div>
|
||||
<p class="note"><strong>Membership fully removed</strong> this session — the join button, the “member price”, and all member wording are gone. Bundles now show a single price with plain bundle-value copy.</p>
|
||||
</div>
|
||||
|
||||
<div class="item partial">
|
||||
<div class="item-head"><span class="badge partial">In progress</span>
|
||||
<p class="quote">The page structure doesn't make sense: Three Classics → 250 g package → Bundles → bath image with general text. The 250 g package and bath image are positioned incorrectly.</p></div>
|
||||
<p class="note">The <strong>bath image is resolved</strong> (now powder, see above). The <strong>section re-ordering</strong> is the open part — your full note here gives us exactly what's needed, and it's queued as the next layout task.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The shop should be organized by product categories. Sport Profi is a laundry product and belongs under “Household”, not “Bathing & Care”.</p></div>
|
||||
<p class="note">The shop is <strong>organized by category</strong>, and <strong>Sport Profi is now filed under Laundry</strong> (Household), no longer under Care.</p>
|
||||
</div>
|
||||
|
||||
<div class="item open">
|
||||
<div class="item-head"><span class="badge open">Needs you</span>
|
||||
<p class="quote">Holste and Linda products have no product descriptions.</p></div>
|
||||
<p class="note">These aren't on the Kaiser-Natron® site, so the copy needs to come from you (or approve us drafting placeholders for review).</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===================== GENERAL ===================== -->
|
||||
<section class="group">
|
||||
<h2>General & Legal <span class="count">7 points</span></h2>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">“The Original from Austria.” In my opinion this is not accurate.</p></div>
|
||||
<p class="note"><strong>Removed:</strong> the “Original from Austria” claim is deleted from the footer tagline (DE + EN). The tagline now reads simply about pure natron for the kitchen, home and care.</p>
|
||||
</div>
|
||||
|
||||
<div class="item open">
|
||||
<div class="item-head"><span class="badge open">Needs you</span>
|
||||
<p class="quote">Terms & Conditions (AGB) are missing.</p></div>
|
||||
<p class="note">Page structure can be scaffolded immediately; the legal text must come from you.</p>
|
||||
</div>
|
||||
|
||||
<div class="item open">
|
||||
<div class="item-head"><span class="badge open">Needs you</span>
|
||||
<p class="quote">Withdrawal / Right of Cancellation is missing. A cancellation button has been mandatory since June 2026.</p></div>
|
||||
<p class="note">We can build the <strong>“Vertrag kündigen” button + flow</strong> now with placeholder text; the binding legal wording comes from you.</p>
|
||||
</div>
|
||||
|
||||
<div class="item open">
|
||||
<div class="item-head"><span class="badge open">Needs you</span>
|
||||
<p class="quote">Shipping information is missing.</p></div>
|
||||
<p class="note">Needs your shipping terms; we'll place them in checkout and a dedicated page.</p>
|
||||
</div>
|
||||
|
||||
<div class="item open">
|
||||
<div class="item-head"><span class="badge open">Needs you</span>
|
||||
<p class="quote">Delivery costs are missing.</p></div>
|
||||
<p class="note">Needs your rates (flat / tiered / free-over-threshold) to display in cart and checkout.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">Payment options are missing.</p></div>
|
||||
<p class="note"><strong>Not missing</strong> — payment options are already present on the site, so no change is needed here.</p>
|
||||
</div>
|
||||
|
||||
<div class="item open">
|
||||
<div class="item-head"><span class="badge open">Needs you</span>
|
||||
<p class="quote">Transparency: the site appears to present itself as the official manufacturer while the imprint says otherwise — this may confuse customers.</p></div>
|
||||
<p class="note">This is a positioning decision for you (official manufacturer vs. reseller). Once decided, we'll make the framing consistent across the site and imprint.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="foot">
|
||||
<span>Kaiser-Natron® — brand review implementation status</span>
|
||||
<span>18 done · 2 kept · 2 in progress · 6 awaiting input</span>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
861
public/dev-doc/index.html
Normal file
861
public/dev-doc/index.html
Normal file
@@ -0,0 +1,861 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Kaiser-Natron® — Restyle Change Log (Developer Handoff)</title>
|
||||
<style>
|
||||
:root {
|
||||
--brand: #006548;
|
||||
--brand-soft: #4a9079;
|
||||
--crimson: #cc0230;
|
||||
--mint: #6eceb2;
|
||||
--gold: #e9c84b;
|
||||
--ink: #0a2c20;
|
||||
--muted: #5c7a6f;
|
||||
--paper: #ffffff;
|
||||
--cream: #f4f7f4;
|
||||
--line: #d9e4df;
|
||||
--kitchen: #c6d47d;
|
||||
--clean: #eb5a61;
|
||||
--wash: #c15a7e;
|
||||
--care: #f1864c;
|
||||
--done: #006548;
|
||||
--partial: #d98a1f;
|
||||
--open: #cc0230;
|
||||
--review: #6b7f8c;
|
||||
--serif: 'Zeitung', 'Iowan Old Style', 'Palatino', Georgia, serif;
|
||||
--sans: 'Zeitung', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
|
||||
--mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, monospace;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
html { -webkit-font-smoothing: antialiased; scroll-behavior: smooth; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--sans);
|
||||
color: var(--ink);
|
||||
background: var(--cream);
|
||||
line-height: 1.55;
|
||||
}
|
||||
.wrap { max-width: 920px; margin: 0 auto; padding: 0 24px 80px; }
|
||||
|
||||
/* ---- Header ---- */
|
||||
header.hero {
|
||||
background: var(--brand);
|
||||
color: #fff;
|
||||
padding: 56px 24px 64px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
header.hero::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0; right: 0; bottom: -1px;
|
||||
height: 64px;
|
||||
background: var(--cream);
|
||||
clip-path: polygon(0 100%, 100% 100%, 100% 38%);
|
||||
}
|
||||
.hero-inner { max-width: 920px; margin: 0 auto; position: relative; z-index: 1; }
|
||||
.eyebrow {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .22em;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--mint);
|
||||
margin: 0 0 14px;
|
||||
}
|
||||
h1 {
|
||||
font-family: var(--serif);
|
||||
font-weight: 600;
|
||||
font-size: clamp(30px, 5vw, 46px);
|
||||
line-height: 1.05;
|
||||
margin: 0 0 14px;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
h1 em { font-style: italic; font-weight: 300; color: var(--mint); }
|
||||
.hero p { max-width: 62ch; color: rgba(255,255,255,.85); margin: 0; font-size: 16px; }
|
||||
.meta { margin-top: 22px; font-size: 13px; color: rgba(255,255,255,.7); }
|
||||
.meta code { background: rgba(255,255,255,.14); padding: 1px 7px; border-radius: 5px; font-family: var(--mono); font-size: 12px; }
|
||||
|
||||
/* ---- Intro / how to read ---- */
|
||||
.intro {
|
||||
background: var(--paper);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 12px;
|
||||
padding: 22px 24px;
|
||||
margin: -34px 0 34px;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
box-shadow: 0 10px 30px rgba(0,101,72,.07);
|
||||
font-size: 14.5px;
|
||||
}
|
||||
.intro p { margin: 0 0 12px; }
|
||||
.intro p:last-child { margin-bottom: 0; }
|
||||
.intro code { background: var(--cream); padding: 1px 6px; border-radius: 5px; font-family: var(--mono); font-size: .9em; color: var(--brand); }
|
||||
|
||||
/* ---- Contents nav ---- */
|
||||
.nav-block { margin: 0 0 38px; }
|
||||
.nav-block h2 {
|
||||
font-family: var(--serif);
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 14px;
|
||||
color: var(--ink);
|
||||
}
|
||||
.nav-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 8px 16px;
|
||||
}
|
||||
.nav-grid a {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 9px;
|
||||
font-size: 13px;
|
||||
text-decoration: none;
|
||||
color: var(--ink);
|
||||
padding: 6px 10px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
background: var(--paper);
|
||||
transition: border-color .15s, background .15s;
|
||||
}
|
||||
.nav-grid a:hover { border-color: var(--brand-soft); background: #fbfdfc; }
|
||||
.nav-grid a .n {
|
||||
flex: none;
|
||||
font-family: var(--serif);
|
||||
font-weight: 700;
|
||||
color: var(--brand);
|
||||
font-size: 12.5px;
|
||||
min-width: 26px;
|
||||
}
|
||||
.nav-grid a.qref { grid-column: 1 / -1; border-left: 3px solid var(--crimson); }
|
||||
.nav-grid a.qref .n { color: var(--crimson); }
|
||||
|
||||
/* ---- Item card ---- */
|
||||
.item {
|
||||
background: var(--paper);
|
||||
border: 1px solid var(--line);
|
||||
border-left-width: 5px;
|
||||
border-left-color: var(--brand);
|
||||
border-radius: 10px;
|
||||
padding: 20px 22px 22px;
|
||||
margin-bottom: 18px;
|
||||
box-shadow: 0 10px 30px rgba(0,101,72,.05);
|
||||
}
|
||||
.item-head { display: flex; align-items: center; gap: 14px; margin-bottom: 6px; }
|
||||
.secnum {
|
||||
flex: none;
|
||||
width: 42px; height: 42px;
|
||||
border-radius: 50%;
|
||||
background: var(--brand);
|
||||
color: #fff;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: var(--serif);
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
box-shadow: 0 4px 12px rgba(0,101,72,.22);
|
||||
}
|
||||
.item-head h3 {
|
||||
font-family: var(--serif);
|
||||
font-weight: 600;
|
||||
font-size: 21px;
|
||||
line-height: 1.15;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ---- File chips ---- */
|
||||
.files { display: flex; flex-wrap: wrap; gap: 7px; margin: 8px 0 16px; }
|
||||
.file-chip {
|
||||
font-family: var(--mono);
|
||||
font-size: 11.5px;
|
||||
background: var(--cream);
|
||||
border: 1px solid var(--line);
|
||||
color: var(--muted);
|
||||
padding: 3px 9px;
|
||||
border-radius: 6px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* ---- Body content ---- */
|
||||
.body { font-size: 14.5px; }
|
||||
.body p { margin: 0 0 12px; }
|
||||
.body ul { margin: 0 0 14px; padding-left: 22px; }
|
||||
.body li { margin: 0 0 6px; }
|
||||
.body li::marker { color: var(--brand-soft); }
|
||||
.body strong { color: var(--brand); font-weight: 600; }
|
||||
.body em { font-style: italic; }
|
||||
.body code {
|
||||
font-family: var(--mono);
|
||||
font-size: .88em;
|
||||
background: var(--cream);
|
||||
border: 1px solid var(--line);
|
||||
padding: 1px 5px;
|
||||
border-radius: 5px;
|
||||
color: var(--ink);
|
||||
}
|
||||
.body h4 {
|
||||
font-family: var(--serif);
|
||||
font-size: 15.5px;
|
||||
font-weight: 600;
|
||||
margin: 18px 0 8px;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
/* ---- code blocks ---- */
|
||||
pre {
|
||||
background: #06231a;
|
||||
color: #d8efe6;
|
||||
border-radius: 10px;
|
||||
padding: 14px 16px;
|
||||
overflow-x: auto;
|
||||
font-family: var(--mono);
|
||||
font-size: 12.5px;
|
||||
line-height: 1.5;
|
||||
margin: 0 0 14px;
|
||||
}
|
||||
pre code { all: unset; font-family: var(--mono); white-space: pre; }
|
||||
|
||||
/* ---- tables ---- */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 4px 0 16px;
|
||||
font-size: 13.5px;
|
||||
}
|
||||
th {
|
||||
text-align: left;
|
||||
background: var(--cream);
|
||||
color: var(--brand);
|
||||
font-weight: 600;
|
||||
padding: 9px 12px;
|
||||
border: 1px solid var(--line);
|
||||
font-size: 12.5px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .03em;
|
||||
}
|
||||
td {
|
||||
padding: 9px 12px;
|
||||
border: 1px solid var(--line);
|
||||
vertical-align: top;
|
||||
}
|
||||
tr:nth-child(even) td { background: #fbfdfc; }
|
||||
td code, th code { font-family: var(--mono); font-size: .9em; background: rgba(0,101,72,.06); padding: 1px 5px; border-radius: 4px; }
|
||||
|
||||
/* ---- callouts ---- */
|
||||
.callout {
|
||||
border-radius: 10px;
|
||||
padding: 13px 16px 13px 16px;
|
||||
margin: 0 0 14px;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
gap: 11px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.callout .ico { flex: none; font-size: 16px; line-height: 1.4; }
|
||||
.callout p { margin: 0; }
|
||||
.callout.warn { background: rgba(217,138,31,.10); border: 1px solid rgba(217,138,31,.32); border-left: 4px solid var(--partial); }
|
||||
.callout.warn strong { color: #9a6212; }
|
||||
.callout.info { background: rgba(110,206,178,.12); border: 1px solid rgba(0,101,72,.22); border-left: 4px solid var(--brand); }
|
||||
.callout.info strong { color: var(--brand); }
|
||||
|
||||
/* ---- colour swatches ---- */
|
||||
.swrow { display: flex; flex-wrap: wrap; gap: 12px; margin: 4px 0 16px; }
|
||||
.swcard {
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 9px;
|
||||
padding: 8px 12px 8px 8px;
|
||||
background: var(--paper);
|
||||
font-size: 13px;
|
||||
}
|
||||
.swbox {
|
||||
width: 34px; height: 34px;
|
||||
border-radius: 7px;
|
||||
flex: none;
|
||||
border: 1px solid rgba(0,0,0,.10);
|
||||
}
|
||||
.swcard .hex { font-family: var(--mono); font-size: 12px; color: var(--muted); display: block; }
|
||||
.swcard .role { font-weight: 600; color: var(--ink); display: block; }
|
||||
.swinline { display: inline-block; width: 12px; height: 12px; border-radius: 3px; vertical-align: middle; border: 1px solid rgba(0,0,0,.12); margin-right: 4px; }
|
||||
|
||||
footer.foot {
|
||||
margin-top: 48px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid var(--line);
|
||||
font-size: 12.5px;
|
||||
color: var(--muted);
|
||||
display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.nav-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
@media print {
|
||||
html { scroll-behavior: auto; }
|
||||
body { background: #fff; }
|
||||
.item, .intro { box-shadow: none; }
|
||||
header.hero { padding-bottom: 48px; }
|
||||
.item { break-inside: avoid; }
|
||||
pre, table { break-inside: avoid; }
|
||||
.nav-block { break-inside: avoid; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="hero">
|
||||
<div class="hero-inner">
|
||||
<p class="eyebrow">Developer Handoff · Restyle Change Log</p>
|
||||
<h1>Kaiser-Natron<sup>®</sup> restyle —<br><em>every change, documented</em></h1>
|
||||
<p>A plain-language summary of every visual change in this restyle pass — the exact file, what changed, and the CSS / Tailwind classes involved. Organised by theme so you can review one concern at a time.</p>
|
||||
<p class="meta">Updated 24 June 2026 · Branch <code>feat/shop-category-sections</code> · 27 changes</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
<div class="intro">
|
||||
<p>The design system is <strong>token-driven</strong>: colours, fonts, and sizes live as CSS custom properties in <code>src/design-system/tokens.css</code> (consumed by Tailwind v4 via <code>@theme</code>). Most colour changes happen there once and cascade everywhere.</p>
|
||||
<p>This log records only the <strong>latest final state</strong> of each item — the file, what it is now, and the token/class — not the iterations it took to get there.</p>
|
||||
</div>
|
||||
|
||||
<!-- ===================== CONTENTS ===================== -->
|
||||
<nav class="nav-block">
|
||||
<h2>Contents</h2>
|
||||
<div class="nav-grid">
|
||||
<a href="#s1"><span class="n">§1</span> New brand colours (design tokens)</a>
|
||||
<a href="#s2"><span class="n">§2</span> Pages are pure white</a>
|
||||
<a href="#s3"><span class="n">§3</span> Typeface → Zeitung (self-hosted)</a>
|
||||
<a href="#s4"><span class="n">§4</span> Buttons</a>
|
||||
<a href="#s5"><span class="n">§5</span> Hero call-to-action buttons</a>
|
||||
<a href="#s6"><span class="n">§6</span> "Add to cart" buttons are crimson</a>
|
||||
<a href="#s7"><span class="n">§7</span> Cart checkout button is crimson</a>
|
||||
<a href="#s8"><span class="n">§8</span> Other solid pills/chips → crimson</a>
|
||||
<a href="#s9"><span class="n">§9</span> Mint highlight on nav tabs & footer links</a>
|
||||
<a href="#s10"><span class="n">§10</span> Yellow highlight removed from hero text</a>
|
||||
<a href="#s11"><span class="n">§11</span> Section dividers: wave → diagonal</a>
|
||||
<a href="#s12"><span class="n">§12</span> Search dropdown prices → white</a>
|
||||
<a href="#s13"><span class="n">§13</span> Brand-hero intro artwork → official assets</a>
|
||||
<a href="#s14"><span class="n">§14</span> 250 g Großpackung box recoloured</a>
|
||||
<a href="#s15"><span class="n">§15</span> Design-system docs page</a>
|
||||
<a href="#s16"><span class="n">§16</span> Brand name — ® + hyphenation pass</a>
|
||||
<a href="#s17"><span class="n">§17</span> Hero headline copy — versatility</a>
|
||||
<a href="#s18"><span class="n">§18</span> Bundle artwork — "AI Edited" disclosure</a>
|
||||
<a href="#s19"><span class="n">§19</span> Revitalization — animation row + CTA removed</a>
|
||||
<a href="#s20"><span class="n">§20</span> Shop category banners + colours + Küche</a>
|
||||
<a href="#s21"><span class="n">§21</span> Category pages wired up + naming aligned</a>
|
||||
<a href="#s22"><span class="n">§22</span> Membership removed — bundles single-price</a>
|
||||
<a href="#s23"><span class="n">§23</span> Second-fold banner image — powder</a>
|
||||
<a href="#s24"><span class="n">§24</span> Revitalization removed from homepage</a>
|
||||
<a href="#s25"><span class="n">§25</span> Sport-Profi recategorised to Laundry</a>
|
||||
<a href="#s26"><span class="n">§26</span> "Das Original aus Österreich" removed</a>
|
||||
<a href="#s27"><span class="n">§27</span> Shop hero — category jump-buttons + gap removed</a>
|
||||
<a href="#qref" class="qref"><span class="n">★</span> Quick reference — the two new colours</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- ===================== §1 ===================== -->
|
||||
<div class="item" id="s1">
|
||||
<div class="item-head"><span class="secnum">§1</span><h3>New brand colours (design tokens)</h3></div>
|
||||
<div class="files"><span class="file-chip">src/design-system/tokens.css</span></div>
|
||||
<div class="body">
|
||||
<p>Two new colours were introduced and two existing ones repurposed.</p>
|
||||
<table>
|
||||
<thead><tr><th>Token</th><th>Value</th><th>Meaning</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td><code>--color-accent-fill</code></td><td><span class="swinline" style="background:#cc0230"></span><code>#cc0230</code></td><td>Crimson — the new fill for all solid CTA buttons, pills and chips</td></tr>
|
||||
<tr><td><code>--color-accent-fill-hover</code></td><td><code>oklch(accent-fill − 12% black)</code></td><td>Darker crimson for hover</td></tr>
|
||||
<tr><td><code>--color-accent-fill-ink</code></td><td><span class="swinline" style="background:#ffffff"></span><code>#ffffff</code></td><td>White — the text/icon colour that sits on crimson</td></tr>
|
||||
<tr><td><code>--color-highlight</code></td><td><span class="swinline" style="background:#6eceb2"></span><code>#6eceb2</code></td><td>Mint — hover/active state for nav tabs and footer links</td></tr>
|
||||
<tr><td><code>--color-accent</code></td><td><span class="swinline" style="background:#e9c84b"></span><code>#e9c84b</code> (unchanged)</td><td>Old warm yellow — now only used as the token behind a few non-button accents</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<pre><code>/* tokens.css — added */
|
||||
--color-accent-fill: #cc0230;
|
||||
--color-accent-fill-hover: color-mix(in oklch, var(--color-accent-fill), black 12%);
|
||||
--color-accent-fill-ink: #ffffff;
|
||||
|
||||
--color-highlight: #6eceb2;</code></pre>
|
||||
<p>Because these are registered in <code>@theme</code>, Tailwind auto-generates the utility classes <code>bg-accent-fill</code>, <code>text-accent-fill-ink</code>, <code>border-accent-fill</code>, <code>hover:bg-accent-fill-hover</code>, and <code>text-highlight</code> / <code>hover:text-highlight</code>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §2 ===================== -->
|
||||
<div class="item" id="s2">
|
||||
<div class="item-head"><span class="secnum">§2</span><h3>Pages are pure white</h3></div>
|
||||
<div class="files"><span class="file-chip">src/design-system/tokens.css</span><span class="file-chip">index.html</span></div>
|
||||
<div class="body">
|
||||
<p>The two off-white page surfaces were set to pure white. Everything that paints a page background (<code>bg-cream</code>, <code>bg-surface</code>) and the cream-coloured logo (<code>text-cream</code>) followed automatically.</p>
|
||||
<pre><code>/* before → after */
|
||||
--color-cream: #f4efe4; → #ffffff;
|
||||
--color-surface: #faf7f1; → #ffffff;</code></pre>
|
||||
<p><code>index.html</code> — the browser theme colour was matched to white:</p>
|
||||
<pre><code><meta name="theme-color" content="#ffffff" /> <!-- was #faf7f1 --></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §3 ===================== -->
|
||||
<div class="item" id="s3">
|
||||
<div class="item-head"><span class="secnum">§3</span><h3>Typeface → Zeitung (self-hosted)</h3></div>
|
||||
<div class="files"><span class="file-chip">src/design-system/tokens.css</span><span class="file-chip">src/assets/styles.css</span><span class="file-chip">src/assets/fonts/</span><span class="file-chip">index.html</span></div>
|
||||
<div class="body">
|
||||
<p>All text now uses <strong>Zeitung</strong>, self-hosted (no external font CDN). The licensed <code>.woff2</code> files were mirrored from the production site into <code>src/assets/fonts/</code> (Regular 400 + Bold 700 — the only two weights that exist; the browser synthesises intermediate weights and there are no italics).</p>
|
||||
<pre><code>/* tokens.css */
|
||||
--font-serif: 'Zeitung', ui-sans-serif, system-ui, -apple-system, Arial, sans-serif;
|
||||
--font-sans: 'Zeitung', ui-sans-serif, system-ui, -apple-system, Arial, sans-serif;</code></pre>
|
||||
<pre><code>/* styles.css — added @font-face */
|
||||
@font-face { font-family:'Zeitung'; font-weight:400; font-display:swap;
|
||||
src:url('./fonts/Zeitung-Regular.woff2') format('woff2'); }
|
||||
@font-face { font-family:'Zeitung'; font-weight:700; font-display:swap;
|
||||
src:url('./fonts/Zeitung-Bold.woff2') format('woff2'); }</code></pre>
|
||||
<p><code>index.html</code> — the Google Fonts <code><link></code> (Fraunces + DM Sans) and its <code>preconnect</code> hints were <strong>removed</strong>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §4 ===================== -->
|
||||
<div class="item" id="s4">
|
||||
<div class="item-head"><span class="secnum">§4</span><h3>Buttons</h3></div>
|
||||
<div class="files"><span class="file-chip">src/design-system/components/Button.vue</span></div>
|
||||
<div class="body">
|
||||
<p><code>Button.vue</code> is the single source of truth for buttons. Variants are picked with <code><Button variant="…"></code>.</p>
|
||||
<h4>4a. Text style — uppercase, 14px</h4>
|
||||
<pre><code>// base string — added `uppercase`
|
||||
'... font-sans font-semibold uppercase ...'
|
||||
|
||||
// sizes — text set to 14px across the board
|
||||
sm: 'text-[14px] px-[18px] py-[9px] tracking-label',
|
||||
md: 'text-[14px] px-[26px] py-[13px] tracking-label',
|
||||
lg: 'text-[14px] px-[34px] py-[17px] tracking-label',</code></pre>
|
||||
<h4>4b. Variant colours</h4>
|
||||
<table>
|
||||
<thead><tr><th>Variant</th><th>Before</th><th>After</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td><code>primary</code> (green button)</td><td>green fill, <strong>yellow</strong> text</td><td>green fill, <strong>white</strong> text — <code>bg-brand text-white border-brand</code></td></tr>
|
||||
<tr><td><code>accent</code> (main CTA)</td><td>yellow fill, green text</td><td><strong>crimson</strong> fill, white text — <code>bg-accent-fill text-accent-fill-ink border-accent-fill</code></td></tr>
|
||||
<tr><td><code>secondary</code></td><td>outline</td><td><strong>crimson</strong> fill, white text (same as accent)</td></tr>
|
||||
<tr><td><code>ghost</code> / <code>danger</code></td><td>unchanged</td><td>unchanged</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="callout info"><span class="ico">ℹ️</span><p><strong>Note:</strong> <code>secondary</code> and <code>accent</code> are currently identical (both crimson). The Hero's "Learn more" secondary CTA (rendered inline, see §5) was matched to the same crimson fill.</p></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §5 ===================== -->
|
||||
<div class="item" id="s5">
|
||||
<div class="item-head"><span class="secnum">§5</span><h3>Hero call-to-action buttons</h3></div>
|
||||
<div class="files"><span class="file-chip">src/design-system/components/Hero.vue</span></div>
|
||||
<div class="body">
|
||||
<p>The Hero renders its <strong>secondary</strong> CTA inline (not via <code><Button></code>), so it has to be styled directly. On brand-green heroes it is now crimson fill + white text, uppercase, 14px:</p>
|
||||
<pre><code>class="… rounded-pill border border-accent-fill bg-accent-fill px-[34px] py-[17px]
|
||||
text-[14px] font-semibold uppercase tracking-label text-accent-fill-ink
|
||||
transition-colors duration-base hover:bg-accent-fill-hover"</code></pre>
|
||||
<p>The Hero's <strong>primary</strong> CTA already uses the <code>accent</code> variant on green surfaces, so it's crimson too.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §6 ===================== -->
|
||||
<div class="item" id="s6">
|
||||
<div class="item-head"><span class="secnum">§6</span><h3>"Add to cart" buttons are crimson</h3></div>
|
||||
<div class="files"><span class="file-chip">src/design-system/components/ProductCard.vue</span><span class="file-chip">src/design-system/components/BundleCard.vue</span><span class="file-chip">src/pages/ShopPage.vue</span><span class="file-chip">src/pages/ProductPage.vue</span><span class="file-chip">src/pages/BundlePage.vue</span></div>
|
||||
<div class="body">
|
||||
<p>Every add-to-cart button is now the crimson <code>accent</code> variant.</p>
|
||||
<table>
|
||||
<thead><tr><th>File</th><th>Change</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td><code>ProductCard.vue</code></td><td><code>ctaVariant</code> prop default <code>'primary'</code> → <code>'accent'</code></td></tr>
|
||||
<tr><td><code>BundleCard.vue</code></td><td>add-to-cart <code><Button></code> <code>variant="primary"</code> → <code>"accent"</code></td></tr>
|
||||
<tr><td><code>ShopPage.vue</code></td><td>product grid <code>:cta-variant="… 'accent' : 'primary'"</code> → <code>cta-variant="accent"</code> (no more alternating)</td></tr>
|
||||
<tr><td><code>ProductPage.vue</code></td><td>main add-to-cart already <code>accent</code> (unchanged)</td></tr>
|
||||
<tr><td><code>BundlePage.vue</code></td><td>add-to-cart already <code>accent</code> (unchanged)</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §7 ===================== -->
|
||||
<div class="item" id="s7">
|
||||
<div class="item-head"><span class="secnum">§7</span><h3>Cart checkout button is crimson</h3></div>
|
||||
<div class="files"><span class="file-chip">src/design-system/components/CartDrawer.vue</span></div>
|
||||
<div class="body">
|
||||
<pre><code><!-- checkout button -->
|
||||
<Button variant="accent" …> <!-- was variant="primary" --></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §8 ===================== -->
|
||||
<div class="item" id="s8">
|
||||
<div class="item-head"><span class="secnum">§8</span><h3>Other solid pills/chips → crimson + white</h3></div>
|
||||
<div class="files"><span class="file-chip">IconButton.vue</span><span class="file-chip">LanguageSwitcher.vue</span><span class="file-chip">Navbar.vue</span><span class="file-chip">Kaiserhacks.vue</span><span class="file-chip">Badge.vue</span><span class="file-chip">About.vue</span></div>
|
||||
<div class="body">
|
||||
<p>All previously-yellow solid fills now use the crimson token pair <code>bg-accent-fill</code> + <code>text-accent-fill-ink</code>.</p>
|
||||
<table>
|
||||
<thead><tr><th>File</th><th>Element</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td><code>IconButton.vue</code></td><td><code>accent</code> variant (cart icon button)</td></tr>
|
||||
<tr><td><code>LanguageSwitcher.vue</code></td><td>active language pill (all 3 tones)</td></tr>
|
||||
<tr><td><code>Navbar.vue</code></td><td>mobile cart CTA pill</td></tr>
|
||||
<tr><td><code>Kaiserhacks.vue</code></td><td>video play chip</td></tr>
|
||||
<tr><td><code>Badge.vue</code></td><td><code>accent</code> badge variant</td></tr>
|
||||
<tr><td><code>About.vue</code></td><td>"HISTORY & SCIENCE" eyebrow (<code>Badge variant="brand"</code> → <code>"accent"</code>) and the "TODAY" timeline pill (<code>.pill-accent</code> CSS now crimson + white)</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<pre><code>/* About.vue — .pill-accent (the "TODAY" pill) */
|
||||
.pill-accent {
|
||||
background: var(--color-accent-fill);
|
||||
color: var(--color-accent-fill-ink);
|
||||
border-color: var(--color-accent-fill);
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §9 ===================== -->
|
||||
<div class="item" id="s9">
|
||||
<div class="item-head"><span class="secnum">§9</span><h3>Mint highlight on nav tabs & footer links</h3></div>
|
||||
<div class="files"><span class="file-chip">src/design-system/components/Navbar.vue</span><span class="file-chip">src/design-system/components/Footer.vue</span></div>
|
||||
<div class="body">
|
||||
<p>The hover/active highlight on the brand-green navbar (and the brand footer links) changed from yellow to mint via the new <code>--color-highlight</code> token:</p>
|
||||
<pre><code>text-accent → text-highlight (active nav tab)
|
||||
hover:text-accent → hover:text-highlight (nav tab + footer link hover)</code></pre>
|
||||
<div class="callout info"><span class="ico">ℹ️</span><p><strong>Not changed:</strong> the mobile cart-count number badge (<code>Navbar.vue</code>, a green circle with a count) is still yellow — it's a count indicator, not a tab highlight. Easy to switch if wanted.</p></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §10 ===================== -->
|
||||
<div class="item" id="s10">
|
||||
<div class="item-head"><span class="secnum">§10</span><h3>Yellow "highlight" removed from hero text & titles</h3></div>
|
||||
<div class="files"><span class="file-chip">src/pages/HomePage.vue</span><span class="file-chip">CategoryPage.vue</span><span class="file-chip">ProductPage.vue</span><span class="file-chip">ShopPage.vue</span><span class="file-chip">BrandHero.vue</span><span class="file-chip">Revitalization.vue</span><span class="file-chip">Kaiserhacks.vue</span></div>
|
||||
<div class="body">
|
||||
<p>The italic emphasis words inside hero/section headlines, and the small eyebrow labels above them, were yellow. They now match the surrounding white hero text.</p>
|
||||
<table>
|
||||
<thead><tr><th>File</th><th>Change</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td><code>HomePage.vue</code>, <code>CategoryPage.vue</code>, <code>ProductPage.vue</code>, <code>ShopPage.vue</code></td><td>headline <code><em></code> emphasis: <code>text-accent-soft</code> → <code>text-cream</code></td></tr>
|
||||
<tr><td><code>BrandHero.vue</code>, <code>Revitalization.vue</code></td><td>same emphasis swap</td></tr>
|
||||
<tr><td><code>CategoryPage.vue</code>, <code>ShopPage.vue</code>, <code>Kaiserhacks.vue</code></td><td>hero eyebrows: <code>text-accent</code> → <code>text-cream/75</code></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>(<code>--color-cream</code> is now <code>#ffffff</code>, so these read as white on the green heroes.)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §11 ===================== -->
|
||||
<div class="item" id="s11">
|
||||
<div class="item-head"><span class="secnum">§11</span><h3>Section dividers: wave → diagonal</h3></div>
|
||||
<div class="files"><span class="file-chip">src/design-system/components/WaveDivider.vue</span><span class="file-chip">src/pages/HomePage.vue</span><span class="file-chip">src/design-system/components/Kaiserhacks.vue</span></div>
|
||||
<div class="body">
|
||||
<p>The soft S-curve between coloured sections became a <strong>straight diagonal</strong> that sits <strong>low on the left, high on the right</strong>, and the divider band was <strong>doubled in height</strong> so the slope is roughly twice as steep.</p>
|
||||
<pre><code>height: h-12 md:h-16 → h-24 md:h-32 (48/64px → 96/128px)
|
||||
viewBox: 0 0 1440 64 → 0 0 1440 128
|
||||
path: (cubic-bézier wave) → M0,0 L0,116 L1440,12 L1440,0 Z</code></pre>
|
||||
<p>The seam-free construction is unchanged: a full-height <code><rect></code> paints the <em>lower</em> section colour and the <code><path></code> paints the <em>upper</em> section colour.</p>
|
||||
<p>The same diagonal divider also sits between the <strong>Kaiserhacks</strong> green header and the white body below it: <code>Kaiserhacks.vue</code> imports <code>WaveDivider</code> and renders <code><WaveDivider from="brand" to="surface" /></code> between the <code>bg-brand</code> header and the content <code><div></code> (which gains <code>-mt-px</code> to sit flush).</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §12 ===================== -->
|
||||
<div class="item" id="s12">
|
||||
<div class="item-head"><span class="secnum">§12</span><h3>Search dropdown prices → white (on green)</h3></div>
|
||||
<div class="files"><span class="file-chip">src/design-system/components/Search.vue</span></div>
|
||||
<div class="body">
|
||||
<p>In the search overlay, the price labels on the brand-green tone were yellow. They are now white to match the rest of the green-surface text:</p>
|
||||
<pre><code>// brand tone
|
||||
price: 'text-accent' → 'text-cream' // (#ffffff on green)</code></pre>
|
||||
<p>The <code>paper</code> and <code>cream</code> tones keep <code>text-brand</code> (unchanged).</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §13 ===================== -->
|
||||
<div class="item" id="s13">
|
||||
<div class="item-head"><span class="secnum">§13</span><h3>Brand-hero intro artwork → official brand assets</h3></div>
|
||||
<div class="files"><span class="file-chip">src/design-system/components/BrandHero.vue</span><span class="file-chip">src/components/heroFigures.js</span><span class="file-chip">src/assets/brand/{hebe,waterfall}.svg</span></div>
|
||||
<div class="body">
|
||||
<p>The home-page intro animation (the in-flow figure entrance — the full-screen <code>SplashIntro</code> overlay was already retired) previously used hand-traced approximations of the woman + waterfall. It now uses the <strong>official Kaiser-Natron brand vectors</strong>: the Ikone ("Hebe") and the Waterfall (2021 Druckdaten-Final), converted from EPS to SVG.</p>
|
||||
<ul>
|
||||
<li><strong>Source SVGs</strong> live in <code>src/assets/brand/</code> for provenance; the extracted path data lives in <code>src/components/heroFigures.js</code> (<code>ladyMint</code>, <code>ladyWhite</code>, <code>waterfall</code>).</li>
|
||||
<li><strong>Dark outline removed</strong> — the brand icon's <code>#006648</code> outline tone is dropped; the figures render as flat mint silhouettes, matching the established splash aesthetic. Mint tones: lady <code>#72c1ad</code>, waterfall <code>#6eceb2</code>; natron handful <code>#ffffff</code>.</li>
|
||||
<li><strong>Composition</strong> — shared <code>0 0 2760 3624</code> viewBox: the lady at the origin (native 1828×3624), the waterfall <strong>half-scale</strong> (<code>scale(0.5)</code>) to her right and <strong>vertically centred</strong> against her (<code>translate(1793,1310)</code>).</li>
|
||||
<li><strong>Animation unchanged</strong> — same choreography/timing: lady slides in from the left (<code>left-m</code>), waterfall from the right (<code>right-m</code>), the white natron fades in once she's landed (<code>mound-m</code>), tagline + SINCE 1881 last; same edge-feather mask and reduced-motion handling.</li>
|
||||
</ul>
|
||||
<div class="callout info"><span class="ico">ℹ️</span><p><strong>Side effect:</strong> the home-page chunk shrank ~214 KB → ~70 KB because the new <code>heroFigures.js</code> (~57 KB) replaces the much larger traced <code>splashPaths.js</code> import. <code>splashPaths.js</code> / <code>SplashIntro.vue</code> remain only as unused legacy.</p></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §14 ===================== -->
|
||||
<div class="item" id="s14">
|
||||
<div class="item-head"><span class="secnum">§14</span><h3>Product image — 250 g Großpackung box recoloured</h3></div>
|
||||
<div class="files"><span class="file-chip">public/products/kaiser-natron-pulver-250-g-grosspackung.webp</span><span class="file-chip">dist/products/…</span></div>
|
||||
<div class="body">
|
||||
<p>The 250 g box product shot had a muted, grey/pine green that didn't match the brighter brand green of the other Kaiser-Natron powder packs (e.g. the 50 g sachet <code>public/products/kaiser-natron-pulver-50-g-beutel.webp</code>). It was replaced with an updated box render carrying the correct vivid brand green (the dark-green 3-D side panels and the red bottom band are intact).</p>
|
||||
<ul>
|
||||
<li><strong>Where product images live:</strong> <code>public/products/*.webp</code> (served as static assets; the build mirrors them to <code>dist/products/*.webp</code>). Convention: <strong>transparent RGBA, ~1200 px tall</strong>.</li>
|
||||
<li>The replacement was supplied as a 939×1200 transparent PNG and saved straight to WebP (<code>quality 92</code>, no scaling needed — already matching the original dimensions), so edges/text stay crisp.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §15 ===================== -->
|
||||
<div class="item" id="s15">
|
||||
<div class="item-head"><span class="secnum">§15</span><h3>Design-system docs page</h3></div>
|
||||
<div class="files"><span class="file-chip">src/pages/design/ColorsSection.vue</span></div>
|
||||
<div class="body">
|
||||
<p>The new <code>accent-fill</code>, <code>accent-fill-hover</code>, <code>accent-fill-ink</code> tokens were added to the colour-swatch reference so the in-app design-system page stays accurate.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §16 ===================== -->
|
||||
<div class="item" id="s16">
|
||||
<div class="item-head"><span class="secnum">§16</span><h3>Brand name — ® trademark + hyphenation pass</h3></div>
|
||||
<div class="files"><span class="file-chip">src/i18n/messages.js</span><span class="file-chip">src/api/products.js</span><span class="file-chip">src/design-system/components/Logo.vue</span><span class="file-chip">src/design-system/components/Navbar.vue</span></div>
|
||||
<div class="body">
|
||||
<p>The brand name is now written <strong>Kaiser-Natron®</strong> consistently — hyphenated, with the ® mark — on every visible mention. Two problems were fixed:</p>
|
||||
<ul>
|
||||
<li><strong>Missing ®</strong> — display headlines, CTAs, the bundle line-item lists and the product <code>brand</code> field carried no trademark mark. (The long Kaiserhacks recipe copy and the product <code>title</code> fields already had <code>Kaiser-Natron®</code> and were left as-is.)</li>
|
||||
<li><strong>Spelling drift</strong> — the English locale (and one German headline) used the un-hyphenated <code>Kaiser Natron</code>. All standardised to the hyphenated form.</li>
|
||||
</ul>
|
||||
<table>
|
||||
<thead><tr><th>File</th><th>What changed</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td><code>src/i18n/messages.js</code></td><td><code>shop.headline</code>, <code>ds.hero.headline.a</code>, <code>home.banner.sub</code>, <code>home.brand.headline.a</code>, <code>home.teaser.cta</code>, and the <code>bundle.*.items.*</code> lists — de <strong>and</strong> en — now read <code>Kaiser-Natron®</code></td></tr>
|
||||
<tr><td><code>src/api/products.js</code></td><td><code>brand: 'Kaiser-Natron'</code> → <code>'Kaiser-Natron®'</code> (all 11 products; shown in search results via <code>Search.vue</code>)</td></tr>
|
||||
<tr><td><code>src/design-system/components/Logo.vue</code></td><td>default accessible <code>title</code> prop <code>'Kaiser Natron'</code> → <code>'Kaiser-Natron®'</code></td></tr>
|
||||
<tr><td><code>src/design-system/components/Navbar.vue</code></td><td>logo link <code>aria-label</code> <code>'Kaiser Natron home'</code> → <code>'Kaiser-Natron home'</code></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="callout info"><span class="ico">ℹ️</span><p><strong>Not touched:</strong> generic ingredient references ("Natron", "Natronwasser", "Natron-basierte …") — those mean the substance, not the brand, so they take no ®. Image <code>alt</code> text keeps the plain hyphenated name (not on-screen).</p></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §17 ===================== -->
|
||||
<div class="item" id="s17">
|
||||
<div class="item-head"><span class="secnum">§17</span><h3>Hero headline copy — versatility, not "shine"</h3></div>
|
||||
<div class="files"><span class="file-chip">src/i18n/messages.js</span></div>
|
||||
<div class="body">
|
||||
<p>The product-hero headline (<code>ds.hero.headline.*</code>, de + en) was reworded from a generic cleaning-shine line to the brand's own versatility voice (drawn from kaiser-natron.de — <em>"Die Verwendungsmöglichkeiten … sind beinah grenzenlos"</em>). The three-part split (<code>a</code> / emphasised <code>em</code> / <code>b</code>) is unchanged; only the words changed.</p>
|
||||
<pre><code>DE "Kaiser-Natron® für alles was glänzen soll."
|
||||
→ "Kaiser-Natron® für fast alles im Alltag."
|
||||
|
||||
EN "Kaiser-Natron® for everything that should shine."
|
||||
→ "Kaiser-Natron® for almost anything at home."</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §18 ===================== -->
|
||||
<div class="item" id="s18">
|
||||
<div class="item-head"><span class="secnum">§18</span><h3>Bundle artwork — "AI Edited" disclosure (L5 + L6)</h3></div>
|
||||
<div class="files"><span class="file-chip">src/api/bundles.js</span><span class="file-chip">BundleCard.vue</span><span class="file-chip">Bundles.vue</span><span class="file-chip">src/pages/HomePage.vue</span><span class="file-chip">src/pages/BundlePage.vue</span></div>
|
||||
<div class="body">
|
||||
<p>The bundle images are AI-composed. Rather than replace them, each is now marked with a small, faint <strong>"AI Edited"</strong> caption in the bottom-right of the image, so the AI origin is disclosed. It's data-driven, so it disappears automatically once real photography replaces a given image.</p>
|
||||
<ul>
|
||||
<li><code>bundles.js</code> — each bundle record gains <code>aiEdited: true</code>.</li>
|
||||
<li><code>BundleCard.vue</code> — new <code>aiEdited</code> Boolean prop; when true, renders the overlay span inside the media area (both the card-link and plain-media branches).</li>
|
||||
<li><code>Bundles.vue</code> — passes <code>:ai-edited="bundle.aiEdited"</code> to all four BundleCard instances (mobile + grid + sidebar + carousel).</li>
|
||||
<li><code>HomePage.vue</code> / <code>BundlePage.vue</code> — carry <code>aiEdited</code> through to the rendered records; BundlePage renders the same overlay on its large hero image (desktop + mobile).</li>
|
||||
</ul>
|
||||
<pre><code><span class="pointer-events-none absolute bottom-0 right-0 z-[1] px-2 py-0.5
|
||||
text-[10px] font-medium uppercase tracking-label text-white/55
|
||||
drop-shadow-[0_1px_2px_rgba(0,0,0,0.45)]">AI Edited</span></code></pre>
|
||||
<div class="callout info"><span class="ico">ℹ️</span><p>Set a bundle's <code>aiEdited: false</code> (or drop it) in <code>bundles.js</code> to remove the badge once its image is a real photo.</p></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §19 ===================== -->
|
||||
<div class="item" id="s19">
|
||||
<div class="item-head"><span class="secnum">§19</span><h3>Revitalization section — animation row + CTA removed (L10)</h3></div>
|
||||
<div class="files"><span class="file-chip">src/pages/HomePage.vue</span></div>
|
||||
<div class="body">
|
||||
<p>The Revitalization section was stripped back. Removed entirely:</p>
|
||||
<ul>
|
||||
<li>the <strong>three-pillar feature row</strong> with the spinning orbit animations (the emoji icons ⚗️💊🌿 were off-brand; the brand owner wanted the whole row gone), and</li>
|
||||
<li>the <strong>"early access" CTA</strong> button (<code>revit.notifyCta</code> — "Get early access" / "Early Access sichern").</li>
|
||||
</ul>
|
||||
<p>This is done at the <strong>usage</strong> site, not the component: <code>revitCopy</code> no longer passes <code>features</code> or <code>notifyCta</code>, and the <code>:features</code> / <code>:notify-cta</code> / <code>@notify</code> bindings (and the orphaned <code>onRevitNotify</code> handler) were removed. The section now renders <strong>eyebrow + headline + sub only</strong>.</p>
|
||||
<p><code>Revitalization.vue</code> is unchanged and still reusable — its <code>v-if="features.length"</code> and <code>v-if="notifyCta"</code> guards simply render nothing when those props are absent. The unused <code>revit.feature.*</code> / <code>revit.notifyCta</code> i18n keys are left in place (harmless) in case the section is restored.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §20 ===================== -->
|
||||
<div class="item" id="s20">
|
||||
<div class="item-head"><span class="secnum">§20</span><h3>Shop page category banners + colours + Küche page (L8/U4)</h3></div>
|
||||
<div class="files"><span class="file-chip">src/design-system/tokens.css</span><span class="file-chip">Hero.vue</span><span class="file-chip">src/pages/ShopPage.vue</span><span class="file-chip">src/router/index.js</span><span class="file-chip">src/pages/CategoryPage.vue</span><span class="file-chip">src/i18n/messages.js</span></div>
|
||||
<div class="body">
|
||||
<p>On the <strong>shop page</strong>, the catalogue is split into <strong>four</strong> use-group sections, each fronted by a <strong>full-width colour banner</strong> in the brand's own use-group colour (sourced from kaiser-natron.de), with diagonal dividers carrying the colour in and back out to the neutral product grid below. (The home page was left unchanged — it keeps its 3-card <code>ProductTeaser</code>.)</p>
|
||||
<h4>Four sections + colours (design tokens)</h4>
|
||||
<p><code>tokens.css</code> — the old "Haushalt" lump was split into <strong>Clean</strong> (cleaning) and <strong>Wash</strong> (laundry):</p>
|
||||
<div class="swrow">
|
||||
<div class="swcard"><span class="swbox" style="background:#c6d47d"></span><span><span class="role">Kitchen · lime</span><span class="hex">#c6d47d</span></span></div>
|
||||
<div class="swcard"><span class="swbox" style="background:#eb5a61"></span><span><span class="role">Clean · grapefruit</span><span class="hex">#eb5a61</span></span></div>
|
||||
<div class="swcard"><span class="swbox" style="background:#c15a7e"></span><span><span class="role">Wash · plum</span><span class="hex">#c15a7e</span></span></div>
|
||||
<div class="swcard"><span class="swbox" style="background:#f1864c"></span><span><span class="role">Care · orange</span><span class="hex">#f1864c</span></span></div>
|
||||
</div>
|
||||
<table>
|
||||
<thead><tr><th>Token</th><th>Hex</th><th>Section</th><th>Products</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td><code>--color-cat-kitchen</code></td><td><span class="swinline" style="background:#c6d47d"></span><code>#c6d47d</code> (lime)</td><td>Küche / cook</td><td>Pulver, Tabletten</td></tr>
|
||||
<tr><td><code>--color-cat-clean</code></td><td><span class="swinline" style="background:#eb5a61"></span><code>#eb5a61</code> (grapefruit)</td><td>Reinigung / clean</td><td>cleaners, sprays, descalers</td></tr>
|
||||
<tr><td><code>--color-cat-wash</code></td><td><span class="swinline" style="background:#c15a7e"></span><code>#c15a7e</code> (plum)</td><td>Wäsche / wash</td><td>wash-soda, starch, stain removers</td></tr>
|
||||
<tr><td><code>--color-cat-care</code></td><td><span class="swinline" style="background:#f1864c"></span><code>#f1864c</code> (orange)</td><td>Pflege / care</td><td>bath, foot-bath, sport</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Tailwind v4 auto-emits <code>bg-cat-kitchen</code> / <code>bg-cat-clean</code> / <code>bg-cat-wash</code> / <code>bg-cat-care</code>.</p>
|
||||
<h4>Product grouping</h4>
|
||||
<p><code>src/api/products.js</code> — <code>USE_CASES</code> is now <code>['cook','clean','wash','care']</code>; <code>Wäsche</code> maps to the new <code>wash</code> group (was <code>clean</code>). <code>productsByUseCase</code> returns all four buckets.</p>
|
||||
<h4>Hero tones</h4>
|
||||
<p><code>Hero.vue</code> has <code>kitchen</code> / <code>clean</code> / <code>wash</code> / <code>care</code> tones. Lime keeps dark ink text; the other three take cream (white) text. Each sets an <code>eyebrowColor</code> applied inline (overrides the global <code>.eyebrow { color: muted }</code>). <code>WaveDivider.vue</code> gained matching <code>kitchen</code> / <code>clean</code> / <code>wash</code> / <code>care</code> tones.</p>
|
||||
<h4>Shop page</h4>
|
||||
<p><code>ShopPage.vue</code> loops the four use-cases; each renders <code>WaveDivider → <Hero :tone="section.cat"> (hero product + mixed-font heading + CTAs) → WaveDivider → a section title + product grid</code>. <code>CAT_TONE</code> maps cook→kitchen, clean→clean, wash→wash, care→care; <code>CAT_HERO_ID</code> picks the headline product (Pulver / Allzweck-Spray / Daunenwasch / Bad). A per-section title (<code>shop.section.<id>.products.title</code>) now sits above each grid.</p>
|
||||
<h4>Banner CTAs</h4>
|
||||
<p>Each banner carries two buttons (via the Hero <code>#actions</code> slot): <strong>"add to cart"</strong> in the brand crimson (<code>Button variant="accent"</code>, adds the section's hero product) and <strong>"learn more"</strong> as a white-outline ghost (<code>border-white/90 text-white</code>, links to the product page).</p>
|
||||
<div class="callout warn"><span class="ico">⚠️</span><p>The white-outline "learn more" reads well on the saturated grapefruit / plum / orange banners but is low-contrast on the light lime (Kitchen) banner — may want a dark-outline variant there.</p></div>
|
||||
<h4>Shop first fold — halved</h4>
|
||||
<p>The green title fold was <code>min-h:calc(100svh − nav)</code> but only holds a compact title band, leaving too much empty green. Reduced to <code>calc(50svh − var(--nav-h))</code>. A diagonal then drops into a <strong>thin white band</strong> (<code>h-6 md:h-10</code>) before the first colour banner, so the green hero and the lime Kitchen banner don't butt directly together.</p>
|
||||
<h4>Küche category page (new, separate from the shop sections)</h4>
|
||||
<p>Added for parity with <code>/haushalt</code> + <code>/pflege</code>:</p>
|
||||
<ul>
|
||||
<li><code>router/index.js</code> — new <code>/kueche</code> route → <code>CategoryPage</code> <code>{ slug: 'kueche', useCase: 'cook' }</code>.</li>
|
||||
<li><code>CategoryPage.vue</code> — <code>slug</code> validator allows <code>kueche</code>; <code>useCase</code> allows <code>cook</code>.</li>
|
||||
<li><code>messages.js</code> — full <code>category.kueche.*</code> copy (de + en), mirroring pflege/haushalt.</li>
|
||||
</ul>
|
||||
<div class="callout info"><span class="ico">ℹ️</span><p><strong>Resolved (see §21).</strong> The three content-complete category pages (<code>/kueche</code>, <code>/haushalt</code>, <code>/pflege</code>) are now wired into the footer. <code>/waesche</code> (wash) is intentionally <strong>deferred</strong> pending brand copy — the shop's in-page <code>wash</code> section covers laundry in the meantime.</p></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §21 ===================== -->
|
||||
<div class="item" id="s21">
|
||||
<div class="item-head"><span class="secnum">§21</span><h3>Category pages wired up + naming aligned to shop sections</h3></div>
|
||||
<div class="files"><span class="file-chip">src/design-system/components/Footer.vue</span><span class="file-chip">src/i18n/messages.js</span></div>
|
||||
<div class="body">
|
||||
<p><strong>Decision.</strong> Of the four use-groups, the three with complete copy (<code>cook</code>/<code>clean</code>/<code>care</code> → <code>/kueche</code>, <code>/haushalt</code>, <code>/pflege</code>) are kept as standalone landing pages <em>alongside</em> the shop's in-page sections, and linked from the footer. The <code>wash</code> group has no standalone page (<code>/waesche</code>) yet — <strong>deferred</strong> until brand copy is supplied; the shop's <code>wash</code> section covers laundry meanwhile.</p>
|
||||
<p><strong>Footer links.</strong> <code>Footer.vue</code> <code>exploreLinks</code> now lists <code>Shop → Küche → Haushalt → Pflege → Bundles → About</code> (the <code>/kueche</code> link was previously missing — page was reachable only by direct URL). Order follows the shop's use-group order.</p>
|
||||
<p><strong>Naming aligned to the shop.</strong> The footer <strong>link labels</strong> and the category-page <strong>eyebrows</strong> now use the shop's plain section names (<code>shop.feature.*</code>) instead of the older descriptive variants, so a section and its landing page read identically:</p>
|
||||
<table>
|
||||
<thead><tr><th>Page (route)</th><th>use-case</th><th>eyebrow + footer label — DE / EN</th><th>was</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td><code>/kueche</code></td><td>cook</td><td><strong>Küche / Kitchen</strong></td><td>"Küche & Backen" / "Kitchen & baking"</td></tr>
|
||||
<tr><td><code>/haushalt</code></td><td>clean</td><td><strong>Reinigung / Clean</strong></td><td>"Haushalt & Reinigung" / "Home & cleaning"</td></tr>
|
||||
<tr><td><code>/pflege</code></td><td>care</td><td><strong>Pflege / Care</strong></td><td>"Pflege & Wohlbefinden" / "Personal care & wellbeing"</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Route slugs are unchanged (<code>/haushalt</code> still serves the <code>clean</code> group); only the visible labels/eyebrows moved to the new names.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §22 ===================== -->
|
||||
<div class="item" id="s22">
|
||||
<div class="item-head"><span class="secnum">§22</span><h3>Membership removed — bundles are single-price (U2)</h3></div>
|
||||
<div class="files"><span class="file-chip">src/api/bundles.js</span><span class="file-chip">BundleCard.vue</span><span class="file-chip">Bundles.vue</span><span class="file-chip">BundlePage.vue</span><span class="file-chip">HomePage.vue</span><span class="file-chip">src/i18n/messages.js</span><span class="file-chip">BundleCardSection.vue</span><span class="file-chip">BundlesSection.vue</span><span class="file-chip">previews/BundlesPreview.vue</span></div>
|
||||
<div class="body">
|
||||
<p>There is <strong>no membership programme</strong>, so every trace of one was removed (the join button went earlier in §U2; this completes it). <strong>Decision: single retail price</strong> — bundles now show only their regular price (e.g. €24,90); the old lower <code>memberPrice</code> was dropped entirely (no discount remains).</p>
|
||||
<ul>
|
||||
<li><strong>Data.</strong> <code>bundles.js</code> — <code>memberPrice</code> deleted from all three bundles.</li>
|
||||
<li><strong><code>BundleCard.vue</code></strong> — removed the <code>memberPrice</code> prop, the <code>memberLabel</code> computed, and the "Mitglieder: €X" line under the price.</li>
|
||||
<li><strong><code>Bundles.vue</code></strong> — removed all four <code>:member-price</code> bindings, the <code>joinCta</code> prop, the <code>join</code> emit, both "become a member" buttons (stacked + sidebar), and the now-unused <code>Button</code> import. Stale "why join" / "member pitch" comments reworded to "why bundle".</li>
|
||||
<li><strong><code>BundlePage.vue</code></strong> — removed the <code>memberPriceLabel</code> computed and the member price line in both desktop and mobile hero blocks.</li>
|
||||
<li><strong><code>HomePage.vue</code></strong> — dropped <code>memberPrice</code> from the localized-bundle mapping.</li>
|
||||
<li><strong>Copy (<code>messages.js</code>).</strong> Deleted orphaned keys <code>bundle.memberPrice</code>, <code>bundles.joinCta</code>, <code>bundles.card.memberPrefix</code>. <code>bundles.card.priceLabel</code> → "Preis" / "Price" (was "Verkaufspreis" / "Retail price"). The section subtitle + three benefits were rewritten from membership perks to <strong>bundle value</strong> (no savings claim, since the price is now flat):
|
||||
<ul>
|
||||
<li>sub: "Kuratierte Sets … in einem Paket." / "Curated sets … in a single pack."</li>
|
||||
<li>benefits: <em>Aufeinander abgestimmt · Alles für einen Bereich · In einer Lieferung</em> (EN: <em>Chosen to work together · Everything for one area · In a single delivery</em>).</li>
|
||||
<li><code>ds.bundleCard.description</code> / <code>ds.bundles.description</code> updated to drop the member-price / member-CTA mentions.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>The <code>headline.em</code> stays "Vorteile / Benefits" — it now reads as the bundles' advantages rather than membership perks.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §23 ===================== -->
|
||||
<div class="item" id="s23">
|
||||
<div class="item-head"><span class="secnum">§23</span><h3>Second-fold banner image — powder, not bath (L7)</h3></div>
|
||||
<div class="files"><span class="file-chip">src/pages/HomePage.vue</span></div>
|
||||
<div class="body">
|
||||
<p>The cream second-fold banner reads <em>"Ein Pulver, hundert Anwendungen im Haushalt"</em> / <em>"One powder, a hundred uses around the home"</em> but showed the <strong>Bad 500 g (bath)</strong> product — and its add-to-cart + "learn more" link pointed there too, contradicting the powder message. Repointed the whole banner to <strong>powder</strong>:</p>
|
||||
<ul>
|
||||
<li><code>imgBanner</code> → <code>/products/kaiser-natron-pulver-3.490-g-eimer.webp</code> (the bulk bucket — visually reinforces "a hundred uses"; deliberately <em>not</em> the 250 g Großpackung, which is already the first-fold hero).</li>
|
||||
<li><code>bannerProductId</code> → <code>kaiser-natron-pulver-3490-g-eimer</code>, so the CTA adds the powder and "learn more" links to <code>/shop/kaiser-natron-pulver-3490-g-eimer</code>.</li>
|
||||
<li><code>image-alt</code> → "Kaiser-Natron® Pulver 3.490 g Eimer".</li>
|
||||
</ul>
|
||||
<p>No new asset needed — the bucket image already shipped in <code>public/products/</code>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §24 ===================== -->
|
||||
<div class="item" id="s24">
|
||||
<div class="item-head"><span class="secnum">§24</span><h3>Revitalization section removed from the homepage</h3></div>
|
||||
<div class="files"><span class="file-chip">src/pages/HomePage.vue</span><span class="file-chip">ShopPage.vue</span><span class="file-chip">CategoryPage.vue</span><span class="file-chip">BundlePage.vue</span><span class="file-chip">ProductPage.vue</span><span class="file-chip">KaiserhacksPage.vue</span><span class="file-chip">LoginPage.vue</span><span class="file-chip">RegisterPage.vue</span><span class="file-chip">LegalPage.vue</span></div>
|
||||
<div class="body">
|
||||
<p>The brand owner flagged the "Revitalization Center" name + icons as off-brand. Removed the section from the public site <strong>for now</strong>:</p>
|
||||
<ul>
|
||||
<li><code>HomePage.vue</code> — removed the <code><Revitalization></code> block and the two diagonal SVG dividers that bracketed it (the cream banner now flows straight into the cream About section), plus the <code>Revitalization</code> import and the <code>revitCopy</code> computed.</li>
|
||||
<li>Stripped the now-dead <code>{ key: 'nav.revitalization', href: '/#revitalize' }</code> entry from every page's nav array (9 files) so nothing links to the missing anchor.</li>
|
||||
</ul>
|
||||
<p>Kept in reserve (not deleted): <code>Revitalization.vue</code>, its design-system docs page, the <code>revit.*</code> i18n keys, and the <code>/design/preview/revitalization</code> route — so the section can be reinstated (with a corrected name) by re-adding the import, <code>revitCopy</code>, the render block, and the nav entries.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §25 ===================== -->
|
||||
<div class="item" id="s25">
|
||||
<div class="item-head"><span class="secnum">§25</span><h3>Sport-Profi recategorised to Laundry (Wäsche)</h3></div>
|
||||
<div class="files"><span class="file-chip">src/api/products.js</span></div>
|
||||
<div class="body">
|
||||
<p>Brand-owner review: <em>Sport Profi is a laundry product and belongs under Household, not Bathing & Care.</em> In the four-group taxonomy laundry = <code>wash</code>, so <code>USE_CASE_BY_CATEGORY.Sport</code> changed <code>'care'</code> → <code>'wash'</code>. The <code>kaiser-natron-sport-profi-250-ml</code> product now appears in the <strong>Wäsche / wash</strong> (plum) section instead of Pflege / care. Doc comment updated to match.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §26 ===================== -->
|
||||
<div class="item" id="s26">
|
||||
<div class="item-head"><span class="secnum">§26</span><h3>"Das Original aus Österreich" removed (G1)</h3></div>
|
||||
<div class="files"><span class="file-chip">src/i18n/messages.js</span></div>
|
||||
<div class="body">
|
||||
<p>Brand-owner review: the "Original from Austria" claim is inaccurate. Removed the leading sentence from <code>footer.tagline</code> (DE + EN); the tagline now opens at <em>"Reines Natron für Küche, Haushalt und Pflege …"</em> / <em>"Pure sodium bicarbonate for the kitchen, the home, and personal care …"</em>.</p>
|
||||
<div class="callout info"><span class="ico">ℹ️</span><p>Other Austria-flavoured strings remain and are separate decisions, not part of this change: <code>footer.madeIn</code> / <code>product.prop.made-in-austria</code> ("In Österreich abgefüllt" / "Bottled in Austria") and the Impressum/Datenschutz Vienna address. Flag to the user if the origin correction should extend to these.</p></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== §27 ===================== -->
|
||||
<div class="item" id="s27">
|
||||
<div class="item-head"><span class="secnum">§27</span><h3>Shop hero — skewed category jump-buttons + white gap removed</h3></div>
|
||||
<div class="files"><span class="file-chip">src/pages/ShopPage.vue</span></div>
|
||||
<div class="body">
|
||||
<p><strong>Jump-buttons.</strong> Under the shop hero's title + sub, a row of four <strong>skewed parallelogram buttons</strong> (one per use-group, each filled with its own category colour) smooth-scrolls to the matching section:</p>
|
||||
<div class="swrow">
|
||||
<div class="swcard"><span class="swbox" style="background:#c6d47d"></span><span><span class="role">Küche / Kitchen</span><span class="hex">dark ink label</span></span></div>
|
||||
<div class="swcard"><span class="swbox" style="background:#eb5a61"></span><span><span class="role">Reinigung / Clean</span><span class="hex">white label</span></span></div>
|
||||
<div class="swcard"><span class="swbox" style="background:#c15a7e"></span><span><span class="role">Wäsche / Wash</span><span class="hex">white label</span></span></div>
|
||||
<div class="swcard"><span class="swbox" style="background:#f1864c"></span><span><span class="role">Pflege / Care</span><span class="hex">white label</span></span></div>
|
||||
</div>
|
||||
<ul>
|
||||
<li>Rendered by looping <code>sections</code>; label is <code>section.feature</code>.</li>
|
||||
<li>Shape: <code>-skew-x-12</code> on the button with a counter-skew <code>skew-x-12</code> on the inner <code><span></code> so the text stays upright — echoes the angled (Soulmates) CI.</li>
|
||||
<li>Colour map <code>CAT_BTN</code>: <code>bg-cat-kitchen text-brand</code> (lime is light → dark ink), the other three <code>bg-cat-* text-white</code>.</li>
|
||||
<li><code>scrollToSection(id)</code> calls <code>el.scrollIntoView({ behavior: 'smooth' })</code>; each section's existing <code>scroll-mt</code> keeps the landing just below the sticky nav.</li>
|
||||
</ul>
|
||||
<p><strong>White gap removed.</strong> The thin white band (<code>-mt-px h-6 md:h-10 bg-cream</code>) and its preceding <code>WaveDivider from="brand" to="cream"</code> — added in §20 — are gone. The green hero now flows <strong>straight into the first colour banner</strong> via a single diagonal: the section loop is <code>(section, i)</code> and the first divider is <code>:from="i === 0 ? 'brand' : 'cream'"</code>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== QUICK REFERENCE ===================== -->
|
||||
<div class="item" id="qref" style="border-left-color: var(--crimson);">
|
||||
<div class="item-head"><span class="secnum" style="background:var(--crimson); box-shadow:0 4px 12px rgba(204,2,48,.22);">★</span><h3>Quick reference — the two new colours</h3></div>
|
||||
<div class="body">
|
||||
<div class="swrow">
|
||||
<div class="swcard"><span class="swbox" style="background:#cc0230"></span><span><span class="role">Crimson</span><span class="hex">#cc0230</span></span></div>
|
||||
<div class="swcard"><span class="swbox" style="background:#6eceb2"></span><span><span class="role">Mint</span><span class="hex">#6eceb2</span></span></div>
|
||||
<div class="swcard"><span class="swbox" style="background:#ffffff"></span><span><span class="role">White</span><span class="hex">#ffffff</span></span></div>
|
||||
</div>
|
||||
<pre><code>Crimson #cc0230 — all buttons / CTAs / solid pills (with #ffffff text)
|
||||
Mint #6eceb2 — nav tab + footer link hover/active highlight
|
||||
White #ffffff — page backgrounds (cream + surface) and button text on green</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="foot">
|
||||
<span>Kaiser-Natron® — developer change log</span>
|
||||
<span>27 documented changes · feat/shop-category-sections</span>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
425
public/review-doc/index.html
Normal file
425
public/review-doc/index.html
Normal file
@@ -0,0 +1,425 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Kaiser-Natron® — Brand Review Status</title>
|
||||
<style>
|
||||
:root {
|
||||
--brand: #006548;
|
||||
--brand-soft: #4a9079;
|
||||
--crimson: #cc0230;
|
||||
--mint: #6eceb2;
|
||||
--gold: #e9c84b;
|
||||
--ink: #0a2c20;
|
||||
--muted: #5c7a6f;
|
||||
--paper: #ffffff;
|
||||
--cream: #f4f7f4;
|
||||
--line: #d9e4df;
|
||||
--kitchen: #c6d47d;
|
||||
--clean: #eb5a61;
|
||||
--wash: #c15a7e;
|
||||
--care: #f1864c;
|
||||
--done: #006548;
|
||||
--partial: #d98a1f;
|
||||
--open: #cc0230;
|
||||
--review: #6b7f8c;
|
||||
--serif: 'Zeitung', 'Iowan Old Style', 'Palatino', Georgia, serif;
|
||||
--sans: 'Zeitung', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
html { -webkit-font-smoothing: antialiased; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--sans);
|
||||
color: var(--ink);
|
||||
background: var(--cream);
|
||||
line-height: 1.55;
|
||||
}
|
||||
.wrap { max-width: 920px; margin: 0 auto; padding: 0 24px 80px; }
|
||||
|
||||
/* ---- Header ---- */
|
||||
header.hero {
|
||||
background: var(--brand);
|
||||
color: #fff;
|
||||
padding: 56px 24px 64px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
header.hero::after {
|
||||
/* angled divider — echoes the Soulmates angular CI, not waves */
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0; right: 0; bottom: -1px;
|
||||
height: 64px;
|
||||
background: var(--cream);
|
||||
clip-path: polygon(0 100%, 100% 100%, 100% 38%);
|
||||
}
|
||||
.hero-inner { max-width: 920px; margin: 0 auto; position: relative; z-index: 1; }
|
||||
.eyebrow {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .22em;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--mint);
|
||||
margin: 0 0 14px;
|
||||
}
|
||||
h1 {
|
||||
font-family: var(--serif);
|
||||
font-weight: 600;
|
||||
font-size: clamp(30px, 5vw, 46px);
|
||||
line-height: 1.05;
|
||||
margin: 0 0 14px;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
h1 em { font-style: italic; font-weight: 300; color: var(--mint); }
|
||||
.hero p { max-width: 60ch; color: rgba(255,255,255,.85); margin: 0; font-size: 16px; }
|
||||
.meta { margin-top: 22px; font-size: 13px; color: rgba(255,255,255,.7); }
|
||||
|
||||
/* ---- Summary chips ---- */
|
||||
.summary {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 12px;
|
||||
margin: -34px 0 38px;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.stat {
|
||||
background: var(--paper);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 12px;
|
||||
padding: 16px 14px;
|
||||
text-align: center;
|
||||
box-shadow: 0 10px 30px rgba(0,101,72,.07);
|
||||
}
|
||||
.stat .n { font-family: var(--serif); font-size: 30px; line-height: 1; font-weight: 600; }
|
||||
.stat .l { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin-top: 7px; }
|
||||
.stat.done .n { color: var(--done); }
|
||||
.stat.review .n { color: var(--review); }
|
||||
.stat.partial .n { color: var(--partial); }
|
||||
.stat.open .n { color: var(--open); }
|
||||
.stat.note .n { color: var(--brand-soft); }
|
||||
|
||||
/* ---- Legend ---- */
|
||||
.legend { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 0 0 34px; font-size: 13px; color: var(--muted); }
|
||||
.legend span { display: inline-flex; align-items: center; gap: 7px; }
|
||||
.dot { width: 11px; height: 11px; border-radius: 50%; display: inline-block; }
|
||||
.dot.done { background: var(--done); }
|
||||
.dot.review { background: var(--review); }
|
||||
.dot.partial { background: var(--partial); }
|
||||
.dot.open { background: var(--open); }
|
||||
.dot.note { background: var(--brand-soft); }
|
||||
|
||||
/* ---- Section ---- */
|
||||
section.group { margin-bottom: 40px; }
|
||||
.group > h2 {
|
||||
font-family: var(--serif);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 4px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid var(--brand);
|
||||
display: flex; align-items: baseline; gap: 12px;
|
||||
}
|
||||
.group > h2 .count { font-family: var(--sans); font-size: 13px; font-weight: 500; color: var(--muted); }
|
||||
|
||||
/* ---- Item card ---- */
|
||||
.item {
|
||||
background: var(--paper);
|
||||
border: 1px solid var(--line);
|
||||
border-left-width: 5px;
|
||||
border-radius: 10px;
|
||||
padding: 16px 18px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.item.done { border-left-color: var(--done); }
|
||||
.item.review { border-left-color: var(--review); }
|
||||
.item.partial { border-left-color: var(--partial); }
|
||||
.item.open { border-left-color: var(--open); }
|
||||
.item.note { border-left-color: var(--brand-soft); }
|
||||
|
||||
.item-head { display: flex; align-items: flex-start; gap: 12px; }
|
||||
.badge {
|
||||
flex: none;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .05em;
|
||||
padding: 4px 10px;
|
||||
border-radius: 999px;
|
||||
white-space: nowrap;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.badge.done { background: rgba(0,101,72,.10); color: var(--done); }
|
||||
.badge.review { background: rgba(107,127,140,.14); color: var(--review); }
|
||||
.badge.partial { background: rgba(217,138,31,.14); color: var(--partial); }
|
||||
.badge.open { background: rgba(204,2,48,.10); color: var(--open); }
|
||||
.badge.note { background: rgba(74,144,121,.14); color: var(--brand-soft); }
|
||||
|
||||
.quote { margin: 0; font-size: 15px; color: var(--ink); }
|
||||
.note {
|
||||
margin: 10px 0 0;
|
||||
font-size: 14px;
|
||||
color: var(--muted);
|
||||
padding-left: 14px;
|
||||
border-left: 2px solid var(--line);
|
||||
}
|
||||
.note strong { color: var(--brand); font-weight: 600; }
|
||||
|
||||
/* category swatch row */
|
||||
.swatches { display: inline-flex; gap: 5px; margin-left: 4px; vertical-align: middle; }
|
||||
.sw { width: 13px; height: 13px; border-radius: 3px; display: inline-block; border: 1px solid rgba(0,0,0,.06); }
|
||||
|
||||
/* opinion block */
|
||||
.opinion {
|
||||
background: var(--paper);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 12px;
|
||||
padding: 22px 24px;
|
||||
margin-top: 12px;
|
||||
font-size: 14.5px;
|
||||
color: var(--ink);
|
||||
}
|
||||
.opinion p { margin: 0 0 12px; }
|
||||
.opinion p:last-child { margin-bottom: 0; }
|
||||
|
||||
footer.foot {
|
||||
margin-top: 48px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid var(--line);
|
||||
font-size: 12.5px;
|
||||
color: var(--muted);
|
||||
display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.summary { grid-template-columns: repeat(2, 1fr); }
|
||||
}
|
||||
@media print {
|
||||
body { background: #fff; }
|
||||
.stat, .item, .opinion { box-shadow: none; }
|
||||
header.hero { padding-bottom: 48px; }
|
||||
.item { break-inside: avoid; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="hero">
|
||||
<div class="hero-inner">
|
||||
<p class="eyebrow">Brand Review · Implementation Status</p>
|
||||
<h1>Kaiser-Natron<sup>®</sup> website review —<br><em>what's done, what's next</em></h1>
|
||||
<p>Every point from the brand-owner review, tracked against the current build. Each item carries its real status and a short note on what was changed or what's still needed.</p>
|
||||
<p class="meta">Prepared 24 June 2026 · Branch <code>feat/shop-category-sections</code> · 28 review points</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
<div class="summary">
|
||||
<div class="stat done"><div class="n">18</div><div class="l">Done</div></div>
|
||||
<div class="stat review"><div class="n">2</div><div class="l">Reviewed / kept</div></div>
|
||||
<div class="stat partial"><div class="n">2</div><div class="l">In progress</div></div>
|
||||
<div class="stat open"><div class="n">6</div><div class="l">Needs your input</div></div>
|
||||
</div>
|
||||
|
||||
<div class="legend">
|
||||
<span><i class="dot done"></i> Done — implemented & on the branch</span>
|
||||
<span><i class="dot review"></i> Reviewed — kept as-is by your decision / verified</span>
|
||||
<span><i class="dot partial"></i> In progress — partially done</span>
|
||||
<span><i class="dot open"></i> Needs your input — legal text, content or a decision</span>
|
||||
</div>
|
||||
|
||||
<!-- ===================== LAYOUT ===================== -->
|
||||
<section class="group">
|
||||
<h2>Layout <span class="count">15 points</span></h2>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The overall layout is not consistent with the Kaiser-Natron® brand identity (CI).</p></div>
|
||||
<p class="note"><strong>Aligned to CI:</strong> official brand palette, the Zeitung typeface, angled (Soulmates) dividers and the official artwork are all in place. Holistic consistency continues as a guiding rule for every change.</p>
|
||||
</div>
|
||||
|
||||
<div class="item review">
|
||||
<div class="item-head"><span class="badge review">Reviewed</span>
|
||||
<p class="quote">The Kaiser-Natron® logo on the homepage is far too small and not prominent enough.</p></div>
|
||||
<p class="note"><strong>Kept at current size</strong> by your call this session — revisit anytime if you'd like it enlarged.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The spring/source has been distorted (mountains, Hebe's hair, the “mountain” by her head, the stream). All illustrations should match the original Kaiser-Natron® design.</p></div>
|
||||
<p class="note"><strong>Brand-hero rebuilt</strong> with the official Hebe + waterfall artwork, replacing the distorted composition.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">Incorrect font and incorrect colour palette.</p></div>
|
||||
<p class="note"><strong>Corrected:</strong> self-hosted Zeitung typeface and the official brand palette (green <code>#006548</code>, crimson, mint, gold) throughout.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The Soulmates angled concept is lost; wave-shaped elements do not fit the structure.</p></div>
|
||||
<p class="note"><strong>Waves removed.</strong> All section dividers are now angled/diagonal, echoing the logo's geometry and rebuilding brand recognition.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The 250 g package image: background colour and product image are not visually aligned.</p></div>
|
||||
<p class="note"><strong>Resolved:</strong> the 250 g box artwork was recoloured to the brand green so product and background sit together.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">“…for everything that should shine. Cleans, bakes and neutralizes…” does not fit the tone of voice.</p></div>
|
||||
<p class="note"><strong>Rewritten</strong> toward versatility — “Kaiser-Natron® für fast alles im Alltag” / “…for almost anything at home”, sourced from the live brand voice.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">Under “Bundles & Benefits”: AI-generated images must be marked as AI content with an icon, beginning in August.</p></div>
|
||||
<p class="note"><strong>Disclosed:</strong> a discreet “AI Edited” caption now sits on each AI-composed bundle image. It switches off automatically once real photos replace them.</p>
|
||||
</div>
|
||||
|
||||
<div class="item partial">
|
||||
<div class="item-head"><span class="badge partial">In progress</span>
|
||||
<p class="quote">The product depictions inside the AI images are inaccurate; as a manufacturer I'd avoid AI imagery altogether.</p></div>
|
||||
<p class="note"><strong>Disclosed for now</strong> with the AI-Edited badge. Full removal is wired and ready — it just needs your <strong>real product photography</strong> to drop in.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">“One powder, a hundred applications…” does not match the bath image shown above it; the powder product should be shown.</p></div>
|
||||
<p class="note"><strong>Fixed this session:</strong> the banner now shows the powder (the bulk bucket), and its “add to cart” / “learn more” point to that powder product.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The “Personal Care”, “Household” and “Kitchen” categories are disrupted, and “Kitchen” is effectively lost.</p></div>
|
||||
<p class="note"><strong>Restored:</strong> the shop is rebuilt into four clear category sections — Kitchen, Cleaning, Laundry, Care — and Kitchen now has its own section and standalone page.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The colour-coding concept of the product groups has been lost.
|
||||
<span class="swatches"><i class="sw" style="background:var(--kitchen)"></i><i class="sw" style="background:var(--clean)"></i><i class="sw" style="background:var(--wash)"></i><i class="sw" style="background:var(--care)"></i></span></p></div>
|
||||
<p class="note"><strong>Re-established</strong> from the brand's own group colours — Kitchen (lime), Cleaning (grapefruit), Laundry (plum), Care (orange) — as full-width banners and dividers.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The icons and name of the “Revitalization Center” do not fit the brand identity.</p></div>
|
||||
<p class="note"><strong>Section removed</strong> from the site for now, so neither the off-brand icons nor the name appear. The component is kept in reserve and can return with the correct naming whenever you want it.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The ® symbol is missing in several places and spelling should be reviewed.</p></div>
|
||||
<p class="note"><strong>Audited:</strong> ® added to every visible mention and the name hyphenated consistently as “Kaiser-Natron®”.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The Kaiser-Natron® logo should be white.</p></div>
|
||||
<p class="note"><strong>Confirmed fine:</strong> the logo renders white on green/dark surfaces and brand-green on light ones — the right behaviour in each context. Signed off as-is.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===================== UI ===================== -->
|
||||
<section class="group">
|
||||
<h2>User Interface <span class="count">6 points</span></h2>
|
||||
|
||||
<div class="item review">
|
||||
<div class="item-head"><span class="badge review">Verified</span>
|
||||
<p class="quote">Missing navigation menu in the mobile view.</p></div>
|
||||
<p class="note"><strong>Navigation is present</strong> on mobile (checked on the current build). If a specific device hid it for you, send a screenshot and we'll chase it.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The animation of Hebe is not successful, in my opinion.</p></div>
|
||||
<p class="note"><strong>Updated:</strong> the intro was reworked around the official Hebe + waterfall artwork, addressing the motion concern.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">“Bundles & Benefits”: “As a member…” — member of what? No information on how to become one or what it costs.</p></div>
|
||||
<p class="note"><strong>Membership fully removed</strong> this session — the join button, the “member price”, and all member wording are gone. Bundles now show a single price with plain bundle-value copy.</p>
|
||||
</div>
|
||||
|
||||
<div class="item partial">
|
||||
<div class="item-head"><span class="badge partial">In progress</span>
|
||||
<p class="quote">The page structure doesn't make sense: Three Classics → 250 g package → Bundles → bath image with general text. The 250 g package and bath image are positioned incorrectly.</p></div>
|
||||
<p class="note">The <strong>bath image is resolved</strong> (now powder, see above). The <strong>section re-ordering</strong> is the open part — your full note here gives us exactly what's needed, and it's queued as the next layout task.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">The shop should be organized by product categories. Sport Profi is a laundry product and belongs under “Household”, not “Bathing & Care”.</p></div>
|
||||
<p class="note">The shop is <strong>organized by category</strong>, and <strong>Sport Profi is now filed under Laundry</strong> (Household), no longer under Care.</p>
|
||||
</div>
|
||||
|
||||
<div class="item open">
|
||||
<div class="item-head"><span class="badge open">Needs you</span>
|
||||
<p class="quote">Holste and Linda products have no product descriptions.</p></div>
|
||||
<p class="note">These aren't on the Kaiser-Natron® site, so the copy needs to come from you (or approve us drafting placeholders for review).</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===================== GENERAL ===================== -->
|
||||
<section class="group">
|
||||
<h2>General & Legal <span class="count">7 points</span></h2>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">“The Original from Austria.” In my opinion this is not accurate.</p></div>
|
||||
<p class="note"><strong>Removed:</strong> the “Original from Austria” claim is deleted from the footer tagline (DE + EN). The tagline now reads simply about pure natron for the kitchen, home and care.</p>
|
||||
</div>
|
||||
|
||||
<div class="item open">
|
||||
<div class="item-head"><span class="badge open">Needs you</span>
|
||||
<p class="quote">Terms & Conditions (AGB) are missing.</p></div>
|
||||
<p class="note">Page structure can be scaffolded immediately; the legal text must come from you.</p>
|
||||
</div>
|
||||
|
||||
<div class="item open">
|
||||
<div class="item-head"><span class="badge open">Needs you</span>
|
||||
<p class="quote">Withdrawal / Right of Cancellation is missing. A cancellation button has been mandatory since June 2026.</p></div>
|
||||
<p class="note">We can build the <strong>“Vertrag kündigen” button + flow</strong> now with placeholder text; the binding legal wording comes from you.</p>
|
||||
</div>
|
||||
|
||||
<div class="item open">
|
||||
<div class="item-head"><span class="badge open">Needs you</span>
|
||||
<p class="quote">Shipping information is missing.</p></div>
|
||||
<p class="note">Needs your shipping terms; we'll place them in checkout and a dedicated page.</p>
|
||||
</div>
|
||||
|
||||
<div class="item open">
|
||||
<div class="item-head"><span class="badge open">Needs you</span>
|
||||
<p class="quote">Delivery costs are missing.</p></div>
|
||||
<p class="note">Needs your rates (flat / tiered / free-over-threshold) to display in cart and checkout.</p>
|
||||
</div>
|
||||
|
||||
<div class="item done">
|
||||
<div class="item-head"><span class="badge done">Done</span>
|
||||
<p class="quote">Payment options are missing.</p></div>
|
||||
<p class="note"><strong>Not missing</strong> — payment options are already present on the site, so no change is needed here.</p>
|
||||
</div>
|
||||
|
||||
<div class="item open">
|
||||
<div class="item-head"><span class="badge open">Needs you</span>
|
||||
<p class="quote">Transparency: the site appears to present itself as the official manufacturer while the imprint says otherwise — this may confuse customers.</p></div>
|
||||
<p class="note">This is a positioning decision for you (official manufacturer vs. reseller). Once decided, we'll make the framing consistent across the site and imprint.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="foot">
|
||||
<span>Kaiser-Natron® — brand review implementation status</span>
|
||||
<span>18 done · 2 kept · 2 in progress · 6 awaiting input</span>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user