---
name: recipe-flowchart-card
description: Generate a "Cooking For Engineers" style recipe flowchart card from any recipe (ingredients + instructions). Produces a self-contained HTML file with a mint-green-bordered, tabbed flowchart table showing ingredients merging into process steps over time, matching Michael Chu's classic Cooking For Engineers visual format. Use this skill whenever the user asks to turn a recipe into a "recipe card," "flowchart recipe," "visual recipe," references "Cooking For Engineers" or "CFE style," or pastes in a recipe and asks for it in table/diagram form. Also trigger if the user asks to generate the prompt/template for making one of these cards from any future recipe.
---

# Recipe Flowchart Card Generator

Recreates the Cooking For Engineers (Michael Chu) recipe flowchart format: ingredients listed down the left, flowing rightward through merged cells as they're combined and processed, ending in a final plated/finished step.

## When to use this

- User pastes a recipe (ingredients + steps) and wants it visualized as a flowchart/table
- User asks for a "recipe card," "CFE-style recipe," or references the Cooking For Engineers format
- User wants a reusable prompt/template to generate this format from any recipe in the future

## Worked examples — use the template you actually have

**Copy CSS/structure verbatim** from the canonical HTML template (colors, fonts, tab markup, table markup, print dual-markup) — don't reinvent the styling from scratch.

How to get that template depends on how these instructions were loaded:

1. **Paste / chat-only sessions (ChatGPT, Gemini, or any chat where no skill package was uploaded)**  
   There are **no** `examples/` files and **no** `input.txt` / `output.html` paths to open. The user will paste a full HTML template in a **following message**. That pasted HTML **is** the sole worked example — treat it as canonical and copy its `<style>`, tabs, table classes, print/screen dual markup, and scripts verbatim. Do not ask for missing example files.

2. **Claude / ChatGPT skill package (`.skill` or zip containing this `SKILL.md`)**  
   Two full input → output pairs are bundled. Read the `output.html` files directly:
   - `examples/pandan-extract/input.txt` → `examples/pandan-extract/output.html` (simple, single-stage)
   - `examples/banana-bread/input.txt` → `examples/banana-bread/output.html` (multi-stage)

   Prefer the multi-stage banana-bread example when the recipe has several converging mixtures; use pandan-extract for a simple one-table case.

## Critical implementation rule: locked visual system (do not invent a new look)

Every card must use this exact visual system. **Copy the full `<style>` block from a worked example** and only change recipe content. Do not swap fonts, invent new colors, restyle tabs, or change cell fills.

### Palette (CSS variables — exact hex values)

```css
:root {
  --rc-black: #000000;
  --rc-muted: #8e9794;
  --rc-yellow: #ffc145;
  --rc-mint: #b8d8ba;
  --rc-mint-deep: #5f8a62;
  --rc-border: #c5d9c7;
  --rc-bg: #ffffff;
  --rc-soft: #f7faf7;
  --rc-amber: #fff8e1;
  --rc-amber-deep: #b8860b;
}
```

### Fonts

- Body / cell text: **Inter** (Google Fonts weights 400/500/600)
- Headings / tabs / stage labels: **Montserrat** (weights 600/700)
- Include the same Google Fonts `<link>` tags as the worked examples

### Cell / section roles (must match)

| Role | Markup | Look |
|------|--------|------|
| Table frame | `table.flow` | 2px solid `--rc-mint-deep` border |
| Ingredient | `td.ingredient` | soft green fill `--rc-soft`; sticky left |
| Process step | `td.step` / `.wide` / `.narrow` | plain white, centered |
| Named output | `td.out` | amber fill `--rc-amber`, uppercase, bold |
| Finish sequence | `td.step.finish` | deep mint fill `--rc-mint-deep`, white text, left-aligned `<ol>` |
| Tips | `.tips` | yellow left border `--rc-yellow`, light yellow wash |
| Active tab underline | `.tab-btn.active` | `--rc-yellow` |
| Full-recipe `h2` underline | `.full-recipe h2` | `--rc-yellow` |
| Technique marker | `.star` | `--rc-amber-deep` |

Do **not** recolor stages per recipe, use purple/blue themes, drop the mint border, or restyle `td.out` / `td.step.finish` differently from the examples.

## Critical implementation rule: the ingredient column must stay sticky on horizontal scroll

