This rune is part of @refrakt-md/learning. Install with npm install @refrakt-md/learning and add "@refrakt-md/learning" to the plugins array in your refrakt.config.json.
Recipe
Structured recipe content. Unordered lists become ingredients, ordered lists become steps, and blockquotes become chef's tips.
Basic usage
A complete recipe with ingredients, instructions, and a tip.
{% recipe prepTime="PT15M" cookTime="PT30M" servings=4 difficulty="easy" %}
# Classic Pasta Carbonara
A rich and creamy Italian pasta dish.
- 400g spaghetti
- 200g pancetta
- 4 egg yolks
- 100g Pecorino Romano
- Black pepper to taste
1. Cook pasta in salted boiling water until al dente
2. Fry pancetta in a large pan until crispy
3. Whisk egg yolks with grated cheese and pepper
4. Toss hot pasta with pancetta, then stir in egg mixture off the heat
> The residual heat from the pasta cooks the eggs — never add eggs directly to a hot pan or they will scramble.
{% /recipe %}<article data-field="content-section" data-rune="recipe" typeof="Recipe" data-rune-fields="{"prepTime":"PT15M","cookTime":"PT30M","servings":"4","difficulty":"easy","media-position":"top"}">
<meta content="PT15M" property="prepTime">
<meta content="PT30M" property="cookTime">
<meta content="4" property="recipeYield">
<h1 id="classic-pasta-carbonara" data-name="headline" property="name">Classic Pasta Carbonara</h1>
<p data-name="blurb" property="description">A rich and creamy Italian pasta dish.</p>
<ul data-name="ingredients">
<li data-name="ingredient" property="recipeIngredient">400g spaghetti</li>
<li data-name="ingredient" property="recipeIngredient">200g pancetta</li>
<li data-name="ingredient" property="recipeIngredient">4 egg yolks</li>
<li data-name="ingredient" property="recipeIngredient">100g Pecorino Romano</li>
<li data-name="ingredient" property="recipeIngredient">Black pepper to taste</li>
</ul>
<ol data-name="steps">
<li data-name="step" typeof="HowToStep" property="recipeInstructions">
<p property="text">Cook pasta in salted boiling water until al dente</p>
</li>
<li data-name="step" typeof="HowToStep" property="recipeInstructions">
<p property="text">Fry pancetta in a large pan until crispy</p>
</li>
<li data-name="step" typeof="HowToStep" property="recipeInstructions">
<p property="text">Whisk egg yolks with grated cheese and pepper</p>
</li>
<li data-name="step" typeof="HowToStep" property="recipeInstructions">
<p property="text">Toss hot pasta with pancetta, then stir in egg mixture off the heat</p>
</li>
</ol>
<div data-name="tips">
<blockquote>
<p>The residual heat from the pasta cooks the eggs — never add eggs directly to a hot pan or they will scramble.</p>
</blockquote>
</div>
</article>Classic Pasta Carbonara
A rich and creamy Italian pasta dish.
- 400g spaghetti
- 200g pancetta
- 4 egg yolks
- 100g Pecorino Romano
- Black pepper to taste
Cook pasta in salted boiling water until al dente
Fry pancetta in a large pan until crispy
Whisk egg yolks with grated cheese and pepper
Toss hot pasta with pancetta, then stir in egg mixture off the heat
The residual heat from the pasta cooks the eggs — never add eggs directly to a hot pan or they will scramble.
<article data-field="content-section" typeof="Recipe" class="rf-recipe rf-recipe--easy" data-media-position="top" data-prep-time="PT15M" data-cook-time="PT30M" data-servings="4" data-difficulty="easy" data-rune="recipe" data-density="full">
<div data-name="content" class="rf-recipe__content">
<header data-name="preamble" class="rf-recipe__preamble" data-section="preamble">
<h1 id="classic-pasta-carbonara" data-name="headline" property="name" class="rf-recipe__headline" data-section="title">Classic Pasta Carbonara</h1>
<p data-name="blurb" property="description" class="rf-recipe__blurb" data-section="description">A rich and creamy Italian pasta dish.</p>
</header>
<dl data-name="metadata" data-zone="metadata" data-zone-layout="definition-list" class="rf-recipe__metadata">
<div data-name="row" data-field="prepTime" class="rf-recipe__row">
<dt data-meta-label="">Prep</dt>
<dd data-meta-type="temporal">15m</dd>
</div>
<div data-name="row" data-field="cookTime" class="rf-recipe__row">
<dt data-meta-label="">Cook</dt>
<dd data-meta-type="temporal">30m</dd>
</div>
<div data-name="row" data-field="servings" class="rf-recipe__row">
<dt data-meta-label="">Serves</dt>
<dd data-meta-type="quantity">4</dd>
</div>
<div data-name="row" data-field="difficulty" class="rf-recipe__row">
<dt data-meta-label="">Difficulty</dt>
<dd>
<span class="rf-badge" data-meta-type="category" data-meta-sentiment="positive">easy</span>
</dd>
</div>
</dl>
<ul data-name="ingredients" class="rf-recipe__ingredients">
<li data-name="ingredient" property="recipeIngredient" class="rf-recipe__ingredient">400g spaghetti</li>
<li data-name="ingredient" property="recipeIngredient" class="rf-recipe__ingredient">200g pancetta</li>
<li data-name="ingredient" property="recipeIngredient" class="rf-recipe__ingredient">4 egg yolks</li>
<li data-name="ingredient" property="recipeIngredient" class="rf-recipe__ingredient">100g Pecorino Romano</li>
<li data-name="ingredient" property="recipeIngredient" class="rf-recipe__ingredient">Black pepper to taste</li>
</ul>
<ol data-name="steps" class="rf-recipe__steps" data-sequence="numbered">
<li data-name="step" typeof="HowToStep" property="recipeInstructions" class="rf-recipe__step">
<p property="text">Cook pasta in salted boiling water until al dente</p>
</li>
<li data-name="step" typeof="HowToStep" property="recipeInstructions" class="rf-recipe__step">
<p property="text">Fry pancetta in a large pan until crispy</p>
</li>
<li data-name="step" typeof="HowToStep" property="recipeInstructions" class="rf-recipe__step">
<p property="text">Whisk egg yolks with grated cheese and pepper</p>
</li>
<li data-name="step" typeof="HowToStep" property="recipeInstructions" class="rf-recipe__step">
<p property="text">Toss hot pasta with pancetta, then stir in egg mixture off the heat</p>
</li>
</ol>
<div data-name="tips" class="rf-recipe__tips">
<blockquote>
<p>The residual heat from the pasta cooks the eggs — never add eggs directly to a hot pan or they will scramble.</p>
</blockquote>
</div>
</div>
<meta content="PT15M" property="prepTime" />
<meta content="PT30M" property="cookTime" />
<meta content="4" property="recipeYield" />
</article>Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
prepTime | string | — | Prep time in ISO 8601 duration (e.g. "PT15M") |
cookTime | string | — | Cook time in ISO 8601 duration |
servings | number | — | Number of servings |
difficulty | string | medium | Difficulty level: easy, medium, or hard |
Section header
Recipe supports an optional eyebrow, headline, and blurb above the section above ingredients and method. Place a short paragraph or heading before the main content to use them. See Page sections for the full syntax.
Layout attributes
The body splits on --- into media → content → footer zones (media-first in source). media-position controls visual placement independently of source order.
| Attribute | Type | Default | Description |
|---|---|---|---|
media-position | string | top | Where the media sits: top, bottom, start (left), end (right), or cover (poster header — see below) |
media-ratio | string | — | Media's share of the row when beside content (start/end): 1/3, 2/5, 1/2, 3/5, 2/3 |
valign | string | — | Cross-axis alignment when media is beside content: top, center, bottom, stretch |
collapse | string | — | Breakpoint at which beside layouts collapse to a stack: sm, md, lg, never |
content-place | string | auto | Cover only. Where the overlaid header anchors: <block> <inline> (each start/center/end), or auto |
Common attributes
All block runes share these attributes for layout and theming.
| Attribute | Type | Default | Description |
|---|---|---|---|
width | string | content | Page grid width: content, wide, or full |
spacing | string | — | Vertical spacing: flush, tight, default, loose, or breathe |
inset | string | — | Horizontal padding: flush, tight, default, loose, or breathe |
tint | string | — | Named colour tint from theme configuration |
tint-mode | string | auto | Colour scheme override: auto, dark, or light |
bg | string | — | Named background preset from theme configuration |
Cover mode
media-position="cover" turns the recipe into a poster: the title block (eyebrow, headline, blurb) overlays the media as a header, and the ingredients, steps, and tips flow below on the page palette. Recipe uses header scope — only the preamble sits on the image, never the long body — so it's the same one-attribute switch as on card, scoped to the part that belongs on the photo.
{% recipe prepTime="PT5M" servings=1 difficulty="easy" media-position="cover" scrim-type="frost" scrim-blur="md" %}

