diff --git a/frontend/src/lib/recipes/RecipeGrid.svelte b/frontend/src/lib/recipes/RecipeGrid.svelte
new file mode 100644
index 0000000..ac713ff
--- /dev/null
+++ b/frontend/src/lib/recipes/RecipeGrid.svelte
@@ -0,0 +1,22 @@
+
+
+{#if recipes.length > 0}
+
+
Noch keine Rezepte vorhanden.
+
+ Rezept hinzufügen
+
+
+{/if}
diff --git a/frontend/src/lib/recipes/RecipeGrid.test.ts b/frontend/src/lib/recipes/RecipeGrid.test.ts
new file mode 100644
index 0000000..fccdbe0
--- /dev/null
+++ b/frontend/src/lib/recipes/RecipeGrid.test.ts
@@ -0,0 +1,41 @@
+import { describe, it, expect } from 'vitest';
+import { render, screen } from '@testing-library/svelte';
+import RecipeGrid from './RecipeGrid.svelte';
+
+const mockRecipes = [
+ { id: 'r1', name: 'Spaghetti Bolognese', cookTimeMin: 30, effort: 'Easy' },
+ { id: 'r2', name: 'Chicken Curry', cookTimeMin: 45, effort: 'Medium' },
+ { id: 'r3', name: 'Caesar Salad', cookTimeMin: 15, effort: 'Easy' }
+];
+
+describe('RecipeGrid', () => {
+ it('renders a card for each recipe', () => {
+ render(RecipeGrid, { props: { recipes: mockRecipes } });
+ expect(screen.getByText('Spaghetti Bolognese')).toBeInTheDocument();
+ expect(screen.getByText('Chicken Curry')).toBeInTheDocument();
+ expect(screen.getByText('Caesar Salad')).toBeInTheDocument();
+ });
+
+ it('renders 3 links for 3 recipes', () => {
+ render(RecipeGrid, { props: { recipes: mockRecipes } });
+ expect(screen.getAllByRole('link')).toHaveLength(3);
+ });
+
+ it('shows empty state when recipes array is empty', () => {
+ render(RecipeGrid, { props: { recipes: [] } });
+ expect(screen.getByText(/keine rezepte/i)).toBeInTheDocument();
+ });
+
+ it('empty state links to recipe creation', () => {
+ render(RecipeGrid, { props: { recipes: [] } });
+ const addLink = screen.getByRole('link', { name: /rezept hinzufügen/i });
+ expect(addLink).toHaveAttribute('href', '/recipes/new');
+ });
+
+ it('grid has 2-col mobile and 4-col desktop classes', () => {
+ render(RecipeGrid, { props: { recipes: mockRecipes } });
+ const grid = document.querySelector('[data-testid="recipe-grid"]');
+ expect(grid?.className).toContain('grid-cols-2');
+ expect(grid?.className).toContain('lg:grid-cols-4');
+ });
+});