Files
mealprep/specs/staples-settings-redesign.html
Marcel Raddatz 2ad75cc1b7 spec(staples): tile redesign, seed catalog & add-ingredient flow
Adds two spec files for issue #59:
- staples-settings-redesign.html — 5 initial concept variations
- staples-settings-tile.html    — chosen direction: tile layout (matching
  SettingsCard shell), German seed catalog (~100 ingredients / 8 categories),
  and inline per-tile add-ingredient flow with duplicate detection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 20:28:57 +02:00

1335 lines
71 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vorräte Settings — 5 Redesign Concepts</title>
<style>
/* === Design Tokens (mirrored from app.css) === */
:root {
--font-display: 'Georgia', serif;
--font-sans: system-ui, sans-serif;
--color-page: #fafaf7;
--color-surface: #f5f4ee;
--color-subtle: #edecea;
--color-border: #d8d7d0;
--color-border-hover: #c0bfb8;
--color-text: #1c1c18;
--color-text-muted: #6b6a63;
--green-tint: #e8f5ea;
--green-light: #aedcb0;
--green-dark: #2e6e39;
--green-deeper: #1e4a26;
--yellow-tint: #fdf6d8;
--yellow-light: #f9e08a;
--yellow-text: #8a6800;
--color-error: #dc4c3e;
--radius-sm: 4px;
--radius-md: 6px;
--radius-lg: 10px;
--radius-xl: 16px;
--radius-full: 9999px;
}
/* === Spec Page Layout === */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: var(--font-sans);
background: #e8e7e0;
color: var(--color-text);
padding: 48px 32px;
}
.spec-title {
font-family: var(--font-display);
font-size: 28px;
font-weight: 500;
margin-bottom: 8px;
}
.spec-meta {
font-size: 13px;
color: var(--color-text-muted);
margin-bottom: 48px;
}
.problem-box {
background: #fff8e1;
border: 1px solid #f9e08a;
border-radius: var(--radius-md);
padding: 20px 24px;
margin-bottom: 48px;
max-width: 820px;
}
.problem-box h3 {
font-size: 11px;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: #8a6800;
margin-bottom: 12px;
}
.problem-box ul {
list-style: none;
display: flex;
flex-direction: column;
gap: 6px;
}
.problem-box li {
font-size: 13px;
color: var(--color-text);
padding-left: 16px;
position: relative;
}
.problem-box li::before {
content: '→';
position: absolute;
left: 0;
color: #c49610;
}
/* Concept section */
.concept {
margin-bottom: 80px;
}
.concept-header {
display: flex;
align-items: baseline;
gap: 16px;
margin-bottom: 8px;
}
.concept-number {
font-size: 11px;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--color-text-muted);
}
.concept-name {
font-family: var(--font-display);
font-size: 22px;
font-weight: 500;
}
.concept-tagline {
font-size: 13px;
color: var(--color-text-muted);
margin-bottom: 24px;
max-width: 640px;
}
.concept-verdict {
font-size: 12px;
color: var(--color-text-muted);
margin-top: 16px;
max-width: 640px;
line-height: 1.6;
border-left: 3px solid var(--color-border);
padding-left: 12px;
}
.concept-verdict strong { color: var(--color-text); }
/* Mockup frames */
.frames {
display: flex;
gap: 32px;
flex-wrap: wrap;
}
.frame {
background: var(--color-page);
border-radius: var(--radius-lg);
overflow: hidden;
box-shadow: 0 2px 8px rgba(0,0,0,0.08), 0 0 0 1px rgba(0,0,0,0.06);
}
.frame-label {
font-size: 10px;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--color-text-muted);
padding: 10px 16px 0;
margin-bottom: 4px;
}
.frame-mobile { width: 320px; }
.frame-desktop { width: 640px; }
/* === Shared UI Primitives === */
.chip {
display: inline-flex;
align-items: center;
font-size: 13px;
font-weight: 500;
letter-spacing: 0.04em;
padding: 5px 12px;
border-radius: var(--radius-full);
border: 1px solid;
cursor: pointer;
white-space: nowrap;
}
.chip-on {
background: var(--green-tint);
border-color: var(--green-light);
color: var(--green-dark);
}
.chip-off {
background: var(--color-surface);
border-color: var(--color-border);
color: var(--color-text-muted);
}
.cat-label {
font-size: 10px;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--color-text-muted);
margin-bottom: 8px;
}
.badge {
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 11px;
font-weight: 500;
border-radius: var(--radius-full);
padding: 1px 7px;
background: var(--green-tint);
color: var(--green-dark);
}
.badge-zero {
background: var(--color-subtle);
color: var(--color-text-muted);
}
.btn-primary {
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 13px;
font-weight: 500;
letter-spacing: 0.04em;
padding: 9px 20px;
border-radius: var(--radius-md);
background: var(--green-dark);
color: white;
border: none;
}
.search-bar {
display: flex;
align-items: center;
gap: 8px;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
padding: 9px 12px;
font-size: 13px;
color: var(--color-text-muted);
}
.search-icon {
width: 14px;
height: 14px;
opacity: 0.5;
}
.divider {
border: none;
border-top: 1px solid var(--color-border);
}
.back-link {
font-size: 12px;
color: var(--color-text-muted);
display: block;
margin-bottom: 12px;
}
.h1 {
font-family: var(--font-display);
font-size: 22px;
font-weight: 500;
margin-bottom: 4px;
}
.h1-mobile {
font-family: var(--font-display);
font-size: 18px;
font-weight: 500;
margin-bottom: 4px;
}
.subtext {
font-size: 11px;
color: var(--color-text-muted);
margin-bottom: 20px;
}
</style>
</head>
<body>
<p class="spec-title">Vorräte Settings — Redesign Concepts</p>
<p class="spec-meta">Atlas · 2026-04-10 · Mealplan Design System · 5 Concepts</p>
<div class="problem-box">
<h3>Diagnosed Problems (current A3/D3)</h3>
<ul>
<li>Chip clouds grow unbounded — categories with 20+ ingredients (Gewürze, Gemüse) swamp the page</li>
<li>3-column grid creates severe visual imbalance between fat and lean categories</li>
<li>No search — finding "Parmesan" requires scanning every chip in Käse+Milchprodukte</li>
<li>No bulk actions — selecting an entire category (e.g. all oils) takes N taps</li>
<li>No count feedback — user can't assess their selection at a glance ("how many staples? Which categories are empty?")</li>
<li>Auto-save hint buried at bottom — user anxiety about whether changes stuck</li>
</ul>
</div>
<!-- ======================================================
CONCEPT 1: ACCORDION CATEGORIES
====================================================== -->
<div class="concept">
<div class="concept-header">
<span class="concept-number">Concept 01</span>
<span class="concept-name">Accordion Categories</span>
</div>
<p class="concept-tagline">
Categories are collapsed by default. A count badge shows selected/total at a glance.
Tap to expand any category — all others stay collapsed. One category in focus at a time.
</p>
<div class="frames">
<!-- Mobile -->
<div class="frame frame-mobile">
<div class="frame-label">Mobile — 320px</div>
<div style="padding: 16px 20px 24px;">
<span class="back-link">← Einstellungen</span>
<div class="h1-mobile">Vorräte</div>
<p class="subtext">Wähle deine regelmäßig vorhandenen Zutaten.</p>
<!-- Accordion items -->
<div style="display:flex; flex-direction:column; gap:0; border:1px solid var(--color-border); border-radius:var(--radius-md); overflow:hidden;">
<!-- Expanded: Gemüse -->
<div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:12px 16px; background:var(--color-surface); cursor:pointer;">
<div style="display:flex; align-items:center; gap:10px;">
<span style="font-size:13px; font-weight:500; color:var(--color-text);">Gemüse</span>
<span class="badge">7 / 18</span>
</div>
<span style="font-size:12px; color:var(--color-text-muted);"></span>
</div>
<div style="padding:12px 16px 16px; background:var(--color-page); border-top:1px solid var(--color-border);">
<!-- All / None row -->
<div style="display:flex; gap:8px; margin-bottom:12px;">
<button style="font-size:11px; font-weight:500; letter-spacing:0.04em; padding:3px 10px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:var(--color-surface); color:var(--color-text-muted); cursor:pointer;">Alle</button>
<button style="font-size:11px; font-weight:500; letter-spacing:0.04em; padding:3px 10px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:var(--color-surface); color:var(--color-text-muted); cursor:pointer;">Keine</button>
</div>
<div style="display:flex; flex-wrap:wrap; gap:6px;">
<span class="chip chip-on">Möhren</span>
<span class="chip chip-on">Zwiebeln</span>
<span class="chip chip-on">Knoblauch</span>
<span class="chip chip-off">Zucchini</span>
<span class="chip chip-off">Aubergine</span>
<span class="chip chip-on">Paprika</span>
<span class="chip chip-off">Spinat</span>
<span class="chip chip-on">Tomaten</span>
<span class="chip chip-off">Lauch</span>
<span class="chip chip-on">Brokkoli</span>
<span class="chip chip-off">Kohl</span>
<span class="chip chip-on">Sellerie</span>
<span class="chip chip-off">Gurke</span>
</div>
</div>
</div>
<div style="border-top:1px solid var(--color-border);">
<div style="display:flex; align-items:center; justify-content:space-between; padding:12px 16px; cursor:pointer;">
<div style="display:flex; align-items:center; gap:10px;">
<span style="font-size:13px; font-weight:500; color:var(--color-text);">Milchprodukte</span>
<span class="badge">4 / 12</span>
</div>
<span style="font-size:12px; color:var(--color-text-muted);"></span>
</div>
</div>
<div style="border-top:1px solid var(--color-border);">
<div style="display:flex; align-items:center; justify-content:space-between; padding:12px 16px; cursor:pointer;">
<div style="display:flex; align-items:center; gap:10px;">
<span style="font-size:13px; font-weight:500; color:var(--color-text);">Gewürze</span>
<span class="badge badge-zero">0 / 24</span>
</div>
<span style="font-size:12px; color:var(--color-text-muted);"></span>
</div>
</div>
<div style="border-top:1px solid var(--color-border);">
<div style="display:flex; align-items:center; justify-content:space-between; padding:12px 16px; cursor:pointer;">
<div style="display:flex; align-items:center; gap:10px;">
<span style="font-size:13px; font-weight:500; color:var(--color-text);">Öle &amp; Fette</span>
<span class="badge">2 / 6</span>
</div>
<span style="font-size:12px; color:var(--color-text-muted);"></span>
</div>
</div>
<div style="border-top:1px solid var(--color-border);">
<div style="display:flex; align-items:center; justify-content:space-between; padding:12px 16px; cursor:pointer;">
<div style="display:flex; align-items:center; gap:10px;">
<span style="font-size:13px; font-weight:500; color:var(--color-text);">Getreide &amp; Körner</span>
<span class="badge badge-zero">0 / 9</span>
</div>
<span style="font-size:12px; color:var(--color-text-muted);"></span>
</div>
</div>
</div>
<p style="margin-top:16px; font-size:11px; color:var(--color-text-muted);">Automatisch gespeichert.</p>
</div>
</div>
<!-- Desktop -->
<div class="frame frame-desktop">
<div class="frame-label">Desktop — 640px (settings column)</div>
<div style="padding: 40px 56px 48px;">
<span class="back-link">← Einstellungen</span>
<div class="h1">Vorräte</div>
<p class="subtext">Wähle deine regelmäßig vorhandenen Zutaten. Automatisch gespeichert.</p>
<div style="display:flex; flex-direction:column; gap:0; border:1px solid var(--color-border); border-radius:var(--radius-md); overflow:hidden;">
<div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:14px 20px; background:var(--color-surface); cursor:pointer;">
<div style="display:flex; align-items:center; gap:12px;">
<span style="font-size:14px; font-weight:500; color:var(--color-text);">Gemüse</span>
<span class="badge">7 / 18</span>
</div>
<div style="display:flex; align-items:center; gap:16px;">
<button style="font-size:11px; font-weight:500; letter-spacing:0.04em; padding:3px 10px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:white; color:var(--color-text-muted); cursor:pointer;">Alle</button>
<button style="font-size:11px; font-weight:500; letter-spacing:0.04em; padding:3px 10px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:white; color:var(--color-text-muted); cursor:pointer;">Keine</button>
<span style="font-size:12px; color:var(--color-text-muted);"></span>
</div>
</div>
<div style="padding:16px 20px 20px; background:var(--color-page); border-top:1px solid var(--color-border);">
<div style="display:flex; flex-wrap:wrap; gap:6px;">
<span class="chip chip-on">Möhren</span>
<span class="chip chip-on">Zwiebeln</span>
<span class="chip chip-on">Knoblauch</span>
<span class="chip chip-off">Zucchini</span>
<span class="chip chip-off">Aubergine</span>
<span class="chip chip-on">Paprika</span>
<span class="chip chip-off">Spinat</span>
<span class="chip chip-on">Tomaten</span>
<span class="chip chip-off">Lauch</span>
<span class="chip chip-on">Brokkoli</span>
<span class="chip chip-off">Kohl</span>
<span class="chip chip-on">Sellerie</span>
</div>
</div>
</div>
<div style="border-top:1px solid var(--color-border);">
<div style="display:flex; align-items:center; justify-content:space-between; padding:14px 20px; cursor:pointer;">
<div style="display:flex; align-items:center; gap:12px;">
<span style="font-size:14px; font-weight:500; color:var(--color-text);">Milchprodukte</span>
<span class="badge">4 / 12</span>
</div>
<span style="font-size:12px; color:var(--color-text-muted);"></span>
</div>
</div>
<div style="border-top:1px solid var(--color-border);">
<div style="display:flex; align-items:center; justify-content:space-between; padding:14px 20px; cursor:pointer;">
<div style="display:flex; align-items:center; gap:12px;">
<span style="font-size:14px; font-weight:500; color:var(--color-text);">Gewürze</span>
<span class="badge badge-zero">0 / 24</span>
</div>
<span style="font-size:12px; color:var(--color-text-muted);"></span>
</div>
</div>
<div style="border-top:1px solid var(--color-border);">
<div style="display:flex; align-items:center; justify-content:space-between; padding:14px 20px; cursor:pointer;">
<div style="display:flex; align-items:center; gap:12px;">
<span style="font-size:14px; font-weight:500; color:var(--color-text);">Öle &amp; Fette</span>
<span class="badge">2 / 6</span>
</div>
<span style="font-size:12px; color:var(--color-text-muted);"></span>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="concept-verdict">
<strong>Trade-off:</strong> Solves visual overload immediately — only one category is in view at a time.
The Alle/Keine actions eliminate bulk-select friction. Count badges answer "where do I still need to configure?"
at a glance. <strong>Risk:</strong> accordion interaction adds a tap per category visit; power users who want
a full overview lose it. Works best when categories are &lt;8. Keyboard nav via Enter/Space on row headers.
</p>
</div>
<!-- ======================================================
CONCEPT 2: LEFT-NAV + FOCUSED CHIP AREA
====================================================== -->
<div class="concept">
<div class="concept-header">
<span class="concept-number">Concept 02</span>
<span class="concept-name">Category Sidebar</span>
</div>
<p class="concept-tagline">
Left panel: sticky category list with count badges — acts as a mini-nav.
Right panel: the selected category's full chip cloud. One category in focus, full list visible.
Mobile collapses to top tabs (scrollable).
</p>
<div class="frames">
<!-- Mobile -->
<div class="frame frame-mobile">
<div class="frame-label">Mobile — horizontal tab strip</div>
<div style="padding: 16px 0 24px;">
<div style="padding:0 20px;">
<span class="back-link">← Einstellungen</span>
<div class="h1-mobile" style="margin-bottom:16px;">Vorräte</div>
</div>
<!-- Scrollable tab strip -->
<div style="display:flex; gap:0; overflow-x:auto; border-bottom:1px solid var(--color-border); padding:0 20px; margin-bottom:20px;">
<div style="display:flex; align-items:center; gap:6px; padding:10px 16px; border-bottom:2px solid var(--green-dark); color:var(--green-dark); white-space:nowrap; cursor:pointer;">
<span style="font-size:13px; font-weight:500;">Gemüse</span>
<span class="badge">7</span>
</div>
<div style="display:flex; align-items:center; gap:6px; padding:10px 16px; border-bottom:2px solid transparent; color:var(--color-text-muted); white-space:nowrap; cursor:pointer;">
<span style="font-size:13px;">Milch</span>
<span class="badge">4</span>
</div>
<div style="display:flex; align-items:center; gap:6px; padding:10px 16px; border-bottom:2px solid transparent; color:var(--color-text-muted); white-space:nowrap; cursor:pointer;">
<span style="font-size:13px;">Gewürze</span>
<span class="badge badge-zero">0</span>
</div>
<div style="display:flex; align-items:center; gap:6px; padding:10px 16px; border-bottom:2px solid transparent; color:var(--color-text-muted); white-space:nowrap; cursor:pointer;">
<span style="font-size:13px;">Öle</span>
<span class="badge">2</span>
</div>
</div>
<!-- Chip area -->
<div style="padding:0 20px;">
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:12px;">
<span style="font-size:11px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Gemüse — 7 gewählt</span>
<div style="display:flex; gap:6px;">
<button style="font-size:11px; font-weight:500; padding:3px 8px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:var(--color-surface); color:var(--color-text-muted); cursor:pointer;">Alle</button>
<button style="font-size:11px; font-weight:500; padding:3px 8px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:var(--color-surface); color:var(--color-text-muted); cursor:pointer;">Keine</button>
</div>
</div>
<div style="display:flex; flex-wrap:wrap; gap:6px;">
<span class="chip chip-on">Möhren</span>
<span class="chip chip-on">Zwiebeln</span>
<span class="chip chip-on">Knoblauch</span>
<span class="chip chip-off">Zucchini</span>
<span class="chip chip-off">Aubergine</span>
<span class="chip chip-on">Paprika</span>
<span class="chip chip-off">Spinat</span>
<span class="chip chip-on">Tomaten</span>
<span class="chip chip-off">Lauch</span>
<span class="chip chip-on">Brokkoli</span>
<span class="chip chip-off">Kohl</span>
<span class="chip chip-on">Sellerie</span>
<span class="chip chip-off">Gurke</span>
<span class="chip chip-off">Blumenkohl</span>
</div>
</div>
</div>
</div>
<!-- Desktop -->
<div class="frame frame-desktop">
<div class="frame-label">Desktop — sidebar + content panel</div>
<div style="display:flex; height:420px;">
<!-- Category sidebar -->
<div style="width:180px; flex-shrink:0; background:var(--color-surface); border-right:1px solid var(--color-border); padding:32px 0; overflow-y:auto;">
<div style="padding:0 16px; margin-bottom:16px;">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Kategorien</span>
</div>
<!-- Active row -->
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 16px; background:var(--green-tint); cursor:pointer; border-right:2px solid var(--green-dark);">
<span style="font-size:13px; font-weight:500; color:var(--green-dark);">Gemüse</span>
<span class="badge">7</span>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 16px; cursor:pointer;">
<span style="font-size:13px; color:var(--color-text);">Milchprodukte</span>
<span class="badge">4</span>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 16px; cursor:pointer;">
<span style="font-size:13px; color:var(--color-text-muted);">Gewürze</span>
<span class="badge badge-zero">0</span>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 16px; cursor:pointer;">
<span style="font-size:13px; color:var(--color-text);">Öle &amp; Fette</span>
<span class="badge">2</span>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 16px; cursor:pointer;">
<span style="font-size:13px; color:var(--color-text-muted);">Getreide</span>
<span class="badge badge-zero">0</span>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 16px; cursor:pointer;">
<span style="font-size:13px; color:var(--color-text);">Fleisch &amp; Fisch</span>
<span class="badge">3</span>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 16px; cursor:pointer;">
<span style="font-size:13px; color:var(--color-text);">Backwaren</span>
<span class="badge">1</span>
</div>
</div>
<!-- Chip area -->
<div style="flex:1; padding:32px 28px; overflow-y:auto;">
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:16px;">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Gemüse — 7 von 18 gewählt</span>
<div style="display:flex; gap:6px;">
<button style="font-size:11px; font-weight:500; padding:4px 10px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:var(--color-surface); color:var(--color-text-muted); cursor:pointer;">Alle wählen</button>
<button style="font-size:11px; font-weight:500; padding:4px 10px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:var(--color-surface); color:var(--color-text-muted); cursor:pointer;">Keine</button>
</div>
</div>
<div style="display:flex; flex-wrap:wrap; gap:6px;">
<span class="chip chip-on">Möhren</span>
<span class="chip chip-on">Zwiebeln</span>
<span class="chip chip-on">Knoblauch</span>
<span class="chip chip-off">Zucchini</span>
<span class="chip chip-off">Aubergine</span>
<span class="chip chip-on">Paprika</span>
<span class="chip chip-off">Spinat</span>
<span class="chip chip-on">Tomaten</span>
<span class="chip chip-off">Lauch</span>
<span class="chip chip-on">Brokkoli</span>
<span class="chip chip-off">Kohl</span>
<span class="chip chip-on">Sellerie</span>
<span class="chip chip-off">Gurke</span>
<span class="chip chip-off">Blumenkohl</span>
<span class="chip chip-off">Kohlrabi</span>
<span class="chip chip-off">Rote Bete</span>
<span class="chip chip-off">Fenchel</span>
<span class="chip chip-off">Erbsen</span>
</div>
</div>
</div>
<div style="padding:12px 28px 16px; border-top:1px solid var(--color-border);">
<span style="font-size:11px; color:var(--color-text-muted);">Automatisch gespeichert · 23 Vorräte insgesamt</span>
</div>
</div>
</div>
<p class="concept-verdict">
<strong>Trade-off:</strong> Best scalability — the sidebar grows gracefully to 15+ categories without
visual breakdown. The "23 Vorräte insgesamt" footer answers the comprehension question for the whole household.
Active/inactive category coloring (green-tint bg + green-dark text) matches the existing nav convention exactly.
<strong>Risk:</strong> Two-panel layouts can feel over-engineered for simple tasks. Mobile tab strip
truncates long category names — needs abbreviation strategy.
</p>
</div>
<!-- ======================================================
CONCEPT 3: SEARCH-FIRST + STICKY HEADERS
====================================================== -->
<div class="concept">
<div class="concept-header">
<span class="concept-number">Concept 03</span>
<span class="concept-name">Search-First</span>
</div>
<p class="concept-tagline">
Search bar dominates the top. Below it: a single scrollable list with sticky category headers (like iOS Contacts).
Searching filters in real-time — category headers collapse when their section is empty.
For power users and anyone who knows what they want.
</p>
<div class="frames">
<!-- Mobile -->
<div class="frame frame-mobile">
<div class="frame-label">Mobile — with active search</div>
<div style="padding: 16px 20px 24px;">
<span class="back-link">← Einstellungen</span>
<div class="h1-mobile" style="margin-bottom:12px;">Vorräte</div>
<!-- Search bar -->
<div style="display:flex; align-items:center; gap:8px; background:var(--color-surface); border:1px solid var(--green-light); border-radius:var(--radius-md); padding:9px 12px; margin-bottom:16px;">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="color:var(--color-text-muted); flex-shrink:0">
<circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/>
</svg>
<span style="font-size:13px; color:var(--color-text);">Par</span>
<span style="display:inline-block; width:1px; height:14px; background:var(--green-dark); animation:blink 1s step-end infinite;"></span>
<button style="margin-left:auto; font-size:12px; color:var(--color-text-muted); background:none; border:none; cursor:pointer;"></button>
</div>
<!-- Results -->
<div style="border-radius:var(--radius-md); overflow:hidden; border:1px solid var(--color-border);">
<!-- Sticky category header -->
<div style="padding:6px 12px; background:var(--color-subtle); border-bottom:1px solid var(--color-border);">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Käse &amp; Milchprodukte</span>
</div>
<!-- Checklist rows -->
<div style="display:flex; align-items:center; justify-content:space-between; padding:11px 16px; background:var(--green-tint); border-bottom:1px solid var(--color-border);">
<span style="font-size:13px; font-weight:500; color:var(--green-dark);">Parmesan</span>
<div style="width:18px; height:18px; border-radius:var(--radius-sm); background:var(--green-dark); display:flex; align-items:center; justify-content:center; flex-shrink:0;">
<svg width="10" height="10" viewBox="0 0 12 12" fill="none"><path d="M2 6l3 3 5-5" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:11px 16px; border-bottom:1px solid var(--color-border);">
<span style="font-size:13px; color:var(--color-text);">Parmesan gerieben</span>
<div style="width:18px; height:18px; border-radius:var(--radius-sm); border:1.5px solid var(--color-border); flex-shrink:0;"></div>
</div>
<div style="padding:6px 12px; background:var(--color-subtle); border-bottom:1px solid var(--color-border); border-top:1px solid var(--color-border);">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Gewürze</span>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:11px 16px; border-bottom:1px solid var(--color-border);">
<span style="font-size:13px; color:var(--color-text);">Paprika edelsüß</span>
<div style="width:18px; height:18px; border-radius:var(--radius-sm); border:1.5px solid var(--color-border); flex-shrink:0;"></div>
</div>
<div style="padding:11px 16px; text-align:center; background:var(--color-page);">
<span style="font-size:12px; color:var(--color-text-muted);">3 Treffer für „Par"</span>
</div>
</div>
<p style="margin-top:12px; font-size:11px; color:var(--color-text-muted);">Automatisch gespeichert.</p>
</div>
</div>
<!-- Desktop: empty search state -->
<div class="frame frame-desktop">
<div class="frame-label">Desktop — idle state (no search)</div>
<div style="padding: 40px 56px 48px;">
<span class="back-link">← Einstellungen</span>
<div style="display:flex; align-items:baseline; justify-content:space-between; margin-bottom:4px;">
<div class="h1">Vorräte</div>
<span style="font-size:12px; color:var(--color-text-muted);">23 gewählt</span>
</div>
<p class="subtext">Automatisch gespeichert. Gilt ab der nächsten Einkaufsliste.</p>
<!-- Search bar -->
<div style="display:flex; align-items:center; gap:8px; background:var(--color-surface); border:1px solid var(--color-border); border-radius:var(--radius-md); padding:9px 12px; margin-bottom:20px;">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="color:var(--color-text-muted); flex-shrink:0">
<circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/>
</svg>
<span style="font-size:13px; color:var(--color-text-muted);">Zutat suchen …</span>
</div>
<!-- Scrollable list with sticky headers (static preview) -->
<div style="border:1px solid var(--color-border); border-radius:var(--radius-md); overflow:hidden; max-height:280px; overflow-y:auto;">
<div style="position:sticky; top:0; padding:6px 16px; background:var(--color-subtle); border-bottom:1px solid var(--color-border);">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Gemüse</span>
</div>
<div style="display:flex; flex-wrap:wrap; gap:6px; padding:12px 16px; border-bottom:1px solid var(--color-border);">
<span class="chip chip-on">Möhren</span>
<span class="chip chip-on">Zwiebeln</span>
<span class="chip chip-on">Knoblauch</span>
<span class="chip chip-off">Zucchini</span>
<span class="chip chip-off">Aubergine</span>
<span class="chip chip-on">Paprika</span>
<span class="chip chip-off">Spinat</span>
<span class="chip chip-on">Tomaten</span>
</div>
<div style="position:sticky; top:0; padding:6px 16px; background:var(--color-subtle); border-bottom:1px solid var(--color-border); border-top:1px solid var(--color-border);">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Milchprodukte</span>
</div>
<div style="display:flex; flex-wrap:wrap; gap:6px; padding:12px 16px; border-bottom:1px solid var(--color-border);">
<span class="chip chip-on">Butter</span>
<span class="chip chip-on">Milch</span>
<span class="chip chip-off">Joghurt</span>
<span class="chip chip-off">Sahne</span>
<span class="chip chip-on">Parmesan</span>
<span class="chip chip-off">Mozzarella</span>
</div>
<div style="position:sticky; top:0; padding:6px 16px; background:var(--color-subtle); border-bottom:1px solid var(--color-border); border-top:1px solid var(--color-border);">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Gewürze</span>
</div>
<div style="display:flex; flex-wrap:wrap; gap:6px; padding:12px 16px;">
<span class="chip chip-off">Salz</span>
<span class="chip chip-off">Pfeffer</span>
<span class="chip chip-off">Kreuzkümmel</span>
<span class="chip chip-off">Paprika edelsüß</span>
<span class="chip chip-off">Kurkuma</span>
</div>
</div>
</div>
</div>
</div>
<p class="concept-verdict">
<strong>Trade-off:</strong> Fastest path for users who know what they want. Search cuts through all category
hierarchy instantly. The checklist row style in search results (vs chips) is intentional — it's denser and
keyboard-navigable (arrow keys + Space). The idle state preserves the chip cloud so casual browsing stays familiar.
<strong>Risk:</strong> Two different interaction patterns (chips vs checklist rows in search) add cognitive load.
The sticky-header list can be hard to test cross-browser.
</p>
</div>
<!-- ======================================================
CONCEPT 4: COMPACT CHECKLIST TABLE
====================================================== -->
<div class="concept">
<div class="concept-header">
<span class="concept-number">Concept 04</span>
<span class="concept-name">Checklist Table</span>
</div>
<p class="concept-tagline">
Abandon chips entirely. A single scrollable table: category, ingredient name, checkbox.
Sorted by category. Extremely keyboard-friendly, screen-reader native, and
far denser — 40 ingredients fit in the same space as 10 chips.
</p>
<div class="frames">
<!-- Mobile -->
<div class="frame frame-mobile">
<div class="frame-label">Mobile — 320px</div>
<div style="padding: 16px 20px 24px;">
<span class="back-link">← Einstellungen</span>
<div class="h1-mobile" style="margin-bottom:4px;">Vorräte</div>
<p class="subtext">23 gewählt · automatisch gespeichert</p>
<!-- Search -->
<div style="display:flex; align-items:center; gap:8px; background:var(--color-surface); border:1px solid var(--color-border); border-radius:var(--radius-md); padding:8px 12px; margin-bottom:12px; font-size:13px; color:var(--color-text-muted);">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="flex-shrink:0"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
Suchen …
</div>
<!-- Table -->
<div style="border:1px solid var(--color-border); border-radius:var(--radius-md); overflow:hidden; font-size:13px;">
<!-- Category header row -->
<div style="display:flex; align-items:center; justify-content:space-between; padding:7px 14px; background:var(--color-subtle); border-bottom:1px solid var(--color-border);">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Gemüse</span>
<span style="font-size:11px; color:var(--color-text-muted);">7 / 18</span>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:10px 14px; background:var(--green-tint); border-bottom:1px solid var(--color-border);">
<span style="color:var(--green-dark); font-weight:500;">Möhren</span>
<input type="checkbox" checked style="width:16px; height:16px; accent-color:var(--green-dark);" readonly>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:10px 14px; border-bottom:1px solid var(--color-border);">
<span>Zwiebeln</span>
<input type="checkbox" checked style="width:16px; height:16px; accent-color:var(--green-dark);" readonly>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:10px 14px; border-bottom:1px solid var(--color-border);">
<span style="color:var(--color-text-muted);">Aubergine</span>
<input type="checkbox" style="width:16px; height:16px; accent-color:var(--green-dark);" readonly>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:10px 14px; border-bottom:1px solid var(--color-border);">
<span style="color:var(--color-text-muted);">Spinat</span>
<input type="checkbox" style="width:16px; height:16px; accent-color:var(--green-dark);" readonly>
</div>
<!-- Next category header -->
<div style="display:flex; align-items:center; justify-content:space-between; padding:7px 14px; background:var(--color-subtle); border-bottom:1px solid var(--color-border); border-top:1px solid var(--color-border);">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Milchprodukte</span>
<span style="font-size:11px; color:var(--color-text-muted);">4 / 12</span>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:10px 14px; background:var(--green-tint); border-bottom:1px solid var(--color-border);">
<span style="color:var(--green-dark); font-weight:500;">Butter</span>
<input type="checkbox" checked style="width:16px; height:16px; accent-color:var(--green-dark);" readonly>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:10px 14px; border-bottom:1px solid var(--color-border);">
<span style="color:var(--color-text-muted);">Joghurt</span>
<input type="checkbox" style="width:16px; height:16px; accent-color:var(--green-dark);" readonly>
</div>
</div>
</div>
</div>
<!-- Desktop: two-column table layout -->
<div class="frame frame-desktop">
<div class="frame-label">Desktop — two-column table</div>
<div style="padding: 40px 56px 48px;">
<span class="back-link">← Einstellungen</span>
<div style="display:flex; align-items:baseline; justify-content:space-between; margin-bottom:4px;">
<div class="h1">Vorräte</div>
<span style="font-size:12px; color:var(--color-text-muted);">23 gewählt</span>
</div>
<p class="subtext">Automatisch gespeichert. Gilt ab der nächsten Einkaufsliste.</p>
<!-- Search + filter bar -->
<div style="display:flex; gap:8px; margin-bottom:16px;">
<div style="flex:1; display:flex; align-items:center; gap:8px; background:var(--color-surface); border:1px solid var(--color-border); border-radius:var(--radius-md); padding:9px 12px; font-size:13px; color:var(--color-text-muted);">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="flex-shrink:0"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
Zutat suchen …
</div>
<select style="font-size:12px; font-weight:500; color:var(--color-text); background:var(--color-surface); border:1px solid var(--color-border); border-radius:var(--radius-md); padding:0 12px; cursor:pointer; appearance:none; padding-right:24px;">
<option>Alle Kategorien</option>
</select>
</div>
<!-- Two-column table -->
<div style="display:grid; grid-template-columns:1fr 1fr; gap:16px; max-height:310px; overflow-y:auto;">
<!-- Column 1 -->
<div style="border:1px solid var(--color-border); border-radius:var(--radius-md); overflow:hidden; font-size:13px; align-self:start;">
<div style="display:flex; align-items:center; justify-content:space-between; padding:7px 14px; background:var(--color-subtle); border-bottom:1px solid var(--color-border);">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Gemüse</span>
<span style="font-size:11px; color:var(--color-text-muted);">7 / 18</span>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 14px; background:var(--green-tint); border-bottom:1px solid var(--color-border);">
<span style="color:var(--green-dark); font-weight:500;">Möhren</span>
<input type="checkbox" checked style="width:15px; height:15px; accent-color:var(--green-dark);" readonly>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 14px; background:var(--green-tint); border-bottom:1px solid var(--color-border);">
<span style="color:var(--green-dark); font-weight:500;">Zwiebeln</span>
<input type="checkbox" checked style="width:15px; height:15px; accent-color:var(--green-dark);" readonly>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 14px; border-bottom:1px solid var(--color-border);">
<span style="color:var(--color-text-muted);">Aubergine</span>
<input type="checkbox" style="width:15px; height:15px; accent-color:var(--green-dark);" readonly>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 14px; border-bottom:1px solid var(--color-border);">
<span style="color:var(--color-text-muted);">Spinat</span>
<input type="checkbox" style="width:15px; height:15px; accent-color:var(--green-dark);" readonly>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 14px;">
<span style="color:var(--color-text-muted);">Zucchini</span>
<input type="checkbox" style="width:15px; height:15px; accent-color:var(--green-dark);" readonly>
</div>
</div>
<!-- Column 2 -->
<div style="border:1px solid var(--color-border); border-radius:var(--radius-md); overflow:hidden; font-size:13px; align-self:start;">
<div style="display:flex; align-items:center; justify-content:space-between; padding:7px 14px; background:var(--color-subtle); border-bottom:1px solid var(--color-border);">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Milchprodukte</span>
<span style="font-size:11px; color:var(--color-text-muted);">4 / 12</span>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 14px; background:var(--green-tint); border-bottom:1px solid var(--color-border);">
<span style="color:var(--green-dark); font-weight:500;">Butter</span>
<input type="checkbox" checked style="width:15px; height:15px; accent-color:var(--green-dark);" readonly>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 14px; background:var(--green-tint); border-bottom:1px solid var(--color-border);">
<span style="color:var(--green-dark); font-weight:500;">Milch</span>
<input type="checkbox" checked style="width:15px; height:15px; accent-color:var(--green-dark);" readonly>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 14px; border-bottom:1px solid var(--color-border);">
<span style="color:var(--color-text-muted);">Joghurt</span>
<input type="checkbox" style="width:15px; height:15px; accent-color:var(--green-dark);" readonly>
</div>
<div style="display:flex; align-items:center; justify-content:space-between; padding:9px 14px;">
<span style="color:var(--color-text-muted);">Sahne</span>
<input type="checkbox" style="width:15px; height:15px; accent-color:var(--green-dark);" readonly>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="concept-verdict">
<strong>Trade-off:</strong> Highest information density. Excellent keyboard navigation (tab to checkbox, space to toggle).
Screen readers get a native checklist — no ARIA juggling needed. The two-column desktop layout keeps categories
side by side without the chip-cloud imbalance problem.
<strong>Risk:</strong> Loses the "selection feels satisfying" quality of chip toggling — a checkbox is functional,
not delightful. Row highlight (green-tint bg) on checked rows restores some of that signal.
May feel clinical for a consumer cooking app.
</p>
</div>
<!-- ======================================================
CONCEPT 5: ENHANCED CURRENT (MINIMAL CHANGE)
====================================================== -->
<div class="concept">
<div class="concept-header">
<span class="concept-number">Concept 05</span>
<span class="concept-name">Enhanced Current</span>
</div>
<p class="concept-tagline">
Keep the chip paradigm — it works. Add three targeted fixes:
(1) category count badges + Alle/Keine micro-actions inline,
(2) a collapsible "overflow" per category beyond 8 chips,
(3) a global count in the header. Zero new navigation patterns to learn.
</p>
<div class="frames">
<!-- Mobile -->
<div class="frame frame-mobile">
<div class="frame-label">Mobile — current feel, fixed overload</div>
<div style="padding: 16px 20px 24px;">
<span class="back-link">← Einstellungen</span>
<div style="display:flex; align-items:baseline; justify-content:space-between; margin-bottom:4px;">
<div class="h1-mobile">Vorräte</div>
<span style="font-size:11px; color:var(--color-text-muted);">23 gewählt</span>
</div>
<p class="subtext">Automatisch gespeichert.</p>
<!-- Category: Gemüse -->
<div style="margin-bottom:20px;">
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:8px;">
<div style="display:flex; align-items:center; gap:8px;">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Gemüse</span>
<span class="badge">7 / 18</span>
</div>
<div style="display:flex; gap:6px;">
<button style="font-size:10px; font-weight:500; padding:2px 7px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:none; color:var(--color-text-muted); cursor:pointer; letter-spacing:0.04em;">Alle</button>
<button style="font-size:10px; font-weight:500; padding:2px 7px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:none; color:var(--color-text-muted); cursor:pointer; letter-spacing:0.04em;">Keine</button>
</div>
</div>
<!-- First 8 chips always visible -->
<div style="display:flex; flex-wrap:wrap; gap:6px; margin-bottom:6px;">
<span class="chip chip-on">Möhren</span>
<span class="chip chip-on">Zwiebeln</span>
<span class="chip chip-on">Knoblauch</span>
<span class="chip chip-on">Paprika</span>
<span class="chip chip-on">Tomaten</span>
<span class="chip chip-on">Brokkoli</span>
<span class="chip chip-off">Zucchini</span>
<span class="chip chip-off">Aubergine</span>
<!-- Overflow trigger -->
<button style="display:inline-flex; align-items:center; font-size:12px; font-weight:500; color:var(--color-text-muted); background:none; border:none; cursor:pointer; padding:4px 2px;">+10 weitere …</button>
</div>
</div>
<!-- Category: Gewürze (empty = badge-zero) -->
<div style="margin-bottom:20px;">
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:8px;">
<div style="display:flex; align-items:center; gap:8px;">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Gewürze</span>
<span class="badge badge-zero">0 / 24</span>
</div>
<div style="display:flex; gap:6px;">
<button style="font-size:10px; font-weight:500; padding:2px 7px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:none; color:var(--color-text-muted); cursor:pointer; letter-spacing:0.04em;">Alle</button>
<button style="font-size:10px; font-weight:500; padding:2px 7px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:none; color:var(--color-text-muted); cursor:pointer; letter-spacing:0.04em;">Keine</button>
</div>
</div>
<div style="display:flex; flex-wrap:wrap; gap:6px;">
<span class="chip chip-off">Salz</span>
<span class="chip chip-off">Pfeffer</span>
<span class="chip chip-off">Kreuzkümmel</span>
<span class="chip chip-off">Kurkuma</span>
<span class="chip chip-off">Zimt</span>
<span class="chip chip-off">Paprika</span>
<span class="chip chip-off">Koriander</span>
<span class="chip chip-off">Thymian</span>
<button style="display:inline-flex; align-items:center; font-size:12px; font-weight:500; color:var(--color-text-muted); background:none; border:none; cursor:pointer; padding:4px 2px;">+16 weitere …</button>
</div>
</div>
<!-- Category: Öle -->
<div>
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:8px;">
<div style="display:flex; align-items:center; gap:8px;">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Öle &amp; Fette</span>
<span class="badge">2 / 6</span>
</div>
<div style="display:flex; gap:6px;">
<button style="font-size:10px; font-weight:500; padding:2px 7px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:none; color:var(--color-text-muted); cursor:pointer; letter-spacing:0.04em;">Alle</button>
<button style="font-size:10px; font-weight:500; padding:2px 7px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:none; color:var(--color-text-muted); cursor:pointer; letter-spacing:0.04em;">Keine</button>
</div>
</div>
<div style="display:flex; flex-wrap:wrap; gap:6px;">
<span class="chip chip-on">Olivenöl</span>
<span class="chip chip-on">Rapsöl</span>
<span class="chip chip-off">Kokosöl</span>
<span class="chip chip-off">Butter</span>
<span class="chip chip-off">Ghee</span>
<span class="chip chip-off">Sesamöl</span>
</div>
</div>
</div>
</div>
<!-- Desktop -->
<div class="frame frame-desktop">
<div class="frame-label">Desktop — 3-col grid, enhanced</div>
<div style="padding: 40px 56px 48px;">
<span class="back-link">← Einstellungen</span>
<div style="display:flex; align-items:baseline; justify-content:space-between; margin-bottom:4px;">
<div class="h1">Vorräte</div>
<span style="font-size:12px; color:var(--color-text-muted);">23 Vorräte gewählt</span>
</div>
<p class="subtext">Automatisch gespeichert. Gilt ab der nächsten Einkaufsliste.</p>
<div style="display:grid; grid-template-columns:1fr 1fr 1fr; gap:24px 32px;">
<!-- Gemüse -->
<div>
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:8px;">
<div style="display:flex; align-items:center; gap:6px;">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Gemüse</span>
<span class="badge">7/18</span>
</div>
<div style="display:flex; gap:4px;">
<button style="font-size:10px; font-weight:500; padding:1px 6px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:none; color:var(--color-text-muted); cursor:pointer;">Alle</button>
<button style="font-size:10px; font-weight:500; padding:1px 6px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:none; color:var(--color-text-muted); cursor:pointer;"></button>
</div>
</div>
<div style="display:flex; flex-wrap:wrap; gap:5px;">
<span class="chip chip-on">Möhren</span>
<span class="chip chip-on">Zwiebeln</span>
<span class="chip chip-on">Knoblauch</span>
<span class="chip chip-on">Paprika</span>
<span class="chip chip-on">Tomaten</span>
<span class="chip chip-on">Brokkoli</span>
<span class="chip chip-off">Zucchini</span>
<span class="chip chip-off">Aubergine</span>
<button style="font-size:11px; color:var(--color-text-muted); background:none; border:none; cursor:pointer; padding:3px 2px;">+10 …</button>
</div>
</div>
<!-- Gewürze -->
<div>
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:8px;">
<div style="display:flex; align-items:center; gap:6px;">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Gewürze</span>
<span class="badge badge-zero">0/24</span>
</div>
<div style="display:flex; gap:4px;">
<button style="font-size:10px; font-weight:500; padding:1px 6px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:none; color:var(--color-text-muted); cursor:pointer;">Alle</button>
<button style="font-size:10px; font-weight:500; padding:1px 6px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:none; color:var(--color-text-muted); cursor:pointer;"></button>
</div>
</div>
<div style="display:flex; flex-wrap:wrap; gap:5px;">
<span class="chip chip-off">Salz</span>
<span class="chip chip-off">Pfeffer</span>
<span class="chip chip-off">Kreuzkümmel</span>
<span class="chip chip-off">Kurkuma</span>
<span class="chip chip-off">Zimt</span>
<span class="chip chip-off">Paprika</span>
<span class="chip chip-off">Thymian</span>
<span class="chip chip-off">Oregano</span>
<button style="font-size:11px; color:var(--color-text-muted); background:none; border:none; cursor:pointer; padding:3px 2px;">+16 …</button>
</div>
</div>
<!-- Öle -->
<div>
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:8px;">
<div style="display:flex; align-items:center; gap:6px;">
<span style="font-size:10px; font-weight:600; letter-spacing:0.08em; text-transform:uppercase; color:var(--color-text-muted);">Öle &amp; Fette</span>
<span class="badge">2/6</span>
</div>
<div style="display:flex; gap:4px;">
<button style="font-size:10px; font-weight:500; padding:1px 6px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:none; color:var(--color-text-muted); cursor:pointer;">Alle</button>
<button style="font-size:10px; font-weight:500; padding:1px 6px; border-radius:var(--radius-full); border:1px solid var(--color-border); background:none; color:var(--color-text-muted); cursor:pointer;"></button>
</div>
</div>
<div style="display:flex; flex-wrap:wrap; gap:5px;">
<span class="chip chip-on">Olivenöl</span>
<span class="chip chip-on">Rapsöl</span>
<span class="chip chip-off">Kokosöl</span>
<span class="chip chip-off">Butter</span>
<span class="chip chip-off">Ghee</span>
<span class="chip chip-off">Sesamöl</span>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="concept-verdict">
<strong>Trade-off:</strong> Lowest risk, smallest diff — the three components (CategorySection, StapleChip, StaplesManager)
need only minor additions. No new navigation paradigm to learn. Count badges on category headers answer the
comprehension question. The "+N weitere…" overflow trigger caps visual height per category.
Alle/Keine bulk actions land where the eye already is (next to the label).
<strong>This is the recommendation for a first iteration</strong> — it fixes the acute pain without a redesign.
Concepts 01 or 02 are step-2 if the dataset grows substantially larger.
</p>
</div>
<!-- ======================================================
MACHINE-READABLE AGENT SECTION
====================================================== -->
<div class="agent-section" aria-hidden="true" style="display:none;">
<!--
╔══════════════════════════════════════════════════════════════╗
║ MACHINE-READABLE SPEC — Staples Settings Redesign ║
║ For: AI implementation agents ║
╚══════════════════════════════════════════════════════════════╝
## SHARED ADDITIONS (apply to ALL concepts)
### CategorySection.svelte — add to every category header
PROP: onSelectAll: () => void
PROP: onDeselectAll: () => void
RENDER: badge showing "{selected} / {total}" next to category label
- selected > 0 → class="badge" (green-tint bg, green-dark text)
- selected === 0 → class="badge-zero" (color-subtle bg, color-text-muted text)
RENDER: two micro-buttons "Alle" / "Keine" at row end
- font-size: 10px, font-weight: 500, tracking: 0.04em
- padding: 2px 7px, border-radius: --radius-full
- border: 1px solid --color-border, background: none, color: --color-text-muted
### StaplesManager.svelte — add to container header
RENDER: total count label, format: "{n} Vorräte gewählt"
- font-size: 12px, color: --color-text-muted
- position: inline end (flex row) next to h1, baseline-aligned
─────────────────────────────────────────────────────────────
## CONCEPT 01 — Accordion
COMPONENT: AccordionCategorySection (replaces CategorySection in StaplesManager)
STATE: openCategoryId: string | null (only one open at a time)
ANATOMY:
<div role="list" style="border:1px solid --color-border; border-radius:--radius-md; overflow:hidden;">
{#each categories}
<div role="listitem">
<button // accordion trigger
aria-expanded={isOpen}
aria-controls="cat-{id}-panel"
style="display:flex; justify-content:space-between; align-items:center;
padding:12px 16px (mobile) | 14px 20px (desktop);
background: isOpen ? --color-surface : --color-page;
border-top: 1px solid --color-border (except first)"
>
<span>category name</span>
<div style="display:flex; gap:16px; align-items:center">
Alle / Keine buttons (only visible when isOpen)
badge
chevron (▲ open | ▼ closed)
</div>
</button>
<div id="cat-{id}-panel" hidden={!isOpen} style="padding:12px 16px (mobile) | 16px 20px (desktop); border-top:1px solid --color-border">
chip cloud
</div>
</div>
{/each}
</div>
KEYBOARD: Enter/Space on trigger toggles; only one open at a time (close others on open)
TRANSITION: display:none / block (no animation needed for v1)
─────────────────────────────────────────────────────────────
## CONCEPT 02 — Category Sidebar
LAYOUT (desktop ≥ md):
display: flex
left panel: width 180px, background: --color-surface, border-right: 1px solid --color-border
overflow-y: auto, padding: 32px 0
section label: "KATEGORIEN" 10px/600/0.08em uppercase, padding: 0 16px, margin-bottom: 16px
each row: display:flex, justify-content:space-between, padding: 9px 16px
active: background --green-tint, color --green-dark, border-right: 2px solid --green-dark
inactive: background transparent, color --color-text, border-right: 2px solid transparent
right panel: flex:1, padding: 32px 28px, overflow-y: auto
LAYOUT (mobile < md):
tab strip: display:flex, overflow-x: auto, border-bottom: 1px solid --color-border
active tab: border-bottom: 2px solid --green-dark, color: --green-dark
inactive tab: border-bottom: 2px solid transparent, color: --color-text-muted
chip area below strip: padding: 0 20px
STATE: activeCategoryId: string (defaults to first category)
FOOTER (desktop): "Automatisch gespeichert · {n} Vorräte insgesamt"
font-size: 11px, color: --color-text-muted
border-top: 1px solid --color-border, padding: 12px 28px
─────────────────────────────────────────────────────────────
## CONCEPT 03 — Search-First
COMPONENT: SearchableStaplesManager (wraps StaplesManager)
STATE: query: string = ''
SEARCH BAR:
border: 1px solid --color-border (idle) | --green-light (focused)
border-radius: --radius-md
padding: 9px 12px, font-size: 13px
icon: magnifier SVG, 14px, color: --color-text-muted
clear button (×): visible when query.length > 0
IDLE STATE (query === ''):
render: standard CategorySection list with sticky headers inside a scrollable container
sticky header: padding 6px 16px, background: --color-subtle, border-bottom: 1px solid --color-border
SEARCH STATE (query.length > 0):
filter all ingredients whose name.toLowerCase().includes(query.toLowerCase())
group matches by category, skip categories with 0 matches
render: result list with category sticky headers + checklist rows (not chips)
result count: "{n} Treffer für „{query}"" at list bottom, 12px, --color-text-muted, centered
CHECKLIST ROW (search results only):
display:flex, justify-content:space-between, align-items:center, padding: 11px 16px
selected: background --green-tint, text color --green-dark, font-weight 500
unselected: background --color-page, text color --color-text
right: 18x18px checkbox div, border-radius --radius-sm
checked: background --green-dark, white checkmark SVG
unchecked: border: 1.5px solid --color-border
─────────────────────────────────────────────────────────────
## CONCEPT 04 — Checklist Table
ABANDON: StapleChip.svelte (no longer used)
NEW COMPONENT: IngredientRow.svelte
INGREDIENT ROW:
<label style="display:flex; justify-content:space-between; align-items:center;
padding: 10px 14px (mobile) | 9px 14px (desktop);
border-bottom: 1px solid --color-border;
background: selected ? --green-tint : --color-page;
cursor: pointer">
<span style="font-size:13px; color: selected ? --green-dark : --color-text;
font-weight: selected ? 500 : 400">{name}</span>
<input type="checkbox" checked={selected}
style="width:16px; height:16px; accent-color: --green-dark"
onchange={onToggle}>
</label>
DESKTOP LAYOUT:
display:grid; grid-template-columns: 1fr 1fr; gap: 16px
each column: one category block (border + border-radius)
overflow categories beyond 2 columns: continue vertically below
FILTER BAR (desktop):
search input (flex:1) + category <select> side by side
select: font-size 12px, same surface+border styling as search
─────────────────────────────────────────────────────────────
## CONCEPT 05 — Enhanced Current (RECOMMENDED FOR v1)
CHANGES REQUIRED:
1. CategorySection.svelte
ADD PROP: onSelectAll: () => void
ADD PROP: onDeselectAll: () => void
MODIFY header row:
- wrap label + badge + action buttons in flex row, justify-content: space-between
- badge: {selected} / {total}, green when selected>0, gray when 0
- action buttons: "Alle" | "Keine" (10px, 500, 0.04em tracking, full-radius, no-bg)
2. CategorySection.svelte — overflow
PROP: visibleLimit: number = 8
COMPUTED: visibleIngredients = ingredients.slice(0, expanded ? ∞ : visibleLimit)
STATE: expanded: boolean = false
RENDER after chips: if ingredients.length > visibleLimit && !expanded:
<button onclick={() => expanded = true} style="font-size:11px; color:--color-text-muted; bg:none; border:none">
+{ingredients.length - visibleLimit} weitere …
</button>
3. StaplesManager.svelte
ADD to handleToggle: propagate selectAll/deselectAll per category via bulk state update
ADD global count display: sum of Object.values(stapleState).filter(Boolean).length
RENDER count next to h1 in +page.svelte (pass as prop or slot)
4. +page.svelte (settings context only)
MODIFY h1 row: flex, space-between, baseline-align
ADD: <span class="subtext-count">{totalSelected} Vorräte gewählt</span>
TOKEN REFERENCE:
| Token | Value | Usage |
|--------------------|-------------- |---------------------------------|
| badge bg (active) | --green-tint | selected > 0 |
| badge text (active)| --green-dark | selected > 0 |
| badge bg (zero) | --color-subtle| selected === 0 |
| badge text (zero) | --color-text-muted | selected === 0 |
| action btn text | --color-text-muted | Alle / Keine |
| action btn border | --color-border | Alle / Keine |
| overflow btn text | --color-text-muted | "+N weitere…" |
| count label | --color-text-muted | header total count |
-->
</div>
</body>
</html>