---
A cocktail classic
## Tequila Sunrise
A layered showstopper that transitions from deep orange to golden yellow — like watching the sun come up in a glass.
- 60ml tequila
- 120ml fresh orange juice
- 15ml grenadine
- Orange slice and cherry for garnish
1. Fill a tall glass with ice and pour in the tequila and orange juice. Stir gently.
2. Slowly pour grenadine over the back of a spoon so it sinks to the bottom.
3. Let the layers settle, then garnish with an orange slice and a cherry.
{% /recipe %}<article data-field="content-section" data-rune="recipe" typeof="Recipe" data-rune-fields="{"prepTime":"PT5M","cookTime":"","servings":"1","difficulty":"easy","media-position":"cover"}">
<meta content="PT5M" property="prepTime">
<meta content="1" property="recipeYield">
<div data-name="media">
<img src="https://assets.refrakt.md/tequila-sunrise.png" alt="A tequila sunrise cocktail" property="image">
</div>
<p data-name="eyebrow">A cocktail classic</p>
<h2 id="tequila-sunrise" data-name="headline" property="name">Tequila Sunrise</h2>
<p data-name="blurb" property="description">A layered showstopper that transitions from deep orange to golden yellow — like watching the sun come up in a glass.</p>
<ul data-name="ingredients">
<li data-name="ingredient" property="recipeIngredient">60ml tequila</li>
<li data-name="ingredient" property="recipeIngredient">120ml fresh orange juice</li>
<li data-name="ingredient" property="recipeIngredient">15ml grenadine</li>
<li data-name="ingredient" property="recipeIngredient">Orange slice and cherry for garnish</li>
</ul>
<ol data-name="steps">
<li data-name="step" typeof="HowToStep" property="recipeInstructions">
<p property="text">Fill a tall glass with ice and pour in the tequila and orange juice. Stir gently.</p>
</li>
<li data-name="step" typeof="HowToStep" property="recipeInstructions">
<p property="text">Slowly pour grenadine over the back of a spoon so it sinks to the bottom.</p>
</li>
<li data-name="step" typeof="HowToStep" property="recipeInstructions">
<p property="text">Let the layers settle, then garnish with an orange slice and a cherry.</p>
</li>
</ol>
<meta data-field="scrim-type" content="frost">
<meta data-field="scrim-blur" content="md">
</article>
A cocktail classic
Tequila Sunrise
A layered showstopper that transitions from deep orange to golden yellow — like watching the sun come up in a glass.
- 60ml tequila
- 120ml fresh orange juice
- 15ml grenadine
- Orange slice and cherry for garnish
Fill a tall glass with ice and pour in the tequila and orange juice. Stir gently.
Slowly pour grenadine over the back of a spoon so it sinks to the bottom.
Let the layers settle, then garnish with an orange slice and a cherry.
<article data-field="content-section" typeof="Recipe" class="rf-recipe rf-recipe--easy rf-recipe--cover" data-media-position="cover" data-prep-time="PT5M" data-cook-time="" data-servings="1" data-difficulty="easy" data-scrim-type="frost" data-scrim-blur="md" data-rune="recipe" data-density="full" data-cover-scope="header">
<div data-name="cover-band" data-color-scheme="dark" class="rf-recipe__cover-band">
<div data-name="media" class="rf-recipe__media" data-section="media" data-media="cover" data-guest-posture="presentational">
<img src="https://assets.refrakt.md/tequila-sunrise.png" alt="A tequila sunrise cocktail" property="image" />
</div>
<header data-name="preamble" class="rf-recipe__preamble" data-section="preamble">
<p data-name="eyebrow" class="rf-recipe__eyebrow">A cocktail classic</p>
<h2 id="tequila-sunrise" data-name="headline" property="name" class="rf-recipe__headline" data-section="title">Tequila Sunrise</h2>
<p data-name="blurb" property="description" class="rf-recipe__blurb" data-section="description">A layered showstopper that transitions from deep orange to golden yellow — like watching the sun come up in a glass.</p>
</header>
</div>
<div data-name="content" class="rf-recipe__content">
<dl data-name="metadata" data-zone="metadata" data-zone-layout="definition-list" class="rf-recipe__metadata">
<div data-name="row" data-field="prepTime" class="rf-recipe__row">
<dt data-meta-label="">Prep</dt>
<dd data-meta-type="temporal">5m</dd>
</div>
<div data-name="row" data-field="servings" class="rf-recipe__row">
<dt data-meta-label="">Serves</dt>
<dd data-meta-type="quantity">1</dd>
</div>
<div data-name="row" data-field="difficulty" class="rf-recipe__row">
<dt data-meta-label="">Difficulty</dt>
<dd>
<span class="rf-badge" data-meta-type="category" data-meta-sentiment="positive">easy</span>
</dd>
</div>
</dl>
<ul data-name="ingredients" class="rf-recipe__ingredients">
<li data-name="ingredient" property="recipeIngredient" class="rf-recipe__ingredient">60ml tequila</li>
<li data-name="ingredient" property="recipeIngredient" class="rf-recipe__ingredient">120ml fresh orange juice</li>
<li data-name="ingredient" property="recipeIngredient" class="rf-recipe__ingredient">15ml grenadine</li>
<li data-name="ingredient" property="recipeIngredient" class="rf-recipe__ingredient">Orange slice and cherry for garnish</li>
</ul>
<ol data-name="steps" class="rf-recipe__steps" data-sequence="numbered">
<li data-name="step" typeof="HowToStep" property="recipeInstructions" class="rf-recipe__step">
<p property="text">Fill a tall glass with ice and pour in the tequila and orange juice. Stir gently.</p>
</li>
<li data-name="step" typeof="HowToStep" property="recipeInstructions" class="rf-recipe__step">
<p property="text">Slowly pour grenadine over the back of a spoon so it sinks to the bottom.</p>
</li>
<li data-name="step" typeof="HowToStep" property="recipeInstructions" class="rf-recipe__step">
<p property="text">Let the layers settle, then garnish with an orange slice and a cherry.</p>
</li>
</ol>
</div>
<meta content="PT5M" property="prepTime" />
<meta content="1" property="recipeYield" />
</article>The cover scrim, content-place anchor, and scrim-type="frost" work exactly as on card — here the frosted band reads behind the title while the metadata and method below stay on the normal surface. Only the overlaid header flips to a light foreground; the body keeps the page palette.