LearningRecipe
note

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="{&quot;prepTime&quot;:&quot;PT15M&quot;,&quot;cookTime&quot;:&quot;PT30M&quot;,&quot;servings&quot;:&quot;4&quot;,&quot;difficulty&quot;:&quot;easy&quot;,&quot;media-position&quot;:&quot;top&quot;}">
  <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
  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.

<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

AttributeTypeDefaultDescription
prepTimestringPrep time in ISO 8601 duration (e.g. "PT15M")
cookTimestringCook time in ISO 8601 duration
servingsnumberNumber of servings
difficultystringmediumDifficulty 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.

AttributeTypeDefaultDescription
media-positionstringtopWhere the media sits: top, bottom, start (left), end (right), or cover (poster header — see below)
media-ratiostringMedia's share of the row when beside content (start/end): 1/3, 2/5, 1/2, 3/5, 2/3
valignstringCross-axis alignment when media is beside content: top, center, bottom, stretch
collapsestringBreakpoint at which beside layouts collapse to a stack: sm, md, lg, never
content-placestringautoCover 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.

AttributeTypeDefaultDescription
widthstringcontentPage grid width: content, wide, or full
spacingstringVertical spacing: flush, tight, default, loose, or breathe
insetstringHorizontal padding: flush, tight, default, loose, or breathe
tintstringNamed colour tint from theme configuration
tint-modestringautoColour scheme override: auto, dark, or light
bgstringNamed 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 tequila sunrise cocktail](https://assets.refrakt.md/tequila-sunrise.png)

---

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="{&quot;prepTime&quot;:&quot;PT5M&quot;,&quot;cookTime&quot;:&quot;&quot;,&quot;servings&quot;:&quot;1&quot;,&quot;difficulty&quot;:&quot;easy&quot;,&quot;media-position&quot;:&quot;cover&quot;}">
  <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 tequila sunrise cocktail

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.

<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.