Layout tree (as in design/layout.json)
{
"pattern": "menu.organic-harvest-menu",
"kind": "menu",
"grid": {
"intro": "1-4",
"dishes": "6-12"
},
"slots": [
"sectionLabel",
"title",
"body",
"image",
"menu[4..12]"
],
"tree": {
"el": "grid",
"gap": 6,
"children": [
{
"el": "box",
"span": "1-4",
"alignSelf": "start",
"gap": 3,
"children": [
{
"el": "text",
"color": "textMuted",
"slot": "sectionLabel",
"role": "eyebrow",
"italic": true
},
{
"el": "text",
"slot": "title",
"role": "h2",
"step": 5,
"weight": 400,
"maxCh": 12
},
{
"el": "text",
"color": "textMuted",
"slot": "body",
"role": "body",
"maxCh": 34
},
{
"el": "media",
"mobile": "hide",
"slot": "image",
"aspect": "1/1",
"treatment": "photo",
"frame": "arch"
}
]
},
{
"el": "repeat",
"span": "6-12",
"alignSelf": "center",
"slot": "menu",
"min": 4,
"max": 12,
"layout": "list",
"gap": 0,
"of": {
"el": "box",
"gap": 1,
"pad": [
3,
0
],
"border": "top",
"children": [
{
"el": "box",
"mobile": "keep",
"dir": "row",
"gap": 2,
"align": "baseline",
"justify": "between",
"children": [
{
"el": "text",
"slot": "title",
"role": "h3",
"step": 3,
"weight": 400
},
{
"el": "text",
"slot": "number",
"role": "label",
"font": "mono"
}
]
},
{
"el": "text",
"color": "textMuted",
"slot": "body",
"role": "body",
"maxCh": 44
}
]
}
}
]
}
}Component example: reference/menu.organic-harvest-menu.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>menu.organic-harvest-menu — Organic Earth</title>
<link rel="stylesheet" href="base.css">
<style>
section { padding: calc(var(--unit) * 16) 0; }
.intro { grid-column: 1 / 5; align-self: start; display: grid; gap: calc(var(--unit) * 3); }
.intro h2 { font-size: var(--step-5); }
.intro .arch { aspect-ratio: 1 / 1; }
.dishes { grid-column: 6 / 13; display: grid; align-self: center; gap: 0; list-style: none; padding: 0; }
.dish { border-top: 1px solid var(--border); padding: calc(var(--unit) * 3) 0; }
.dish .row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.dish h3 { font-size: var(--step-3); font-weight: 400; }
.price { font: 400 calc(var(--base) * 0.85)/1 ui-monospace, monospace; }
.dish .muted { font-size: calc(var(--base) * 0.85); max-width: 44ch; }
@media (max-width: 640px) { .intro .arch { display: none; } }
</style>
</head>
<body>
<section class="wrap">
<div class="grid">
<div class="intro">
<p class="eyebrow">This week at the counter</p>
<h2>Autumn bake</h2>
<p class="muted">Changes every Wednesday with what the farms send us.</p>
<div class="arch"><img src="https://picsum.photos/seed/buns/600/800" alt="Cardamom buns on parchment" width="600" height="800"></div>
</div>
<ul class="dishes">
<li class="dish"><div class="row"><h3>Country sourdough</h3><span class="price">£6.20</span></div><p class="muted">Wholemeal and white, 36-hour ferment, dark crust.</p></li>
<li class="dish"><div class="row"><h3>Seeded rye</h3><span class="price">£5.80</span></div><p class="muted">Sunflower, linseed and pumpkin seeds, dense and sour.</p></li>
<li class="dish"><div class="row"><h3>Cardamom bun</h3><span class="price">£3.40</span></div><p class="muted">Knotted, glazed, ground cardamom from a single grower.</p></li>
<li class="dish"><div class="row"><h3>Squash focaccia</h3><span class="price">£4.10</span></div><p class="muted">Roast crown prince squash, sage and flaky salt.</p></li>
<li class="dish"><div class="row"><h3>Apple galette</h3><span class="price">£4.60</span></div><p class="muted">Bramleys from the orchard up the hill, rye pastry.</p></li>
<li class="dish"><div class="row"><h3>Oat porridge</h3><span class="price">£5.00</span></div><p class="muted">Pinhead oats, brown butter, poached pear.</p></li>
</ul>
</div>
</section>
</body>
</html>