Every `td.ingredient` cell must use `position: sticky; left: 0; z-index: 2;` (plus a subtle `box-shadow` to separate it from scrolling content behind it). Wide flowcharts scroll horizontally inside `.table-scroll`, and without this rule the ingredient names scroll off-screen, leaving no way to tell which ingredient a given process step corresponds to. Both worked examples now include this — copy it verbatim into any new card's CSS.

## Critical implementation rule: keep finish-column numbered lists tight

`td.step.finish` cells are narrow mint columns that hold a short numbered sequence (`<ol>` of 2–4 steps like cool → unmold → slice). **Do not rely on the browser's default `<ol>` padding** — it's ~40px and steals so much width that words truncate mid-string (`parchmen` / `t`, `completel` / `y`). Every card must include this CSS, copied from the worked examples:

```css
td.step.finish ol {
  margin: 0;
  padding-left: 1.15em;
  padding-right: 0;
}
td.step.finish li {
  margin-bottom: 6px;
  overflow-wrap: anywhere;
}
td.step.finish li:last-child {
  margin-bottom: 0;
}
```

`1.15em` keeps the numbers readable while giving the text nearly the full cell width. Apply this whenever a finish cell uses an `<ol>` — both worked examples do.

## Critical implementation rule: every stage table needs a dual screen/print markup

A browser can't auto-split a wide table across print pages, so CSS alone can't make a wide flowchart print cleanly — the fix is dual markup: build every stage table twice, and let `@media print` swap which copy shows. **Both worked examples now do this for every stage — copy the pattern verbatim.**

1. **Wrap the existing scrollable table** in `<div class="table-scroll screen-only">` (unchanged, still horizontal-scrolls on screen), then add a sibling `<div class="print-only">` right after it containing a print-safe copy of the same stage.
2. **Toggle by media type** — this CSS block goes in every card's `<style>`, copied verbatim from the worked examples:
   ```css
   .print-only { display: none; }
   @media print {
     .screen-only { display: none !important; }
     .print-only  { display: block !important; }
     /* Both tabs print: hide the tab switcher, force both panels visible,
        and start Full Recipe on a new page after the flowchart card. */
     .tabs { display: none !important; }
     .tab-panel { display: block !important; }
     #panel-full, .tab-panel.full-recipe {
       break-before: page;
       page-break-before: always;
     }
     @page { size: letter portrait; margin: 0.55in; }
     table.flow.print-table { table-layout: fixed; width: 100%; }
     table.flow.print-table td {
       white-space: normal; overflow-wrap: break-word;
       word-break: break-word; min-width: 0;
     }
   }
   @media screen and (max-width: 480px) {
     td.ingredient { min-width: 92px; }
     td.step { min-width: 48px; }
     td.step.wide { min-width: 78px; }
     td.step.narrow { min-width: 40px; }
   }
   ```
   `table-layout: fixed` + `overflow-wrap` is what forces text to wrap and columns to stay inside the page instead of overflowing. The mobile query never splits anything — it just shrinks min-widths so the existing horizontal scrollbar kicks in sooner.

   **PDF / print must include both tabs.** On screen, only one `.tab-panel` is visible at a time. In `@media print`, both panels must show (`display: block !important`), the `.tabs` bar is hidden, and `#panel-full` / `.tab-panel.full-recipe` starts on a **new page** via `break-before: page` (with `page-break-before: always` for older engines). Never ship a card whose print/PDF output is only the flowchart and omits the Full Recipe write-up.
3. **Cap the print copy at 5 columns** (identifier + 4) — that's what fits comfortably in Letter-portrait's ~7.5in usable width, given this skill's typical column widths.
   - If a stage's screen table has more columns than that, split the print copy into two (or more) stacked `<table class="flow print-table">` blocks.
   - Split at a natural named output when possible (e.g., "Batter") — the second segment's first cell becomes a `<td class="carry">↳ Batter</td>` referencing that output, and the segment gets its own `<h2 class="stage print-continued">Stage Name (continued)</h2>` heading. See the banana bread example's "Assembly & Bake" stage for the canonical case.
   - If there's no natural intermediate output at the split point (e.g., a column whose `rowspan` already covers every row in the stage — meaning all ingredient rows have already converged), the continuation table only needs a single row: one `td.carry` cell describing what's been combined so far, then the remaining columns. See the banana bread example's "Wet Mixture" stage.
   - Stages that already fit in 5 columns don't need a split — the print copy is a direct duplicate of the screen table, just marked `print-table` (see the pandan-extract example, or the Bananas/Dry Mix stages in banana bread).

