# Weekly meal planner: first implementation prompt

Act as a software developer. Build the small browser app specified below.
Before changing code, inspect the repository and follow its existing conventions.
If a required choice is missing, ask me. Do not silently add product features.

## User and outcome

The user is a parent who wants to plan seven dinners and copy a grocery list.
The first useful outcome is a grocery list made from meals they entered.
This is a teaching example, not a tested commercial product or a nutrition tool.

## Scope

Use the existing frontend stack. For an empty project, use React, TypeScript,
and Vite. Store this prototype in the current browser. No account, payment,
AI generation, recipe imports, barcode scanning, or household sharing.
Warn users that clearing browser storage removes their saved plan.

## Data and rules

A meal has an ID, a title, and an array of ingredients. The title is required
and must contain 1–80 characters after trimming. Each ingredient has a name
(1–80 trimmed characters), a positive numeric quantity, and one unit from:
g, ml, or item. A saved meal needs at least one valid ingredient.

A week has seven slots, Monday through Sunday. A slot contains either a meal
ID or no meal. Allow the same meal on multiple days. Each assignment adds one
complete batch of its ingredients. Do not multiply by household size.

To build the grocery list, group ingredients by trimmed, lower-case name and
unit. Sum quantities within each group. Do not combine different units and do
not infer that different names refer to the same food. Show quantities rounded
to at most two decimal places. Sort rows alphabetically by normalized name,
then by unit. Unassigned days add nothing.

Example: Monday has Pasta with 200 g of Tomato and 150 g of pasta. Tuesday has
Soup with 300 g of tomato and 400 ml of stock. Expected grocery rows:
150 g pasta; 400 ml stock; 500 g tomato. Adding 2 item tomato must produce a
separate row. No serving estimates or nutrition claims are required.

## Screen and interactions

Show a meal form, saved meals, seven labeled day selectors, and a grocery list.
Keep the layout usable at 320 CSS pixels without horizontal page scrolling.
Every input needs a visible label. All controls must work with a keyboard.
Show validation errors beside the relevant input and focus the first invalid
field after submission. Do not discard a partially completed form on error.

The grocery list updates when an assignment changes. Add a Copy grocery list
button that writes one ingredient per line. Announce success accessibly only
after copying succeeds. If clipboard access fails, show selectable text and a
clear instruction to copy it manually.

## Persistence and failure states

Save valid meals and assignments after each change. Reload restores both.
Deleting a meal requires confirmation and clears every day that references it.
If storage is unavailable, keep the app usable for the current session and
show that changes will not survive a reload. If saved data cannot be parsed or
fails validation, explain the problem and ask before replacing it.

## Acceptance checks

1. An empty title or zero ingredient quantity prevents saving and shows an error.
2. The Pasta and Soup example produces exactly the expected grocery quantities.
3. Tomato and tomato merge when their units match; g and item stay separate.
4. Assigning Pasta twice produces 400 g tomato and 300 g pasta.
5. Removing a day assignment removes only that day's ingredient contribution.
6. Reload preserves saved meals and day assignments when storage is available.
7. Deleting a meal clears its assignments without leaving broken references.
8. Keyboard users can add a meal, assign it, and copy the list.
9. A failed clipboard operation never reports success.

## Delivery

First state your implementation plan and any unresolved requirements. Then
implement this scope. Run focused tests for ingredient grouping, repeated meals,
validation, and persistence failures. Report what you tested and any limits.
Do not claim the app is ready until those checks pass.
