feat(recipes): add image upload, fix save 500, seed HelloFresh data
- Store hero image as base64 data URI in text column (V023 migration) - Add file upload UI to RecipeForm with FileReader preview - Remove isChildFriendly from RecipeCreateRequest (no form field) - Fix 500 on save: effort values now lowercase, serves/cookTimeMin changed from primitive short to nullable Integer to survive omitted fields - Fix empty categories panel: removed stale tagType=category filter - Group category tags by type with German headings in recipe form - Split SuggestionResponse.SuggestionRecipe (no image) from SlotRecipe - Seed 11 HelloFresh recipes with ingredients, steps and tags (V101) - Add frontend e2e scaffold, specs and dev yml Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
761
specs/e2-members.html
Normal file
761
specs/e2-members.html
Normal file
@@ -0,0 +1,761 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>E2 — Mitglieder · 5 Variationen</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,300;9..144,400;9..144,500&family=DM+Sans:wght@300;400;500;600&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet"/>
|
||||
<!--
|
||||
spec:agent
|
||||
document: E2 Members Page — Design Variations
|
||||
version: 1.0
|
||||
journey: J7 Manage household members
|
||||
route: /members
|
||||
screen: E2
|
||||
variations: V1 Roster list | V2 Card grid | V3 Split panel | V4 Dense table | V5 Expandable rows
|
||||
last-updated: 2026-04
|
||||
-->
|
||||
<style>
|
||||
:root {
|
||||
--color-page: #FAFAF7;
|
||||
--color-surface: #F5F4EE;
|
||||
--color-subtle: #EDECEA;
|
||||
--color-border: #D8D7D0;
|
||||
--color-text-muted: #6B6A63;
|
||||
--color-text: #1C1C18;
|
||||
--green-tint: #E8F5EA;
|
||||
--green-light: #AEDCB0;
|
||||
--green: #3D8C4A;
|
||||
--green-dark: #2E6E39;
|
||||
--green-deeper: #1E4A26;
|
||||
--yellow-tint: #FDF6D8;
|
||||
--yellow-light: #F9E08A;
|
||||
--yellow-text: #8A6800;
|
||||
--color-error: #DC4C3E;
|
||||
--blue-tint: #E6F1FB;
|
||||
--blue: #185FA5;
|
||||
--blue-dark: #0C447C;
|
||||
--font-display: 'Fraunces', Georgia, serif;
|
||||
--font-sans: 'DM Sans', system-ui, sans-serif;
|
||||
--font-mono: 'DM Mono', monospace;
|
||||
--radius-sm: 4px; --radius-md: 6px; --radius-lg: 10px; --radius-xl: 16px; --radius-full: 9999px;
|
||||
--shadow-card: 0 1px 3px rgba(28,28,24,.06), 0 1px 2px rgba(28,28,24,.04);
|
||||
--shadow-raised: 0 4px 12px rgba(28,28,24,.08), 0 2px 4px rgba(28,28,24,.04);
|
||||
}
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body { font-family: var(--font-sans); background: var(--color-page); color: var(--color-text); font-size: 14px; line-height: 1.6; }
|
||||
|
||||
/* ── Doc layout ── */
|
||||
.doc { max-width: 960px; margin: 0 auto; padding: 48px 40px 96px; }
|
||||
.doc-header { display: flex; justify-content: space-between; align-items: flex-end; padding-bottom: 28px; border-bottom: 1px solid var(--color-border); margin-bottom: 48px; }
|
||||
.doc-header h1 { font-family: var(--font-display); font-size: 26px; font-weight: 500; letter-spacing: -0.02em; margin-bottom: 4px; }
|
||||
.doc-header p { font-size: 13px; color: var(--color-text-muted); }
|
||||
.doc-meta { font-family: var(--font-mono); font-size: 11px; color: var(--color-text-muted); text-align: right; line-height: 1.9; }
|
||||
.intro { font-size: 14px; line-height: 1.75; color: var(--color-text); max-width: 640px; margin-bottom: 48px; }
|
||||
.section-label { font-size: 10px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--color-text-muted); padding-bottom: 10px; border-bottom: 1px solid var(--color-border); margin-bottom: 36px; }
|
||||
|
||||
/* ── Variation sections ── */
|
||||
.variation { margin-bottom: 72px; }
|
||||
.var-header { display: flex; align-items: flex-start; gap: 20px; margin-bottom: 20px; }
|
||||
.var-num { font-family: var(--font-display); font-size: 44px; font-weight: 300; color: var(--green-light); line-height: 1; flex-shrink: 0; width: 56px; letter-spacing: -0.03em; }
|
||||
.var-meta { flex: 1; padding-top: 4px; }
|
||||
.var-title { font-size: 18px; font-weight: 500; letter-spacing: -0.01em; margin-bottom: 4px; }
|
||||
.var-desc { font-size: 13px; color: var(--color-text-muted); line-height: 1.5; max-width: 540px; }
|
||||
.var-tag { font-size: 10px; font-weight: 500; letter-spacing: 0.07em; text-transform: uppercase; padding: 3px 8px; border-radius: var(--radius-sm); background: var(--color-subtle); color: var(--color-text-muted); white-space: nowrap; margin-top: 6px; display: inline-block; }
|
||||
.var-tag.rec { background: var(--green-tint); color: var(--green-dark); }
|
||||
|
||||
/* ── Preview containers ── */
|
||||
.preview-pair { display: flex; gap: 24px; align-items: flex-start; margin-bottom: 20px; }
|
||||
.preview-d-wrap { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
|
||||
.preview-m-wrap { flex-shrink: 0; display: flex; flex-direction: column; gap: 6px; }
|
||||
.preview-label { font-size: 9px; font-weight: 500; letter-spacing: 0.09em; text-transform: uppercase; color: var(--color-text-muted); }
|
||||
.preview-d-clip { height: 340px; overflow: hidden; border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-page); }
|
||||
.preview-d-scale { transform: scale(0.5); transform-origin: top left; width: 200%; }
|
||||
.preview-m-clip { width: 196px; height: 340px; overflow: hidden; border: 1.5px solid var(--color-border); border-radius: 24px; background: var(--color-page); }
|
||||
.preview-m-scale { transform: scale(0.5); transform-origin: top left; width: 200%; }
|
||||
|
||||
/* ── Notes ── */
|
||||
.var-notes { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 16px 20px; }
|
||||
.var-notes-label { font-size: 9px; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-text-muted); margin-bottom: 10px; }
|
||||
.var-notes ul { list-style: none; display: flex; flex-direction: column; gap: 5px; }
|
||||
.var-notes li { font-size: 12px; color: var(--color-text-muted); line-height: 1.5; display: flex; align-items: flex-start; gap: 8px; }
|
||||
.var-notes li::before { content: '→'; color: var(--green); font-weight: 500; flex-shrink: 0; }
|
||||
|
||||
/* ── Agent section ── */
|
||||
.agent-section { background: var(--color-text); color: #E8E8E2; padding: 40px 48px; margin-top: 64px; }
|
||||
.agent-section h2 { font-size: 10px; font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase; color: #6B6A63; margin-bottom: 4px; }
|
||||
.agent-section > p { font-size: 13px; color: #9A9990; margin-bottom: 28px; line-height: 1.6; max-width: 640px; }
|
||||
.spec-comment { font-family: var(--font-mono); font-size: 11px; color: #3A3A36; margin-bottom: 32px; line-height: 1.9; white-space: pre-wrap; }
|
||||
.agent-table { width: 100%; border-collapse: collapse; font-family: var(--font-mono); font-size: 11px; margin-bottom: 40px; }
|
||||
.agent-table thead tr { border-bottom: 1px solid #2A2A26; }
|
||||
.agent-table th { text-align: left; padding: 8px 14px; font-size: 9px; font-weight: 500; letter-spacing: 0.09em; text-transform: uppercase; color: #5A5A55; font-family: var(--font-sans); }
|
||||
.agent-table td { padding: 9px 14px; border-bottom: 1px solid #1E1E1A; vertical-align: top; line-height: 1.5; }
|
||||
.agent-table tr:last-child td { border-bottom: none; }
|
||||
.agent-table td:first-child { color: #7A7A72; white-space: nowrap; }
|
||||
.agent-table td:nth-child(2) { color: #E8E8E2; font-weight: 500; }
|
||||
.agent-table td:nth-child(3) { color: #5A5A55; }
|
||||
.group-row td { padding-top: 20px; font-family: var(--font-sans); font-size: 9px; font-weight: 500; letter-spacing: 0.09em; text-transform: uppercase; color: #3A3A36; border-bottom: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="doc">
|
||||
|
||||
<div class="doc-header">
|
||||
<div>
|
||||
<h1>E2 — Mitglieder</h1>
|
||||
<p>5 Design-Variationen · Desktop-first · Route /members · Journey J7</p>
|
||||
</div>
|
||||
<div class="doc-meta">
|
||||
Version: 1.0<br>
|
||||
Screen: E2<br>
|
||||
Journey: J7<br>
|
||||
Actor: Planner<br>
|
||||
Last updated: 2026-04
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="intro">The members page is a rarely-visited, high-trust page. The planner opens it when the household changes — a new partner joins, a family member needs access removed. The household is typically 2–4 people. Five variations explore the range from a simple list to a panel-based layout. The recommended variation for v1 is <strong style="font-weight:500">V1 (Roster list)</strong> — fewest moving parts, matches the access frequency, household size, and task urgency.</p>
|
||||
|
||||
<div class="section-label">Five design variations</div>
|
||||
|
||||
|
||||
<!-- ══════════════════════════════════════
|
||||
V1 — ROSTER LIST
|
||||
══════════════════════════════════════ -->
|
||||
<div class="variation">
|
||||
<div class="var-header">
|
||||
<div class="var-num">V1</div>
|
||||
<div class="var-meta">
|
||||
<div class="var-title">Roster-Liste</div>
|
||||
<div class="var-desc">Lineares Listenformat. Alle Mitglieder als Zeilen mit Avatar, Name, Rolle und Beitrittsdatum. Ausstehende Einladungen darunter. Minimale kognitive Last für eine seltene Aufgabe.</div>
|
||||
<span class="var-tag rec">Empfohlen · v1</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="preview-pair">
|
||||
<!-- Desktop -->
|
||||
<div class="preview-d-wrap">
|
||||
<div class="preview-label">Desktop · 1200px</div>
|
||||
<div class="preview-d-clip">
|
||||
<div class="preview-d-scale">
|
||||
<div style="display:flex;width:1200px;min-height:680px;background:var(--color-page);">
|
||||
<!-- Sidebar -->
|
||||
<aside style="width:224px;flex-shrink:0;background:var(--color-surface);border-right:1px solid var(--color-border);padding:0;display:flex;flex-direction:column;min-height:680px;">
|
||||
<div style="padding:18px 16px 16px;border-bottom:1px solid var(--color-border);display:flex;align-items:center;gap:10px;">
|
||||
<div style="width:22px;height:22px;background:var(--green);border-radius:5px;flex-shrink:0;"></div>
|
||||
<div><div style="font-family:var(--font-display);font-size:15px;font-weight:500;color:var(--color-text);letter-spacing:-0.01em;">Mealprep</div><div style="font-size:10px;color:var(--color-text-muted);letter-spacing:0.01em;">Familie Raddatz</div></div>
|
||||
</div>
|
||||
<nav style="padding:16px 0;flex:1;">
|
||||
<div style="font-size:8px;font-weight:500;letter-spacing:0.1em;text-transform:uppercase;color:var(--color-text-muted);padding:0 16px 6px;">Plan</div>
|
||||
<a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Planer</a>
|
||||
<a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Rezepte</a>
|
||||
<a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Einkauf</a>
|
||||
<div style="font-size:8px;font-weight:500;letter-spacing:0.1em;text-transform:uppercase;color:var(--color-text-muted);padding:16px 16px 6px;">Haushalt</div>
|
||||
<a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;background:var(--green-tint);color:var(--green-dark);font-weight:500;text-decoration:none;border-radius:var(--radius-md);margin:0 8px;"><span style="width:16px;height:16px;background:var(--green-light);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Mitglieder</a>
|
||||
<a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;margin:0 8px;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Einstellungen</a>
|
||||
</nav>
|
||||
</aside>
|
||||
<!-- Content -->
|
||||
<main style="flex:1;padding:40px 56px;overflow:hidden;">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:32px;">
|
||||
<div style="display:flex;align-items:center;gap:12px;">
|
||||
<h1 style="font-family:var(--font-display);font-size:28px;font-weight:500;letter-spacing:-0.02em;color:var(--color-text);">Mitglieder</h1>
|
||||
<span style="background:var(--color-subtle);color:var(--color-text-muted);font-size:12px;font-weight:500;padding:2px 9px;border-radius:var(--radius-full);">3</span>
|
||||
</div>
|
||||
<button style="background:var(--green-dark);color:#fff;font-family:var(--font-sans);font-size:13px;font-weight:500;letter-spacing:0.04em;padding:10px 20px;border-radius:var(--radius-md);border:none;cursor:pointer;">Mitglied einladen</button>
|
||||
</div>
|
||||
<!-- Members -->
|
||||
<div style="margin-bottom:32px;">
|
||||
<div style="display:flex;align-items:center;gap:14px;padding:14px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:40px;height:40px;border-radius:50%;background:var(--green-tint);display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600;color:var(--green-dark);flex-shrink:0;font-family:var(--font-sans);">MR</div>
|
||||
<div style="flex:1;">
|
||||
<div style="font-size:14px;font-weight:500;color:var(--color-text);">Marcel Raddatz</div>
|
||||
<div style="font-size:12px;color:var(--color-text-muted);">Beigetreten 14. Januar 2026</div>
|
||||
</div>
|
||||
<span style="padding:3px 10px;border-radius:var(--radius-full);font-size:11px;font-weight:500;background:var(--green-tint);color:var(--green-dark);">Planner</span>
|
||||
<div style="width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:var(--color-text-muted);font-size:18px;cursor:pointer;">⋯</div>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:14px;padding:14px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:40px;height:40px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600;color:var(--blue-dark);flex-shrink:0;font-family:var(--font-sans);">SR</div>
|
||||
<div style="flex:1;">
|
||||
<div style="font-size:14px;font-weight:500;color:var(--color-text);">Sarah Raddatz</div>
|
||||
<div style="font-size:12px;color:var(--color-text-muted);">Beigetreten 15. Januar 2026</div>
|
||||
</div>
|
||||
<span style="padding:3px 10px;border-radius:var(--radius-full);font-size:11px;font-weight:500;background:var(--blue-tint);color:var(--blue-dark);">Mitglied</span>
|
||||
<div style="width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:var(--color-text-muted);font-size:18px;cursor:pointer;">⋯</div>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:14px;padding:14px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:40px;height:40px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600;color:var(--blue-dark);flex-shrink:0;font-family:var(--font-sans);">TM</div>
|
||||
<div style="flex:1;">
|
||||
<div style="font-size:14px;font-weight:500;color:var(--color-text);">Tom Meier</div>
|
||||
<div style="font-size:12px;color:var(--color-text-muted);">Beigetreten 3. März 2026</div>
|
||||
</div>
|
||||
<span style="padding:3px 10px;border-radius:var(--radius-full);font-size:11px;font-weight:500;background:var(--blue-tint);color:var(--blue-dark);">Mitglied</span>
|
||||
<div style="width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:var(--color-text-muted);font-size:18px;cursor:pointer;">⋯</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pending invites -->
|
||||
<div style="font-size:11px;font-weight:500;letter-spacing:0.06em;text-transform:uppercase;color:var(--color-text-muted);margin-bottom:12px;">Ausstehende Einladungen · 1</div>
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:14px 16px;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);">
|
||||
<div style="font-family:var(--font-mono);font-size:13px;color:var(--color-text);flex:1;">inv_x8K2j</div>
|
||||
<div style="font-size:12px;color:var(--yellow-text);background:var(--yellow-tint);padding:2px 8px;border-radius:var(--radius-sm);">Läuft ab in 2 Tagen</div>
|
||||
<button style="font-family:var(--font-sans);font-size:12px;font-weight:500;padding:6px 14px;border-radius:var(--radius-md);background:var(--color-page);border:1px solid var(--color-border);cursor:pointer;color:var(--color-text);">Kopieren</button>
|
||||
<button style="font-family:var(--font-sans);font-size:12px;font-weight:500;padding:6px 14px;border-radius:var(--radius-md);background:var(--color-page);border:1px solid var(--color-border);cursor:pointer;color:var(--color-text);">Neu generieren</button>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Mobile -->
|
||||
<div class="preview-m-wrap">
|
||||
<div class="preview-label">Mobile · 390px</div>
|
||||
<div class="preview-m-clip">
|
||||
<div class="preview-m-scale">
|
||||
<div style="width:390px;min-height:680px;background:var(--color-page);display:flex;flex-direction:column;">
|
||||
<div style="padding:16px 20px 12px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--color-border);background:var(--color-surface);">
|
||||
<div style="font-family:var(--font-display);font-size:20px;font-weight:500;letter-spacing:-0.02em;">Mitglieder</div>
|
||||
<button style="background:var(--green-dark);color:#fff;font-size:12px;font-weight:500;padding:8px 14px;border-radius:var(--radius-md);border:none;">+ Einladen</button>
|
||||
</div>
|
||||
<div style="flex:1;overflow:hidden;padding:0 20px;">
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--green-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--green-dark);flex-shrink:0;">MR</div>
|
||||
<div style="flex:1;"><div style="font-size:14px;font-weight:500;">Marcel Raddatz</div><div style="font-size:11px;color:var(--color-text-muted);">Planner · Seit 14.1.26</div></div>
|
||||
<div style="font-size:18px;color:var(--color-text-muted);">⋯</div>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">SR</div>
|
||||
<div style="flex:1;"><div style="font-size:14px;font-weight:500;">Sarah Raddatz</div><div style="font-size:11px;color:var(--color-text-muted);">Mitglied · Seit 15.1.26</div></div>
|
||||
<div style="font-size:18px;color:var(--color-text-muted);">⋯</div>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">TM</div>
|
||||
<div style="flex:1;"><div style="font-size:14px;font-weight:500;">Tom Meier</div><div style="font-size:11px;color:var(--color-text-muted);">Mitglied · Seit 3.3.26</div></div>
|
||||
<div style="font-size:18px;color:var(--color-text-muted);">⋯</div>
|
||||
</div>
|
||||
<div style="padding:16px 0 12px;"><div style="font-size:10px;font-weight:500;letter-spacing:0.06em;text-transform:uppercase;color:var(--color-text-muted);margin-bottom:10px;">Einladungen · 1</div>
|
||||
<div style="padding:12px 14px;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;"><span style="font-family:var(--font-mono);font-size:12px;">inv_x8K2j</span><span style="font-size:11px;color:var(--yellow-text);">2 Tage</span></div>
|
||||
<div style="display:flex;gap:8px;"><button style="flex:1;font-size:12px;font-weight:500;padding:6px;border-radius:var(--radius-md);background:var(--color-page);border:1px solid var(--color-border);cursor:pointer;">Kopieren</button><button style="flex:1;font-size:12px;font-weight:500;padding:6px;border-radius:var(--radius-md);background:var(--color-page);border:1px solid var(--color-border);cursor:pointer;">Neu</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<nav style="background:var(--color-surface);border-top:1px solid var(--color-border);padding:8px 0 20px;display:flex;">
|
||||
<a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Planer</a>
|
||||
<a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Rezepte</a>
|
||||
<a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Einkauf</a>
|
||||
<a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--green-dark);font-weight:500;text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--green-light);border-radius:3px;display:inline-block;"></span>Einstellungen</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="var-notes">
|
||||
<div class="var-notes-label">Design-Entscheidungen</div>
|
||||
<ul>
|
||||
<li>Planner-Avatar in Grün (--green-tint), Mitglieder-Avatar in Blau (--blue-tint) — Rollenfarben konsistent mit den Rollenbadges in der Spec.</li>
|
||||
<li>Kebab-Menü (⋯) öffnet ein Kontextmenü mit "Zugang entziehen". Destructive action erfordert Bestätigung mit Mitgliedsnamen.</li>
|
||||
<li>Ausstehende Einladungen haben einen gelben Ablauf-Badge wenn ≤ 3 Tage verbleiben, grau wenn mehr Zeit bleibt.</li>
|
||||
<li>Auf Mobile: "Einladen"-Button als Kompakt-CTA im Seitenkopf (kein großes Hero-Element) — die Seite ist keine Onboarding-Seite, sondern eine Management-Seite.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ══════════════════════════════════════
|
||||
V2 — CARD GRID
|
||||
══════════════════════════════════════ -->
|
||||
<div class="variation">
|
||||
<div class="var-header">
|
||||
<div class="var-num">V2</div>
|
||||
<div class="var-meta">
|
||||
<div class="var-title">Kachelraster</div>
|
||||
<div class="var-desc">Jedes Mitglied als eigenständige Kachel mit großem Avatar-Kreis, Name, Rolle und Datum. Eine "+" Kachel mit gestricheltem Rand fungiert als Invite-CTA. Visuelle, scannable Übersicht.</div>
|
||||
<span class="var-tag">Geeignet ab 4+ Mitgliedern</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="preview-pair">
|
||||
<div class="preview-d-wrap">
|
||||
<div class="preview-label">Desktop · 1200px</div>
|
||||
<div class="preview-d-clip">
|
||||
<div class="preview-d-scale">
|
||||
<div style="display:flex;width:1200px;min-height:680px;background:var(--color-page);">
|
||||
<aside style="width:224px;flex-shrink:0;background:var(--color-surface);border-right:1px solid var(--color-border);padding:0;display:flex;flex-direction:column;min-height:680px;">
|
||||
<div style="padding:18px 16px 16px;border-bottom:1px solid var(--color-border);display:flex;align-items:center;gap:10px;"><div style="width:22px;height:22px;background:var(--green);border-radius:5px;flex-shrink:0;"></div><div><div style="font-family:var(--font-display);font-size:15px;font-weight:500;color:var(--color-text);">Mealprep</div><div style="font-size:10px;color:var(--color-text-muted);">Familie Raddatz</div></div></div>
|
||||
<nav style="padding:16px 0;flex:1;"><div style="font-size:8px;font-weight:500;letter-spacing:0.1em;text-transform:uppercase;color:var(--color-text-muted);padding:0 16px 6px;">Plan</div><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Planer</a><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Rezepte</a><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Einkauf</a><div style="font-size:8px;font-weight:500;letter-spacing:0.1em;text-transform:uppercase;color:var(--color-text-muted);padding:16px 16px 6px;">Haushalt</div><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;background:var(--green-tint);color:var(--green-dark);font-weight:500;text-decoration:none;border-radius:var(--radius-md);margin:0 8px;"><span style="width:16px;height:16px;background:var(--green-light);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Mitglieder</a><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;margin:0 8px;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Einstellungen</a></nav>
|
||||
</aside>
|
||||
<main style="flex:1;padding:40px 56px;">
|
||||
<h1 style="font-family:var(--font-display);font-size:28px;font-weight:500;letter-spacing:-0.02em;margin-bottom:32px;">Mitglieder</h1>
|
||||
<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:16px;">
|
||||
<!-- Member card -->
|
||||
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-xl);padding:24px 20px;display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center;box-shadow:var(--shadow-card);">
|
||||
<div style="width:56px;height:56px;border-radius:50%;background:var(--green-tint);display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:600;color:var(--green-dark);">MR</div>
|
||||
<div><div style="font-size:14px;font-weight:500;">Marcel Raddatz</div><div style="font-size:11px;color:var(--color-text-muted);margin-top:2px;">14. Jan 2026</div></div>
|
||||
<span style="padding:3px 10px;border-radius:var(--radius-full);font-size:11px;font-weight:500;background:var(--green-tint);color:var(--green-dark);">Planner</span>
|
||||
</div>
|
||||
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-xl);padding:24px 20px;display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center;box-shadow:var(--shadow-card);">
|
||||
<div style="width:56px;height:56px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:600;color:var(--blue-dark);">SR</div>
|
||||
<div><div style="font-size:14px;font-weight:500;">Sarah Raddatz</div><div style="font-size:11px;color:var(--color-text-muted);margin-top:2px;">15. Jan 2026</div></div>
|
||||
<span style="padding:3px 10px;border-radius:var(--radius-full);font-size:11px;font-weight:500;background:var(--blue-tint);color:var(--blue-dark);">Mitglied</span>
|
||||
</div>
|
||||
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-xl);padding:24px 20px;display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center;box-shadow:var(--shadow-card);">
|
||||
<div style="width:56px;height:56px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:600;color:var(--blue-dark);">TM</div>
|
||||
<div><div style="font-size:14px;font-weight:500;">Tom Meier</div><div style="font-size:11px;color:var(--color-text-muted);margin-top:2px;">3. Mär 2026</div></div>
|
||||
<span style="padding:3px 10px;border-radius:var(--radius-full);font-size:11px;font-weight:500;background:var(--blue-tint);color:var(--blue-dark);">Mitglied</span>
|
||||
</div>
|
||||
<!-- Invite tile -->
|
||||
<div style="border:2px dashed var(--color-border);border-radius:var(--radius-xl);padding:24px 20px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;text-align:center;cursor:pointer;">
|
||||
<div style="width:56px;height:56px;border-radius:50%;background:var(--color-subtle);display:flex;align-items:center;justify-content:center;font-size:24px;color:var(--color-text-muted);">+</div>
|
||||
<div style="font-size:13px;font-weight:500;color:var(--color-text-muted);">Einladen</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="preview-m-wrap">
|
||||
<div class="preview-label">Mobile · 390px</div>
|
||||
<div class="preview-m-clip">
|
||||
<div class="preview-m-scale">
|
||||
<div style="width:390px;min-height:680px;background:var(--color-page);display:flex;flex-direction:column;">
|
||||
<div style="padding:16px 20px 12px;border-bottom:1px solid var(--color-border);background:var(--color-surface);"><div style="font-family:var(--font-display);font-size:20px;font-weight:500;">Mitglieder</div></div>
|
||||
<div style="flex:1;padding:16px 20px;display:grid;grid-template-columns:1fr 1fr;gap:12px;align-content:start;">
|
||||
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;">
|
||||
<div style="width:44px;height:44px;border-radius:50%;background:var(--green-tint);display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:600;color:var(--green-dark);">MR</div>
|
||||
<div style="font-size:13px;font-weight:500;">Marcel R.</div>
|
||||
<span style="font-size:10px;font-weight:500;padding:2px 8px;border-radius:var(--radius-full);background:var(--green-tint);color:var(--green-dark);">Planner</span>
|
||||
</div>
|
||||
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;">
|
||||
<div style="width:44px;height:44px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:600;color:var(--blue-dark);">SR</div>
|
||||
<div style="font-size:13px;font-weight:500;">Sarah R.</div>
|
||||
<span style="font-size:10px;font-weight:500;padding:2px 8px;border-radius:var(--radius-full);background:var(--blue-tint);color:var(--blue-dark);">Mitglied</span>
|
||||
</div>
|
||||
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;">
|
||||
<div style="width:44px;height:44px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:600;color:var(--blue-dark);">TM</div>
|
||||
<div style="font-size:13px;font-weight:500;">Tom M.</div>
|
||||
<span style="font-size:10px;font-weight:500;padding:2px 8px;border-radius:var(--radius-full);background:var(--blue-tint);color:var(--blue-dark);">Mitglied</span>
|
||||
</div>
|
||||
<div style="border:2px dashed var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;text-align:center;cursor:pointer;">
|
||||
<div style="width:44px;height:44px;border-radius:50%;background:var(--color-subtle);display:flex;align-items:center;justify-content:center;font-size:20px;color:var(--color-text-muted);">+</div>
|
||||
<div style="font-size:12px;font-weight:500;color:var(--color-text-muted);">Einladen</div>
|
||||
</div>
|
||||
</div>
|
||||
<nav style="background:var(--color-surface);border-top:1px solid var(--color-border);padding:8px 0 20px;display:flex;"><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Planer</a><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Rezepte</a><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Einkauf</a><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--green-dark);font-weight:500;text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--green-light);border-radius:3px;display:inline-block;"></span>Einstellungen</a></nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="var-notes">
|
||||
<div class="var-notes-label">Design-Entscheidungen</div>
|
||||
<ul>
|
||||
<li>Kachelgröße funktioniert nur bis ca. 6 Mitgliedern — ab 7+ muss auf Liste zurückgefallen werden. Für die typische Haushaltsgröße (2–4) unnötig visuell.</li>
|
||||
<li>Die "+" Einladen-Kachel mit gestricheltem Rahmen ist ein etabliertes Muster für "leerer Slot zum Hinzufügen" — sofort verständlich ohne Label-Erklärung.</li>
|
||||
<li>Schlechter als V1 für Remove-Aktionen: Die Entfernen-Aktion ist auf der Kachel nicht sichtbar — man muss sie irgendwo verstecken (Hover-State, Kontextmenü). Auf Mobile nicht erreichbar ohne Tap-Geste.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ══════════════════════════════════════
|
||||
V3 — SPLIT PANEL
|
||||
══════════════════════════════════════ -->
|
||||
<div class="variation">
|
||||
<div class="var-header">
|
||||
<div class="var-num">V3</div>
|
||||
<div class="var-meta">
|
||||
<div class="var-title">Split-Panel</div>
|
||||
<div class="var-desc">Geteilte Ansicht: links die Mitgliederliste, rechts das Einladungs-Management-Panel. Auf Desktop zeigt das rechte Panel immer den aktuellen Invite-Status. Auf Mobile: Tab-Navigation zwischen den beiden Bereichen.</div>
|
||||
<span class="var-tag">Für Haushalte mit häufigen Mitgliederwechseln</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="preview-pair">
|
||||
<div class="preview-d-wrap">
|
||||
<div class="preview-label">Desktop · 1200px</div>
|
||||
<div class="preview-d-clip">
|
||||
<div class="preview-d-scale">
|
||||
<div style="display:flex;width:1200px;min-height:680px;background:var(--color-page);">
|
||||
<aside style="width:224px;flex-shrink:0;background:var(--color-surface);border-right:1px solid var(--color-border);padding:0;display:flex;flex-direction:column;min-height:680px;"><div style="padding:18px 16px 16px;border-bottom:1px solid var(--color-border);display:flex;align-items:center;gap:10px;"><div style="width:22px;height:22px;background:var(--green);border-radius:5px;flex-shrink:0;"></div><div><div style="font-family:var(--font-display);font-size:15px;font-weight:500;color:var(--color-text);">Mealprep</div><div style="font-size:10px;color:var(--color-text-muted);">Familie Raddatz</div></div></div><nav style="padding:16px 0;flex:1;"><div style="font-size:8px;font-weight:500;letter-spacing:0.1em;text-transform:uppercase;color:var(--color-text-muted);padding:0 16px 6px;">Plan</div><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Planer</a><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Rezepte</a><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Einkauf</a><div style="font-size:8px;font-weight:500;letter-spacing:0.1em;text-transform:uppercase;color:var(--color-text-muted);padding:16px 16px 6px;">Haushalt</div><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;background:var(--green-tint);color:var(--green-dark);font-weight:500;text-decoration:none;border-radius:var(--radius-md);margin:0 8px;"><span style="width:16px;height:16px;background:var(--green-light);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Mitglieder</a><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;margin:0 8px;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Einstellungen</a></nav></aside>
|
||||
<!-- Split content -->
|
||||
<div style="flex:1;display:flex;overflow:hidden;">
|
||||
<!-- Left: member list -->
|
||||
<div style="width:340px;flex-shrink:0;border-right:1px solid var(--color-border);padding:32px 28px;background:var(--color-surface);">
|
||||
<div style="display:flex;align-items:center;gap:10px;margin-bottom:24px;">
|
||||
<span style="font-size:16px;font-weight:500;color:var(--color-text);">Mitglieder</span>
|
||||
<span style="background:var(--color-subtle);color:var(--color-text-muted);font-size:11px;font-weight:500;padding:1px 7px;border-radius:var(--radius-full);">3</span>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:10px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--green-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--green-dark);flex-shrink:0;">MR</div>
|
||||
<div style="flex:1;"><div style="font-size:13px;font-weight:500;">Marcel Raddatz</div><div style="font-size:11px;color:var(--color-text-muted);">Planner</div></div>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:10px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">SR</div>
|
||||
<div style="flex:1;"><div style="font-size:13px;font-weight:500;">Sarah Raddatz</div><div style="font-size:11px;color:var(--color-text-muted);">Mitglied</div></div>
|
||||
<button style="font-size:11px;color:var(--color-error);background:none;border:none;cursor:pointer;padding:4px;">Entfernen</button>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:10px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">TM</div>
|
||||
<div style="flex:1;"><div style="font-size:13px;font-weight:500;">Tom Meier</div><div style="font-size:11px;color:var(--color-text-muted);">Mitglied</div></div>
|
||||
<button style="font-size:11px;color:var(--color-error);background:none;border:none;cursor:pointer;padding:4px;">Entfernen</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Right: invite panel -->
|
||||
<div style="flex:1;padding:32px 36px;">
|
||||
<div style="font-size:16px;font-weight:500;margin-bottom:20px;">Mitglied einladen</div>
|
||||
<div style="font-size:13px;color:var(--color-text-muted);margin-bottom:16px;line-height:1.5;">Teile diesen Link per WhatsApp, SMS oder E-Mail. Der Empfänger erstellt ein Konto und tritt automatisch dem Haushalt bei.</div>
|
||||
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);padding:12px 14px;display:flex;align-items:center;gap:10px;margin-bottom:12px;">
|
||||
<span style="font-family:var(--font-mono);font-size:12px;color:var(--color-text-muted);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">https://mealprep.app/join/inv_x8K2j</span>
|
||||
<button style="font-size:12px;font-weight:500;padding:6px 14px;border-radius:var(--radius-md);background:var(--green-dark);color:#fff;border:none;cursor:pointer;white-space:nowrap;">Kopieren</button>
|
||||
</div>
|
||||
<button style="width:100%;font-size:13px;font-weight:500;padding:10px;border-radius:var(--radius-md);background:var(--color-page);border:1px solid var(--color-border);cursor:pointer;margin-bottom:28px;">Neuen Link generieren</button>
|
||||
<div style="font-size:11px;font-weight:500;letter-spacing:0.06em;text-transform:uppercase;color:var(--color-text-muted);margin-bottom:12px;">Ausstehende Einladungen · 1</div>
|
||||
<div style="display:flex;align-items:center;gap:10px;padding:12px 14px;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);">
|
||||
<span style="font-family:var(--font-mono);font-size:12px;flex:1;">inv_x8K2j</span>
|
||||
<span style="font-size:11px;color:var(--yellow-text);background:var(--yellow-tint);padding:2px 7px;border-radius:var(--radius-sm);">2 Tage</span>
|
||||
<button style="font-size:18px;color:var(--color-text-muted);background:none;border:none;cursor:pointer;">✕</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="preview-m-wrap">
|
||||
<div class="preview-label">Mobile · 390px (Tab-Navigation)</div>
|
||||
<div class="preview-m-clip">
|
||||
<div class="preview-m-scale">
|
||||
<div style="width:390px;min-height:680px;background:var(--color-page);display:flex;flex-direction:column;">
|
||||
<div style="padding:16px 20px 0;background:var(--color-surface);border-bottom:1px solid var(--color-border);">
|
||||
<div style="font-family:var(--font-display);font-size:20px;font-weight:500;margin-bottom:12px;">Mitglieder</div>
|
||||
<div style="display:flex;gap:0;">
|
||||
<button style="flex:1;padding:8px;font-size:13px;font-weight:500;border:none;border-bottom:2px solid var(--green-dark);background:none;color:var(--green-dark);cursor:pointer;">Mitglieder (3)</button>
|
||||
<button style="flex:1;padding:8px;font-size:13px;font-weight:500;border:none;border-bottom:2px solid transparent;background:none;color:var(--color-text-muted);cursor:pointer;">Einladen</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="flex:1;padding:0 20px;">
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--green-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--green-dark);flex-shrink:0;">MR</div>
|
||||
<div style="flex:1;"><div style="font-size:14px;font-weight:500;">Marcel Raddatz</div><div style="font-size:11px;color:var(--color-text-muted);">Planner</div></div>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">SR</div>
|
||||
<div style="flex:1;"><div style="font-size:14px;font-weight:500;">Sarah Raddatz</div><div style="font-size:11px;color:var(--color-text-muted);">Mitglied</div></div>
|
||||
<button style="font-size:11px;color:var(--color-error);background:none;border:none;cursor:pointer;">Entfernen</button>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">TM</div>
|
||||
<div style="flex:1;"><div style="font-size:14px;font-weight:500;">Tom Meier</div><div style="font-size:11px;color:var(--color-text-muted);">Mitglied</div></div>
|
||||
<button style="font-size:11px;color:var(--color-error);background:none;border:none;cursor:pointer;">Entfernen</button>
|
||||
</div>
|
||||
</div>
|
||||
<nav style="background:var(--color-surface);border-top:1px solid var(--color-border);padding:8px 0 20px;display:flex;"><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Planer</a><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Rezepte</a><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Einkauf</a><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--green-dark);font-weight:500;text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--green-light);border-radius:3px;display:inline-block;"></span>Einstellungen</a></nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="var-notes">
|
||||
<div class="var-notes-label">Design-Entscheidungen</div>
|
||||
<ul>
|
||||
<li>Das rechte Panel zeigt immer den Invite-Status — kein Modal, kein Navigationsschritt. Gut für Haushalte, die regelmäßig neue Mitglieder onboarden (z. B. Wohngemeinschaften).</li>
|
||||
<li>"Entfernen" ist im linken Panel direkt sichtbar als Text-Link in Fehlerfarbe — kein verstecktes Kebab-Menü. Spart einen Schritt, erhöht aber das Risiko eines versehentlichen Taps auf Mobile.</li>
|
||||
<li>Mobile Tab-Navigation: Tabs mit Unterstrich-Indikator. Die "Mitglieder"-Seite ist der Default. "Einladen"-Tab zeigt das Invite-Panel mit Link-Generator und ausstehendem Invite.</li>
|
||||
<li>Nachteil: Mehr UI-Fläche für eine seltene Funktion (Invite). Für Haushalte mit 2 Personen wirkt das Panel überdimensioniert.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ══════════════════════════════════════
|
||||
V4 — DENSE TABLE
|
||||
══════════════════════════════════════ -->
|
||||
<div class="variation">
|
||||
<div class="var-header">
|
||||
<div class="var-num">V4</div>
|
||||
<div class="var-meta">
|
||||
<div class="var-title">Datentabelle</div>
|
||||
<div class="var-desc">Tabellarisches Format mit sortierbaren Spalten: Name, Rolle, Beigetreten, Status, Aktionen. Inline-Aktionen statt Kontextmenü. Kompakt und informationsdicht.</div>
|
||||
<span class="var-tag">Für Power-User · Viele Mitglieder</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="preview-pair">
|
||||
<div class="preview-d-wrap">
|
||||
<div class="preview-label">Desktop · 1200px</div>
|
||||
<div class="preview-d-clip">
|
||||
<div class="preview-d-scale">
|
||||
<div style="display:flex;width:1200px;min-height:680px;background:var(--color-page);">
|
||||
<aside style="width:224px;flex-shrink:0;background:var(--color-surface);border-right:1px solid var(--color-border);padding:0;display:flex;flex-direction:column;min-height:680px;"><div style="padding:18px 16px 16px;border-bottom:1px solid var(--color-border);display:flex;align-items:center;gap:10px;"><div style="width:22px;height:22px;background:var(--green);border-radius:5px;flex-shrink:0;"></div><div><div style="font-family:var(--font-display);font-size:15px;font-weight:500;color:var(--color-text);">Mealprep</div><div style="font-size:10px;color:var(--color-text-muted);">Familie Raddatz</div></div></div><nav style="padding:16px 0;flex:1;"><div style="font-size:8px;font-weight:500;letter-spacing:0.1em;text-transform:uppercase;color:var(--color-text-muted);padding:0 16px 6px;">Plan</div><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Planer</a><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Rezepte</a><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Einkauf</a><div style="font-size:8px;font-weight:500;letter-spacing:0.1em;text-transform:uppercase;color:var(--color-text-muted);padding:16px 16px 6px;">Haushalt</div><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;background:var(--green-tint);color:var(--green-dark);font-weight:500;text-decoration:none;border-radius:var(--radius-md);margin:0 8px;"><span style="width:16px;height:16px;background:var(--green-light);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Mitglieder</a><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;margin:0 8px;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Einstellungen</a></nav></aside>
|
||||
<main style="flex:1;padding:40px 56px;">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:28px;">
|
||||
<h1 style="font-family:var(--font-display);font-size:28px;font-weight:500;letter-spacing:-0.02em;">Mitglieder</h1>
|
||||
<button style="background:var(--green-dark);color:#fff;font-family:var(--font-sans);font-size:13px;font-weight:500;letter-spacing:0.04em;padding:10px 20px;border-radius:var(--radius-md);border:none;cursor:pointer;">Mitglied einladen</button>
|
||||
</div>
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px;">
|
||||
<thead>
|
||||
<tr style="border-bottom:1px solid var(--color-border);">
|
||||
<th style="text-align:left;padding:8px 12px;font-size:10px;font-weight:500;letter-spacing:0.07em;text-transform:uppercase;color:var(--color-text-muted);cursor:pointer;">Name ↕</th>
|
||||
<th style="text-align:left;padding:8px 12px;font-size:10px;font-weight:500;letter-spacing:0.07em;text-transform:uppercase;color:var(--color-text-muted);">Rolle</th>
|
||||
<th style="text-align:left;padding:8px 12px;font-size:10px;font-weight:500;letter-spacing:0.07em;text-transform:uppercase;color:var(--color-text-muted);cursor:pointer;">Beigetreten ↕</th>
|
||||
<th style="text-align:left;padding:8px 12px;font-size:10px;font-weight:500;letter-spacing:0.07em;text-transform:uppercase;color:var(--color-text-muted);">Status</th>
|
||||
<th style="text-align:right;padding:8px 12px;font-size:10px;font-weight:500;letter-spacing:0.07em;text-transform:uppercase;color:var(--color-text-muted);">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr style="border-bottom:1px solid var(--color-subtle);">
|
||||
<td style="padding:12px 12px;"><div style="display:flex;align-items:center;gap:10px;"><div style="width:30px;height:30px;border-radius:50%;background:var(--green-tint);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600;color:var(--green-dark);flex-shrink:0;">MR</div><span style="font-weight:500;">Marcel Raddatz</span></div></td>
|
||||
<td style="padding:12px 12px;"><span style="padding:2px 8px;border-radius:var(--radius-full);font-size:11px;font-weight:500;background:var(--green-tint);color:var(--green-dark);">Planner</span></td>
|
||||
<td style="padding:12px 12px;color:var(--color-text-muted);">14. Jan 2026</td>
|
||||
<td style="padding:12px 12px;"><span style="font-size:11px;color:var(--green-dark);">Aktiv</span></td>
|
||||
<td style="padding:12px 12px;text-align:right;color:var(--color-text-muted);font-size:12px;">—</td>
|
||||
</tr>
|
||||
<tr style="border-bottom:1px solid var(--color-subtle);">
|
||||
<td style="padding:12px 12px;"><div style="display:flex;align-items:center;gap:10px;"><div style="width:30px;height:30px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">SR</div><span style="font-weight:500;">Sarah Raddatz</span></div></td>
|
||||
<td style="padding:12px 12px;"><span style="padding:2px 8px;border-radius:var(--radius-full);font-size:11px;font-weight:500;background:var(--blue-tint);color:var(--blue-dark);">Mitglied</span></td>
|
||||
<td style="padding:12px 12px;color:var(--color-text-muted);">15. Jan 2026</td>
|
||||
<td style="padding:12px 12px;"><span style="font-size:11px;color:var(--green-dark);">Aktiv</span></td>
|
||||
<td style="padding:12px 12px;text-align:right;"><button style="font-size:12px;color:var(--color-error);background:none;border:none;cursor:pointer;padding:4px 8px;">Entfernen</button></td>
|
||||
</tr>
|
||||
<tr style="border-bottom:1px solid var(--color-subtle);">
|
||||
<td style="padding:12px 12px;"><div style="display:flex;align-items:center;gap:10px;"><div style="width:30px;height:30px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">TM</div><span style="font-weight:500;">Tom Meier</span></div></td>
|
||||
<td style="padding:12px 12px;"><span style="padding:2px 8px;border-radius:var(--radius-full);font-size:11px;font-weight:500;background:var(--blue-tint);color:var(--blue-dark);">Mitglied</span></td>
|
||||
<td style="padding:12px 12px;color:var(--color-text-muted);">3. Mär 2026</td>
|
||||
<td style="padding:12px 12px;"><span style="font-size:11px;color:var(--green-dark);">Aktiv</span></td>
|
||||
<td style="padding:12px 12px;text-align:right;"><button style="font-size:12px;color:var(--color-error);background:none;border:none;cursor:pointer;padding:4px 8px;">Entfernen</button></td>
|
||||
</tr>
|
||||
<!-- Pending invite row -->
|
||||
<tr style="background:var(--color-subtle);">
|
||||
<td style="padding:12px 12px;"><div style="display:flex;align-items:center;gap:10px;"><div style="width:30px;height:30px;border-radius:50%;background:var(--color-border);display:flex;align-items:center;justify-content:center;font-size:16px;color:var(--color-text-muted);flex-shrink:0;">?</div><span style="font-family:var(--font-mono);font-size:12px;color:var(--color-text-muted);">inv_x8K2j</span></div></td>
|
||||
<td style="padding:12px 12px;color:var(--color-text-muted);font-size:12px;">—</td>
|
||||
<td style="padding:12px 12px;color:var(--color-text-muted);font-size:12px;">—</td>
|
||||
<td style="padding:12px 12px;"><span style="font-size:11px;color:var(--yellow-text);background:var(--yellow-tint);padding:2px 7px;border-radius:var(--radius-sm);">Ausstehend · 2 Tage</span></td>
|
||||
<td style="padding:12px 12px;text-align:right;display:flex;justify-content:flex-end;gap:8px;"><button style="font-size:12px;color:var(--color-text-muted);background:none;border:none;cursor:pointer;padding:4px 8px;">Kopieren</button><button style="font-size:12px;color:var(--color-error);background:none;border:none;cursor:pointer;padding:4px 8px;">Ablehnen</button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="preview-m-wrap">
|
||||
<div class="preview-label">Mobile · 390px (Karten-Fallback)</div>
|
||||
<div class="preview-m-clip">
|
||||
<div class="preview-m-scale">
|
||||
<div style="width:390px;min-height:680px;background:var(--color-page);display:flex;flex-direction:column;">
|
||||
<div style="padding:16px 20px 12px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--color-border);background:var(--color-surface);"><div style="font-family:var(--font-display);font-size:20px;font-weight:500;">Mitglieder</div><button style="background:var(--green-dark);color:#fff;font-size:12px;font-weight:500;padding:7px 14px;border-radius:var(--radius-md);border:none;">+ Einladen</button></div>
|
||||
<div style="flex:1;padding:12px 20px;display:flex;flex-direction:column;gap:8px;">
|
||||
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:12px 14px;display:flex;align-items:center;gap:12px;">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--green-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--green-dark);flex-shrink:0;">MR</div>
|
||||
<div style="flex:1;"><div style="font-size:13px;font-weight:500;">Marcel Raddatz</div><div style="font-size:11px;color:var(--color-text-muted);">Planner · 14. Jan 2026</div></div>
|
||||
</div>
|
||||
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:12px 14px;display:flex;align-items:center;gap:12px;">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">SR</div>
|
||||
<div style="flex:1;"><div style="font-size:13px;font-weight:500;">Sarah Raddatz</div><div style="font-size:11px;color:var(--color-text-muted);">Mitglied · 15. Jan 2026</div></div>
|
||||
<button style="font-size:11px;color:var(--color-error);background:none;border:none;cursor:pointer;padding:4px;">Entfernen</button>
|
||||
</div>
|
||||
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:12px 14px;display:flex;align-items:center;gap:12px;">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">TM</div>
|
||||
<div style="flex:1;"><div style="font-size:13px;font-weight:500;">Tom Meier</div><div style="font-size:11px;color:var(--color-text-muted);">Mitglied · 3. Mär 2026</div></div>
|
||||
<button style="font-size:11px;color:var(--color-error);background:none;border:none;cursor:pointer;padding:4px;">Entfernen</button>
|
||||
</div>
|
||||
<div style="background:var(--color-subtle);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:12px 14px;">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;"><span style="font-family:var(--font-mono);font-size:12px;color:var(--color-text-muted);">inv_x8K2j</span><span style="font-size:11px;color:var(--yellow-text);">Ausstehend · 2 Tage</span></div>
|
||||
<div style="display:flex;gap:8px;"><button style="flex:1;font-size:11px;font-weight:500;padding:5px;border-radius:var(--radius-sm);background:var(--color-page);border:1px solid var(--color-border);cursor:pointer;">Kopieren</button><button style="font-size:11px;font-weight:500;padding:5px 10px;border-radius:var(--radius-sm);background:none;border:none;cursor:pointer;color:var(--color-error);">Ablehnen</button></div>
|
||||
</div>
|
||||
</div>
|
||||
<nav style="background:var(--color-surface);border-top:1px solid var(--color-border);padding:8px 0 20px;display:flex;"><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Planer</a><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Rezepte</a><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Einkauf</a><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--green-dark);font-weight:500;text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--green-light);border-radius:3px;display:inline-block;"></span>Einstellungen</a></nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="var-notes">
|
||||
<div class="var-notes-label">Design-Entscheidungen</div>
|
||||
<ul>
|
||||
<li>Ausstehende Einladungen als Tabellenzeilen mit grauem Hintergrund und "?" Avatar — visuell klar von aktiven Mitgliedern getrennt, ohne eigenen Abschnitt zu benötigen.</li>
|
||||
<li>Sortierbare Spalten (↕) nur auf Desktop sinnvoll — bei 2–4 Mitgliedern keine echte Notwendigkeit. Für Wohngemeinschaften mit 6+ Personen relevant.</li>
|
||||
<li>Mobile Fallback: Karten statt Tabelle. Tabellen-Layouts kollabieren auf kleinen Bildschirmen schlecht — Karten sind das korrekte Muster für den selben Inhalt auf Mobile.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ══════════════════════════════════════
|
||||
V5 — EXPANDABLE ROWS
|
||||
══════════════════════════════════════ -->
|
||||
<div class="variation">
|
||||
<div class="var-header">
|
||||
<div class="var-num">V5</div>
|
||||
<div class="var-meta">
|
||||
<div class="var-title">Erweiterbare Zeilen</div>
|
||||
<div class="var-desc">Liste mit progressiver Offenlegung. Jede Mitgliederzeile lässt sich aufklappen, um Detailinfos und Aktionen zu zeigen. Kompakte Standardansicht, Details bei Bedarf — kein Seitennavigation nötig.</div>
|
||||
<span class="var-tag">Gute Balance zwischen V1 und V4</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="preview-pair">
|
||||
<div class="preview-d-wrap">
|
||||
<div class="preview-label">Desktop · 1200px (Sarah-Zeile aufgeklappt)</div>
|
||||
<div class="preview-d-clip">
|
||||
<div class="preview-d-scale">
|
||||
<div style="display:flex;width:1200px;min-height:680px;background:var(--color-page);">
|
||||
<aside style="width:224px;flex-shrink:0;background:var(--color-surface);border-right:1px solid var(--color-border);padding:0;display:flex;flex-direction:column;min-height:680px;"><div style="padding:18px 16px 16px;border-bottom:1px solid var(--color-border);display:flex;align-items:center;gap:10px;"><div style="width:22px;height:22px;background:var(--green);border-radius:5px;flex-shrink:0;"></div><div><div style="font-family:var(--font-display);font-size:15px;font-weight:500;color:var(--color-text);">Mealprep</div><div style="font-size:10px;color:var(--color-text-muted);">Familie Raddatz</div></div></div><nav style="padding:16px 0;flex:1;"><div style="font-size:8px;font-weight:500;letter-spacing:0.1em;text-transform:uppercase;color:var(--color-text-muted);padding:0 16px 6px;">Plan</div><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Planer</a><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Rezepte</a><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Einkauf</a><div style="font-size:8px;font-weight:500;letter-spacing:0.1em;text-transform:uppercase;color:var(--color-text-muted);padding:16px 16px 6px;">Haushalt</div><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;background:var(--green-tint);color:var(--green-dark);font-weight:500;text-decoration:none;border-radius:var(--radius-md);margin:0 8px;"><span style="width:16px;height:16px;background:var(--green-light);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Mitglieder</a><a style="display:flex;align-items:center;gap:8px;padding:7px 16px;font-size:13px;color:var(--color-text-muted);text-decoration:none;margin:0 8px;"><span style="width:16px;height:16px;background:var(--color-border);border-radius:3px;flex-shrink:0;display:inline-block;"></span>Einstellungen</a></nav></aside>
|
||||
<main style="flex:1;padding:40px 56px;">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:28px;">
|
||||
<div style="display:flex;align-items:center;gap:12px;"><h1 style="font-family:var(--font-display);font-size:28px;font-weight:500;letter-spacing:-0.02em;">Mitglieder</h1><span style="background:var(--color-subtle);color:var(--color-text-muted);font-size:12px;font-weight:500;padding:2px 9px;border-radius:var(--radius-full);">3</span></div>
|
||||
<button style="background:var(--green-dark);color:#fff;font-family:var(--font-sans);font-size:13px;font-weight:500;letter-spacing:0.04em;padding:10px 20px;border-radius:var(--radius-md);border:none;cursor:pointer;">Mitglied einladen</button>
|
||||
</div>
|
||||
<!-- Collapsed row -->
|
||||
<div style="display:flex;align-items:center;gap:14px;padding:14px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:40px;height:40px;border-radius:50%;background:var(--green-tint);display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600;color:var(--green-dark);flex-shrink:0;">MR</div>
|
||||
<div style="flex:1;"><div style="font-size:14px;font-weight:500;">Marcel Raddatz</div></div>
|
||||
<span style="padding:3px 10px;border-radius:var(--radius-full);font-size:11px;font-weight:500;background:var(--green-tint);color:var(--green-dark);">Planner</span>
|
||||
<div style="font-size:12px;color:var(--color-text-muted);cursor:pointer;padding:4px 8px;">Details ▼</div>
|
||||
</div>
|
||||
<!-- Expanded row -->
|
||||
<div style="border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="display:flex;align-items:center;gap:14px;padding:14px 0;background:var(--color-surface);border-radius:var(--radius-md) var(--radius-md) 0 0;padding:14px 16px;">
|
||||
<div style="width:40px;height:40px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">SR</div>
|
||||
<div style="flex:1;"><div style="font-size:14px;font-weight:500;">Sarah Raddatz</div></div>
|
||||
<span style="padding:3px 10px;border-radius:var(--radius-full);font-size:11px;font-weight:500;background:var(--blue-tint);color:var(--blue-dark);">Mitglied</span>
|
||||
<div style="font-size:12px;color:var(--color-text-muted);cursor:pointer;padding:4px 8px;">Details ▲</div>
|
||||
</div>
|
||||
<div style="background:var(--color-surface);padding:0 16px 16px;border-radius:0 0 var(--radius-md) var(--radius-md);display:flex;align-items:center;justify-content:space-between;">
|
||||
<div style="font-size:13px;color:var(--color-text-muted);">Beigetreten 15. Januar 2026 · Zugang zu Planer (Lesen) und Einkauf</div>
|
||||
<button style="font-size:13px;font-weight:500;color:var(--color-error);background:none;border:1px solid var(--color-error);padding:7px 16px;border-radius:var(--radius-md);cursor:pointer;">Zugang entziehen</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Collapsed row -->
|
||||
<div style="display:flex;align-items:center;gap:14px;padding:14px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:40px;height:40px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">TM</div>
|
||||
<div style="flex:1;"><div style="font-size:14px;font-weight:500;">Tom Meier</div></div>
|
||||
<span style="padding:3px 10px;border-radius:var(--radius-full);font-size:11px;font-weight:500;background:var(--blue-tint);color:var(--blue-dark);">Mitglied</span>
|
||||
<div style="font-size:12px;color:var(--color-text-muted);cursor:pointer;padding:4px 8px;">Details ▼</div>
|
||||
</div>
|
||||
<!-- Invite section -->
|
||||
<div style="margin-top:24px;"><div style="font-size:11px;font-weight:500;letter-spacing:0.06em;text-transform:uppercase;color:var(--color-text-muted);margin-bottom:12px;">Einladungen · 1</div>
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:12px 16px;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);"><span style="font-family:var(--font-mono);font-size:13px;flex:1;">inv_x8K2j</span><span style="font-size:11px;color:var(--yellow-text);background:var(--yellow-tint);padding:2px 8px;border-radius:var(--radius-sm);">2 Tage</span><button style="font-size:12px;font-weight:500;padding:6px 14px;border-radius:var(--radius-md);background:var(--color-page);border:1px solid var(--color-border);cursor:pointer;">Kopieren</button></div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="preview-m-wrap">
|
||||
<div class="preview-label">Mobile · 390px</div>
|
||||
<div class="preview-m-clip">
|
||||
<div class="preview-m-scale">
|
||||
<div style="width:390px;min-height:680px;background:var(--color-page);display:flex;flex-direction:column;">
|
||||
<div style="padding:16px 20px 12px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--color-border);background:var(--color-surface);"><div style="font-family:var(--font-display);font-size:20px;font-weight:500;">Mitglieder</div><button style="background:var(--green-dark);color:#fff;font-size:12px;font-weight:500;padding:7px 14px;border-radius:var(--radius-md);border:none;">+ Einladen</button></div>
|
||||
<div style="flex:1;padding:0 20px;">
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--green-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--green-dark);flex-shrink:0;">MR</div>
|
||||
<div style="flex:1;"><div style="font-size:14px;font-weight:500;">Marcel Raddatz</div><div style="font-size:11px;color:var(--color-text-muted);">Planner</div></div>
|
||||
<div style="font-size:16px;color:var(--color-text-muted);cursor:pointer;">▼</div>
|
||||
</div>
|
||||
<!-- Expanded -->
|
||||
<div style="border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:12px 0 8px;background:var(--color-surface);margin:0 -4px;padding:12px 8px 8px;">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">SR</div>
|
||||
<div style="flex:1;"><div style="font-size:14px;font-weight:500;">Sarah Raddatz</div><div style="font-size:11px;color:var(--color-text-muted);">Mitglied</div></div>
|
||||
<div style="font-size:16px;color:var(--color-text-muted);cursor:pointer;">▲</div>
|
||||
</div>
|
||||
<div style="background:var(--color-surface);padding:0 8px 12px;margin:0 -4px;"><div style="font-size:12px;color:var(--color-text-muted);margin-bottom:10px;">Seit 15. Januar 2026 · Lesen + Einkauf</div><button style="width:100%;font-size:13px;font-weight:500;color:var(--color-error);background:none;border:1px solid var(--color-error);padding:8px;border-radius:var(--radius-md);cursor:pointer;">Zugang entziehen</button></div>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--color-subtle);">
|
||||
<div style="width:36px;height:36px;border-radius:50%;background:var(--blue-tint);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--blue-dark);flex-shrink:0;">TM</div>
|
||||
<div style="flex:1;"><div style="font-size:14px;font-weight:500;">Tom Meier</div><div style="font-size:11px;color:var(--color-text-muted);">Mitglied</div></div>
|
||||
<div style="font-size:16px;color:var(--color-text-muted);cursor:pointer;">▼</div>
|
||||
</div>
|
||||
</div>
|
||||
<nav style="background:var(--color-surface);border-top:1px solid var(--color-border);padding:8px 0 20px;display:flex;"><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Planer</a><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Rezepte</a><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--color-text-muted);text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--color-border);border-radius:3px;display:inline-block;"></span>Einkauf</a><a style="flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;font-size:10px;color:var(--green-dark);font-weight:500;text-decoration:none;padding:4px 0;"><span style="width:20px;height:20px;background:var(--green-light);border-radius:3px;display:inline-block;"></span>Einstellungen</a></nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="var-notes">
|
||||
<div class="var-notes-label">Design-Entscheidungen</div>
|
||||
<ul>
|
||||
<li>Der "Zugang entziehen"-Button ist erst nach dem Aufklappen sichtbar — eine natürliche Bestätigungsbarriere ohne expliziten Bestätigungsdialog für das erste Tap.</li>
|
||||
<li>Aufgeklappte Zeile erhält leichten Surface-Hintergrund (--color-surface) zur visuellen Abgrenzung vom Rest der Liste.</li>
|
||||
<li>Besser als V1 wenn die Entfernen-Aktion prominent sein soll, aber nicht permanent sichtbar. Schlechter als V1 wenn maximale Einfachheit das Ziel ist.</li>
|
||||
<li>Auf Mobile: "▼" Chevron als Tap-Target — muss mindestens 44×44px sein. Den gesamten Zeilenbereich tapbar machen ist vorzuziehen.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div><!-- /doc -->
|
||||
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════
|
||||
MACHINE-READABLE SPEC (LLM AGENT REGION)
|
||||
════════════════════════════════════════════════════════ -->
|
||||
<!--
|
||||
spec:agent:start
|
||||
document: E2 Members Page
|
||||
version: 1.0
|
||||
-->
|
||||
<div class="agent-section">
|
||||
<h2>Machine-readable spec — E2 Mitglieder</h2>
|
||||
<p>Authoritative implementation reference for the /members page. Use before building any component for this route.</p>
|
||||
|
||||
<pre class="spec-comment">/* E2 Members page — implementation rules
|
||||
* 1. Recommended variation: V1 (Roster list). Simplest, lowest overhead, matches household size 2–4.
|
||||
* 2. Avatar colours: Planner = --green-tint bg + --green-dark text. Member = --blue-tint bg + --blue-dark text. Initials only.
|
||||
* 3. Role badges: same colour pairing as avatars. border-radius: --radius-full. font-size: 11px. font-weight: 500.
|
||||
* 4. The planner cannot remove themselves — no remove action on the Planner's row ever.
|
||||
* 5. Pending invites: show expiry in --yellow-tint + --yellow-text when ≤ 3 days remaining, --color-subtle + --color-text-muted otherwise.
|
||||
* 6. Remove action is destructive — requires a confirmation dialog with the member's name before execution.
|
||||
* 7. Invite mechanism: generate a link/code. Copy to clipboard. No email delivery system in v1.
|
||||
* 8. Expired invites: show "Abgelaufen" state. Provide one-tap regeneration — do not require re-opening an invite flow.
|
||||
* 9. Household members can view this page in read-only mode (no invite button, no remove actions, no pending invites section).
|
||||
* 10. Desktop sidebar: "Mitglieder" item is active, under "Haushalt" section. Mobile: "Einstellungen" tab is active.
|
||||
* 11. WCAG 2.2 AA: avatar initials need 4.5:1 contrast. Role badge text needs 4.5:1 contrast. Confirm before implementing.
|
||||
*/</pre>
|
||||
|
||||
<table class="agent-table">
|
||||
<thead>
|
||||
<tr><th>Element</th><th>Value / Rule</th><th>Notes</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="group-row"><td colspan="3">Avatar</td></tr>
|
||||
<tr><td>Size</td><td>40px × 40px (desktop) · 36px × 36px (mobile)</td><td>border-radius: 50%</td></tr>
|
||||
<tr><td>Planner colour</td><td>bg --green-tint · text --green-dark</td><td>Contrast OK: #2E6E39 on #E8F5EA ≈ 6.1:1</td></tr>
|
||||
<tr><td>Member colour</td><td>bg --blue-tint · text --blue-dark</td><td>Contrast OK: #0C447C on #E6F1FB ≈ 7.4:1</td></tr>
|
||||
<tr><td>Content</td><td>First letter of first + last name (uppercase)</td><td>Max 2 characters</td></tr>
|
||||
<tr class="group-row"><td colspan="3">Role badge</td></tr>
|
||||
<tr><td>Shape</td><td>border-radius: --radius-full · padding: 3px 10px</td><td>font-size: 11px · font-weight: 500</td></tr>
|
||||
<tr><td>Planner</td><td>bg --green-tint · color --green-dark</td><td>Label: "Planner"</td></tr>
|
||||
<tr><td>Member</td><td>bg --blue-tint · color --blue-dark</td><td>Label: "Mitglied"</td></tr>
|
||||
<tr class="group-row"><td colspan="3">Invite / pending</td></tr>
|
||||
<tr><td>Expiry badge — urgent (≤3d)</td><td>bg --yellow-tint · color --yellow-text</td><td>"Läuft ab in N Tagen"</td></tr>
|
||||
<tr><td>Expiry badge — normal</td><td>bg --color-subtle · color --color-text-muted</td><td>"Läuft ab am DD. MMM"</td></tr>
|
||||
<tr><td>Code font</td><td>font-family: --font-mono · font-size: 13px</td><td>Invite codes are monospace</td></tr>
|
||||
<tr class="group-row"><td colspan="3">Interactions</td></tr>
|
||||
<tr><td>Remove action</td><td>Confirmation dialog required</td><td>Dialog must show member name. Irreversible — member loses access immediately.</td></tr>
|
||||
<tr><td>Copy invite link</td><td>navigator.clipboard.writeText()</td><td>Show transient "Kopiert!" feedback (checkmark, 2s)</td></tr>
|
||||
<tr><td>Regenerate invite</td><td>POST /household/invite — returns new code</td><td>Old code is immediately invalidated</td></tr>
|
||||
<tr class="group-row"><td colspan="3">Responsive</td></tr>
|
||||
<tr><td>Desktop (≥1024px)</td><td>224px sidebar + full content area</td><td>Active sidebar item: Mitglieder (Haushalt section)</td></tr>
|
||||
<tr><td>Mobile (<768px)</td><td>No sidebar · bottom nav · "Einstellungen" tab active</td><td>V3 mobile uses tab bar within page, not app bottom nav tabs</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!--
|
||||
spec:agent:end
|
||||
-->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user