### Print continuation look (greyed header + carry cell) — required CSS

When a wide stage splits into a second print table, the continuation must look visually secondary (greyed), not like a brand-new stage. Every card's `<style>` must include:

```css
h2.stage.print-continued {
  font-style: italic;
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--rc-muted);
  margin: 10px 0 6px 0;
}
td.carry {
  font-style: italic;
  color: var(--rc-muted);
  background: var(--rc-soft);
}
```

Rules:
- Continuation heading text is always `Stage Name (continued)` on `<h2 class="stage print-continued">`.
- The first cell of the continuation table is always `<td class="carry">` (usually `↳ …`), never a normal black `td.ingredient`.
- Do not use bold black stage styling for the continued heading — muted/italic is what signals “same stage, next columns” in the PDF.

## Critical implementation rule: use real HTML `<table>` + `rowspan`/`colspan`, never CSS grid/flexbox

An earlier version of this skill built cells with CSS Grid and `display:flex` on each cell. This broke badly: `display:flex` on a cell containing mixed text and `<b>`/`<i>` tags splits the text into separate flex items instead of letting it wrap as normal prose, producing jumbled, overlapping text. CSS Grid also has no equivalent of native rowspan behavior, so merges required fragile manual row/column math that was error-prone.

**Always build the flowchart with a real `<table class="flow">`, using native `rowspan` on `<td>` elements to show ingredients merging.** This is what both worked examples do, and it's far more robust:

- Each ingredient gets its own `<tr>` with a `<td class="ingredient">` cell.
- A process step that combines N ingredient-rows gets `rowspan="N"` and is placed once, in the `<tr>` of the *first* ingredient it applies to.
- Rows for ingredients that enter later only need a single `<td class="ingredient">` — the browser automatically places it in the first unoccupied column (normally the ingredient column), and any columns with no active rowspan and no cell for that row are simply left blank. This is expected and matches the reference look (see the pandan example's "½ cup water" row, which has no wash/cut cell).
- Never add filler/empty `<td>` cells to "pad" a row — let the table's natural placement handle it.

## How to build the card

Output a **single self-contained HTML file** (the CSS block from the worked examples, inline, no external dependencies except the Google Fonts `<link>` tags), following these rules:

1. **Overall page structure**: `<h1>` with recipe name + a `.by` span for yield/serving/source, then a `.tabs` bar with two buttons — "Recipe Card" (active by default) and "Full Recipe" — toggling two `.tab-panel` divs via the `showTab()` script. Reuse the exact script and CSS from the worked examples.

2. **Recipe Card tab**: this holds the flowchart itself.
   - **Group ingredients into sub-recipe blocks** if the recipe has distinct components (e.g., "wet mixture," "dry mix," "infusion"). Each block gets its own `<h2 class="stage">` label and its own `<table class="flow">`, stacked vertically.
   - **Left-to-right flow logic**: each row starts with one ingredient (`td.ingredient`). As ingredients combine, use `rowspan` on the process-step `<td>`s (`td.step`, `td.step.wide`, `td.step.narrow`) to show them converging into a single action. The final result of a block gets a `td.out` cell (or `td.step.finish` for a multi-line final sequence, as in the pandan example).
   - **Process step labels**: short, verb-first descriptions, always including timing/temperature when given in the source. Mark the 3–5 most technique-critical steps with `<span class="star">*</span>` and expand on them in the Tips box below the table — don't star everything.
   - **Sequential singular steps** (no merging needed — e.g., "cool 15 min" → "bake" → "cool completely") continue as their own columns to the right, still carried by the same `rowspan` chain from the last merge point.
   - **Tips box** (`.tips`): 3–5 items, each `<strong>label:</strong> explanation`, directly elaborating on the starred steps above.

3. **Full Recipe tab**: a plain-language fallback — `<h2>Ingredients</h2>` as a `<ul>`, `<h2>Instructions</h2>` as a numbered `<ol>` (nested `<ol>` for sub-steps, matching the source recipe's own step grouping), a repeated Tips/Why-it-works box, and a closing line with prep/bake/total time + yield (+ source link if the recipe came from a named source).

4. **Ingredient formatting**: quantity + name, matching the source recipe's own units — don't convert or add units that aren't already present.

5. **Completeness**: every mixing, resting, temperature, or timing detail from the source recipe must appear somewhere on the card (flowchart cell, tip, or Full Recipe step). Collapse sub-steps into one clear cell rather than omitting detail — never drop information to simplify the visual.

## Output

- If the user gave a recipe directly: build the HTML file and present it as an artifact/file.
- If the user wants the reusable prompt itself (not a rendered card): output the instructions above as a copy-pasteable prompt template with a `[PASTE RECIPE HERE]` placeholder, so it can be used in any future chat.

## After presenting the card

Once the HTML file has been generated and presented, ask the user a **single follow-up** using this **exact wording** (same structure and option labels every time — do not paraphrase, reorder, or invent alternate phrasings):

> Your recipe card is ready. What would you like to do next?
>
> 1. **Edit** — change ingredients, steps, styling, or fix anything that looks off
> 2. **Save locally as HTML**
> 3. **Save locally as PDF**
> 4. **Save to Google Drive as HTML**
> 5. **Save to Google Drive as PDF**
>
> Reply with a number (or a few, e.g. “3 and 5”).

The “Reply with a number…” sentence must be on its **own line after the numbered list** (blank line between option 5 and that sentence) — never on the same line as option 5.

Do **not** run any of those actions unprompted — wait for the user to pick.

How to carry out each choice once selected:

1. **Edit** — apply the edit directly to the HTML and re-present it, then ask the same follow-up again (same wording).
2. **Save locally as HTML**
   - **Skill package / artifact environment:** save the self-contained HTML (e.g. to `/mnt/user-data/outputs` when that path exists) and present it for download.
   - **Paste / chat-only (ChatGPT, Gemini):** provide the full HTML in a fenced html code block so the user can copy it into a `.html` file. Do not claim a local file was written on their machine unless the product actually offers a download.
3. **Save locally as PDF**
   - **When `scripts/render_pdf.py` is available** (bundled with the `.skill` package): convert with Playwright/Chromium, then save for download:
     ```bash
     python scripts/render_pdf.py <path-to-card.html> <path-to-output.pdf>
     ```
     **Do not use the generic `pdf` skill or `wkhtmltopdf` for this** — wkhtmltopdf's older Qt engine doesn't honor `@media print`, so it renders the wide `.screen-only` table instead of the column-capped `.print-only` split and the output overflows the page.
   - **Paste / chat-only (no render script):** do **not** invent a PDF binary. Tell the user to open the HTML in a browser and use **Print → Save as PDF** (or the browser’s Export to PDF). Remind them that print layout depends on the dual `screen-only` / `print-only` markup already in the card — they should print/export from the browser, not screenshot the on-screen scrollable table.
4. **Save to Google Drive as HTML** — upload the HTML file as-is when a Google Drive connector is available; otherwise give clear copy/download steps and ask them to upload manually or connect Drive.
5. **Save to Google Drive as PDF** — produce/obtain a PDF the same way as option 3 for this environment, then upload when Drive is available; otherwise give the HTML and the browser Print → Save as PDF + upload instructions.

Notes:

- If the user picks any option, carry it out directly rather than re-asking for confirmation — they've already chosen.
- Options 3 and 5 both need a PDF. If a PDF was already generated earlier in the conversation, reuse it instead of re-rendering.
- Options 4 and 5 require a Google Drive connector when available. If none is available, say so and give manual steps rather than failing silently.
- Never tell the user to open `examples/…`, `input.txt`, `output.html`, or `scripts/render_pdf.py` unless those files were actually provided in this session (skill package). In paste-only chats they do not exist.
- The user may ask for more than one at once (e.g. “3 and 5”) — do them in sequence and confirm each.
- After completing any of 2–5, you may briefly re-offer remaining options, but keep the same five labels (`Edit` / `Save locally as HTML` / `Save locally as PDF` / `Save to Google Drive as HTML` / `Save to Google Drive as PDF`) — do not invent new wording.

## Reference example

The canonical visual reference is Michael Chu's Cooking For Engineers "Macaroni and Cheese Bake" recipe card: ingredient rows on the left, converging through labeled process cells (e.g., "cook while stirring until light brown," "stir in slowly," "remove from heat when thickened"), ending in "pour into pan → top → bake → let rest." Match that density and merging logic using the HTML template available in this session (pasted template and/or bundled `examples/` outputs) — same structure for any new recipe, regardless of cuisine or complexity.
