SpaceXAI Grok 4.7 – Food and Drink
via xAI · Generated
- AIMAC Debt 4.70
- Cost $0.08
- Total Violations 17
- HTML Size 37 KB
- Em Dashes 19
Screenshot
View Live Page
Accessibility Issues Found
17 Serious
-
color-contrast serious 17 instances
Elements must meet minimum color contrast ratio thresholds
Example HTML
<p class="eyebrow">Seasonal menus</p>
Artifacts
View Generated HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ember & Olive — Seasonal gastronomy for the modern table</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,500;0,700;1,500&family=Source+Sans+3:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--ink: #1b1712;
--olive: #2e3b2c;
--olive-deep: #1e291d;
--copper: #b co 6a3e;
--copper: #b56a3c;
--cream: #f4efe6;
--paper: #fbf8f3;
--sand: #e7dfd2;
--muted: #6d645b;
--line: #d9cfc2;
--white: #fffdf9;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
color: var(--ink);
background: var(--paper);
font-family: "Source Sans 3", "Source Sans Pro", sans-serif;
font-size: 17px;
line-height: 1.65;
}
img { max-width: 100%; display: block; }
a { color: var(--olive); }
.wrap { width: min(1180px, calc(100% - 40px)); margin: 0 auto; }
.eyebrow {
letter-spacing: 0.18em;
text-transform: uppercase;
font-size: 0.75rem;
font-weight: 700;
color: var(--copper);
margin: 0 0 0.5rem;
}
h1, h2, h3, h4 { font-family: "Playfair Display", Georgia, serif; line-height: 1.15; font-weight: 500; }
h2 { font-size: clamp(2rem, 3.4vw, 2.8rem); margin: 0 0 0.8rem; }
h3 { font-size: 1.45rem; margin: 0 0 0.5rem; }
p { margin: 0 0 1rem; }
.btn {
display: inline-block;
background: var(--olive);
color: var(--cream);
text-decoration: none;
padding: 0.85rem 1.25rem;
border-radius: 999px;
font-weight: 700;
border: 0;
cursor: pointer;
font-size: 0.95rem;
}
.btn:hover { background: var(--olive-deep); }
.btn.copper { background: var(--copper); color: #fff; }
.btn.ghost { background: transparent; color: var(--cream); border: 1px solid rgba(244,239,230,0.55); }
.btn.ghost-dark { background: transparent; color: var(--olive); border: 1px solid var(--olive); }
header.site {
position: sticky; top: 0; z-index: 20;
background: rgba(251,248,243,0.94);
backdrop-filter: blur(10px);
border-bottom: 1px solid var(--line);
}
.topbar {
display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
padding: 0.85rem 0;
}
.brand { display: flex; align-items: center; gap: 0.8rem; text-decoration: none; color: inherit; }
.brand img { width: 52px; height: 52px; border-radius: 50%; }
.brand strong { display: block; font-family: "Playfair Display", serif; font-size: 1.35rem; }
.brand span { display: block; color: var(--muted); font-size: 0.82rem; max-width: 280px; line-height: 1.3; }
nav.primary { display: flex; flex-wrap: wrap; gap: 0.85rem 1.1rem; justify-content: flex-end; }
nav.primary a { text-decoration: none; color: var(--ink); font-weight: 600; font-size: 0.92rem; }
nav.primary a:hover { color: var(--copper); }
.hero {
position: relative;
min-height: 640px;
display: grid;
align-items: end;
color: var(--cream);
background: #1b1712 url("https://picsum.photos/1600/900") center/cover no-repeat;
}
.hero::after {
content: "";
position: absolute; inset: 0;
background: linear-gradient(90deg, rgba(20,16,12,0.82) 0%, rgba(20,16,12,0.35) 70%, rgba(20,16,12,0.2) 100%);
}
.hero-inner { position: relative; z-index: 1; padding: 5.5rem 0 3.5rem; width: min(760px, calc(100% - 40px)); margin-left: max(20px, calc((100% - 1180px) / 2)); }
.hero h1 { font-size: clamp(3rem, 6vw, 5.2rem); margin: 0 0 1rem; color: #fff; }
.hero p { font-size: 1.12rem; max-width: 62ch; color: #f3eadf; }
.cta-row { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.4rem; }
.trust {
display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line);
border-bottom: 1px solid var(--line);
}
.trust div { background: var(--white); padding: 1.2rem 1.3rem; }
.trust strong { display: block; font-family: "Playfair Display", serif; font-size: 1.35rem; }
.trust span { color: var(--muted); font-size: 0.9rem; }
.layout { display: grid; grid-template-columns: 1fr 320px; gap: 2.5rem; padding: 3.5rem 0 1rem; }
section { margin-bottom: 3.4rem; }
.lede { font-size: 1.12rem; color: #3c352e; }
.split { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 1.6rem; align-items: center; }
.split img, .card img, .trend img { border-radius: 16px; width: 100%; height: 280px; object-fit: cover; }
.menu-grid, .review-grid, .class-grid, .trend-grid, .t-grid { display: grid; gap: 1rem; }
.menu-grid { grid-template-columns: 1fr 1fr; margin-top: 1.2rem; }
.card, .review, .class-card, .trend, .t-card, .faq details, .calc, .side-box, form.reserve {
background: var(--white);
border: 1px solid var(--line);
border-radius: 16px;
padding: 1.15rem;
}
.card h3, .review h3 { font-size: 1.25rem; }
.meta { color: var(--muted); font-size: 0.88rem; margin-bottom: 0.4rem; }
.tag {
display: inline-block; background: #efe4d4; color: #6a3d22; border-radius: 999px;
padding: 0.15rem 0.55rem; font-size: 0.78rem; font-weight: 700; margin-right: 0.3rem;
}
.trend-grid { grid-template-columns: 1.2fr 0.8fr; }
.review-grid, .class-grid, .t-grid { grid-template-columns: 1fr 1fr 1fr; }
.review img.avatar, .chef img { width: 56px; height: 56px; border-radius: 50%; object-fit: cover; }
.person { display: flex; gap: 0.75rem; align-items: center; margin-bottom: 0.6rem; }
.side-box { margin-bottom: 1rem; }
.special { display: flex; justify-content: space-between; gap: 0.6rem; border-bottom: 1px dashed var(--line); padding: 0.55rem 0; }
.special:last-child { border-bottom: 0; }
.price { font-weight: 700; color: var(--olive); }
.band {
background: var(--olive);
color: var(--cream);
padding: 3rem 0;
margin: 1rem 0 3rem;
}
.band h2, .band p { color: var(--cream); }
.calc label, form.reserve label { display: block; font-weight: 700; font-size: 0.88rem; margin: 0.7rem 0 0.25rem; }
input, select, textarea {
width: 100%; padding: 0.7rem 0.75rem; border-radius: 10px; border: 1px solid var(--line);
font: inherit; background: #fff;
}
.calc-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.7rem; }
.result {
margin-top: 1rem; background: var(--cream); border-radius: 12px; padding: 1rem;
display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.6rem;
}
.result strong { display: block; font-size: 1.4rem; font-family: "Playfair Display", serif; }
.note { font-size: 0.88rem; color: var(--muted); }
.faq details { margin-bottom: 0.6rem; }
.faq summary { cursor: pointer; font-weight: 700; font-size: 1.05rem; }
.faq details p { margin-top: 0.7rem; }
footer {
background: var(--ink); color: #e7dfd4; padding: 3rem 0 1.4rem; margin-top: 2rem;
}
footer a { color: #f4efe6; text-decoration: none; }
.foot-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 1.5rem; }
footer h4 { margin: 0 0 0.6rem; color: #fff; }
footer ul { list-style: none; padding: 0; margin: 0; }
footer li { margin: 0.35rem 0; }
.legal { border-top: 1px solid #3a342d; margin-top: 1.6rem; padding-top: 1rem; display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; font-size: 0.9rem; color: #c9bfb3; }
.stars { color: var(--copper); letter-spacing: 0.08em; }
@media (max-width: 980px) {
.layout, .split, .trend-grid, .foot-grid, .review-grid, .class-grid, .t-grid, .trust, .calc-grid, .result, .menu-grid {
grid-template-columns: 1fr;
}
.topbar { flex-direction: column; align-items: flex-start; }
nav.primary { justify-content: flex-start; }
.hero { min-height: 520px; }
}
</style>
</head>
<body>
<header class="site">
<div class="wrap topbar">
<a class="brand" href="#top">
<img src="https://placehold.co/96x96/2e3b2c/f4efe6?text=E%26O&font=playfair+display" alt="Ember and Olive monogram logo">
<div>
<strong>Ember & Olive</strong>
<span>Seasonal gastronomy, honest restaurant guides, and the craft of the table.</span>
</div>
</a>
<nav class="primary" aria-label="Primary">
<a href="#seasonal">Seasonal Menus</a>
<a href="#reviews">Restaurant Reviews</a>
<a href="#classes">Cooking Classes</a>
<a href="#technique">Technique Tutorials</a>
<a href="#trends">Culinary Trends</a>
<a href="#nutrition">Nutrition</a>
<a href="#reservations">Reservations</a>
</nav>
</div>
</header>
<section class="hero" id="top">
<div class="hero-inner">
<p class="eyebrow">Food & drink desk · Portland & beyond</p>
<h1>Cook with the season. Dine with intention.</h1>
<p>Ember & Olive is an independent culinary journal for home cooks, hosts, and curious diners. We publish market-led recipes, sommelier-guided pairings, and restaurant criticism that treats hospitality as a craft—not a trend cycle. From a Tuesday lentil pot to a Saturday tasting menu, we write about flavor the way a good kitchen talks: specifically, generously, and without theatrics.</p>
<p>This season we are following early peas, young garlic, and coastal oysters, with technique notes on emulsions, fond, and the quiet architecture of umami.</p>
<div class="cta-row">
<a class="btn copper" href="#seasonal">View Menu</a>
<a class="btn ghost" href="#order">Start Order</a>
<a class="btn ghost" href="#reservations">Reserve a Table</a>
</div>
</div>
</section>
<div class="trust">
<div><strong>240+</strong><span>tested seasonal recipes</span></div>
<div><strong>86</strong><span>restaurant reviews this year</span></div>
<div><strong>12</strong><span>working chefs on the bench</span></div>
<div><strong>4.9</strong><span>average class rating</span></div>
</div>
<div class="wrap layout">
<main>
<section id="seasonal">
<p class="eyebrow">Seasonal menus</p>
<h2>What the market is asking for this week</h2>
<div class="split">
<div>
<p class="lede">A seasonal menu is not a mood board. It is a negotiation between weather, soil, and the appetite sitting across from you. Our April table leans bright and mineral: snap peas blistered in olive oil, a chilled fennel broth finished with lemon zest, and a slow roast of spring lamb whose crust carries rosemary, cracked pepper, and a spoon of anchovy for depth rather than drama.</p>
<p>We build each menu around one quiet center of umami—aged cheese rind in a vegetable stock, dried mushroom in a pan sauce, or a spoon of miso whisked into warm butter—so the plate tastes complete without shouting. Pairings are written with our resident sommelier, Elise Marquet, who prefers wines that can sit beside food instead of performing over it: a saline Muscadet with oysters, a chilled Trousseau with charred leeks, a low-oak Chardonnay when butter and brown butter are doing the talking.</p>
<p>Subscribers receive the full written menu, a shopping list scaled for four or eight, and a twenty-minute mise en place plan so service does not become a scramble. If you would rather not shop, the Ember Pantry box mirrors the same list and ships chilled twice a week inside the metro area.</p>
<div class="cta-row">
<a class="btn" href="#menus">View Menu</a>
<a class="btn copper" href="#order">Order Now</a>
</div>
</div>
<img src="https://picsum.photos/900/700" alt="Seasonal table setting photographed in warm natural light">
</div>
<div class="menu-grid" id="menus">
<article class="card">
<p class="meta">Weeknight · 35 minutes · serves 4</p>
<h3>Green garlic risotto with peas</h3>
<p>Toasted carnaroli, a ladle of light chicken or mushroom stock, and green garlic sweated until sweet. Finish off heat with butter, lemon, and a snowfall of pecorino. The peas go in at the last minute so they stay vivid. A glass of Vermentino keeps the richness in check.</p>
<span class="tag">Umami</span><span class="tag">Spring</span>
</article>
<article class="card">
<p class="meta">Sunday · slow · serves 6</p>
<h3>Lamb shoulder, anchovy, and herbs</h3>
<p>A low oven, a covered pot, and patience. Anchovy melts into the jus and reads as savoriness, not fish. Serve with crushed potatoes and a sharp salad of radish and mint. Elise suggests a cool-climate Syrah or, for the table that prefers beer, a dry farmhouse ale.</p>
<span class="tag">Gastronomy</span><span class="tag">Roast</span>
</article>
<article class="card">
<p class="meta">First course · 20 minutes</p>
<h3>Chilled fennel broth, citrus oil</h3>
<p>Fennel, leek, and a strip of lemon peel simmered gently, strained, and chilled. A thread of olive oil pressed with orange peel lifts the aroma. This is the kind of clear, precise cooking that makes a longer menu feel composed rather than heavy.</p>
<span class="tag">Technique</span><span class="tag">Light</span>
</article>
<article class="card">
<p class="meta">Dessert · make-ahead</p>
<h3>Olive oil cake, roasted strawberries</h3>
<p>A tender crumb scented with citrus zest and a generous pour of peppery oil. Strawberries roast just until they slump, then get a pinch of black pepper. It is not fussy gastronomy; it is the cake people ask for the recipe of before coffee is poured.</p>
<span class="tag">Bake</span><span class="tag">Share</span>
</article>
</div>
</section>
<section id="technique">
<p class="eyebrow">Technique tutorials</p>
<h2>The small skills that change a whole dinner</h2>
<p>Most disappointing home cooking is not a failure of taste. It is a failure of sequence: the pan too cool, the salt too late, the stock added in a rush. Our tutorials slow those moments down. We film and write them the way a patient chef de partie would explain them on a quiet Tuesday—hands in frame, no mystery powders, no equipment you cannot find in a serious home kitchen.</p>
<p>This month’s bench focuses on three foundations. First, building a pan sauce from fond without scorching the sugars. Second, mounting an emulsion—beurre blanc, a loose aioli, a vinaigrette that holds through service. Third, seasoning in layers so umami arrives as roundness, not as a single salty hit at the end. Each lesson includes a troubleshooting card: what split sauces look like, how to rescue a tight risotto, and when to stop stirring and trust the heat.</p>
<div class="split">
<img src="https://picsum.photos/880/640" alt="Close view of hands working at a wooden prep counter">
<div>
<h3>From fond to finish</h3>
<p>After searing, leave the browned bits. Deglaze with a splash of dry white wine or stock, scrape honestly, and reduce until the liquid coats a spoon. A knob of cold butter swirled in off the flame gives gloss and a softer edge. If the sauce tastes flat, it usually needs acid or salt—not another herb. Taste with the food it will meet, not from the pan alone.</p>
<p>Students in our evening labs practice this on chicken thighs and mushrooms, then apply the same logic to fish and vegetables. The point is transferable judgment, the thing no recipe can fully print.</p>
<a class="btn" href="#classes">Join a Technique Lab</a>
</div>
</div>
</section>
<section id="trends">
<p class="eyebrow">Culinary trends</p>
<h2>What is actually changing in the dining room</h2>
<p>We are wary of trend language, but some shifts are structural. Kitchens are cooking with more fermentation, not as a novelty but as a way to keep flavor through leaner, vegetable-forward menus. Natural wine lists are maturing: fewer cloudy bottles chosen for the story, more precise pours chosen by a sommelier who can explain acidity, skin contact, and what belongs beside charred alliums. Waste is being treated as a cost and a creative constraint—stalks into stocks, citrus peels into oils, bread into a proper panzanella instead of a guilty afterthought.</p>
<div class="trend-grid">
<article class="trend">
<img src="https://picsum.photos/1000/620" alt="Dining room interior with long wooden tables">
<h3>Fermentation, quietly</h3>
<p>The interesting work is no longer a kimchi on every plate. It is a house shrub in a spritz, a lactic brine that brightens roasted roots, a garum used by the drop the way a classical kitchen used demi-glace. We visit three Portland kitchens this month that ferment for function: longer shelf life, deeper savor, and menus that still feel clean.</p>
<p>If you cook at home, start smaller than the internet suggests. A cabbage kraut, a quick pickle, and one chili oil will teach you more than a shelf of abandoned jars. Smell daily. Salt with a scale. Write dates on tape, not in your memory.</p>
</article>
<article class="trend">
<h3>The new hospitality test</h3>
<p>Guests are less impressed by spectacle and more attentive to pacing, temperature, and whether a server can describe a dish without reciting adjectives. Our review desk scores hospitality alongside gastronomy: Was the wine list a conversation? Did the kitchen send food that matched the room’s noise and the table’s time?</p>
<p>That standard shapes how we teach, too. A beautiful emulsion means little if it arrives cold, or if the host is still hunting for plates while guests stand in the kitchen. Technique and hosting are the same subject.</p>
<a class="btn ghost-dark" href="#reviews">Read the reviews</a>
</article>
</div>
</section>
<section id="reviews">
<p class="eyebrow">Restaurant reviews</p>
<h2>Rooms worth crossing town for</h2>
<p>Our critics dine anonymously, pay their own checks, and return when a kitchen is uneven—once is a snapshot, twice is a judgment. Reviews discuss seasoning, sourcing, value, and whether the sommelier’s list has a point of view. We do not trade stars for access, and we correct the record when a restaurant changes chefs or concept.</p>
<div class="review-grid">
<article class="review">
<p class="stars" aria-label="4.5 out of 5">★★★★★</p>
<h3>Orchard Station</h3>
<p class="meta">Alberta · wood fire · $$</p>
<p>A hearth restaurant that understands restraint. The cabbage steak with brown-butter hazelnuts is the dish people will imitate badly for a year. Service is warm without hovering, and the short wine list is edited by someone who has actually eaten the food.</p>
</article>
<article class="review">
<p class="stars" aria-label="4 out of 5">★★★★☆</p>
<h3>Brine & Barley</h3>
<p class="meta">Pearl · seafood · $$$</p>
<p>Oysters are impeccable, the crudo correctly cold, and the chowder finally seasoned like a coastal kitchen rather than a hotel. Skip the overbuilt dessert; order a second dozen and a glass of grower Champagne. Book the counter if you want to watch the garde manger work.</p>
</article>
<article class="review">
<p class="stars" aria-label="4.5 out of 5">★★★★★</p>
<h3>Little Provenance</h3>
<p class="meta">Division · tasting · $$$$</p>
<p>Eight courses, no foam, no lecture. A carrot cooked in whey, a trout with dill pollen, a cheese service that a serious sommelier would respect. It is expensive and worth it when you want gastronomy that still tastes like dinner.</p>
</article>
</div>
</section>
<section id="classes">
<p class="eyebrow">Cooking classes</p>
<h2>Stand at the bench with working cooks</h2>
<p>Classes run in our test kitchen on Market Lane and, once a month, as a pop-up inside a partner restaurant after service. Groups are capped at twelve so instructors can correct a grip, a heat, or a seasoning call in real time. You leave with recipes scaled for home, a tasting notebook, and the particular confidence that comes from having made the sauce yourself.</p>
<div class="class-grid">
<article class="class-card">
<h3>Knife & mise</h3>
<p class="meta">Thursday evenings · $95</p>
<p>Dice, chiffonade, and the logic of prepping a three-course menu so the last plate does not suffer. Ideal if your boards are scarred and your onions still make you cry in uneven pieces.</p>
</article>
<article class="class-card">
<h3>Sauces & emulsions</h3>
<p class="meta">Saturday morning · $120</p>
<p>Pan sauces, beurre blanc, mayonnaise, and vinaigrettes that survive a dinner party. We taste for acid, fat, and salt until the language becomes automatic.</p>
</article>
<article class="class-card">
<h3>Wine with the meal</h3>
<p class="meta">With sommelier Elise · $140</p>
<p>Four dishes, six glasses, and a practical map of pairing: weight, acid, oak, and when water or tea is the better companion. No jargon without a translation.</p>
</article>
</div>
<div class="cta-row" style="margin-top:1rem;">
<a class="btn copper" href="#reservations">Reserve a Seat</a>
<a class="btn ghost-dark" href="#order">Start Order for class ingredients</a>
</div>
</section>
<section id="stories">
<p class="eyebrow">From the journal</p>
<h2>Longer reads for people who cook and people who book</h2>
<p>Between the menus and the criticism, the journal holds interviews and field notes. This week: a morning with a Willamette vegetable grower who plants for flavor rather than shipping weight; a sommelier’s argument for shorter lists; and a home cook’s account of feeding a crowded table without losing the plot. We write in full paragraphs because flavor, cost, and hospitality rarely fit in a caption.</p>
<p>If you are building a household repertoire, start with our technique archive and one seasonal menu. If you are choosing a restaurant for a milestone, read two reviews and the pairing note—then make the reservation while the room still has a table by the window.</p>
</section>
</main>
<aside>
<div class="side-box">
<p class="eyebrow">Daily specials</p>
<h3>Counter today</h3>
<p>Our test-kitchen counter serves a short lunch to neighbors and students. Walk-ins until 1:30, or order ahead for pickup.</p>
<div class="special"><span>Pea toast, ricotta, chili oil</span><span class="price">$14</span></div>
<div class="special"><span>Lamb broth, herbs, grilled bread</span><span class="price">$16</span></div>
<div class="special"><span>Olive oil cake slice</span><span class="price">$7</span></div>
<div class="special"><span>Sommelier’s glass pour</span><span class="price">$12</span></div>
<div class="cta-row"><a class="btn" href="#order">Order Now</a></div>
</div>
<div class="side-box">
<p class="eyebrow">Featured chefs</p>
<h3>On the bench</h3>
<div class="person">
<img class="avatar" src="https://i.pravatar.cc/80?u=amara-vell" alt="Portrait of Chef Amara Vell" width="56" height="56">
<div><strong>Amara Vell</strong><br><span class="meta">Executive editor & roast specialist</span></div>
</div>
<p>Amara ran the fire station at two Portland rooms before joining the journal. She writes our Sunday roasts and teaches knife labs.</p>
<div class="person">
<img src="https://i.pravatar.cc/80?u=elise-marquet" alt="Portrait of sommelier Elise Marquet" width="56" height="56">
<div><strong>Elise Marquet</strong><br><span class="meta">Sommelier & pairing editor</span></div>
</div>
<p>Elise builds lists that a cook can understand: acid first, story second. Her Friday notes are the most forwarded thing we publish.</p>
<div class="person">
<img src="https://i.pravatar.cc/80?u=jonah-pere" alt="Portrait of Chef Jonah Pere" width="56" height="56">
<div><strong>Jonah Pere</strong><br><span class="meta">Ferments & vegetable cookery</span></div>
</div>
<p>Jonah keeps the crocks and writes the waste-wise column. Interview drop: how a restaurant pickle program actually pays for itself.</p>
</div>
<div class="side-box">
<p class="eyebrow">Pantry note</p>
<h3>Keep these three</h3>
<p>Good olive oil, a vinegar with real acidity, and flaky salt. Most “missing flavor” is one of those three arriving too late. Add dried mushrooms if you want a pantry source of umami that does not rely on meat stock.</p>
</div>
</aside>
</div>
<section class="band" id="order">
<div class="wrap">
<p class="eyebrow">Ember Pantry</p>
<h2>Start an order for the week’s menu</h2>
<p>The Tuesday box mirrors our published seasonal menu: produce from two partner farms, a protein or a considered vegetarian center, dairy or a plant alternative, and the small aromatics the recipes actually use. We do not pad the box with novelty condiments. You cook from a plan, not from guilt about a lonely bunch of herbs.</p>
<p>Choose four or eight servings. Delivery inside Portland is Tuesday and Friday before noon; pickup at Market Lane is free. First-time subscribers receive the technique card for that week’s sauce or emulsion.</p>
<div class="cta-row">
<a class="btn copper" href="#reservations">Start Order</a>
<a class="btn ghost" href="#seasonal">View Menu</a>
</div>
</div>
</section>
<div class="wrap">
<section id="nutrition">
<p class="eyebrow">Nutrition resources</p>
<h2>A practical plate calculator</h2>
<p>Nutrition talk in food media often swings between denial and arithmetic. We prefer a middle path: cook food you want to eat, then understand roughly what the plate is doing. This calculator estimates energy and macros from amounts you actually measure in a home kitchen. It is a planning aid for balanced weeknight cooking, not a medical device and not a substitute for advice from a registered dietitian or your clinician.</p>
<p>Enter cooked weights where you can. A palm-sized portion of fish, a generous cup of grains, a real serving of vegetables, and an honest pour of oil will tell you more than a generic “healthy plate” graphic. If a number surprises you, adjust the oil or the portion before you adjust the joy.</p>
<div class="calc">
<form id="calc-form">
<div class="calc-grid">
<div>
<label for="protein">Protein food (grams)</label>
<input id="protein" type="number" min="0" max="800" value="160" required>
</div>
<div>
<label for="grain">Cooked grains or starch (grams)</label>
<input id="grain" type="number" min="0" max="800" value="180">
</div>
<div>
<label for="veg">Vegetables (grams)</label>
<input id="veg" type="number" min="0" max="1000" value="250">
</div>
<div>
<label for="fat">Added oil or butter (grams)</label>
<input id="fat" type="number" min="0" max="120" value="14">
</div>
</div>
<label for="style">Plate style</label>
<select id="style">
<option value="fish">Fish or seafood</option>
<option value="poultry">Poultry</option>
<option value="legume">Legumes and vegetables</option>
<option value="red">Red meat, modest portion</option>
</select>
<div class="cta-row">
<button class="btn" type="submit">Estimate plate</button>
</div>
</form>
<div class="result" id="result" aria-live="polite">
<div><strong id="kcal">—</strong><span>estimated kcal</span></div>
<div><strong id="pg">—</strong><span>protein</span></div>
<div><strong id="cg">—</strong><span>carbohydrate</span></div>
<div><strong id="fg">—</strong><span>fat</span></div>
</div>
<p id="advice" class="note">Add your amounts and estimate a single plated serving. Figures are approximate averages for teaching, not laboratory analysis.</p>
</div>
</section>
<section>
<p class="eyebrow">From the table</p>
<h2>What readers and students say</h2>
<div class="t-grid">
<article class="t-card">
<div class="person">
<img src="https://i.pravatar.cc/80?u=nina-cho" alt="Portrait of Nina Cho" width="56" height="56">
<div><strong>Nina Cho</strong><br><span class="meta">Home cook, Division</span></div>
</div>
<p>“The seasonal menu finally made weeknights feel composed. I stopped buying ingredients for five abandoned recipes and started cooking one plan well. The beurre blanc lesson alone paid for the class.”</p>
</article>
<article class="t-card">
<div class="person">
<img src="https://i.pravatar.cc/80?u=marcus-hale" alt="Portrait of Marcus Hale" width="56" height="56">
<div><strong>Marcus Hale</strong><br><span class="meta">Hosts a monthly supper</span></div>
</div>
<p>“Elise’s pairing notes are the opposite of snobbery. I can pour two wines for eight people and explain them without pretending I run a cellar. Guests notice the pacing more than the garnish.”</p>
</article>
<article class="t-card">
<div class="person">
<img src="https://i.pravatar.cc/80?u=priya-santos" alt="Portrait of Priya Santos" width="56" height="56">
<div><strong>Priya Santos</strong><br><span class="meta">Dining editor, visiting</span></div>
</div>
<p>“Their reviews have a point of view and a memory. When a kitchen improves, they say so. That is rarer in restaurant writing than a perfect adjective.”</p>
</article>
</div>
</section>
<section class="faq" id="faq">
<p class="eyebrow">Questions</p>
<h2>Before you book, cook, or subscribe</h2>
<details open>
<summary>Do the recipes assume professional equipment?</summary>
<p>No. We test on a home range with one good pan, a decent knife, and a scale. When a technique benefits from a tool—an immersion blender for a soup, a thermometer for a roast—we say so and offer a workaround. Gastronomy here means attention, not a gadget drawer.</p>
</details>
<details>
<summary>How do restaurant reservations through Ember & Olive work?</summary>
<p>We hold a small number of partner tables each week at rooms we have reviewed and still stand behind. Request a time below; our desk confirms by email within one business day. We do not charge a booking fee. The restaurant’s own cancellation policy applies, and we will send it with your confirmation.</p>
</details>
<details>
<summary>Can the nutrition calculator replace a diet plan?</summary>
<p>It cannot. The estimates use typical composition values so you can compare plates and portions. Allergies, medical conditions, athletic targets, and clinical nutrition need a qualified professional. Use the tool to cook more deliberately, then get personal advice where it matters.</p>
</details>
<details>
<summary>Are cooking classes suitable for beginners?</summary>
<p>Knife & mise and the weeknight sauce lab are built for confident beginners. The sommelier evening assumes you enjoy wine but does not require credentials. Tell us your experience when you reserve a seat so we can pair you with the right bench.</p>
</details>
</section>
<section id="reservations">
<p class="eyebrow">Reservations</p>
<h2>Request a table, a class seat, or a pantry start</h2>
<p>Use one note for the thing you actually want: a partner-restaurant table, a place in Thursday’s knife lab, or the first Ember Pantry delivery. We read every request. If a seating is gone, we offer the nearest alternative rather than a vague waitlist.</p>
<form class="reserve" id="reserve-form">
<label for="name">Name</label>
<input id="name" name="name" required placeholder="Your name">
<label for="email">Email</label>
<input id="email" name="email" type="email" required placeholder="you@example.com">
<label for="kind">Request</label>
<select id="kind" name="kind">
<option>Restaurant table via partner desk</option>
<option>Cooking class seat</option>
<option>Start pantry order</option>
<option>Sommelier pairing evening</option>
</select>
<label for="when">Preferred date</label>
<input id="when" name="when" type="date">
<label for="note">Notes</label>
<textarea id="note" name="note" rows="4" placeholder="Party size, dietary needs, or which menu you want to cook."></textarea>
<div class="cta-row">
<button class="btn copper" type="submit">Reserve a Table</button>
<a class="btn ghost-dark" href="#order">Order Now</a>
</div>
<p id="form-msg" class="note" role="status"></p>
</form>
</section>
<section id="privacy">
<h2>Privacy</h2>
<p>Ember & Olive collects only what a reservation, class enrollment, or pantry order requires: your name, email, party details, and delivery notes. We do not sell reader lists. Analytics on this page are aggregated. You may ask us to delete a request by writing to privacy@emberandolive.example. Payment details, when an order is confirmed, are handled by our processor and are not stored in the editorial inbox.</p>
</section>
<section id="terms">
<h2>Terms</h2>
<p>Recipes are published for personal cooking. Restaurant reviews are opinion, based on paid visits, and may age as kitchens change. Class seats are held for fifteen minutes past the start time. Pantry boxes are perishable; report an issue the day of delivery and we will replace or refund the affected items. Partner reservations are subject to each restaurant’s house policies, which we pass along at confirmation.</p>
</section>
</div>
<footer>
<div class="wrap foot-grid">
<div>
<h4>Ember & Olive</h4>
<p>A culinary journal and reservation desk for people who care how food is grown, cooked, and served. Seasonal menus, technique, and criticism from a small staff in Portland.</p>
<p>418 Market Lane, Suite 6<br>Portland, Oregon 97204<br>(503) 555-0148<br>hello@emberandolive.example</p>
</div>
<div>
<h4>Explore</h4>
<ul>
<li><a href="#seasonal">Seasonal Menus</a></li>
<li><a href="#reviews">Restaurant Reviews</a></li>
<li><a href="#classes">Cooking Classes</a></li>
<li><a href="#technique">Technique Tutorials</a></li>
<li><a href="#reservations">Reservations</a></li>
</ul>
</div>
<div>
<h4>House</h4>
<ul>
<li><a href="#privacy">Privacy</a></li>
<li><a href="#terms">Terms</a></li>
<li><a href="#nutrition">Nutrition</a></li>
<li><a href="#faq">FAQ</a></li>
</ul>
</div>
<div>
<h4>Social</h4>
<ul>
<li><a href="https://instagram.com" rel="noopener">Instagram</a></li>
<li><a href="https://youtube.com" rel="noopener">YouTube lessons</a></li>
<li><a href="https://pinterest.com" rel="noopener">Pinterest</a></li>
<li><a href="mailto:hello@emberandolive.example">Email the desk</a></li>
</ul>
</div>
</div>
<div class="wrap legal">
<span>© 2026 Ember & Olive Editorial. All rights reserved.</span>
<span>Cook well. Book honestly. Taste before you salt again.</span>
</div>
</footer>
<script>
(function () {
var factors = {
fish: { p: 0.22, c: 0, f: 0.05 },
poultry: { p: 0.27, c: 0, f: 0.06 },
legume: { p: 0.08, c: 0.18, f: 0.02 },
red: { p: 0.25, c: 0, f: 0.12 }
};
var form = document.getElementById("calc-form");
form.addEventListener("submit", function (e) {
e.preventDefault();
var proteinG = Number(document.getElementById("protein").value) || 0;
var grainG = Number(document.getElementById("grain").value) || 0;
var vegG = Number(document.getElementById("veg").value) || 0;
var fatG = Number(document.getElementById("fat").value) || 0;
var style = factors[document.getElementById("style").value];
var protein = proteinG * style.p + vegG * 0.02 + grainG * 0.03;
var carbs = grainG * 0.28 + vegG * 0.06 + proteinG * style.c;
var fat = fatG * 0.99 + proteinG * style.f + grainG * 0.01;
var kcal = protein * 4 + carbs * 4 + fat * 9;
document.getElementById("kcal").textContent = Math.round(kcal);
document.getElementById("pg").textContent = Math.round(protein) + " g";
document.getElementById("cg").textContent = Math.round(carbs) + " g";
document.getElementById("fg").textContent = Math.round(fat) + " g";
var note = "A balanced plate often lands near half vegetables by volume, a clear protein, and a starch that fits the evening. ";
if (fatG > 25) note += "The oil or butter is doing a lot of the calories—taste before adding more at the table. ";
if (vegG < 120) note += "Vegetables are light here; a salad or extra greens would add fiber without much energy. ";
if (protein < 20) note += "Protein is modest; add legumes, eggs, fish, or dairy if this is a main meal. ";
else note += "Protein looks serviceable for a main plate. Pair with acid—lemon, vinegar—so richness stays lively. ";
document.getElementById("advice").textContent = note + "Estimates only; not clinical nutrition advice.";
});
document.getElementById("reserve-form").addEventListener("submit", function (e) {
e.preventDefault();
var kind = document.getElementById("kind").value;
document.getElementById("form-msg").textContent = "Request received for “" + kind + "”. A coordinator will confirm by email within one business day. This demo does not send data to a server.";
});
})();
</script>
</body>
</html>
View Axe Report (JSON)
{
"testEngine": {
"name": "axe-core",
"version": "4.10.2"
},
"testRunner": {
"name": "axe"
},
"testEnvironment": {
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36",
"windowWidth": 1280,
"windowHeight": 720,
"orientationAngle": 0,
"orientationType": "landscape-primary"
},
"timestamp": "2026-11-12T10:04:06.080Z",
"url": "https://benchmark.aimac.invalid/5316328a8c2a7baaf0ed45fad21807c3f60a2a4f73f5e99f64f4080d0c648150.html",
"toolOptions": {
"runOnly": {
"type": "tag",
"values": [
"wcag2a",
"wcag2aa",
"wcag21a",
"wcag21aa",
"wcag22a",
"wcag22aa"
]
},
"resultTypes": [
"violations"
],
"reporter": "v1"
},
"inapplicable": [
{
"id": "area-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag244",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.2.4.4",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure <area> elements of image maps have alternative text",
"help": "Active <area> elements must have alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/area-alt?application=axeAPI",
"nodes": []
},
{
"id": "aria-braille-equivalent",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure aria-braillelabel and aria-brailleroledescription have a non-braille equivalent",
"help": "aria-braille attributes must have a non-braille equivalent",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-braille-equivalent?application=axeAPI",
"nodes": []
},
{
"id": "aria-command-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure every ARIA button, link and menuitem has an accessible name",
"help": "ARIA commands must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-command-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-hidden-focus",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag412",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure aria-hidden elements are not focusable nor contain focusable elements",
"help": "ARIA hidden element must not be focusable or contain focusable elements",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-hidden-focus?application=axeAPI",
"nodes": []
},
{
"id": "aria-input-field-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure every ARIA input field has an accessible name",
"help": "ARIA input fields must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-input-field-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-meter-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag111",
"EN-301-549",
"EN-9.1.1.1"
],
"description": "Ensure every ARIA meter node has an accessible name",
"help": "ARIA meter nodes must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-meter-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-progressbar-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag111",
"EN-301-549",
"EN-9.1.1.1"
],
"description": "Ensure every ARIA progressbar node has an accessible name",
"help": "ARIA progressbar nodes must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-progressbar-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-required-children",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure elements with an ARIA role that require child roles contain them",
"help": "Certain ARIA roles must contain particular children",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-required-children?application=axeAPI",
"nodes": []
},
{
"id": "aria-required-parent",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure elements with an ARIA role that require parent roles are contained by them",
"help": "Certain ARIA roles must be contained by particular parents",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-required-parent?application=axeAPI",
"nodes": []
},
{
"id": "aria-toggle-field-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure every ARIA toggle field has an accessible name",
"help": "ARIA toggle fields must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-toggle-field-name?application=axeAPI",
"nodes": []
},
{
"id": "aria-tooltip-name",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure every ARIA tooltip node has an accessible name",
"help": "ARIA tooltip nodes must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-tooltip-name?application=axeAPI",
"nodes": []
},
{
"id": "autocomplete-valid",
"impact": null,
"tags": [
"cat.forms",
"wcag21aa",
"wcag135",
"EN-301-549",
"EN-9.1.3.5",
"ACT"
],
"description": "Ensure the autocomplete attribute is correct and suitable for the form field",
"help": "autocomplete attribute must be used correctly",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/autocomplete-valid?application=axeAPI",
"nodes": []
},
{
"id": "blink",
"impact": null,
"tags": [
"cat.time-and-media",
"wcag2a",
"wcag222",
"section508",
"section508.22.j",
"TTv5",
"TT2.b",
"EN-301-549",
"EN-9.2.2.2"
],
"description": "Ensure <blink> elements are not used",
"help": "<blink> elements are deprecated and must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/blink?application=axeAPI",
"nodes": []
},
{
"id": "definition-list",
"impact": null,
"tags": [
"cat.structure",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure <dl> elements are structured correctly",
"help": "<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script>, <template> or <div> elements",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/definition-list?application=axeAPI",
"nodes": []
},
{
"id": "dlitem",
"impact": null,
"tags": [
"cat.structure",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure <dt> and <dd> elements are contained by a <dl>",
"help": "<dt> and <dd> elements must be contained by a <dl>",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/dlitem?application=axeAPI",
"nodes": []
},
{
"id": "frame-focusable-content",
"impact": null,
"tags": [
"cat.keyboard",
"wcag2a",
"wcag211",
"TTv5",
"TT4.a",
"EN-301-549",
"EN-9.2.1.1"
],
"description": "Ensure <frame> and <iframe> elements with focusable content do not have tabindex=-1",
"help": "Frames with focusable content must not have tabindex=-1",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/frame-focusable-content?application=axeAPI",
"nodes": []
},
{
"id": "frame-title-unique",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag412",
"TTv5",
"TT12.d",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure <iframe> and <frame> elements contain a unique title attribute",
"help": "Frames must have a unique title attribute",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/frame-title-unique?application=axeAPI",
"nodes": []
},
{
"id": "frame-title",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag412",
"section508",
"section508.22.i",
"TTv5",
"TT12.d",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure <iframe> and <frame> elements have an accessible name",
"help": "Frames must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/frame-title?application=axeAPI",
"nodes": []
},
{
"id": "html-xml-lang-mismatch",
"impact": null,
"tags": [
"cat.language",
"wcag2a",
"wcag311",
"EN-301-549",
"EN-9.3.1.1",
"ACT"
],
"description": "Ensure that HTML elements with both valid lang and xml:lang attributes agree on the base language of the page",
"help": "HTML elements with lang and xml:lang must have the same base language",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/html-xml-lang-mismatch?application=axeAPI",
"nodes": []
},
{
"id": "input-button-name",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure input buttons have discernible text",
"help": "Input buttons must have discernible text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/input-button-name?application=axeAPI",
"nodes": []
},
{
"id": "input-image-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT7.a",
"EN-301-549",
"EN-9.1.1.1",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure <input type=\"image\"> elements have alternative text",
"help": "Image buttons must have alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/input-image-alt?application=axeAPI",
"nodes": []
},
{
"id": "link-in-text-block",
"impact": null,
"tags": [
"cat.color",
"wcag2a",
"wcag141",
"TTv5",
"TT13.a",
"EN-301-549",
"EN-9.1.4.1"
],
"description": "Ensure links are distinguished from surrounding text in a way that does not rely on color",
"help": "Links must be distinguishable without relying on color",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/link-in-text-block?application=axeAPI",
"nodes": []
},
{
"id": "marquee",
"impact": null,
"tags": [
"cat.parsing",
"wcag2a",
"wcag222",
"TTv5",
"TT2.b",
"EN-301-549",
"EN-9.2.2.2"
],
"description": "Ensure <marquee> elements are not used",
"help": "<marquee> elements are deprecated and must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/marquee?application=axeAPI",
"nodes": []
},
{
"id": "meta-refresh",
"impact": null,
"tags": [
"cat.time-and-media",
"wcag2a",
"wcag221",
"TTv5",
"TT8.a",
"EN-301-549",
"EN-9.2.2.1"
],
"description": "Ensure <meta http-equiv=\"refresh\"> is not used for delayed refresh",
"help": "Delayed refresh under 20 hours must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/meta-refresh?application=axeAPI",
"nodes": []
},
{
"id": "object-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"section508",
"section508.22.a",
"EN-301-549",
"EN-9.1.1.1"
],
"description": "Ensure <object> elements have alternative text",
"help": "<object> elements must have alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/object-alt?application=axeAPI",
"nodes": []
},
{
"id": "role-img-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"section508",
"section508.22.a",
"TTv5",
"TT7.a",
"EN-301-549",
"EN-9.1.1.1",
"ACT"
],
"description": "Ensure [role=\"img\"] elements have alternative text",
"help": "[role=\"img\"] elements must have an alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/role-img-alt?application=axeAPI",
"nodes": []
},
{
"id": "scrollable-region-focusable",
"impact": null,
"tags": [
"cat.keyboard",
"wcag2a",
"wcag211",
"wcag213",
"TTv5",
"TT4.a",
"EN-301-549",
"EN-9.2.1.1",
"EN-9.2.1.3"
],
"description": "Ensure elements that have scrollable content are accessible by keyboard",
"help": "Scrollable region must have keyboard access",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/scrollable-region-focusable?application=axeAPI",
"nodes": []
},
{
"id": "server-side-image-map",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag211",
"section508",
"section508.22.f",
"TTv5",
"TT4.a",
"EN-301-549",
"EN-9.2.1.1"
],
"description": "Ensure that server-side image maps are not used",
"help": "Server-side image maps must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/server-side-image-map?application=axeAPI",
"nodes": []
},
{
"id": "svg-img-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"section508",
"section508.22.a",
"TTv5",
"TT7.a",
"EN-301-549",
"EN-9.1.1.1",
"ACT"
],
"description": "Ensure <svg> elements with an img, graphics-document or graphics-symbol role have an accessible text",
"help": "<svg> elements with an img role must have an alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/svg-img-alt?application=axeAPI",
"nodes": []
},
{
"id": "td-headers-attr",
"impact": null,
"tags": [
"cat.tables",
"wcag2a",
"wcag131",
"section508",
"section508.22.g",
"TTv5",
"TT14.b",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure that each cell in a table that uses the headers attribute refers only to other cells in that table",
"help": "Table cells that use the headers attribute must only refer to cells in the same table",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/td-headers-attr?application=axeAPI",
"nodes": []
},
{
"id": "th-has-data-cells",
"impact": null,
"tags": [
"cat.tables",
"wcag2a",
"wcag131",
"section508",
"section508.22.g",
"TTv5",
"TT14.b",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure that <th> elements and elements with role=columnheader/rowheader have data cells they describe",
"help": "Table headers in a data table must refer to data cells",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/th-has-data-cells?application=axeAPI",
"nodes": []
},
{
"id": "valid-lang",
"impact": null,
"tags": [
"cat.language",
"wcag2aa",
"wcag312",
"TTv5",
"TT11.b",
"EN-301-549",
"EN-9.3.1.2",
"ACT"
],
"description": "Ensure lang attributes have valid values",
"help": "lang attribute must have a valid value",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/valid-lang?application=axeAPI",
"nodes": []
},
{
"id": "video-caption",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag122",
"section508",
"section508.22.a",
"TTv5",
"TT17.a",
"EN-301-549",
"EN-9.1.2.2"
],
"description": "Ensure <video> elements have captions",
"help": "<video> elements must have captions",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/video-caption?application=axeAPI",
"nodes": []
},
{
"id": "no-autoplay-audio",
"impact": null,
"tags": [
"cat.time-and-media",
"wcag2a",
"wcag142",
"TTv5",
"TT2.a",
"EN-301-549",
"EN-9.1.4.2",
"ACT"
],
"description": "Ensure <video> or <audio> elements do not autoplay audio for more than 3 seconds without a control mechanism to stop or mute the audio",
"help": "<video> or <audio> elements must not play automatically",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/no-autoplay-audio?application=axeAPI",
"nodes": []
}
],
"passes": [
{
"id": "aria-allowed-attr",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure an element's role supports its ARIA attributes",
"help": "Elements must only use supported ARIA attributes",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-allowed-attr?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "aria-allowed-attr",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA attributes are used correctly for the defined role"
}
],
"none": [
{
"id": "aria-unsupported-attr",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA attribute is supported"
}
],
"impact": null,
"html": "<nav class=\"primary\" aria-label=\"Primary\">",
"target": [
"nav"
]
}
]
},
{
"id": "aria-conditional-attr",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure ARIA attributes are used as described in the specification of the element's role",
"help": "ARIA attributes must be used as specified for the element's role",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-conditional-attr?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "aria-conditional-attr",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "ARIA attribute is allowed"
}
],
"none": [],
"impact": null,
"html": "<nav class=\"primary\" aria-label=\"Primary\">",
"target": [
"nav"
]
}
]
},
{
"id": "aria-deprecated-role",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure elements do not use deprecated roles",
"help": "Deprecated ARIA roles must not be used",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-deprecated-role?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "deprecatedrole",
"data": null,
"relatedNodes": [],
"impact": "minor",
"message": "ARIA role is not deprecated"
}
],
"impact": null,
"html": "<p id=\"form-msg\" class=\"note\" role=\"status\"></p>",
"target": [
"#form-msg"
]
}
]
},
{
"id": "aria-hidden-body",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag131",
"wcag412",
"EN-301-549",
"EN-9.1.3.1",
"EN-9.4.1.2"
],
"description": "Ensure aria-hidden=\"true\" is not present on the document body.",
"help": "aria-hidden=\"true\" must not be present on the document body",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-hidden-body?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "aria-hidden-body",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "No aria-hidden attribute is present on document body"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<body>",
"target": [
"body"
]
}
]
},
{
"id": "aria-prohibited-attr",
"impact": "serious",
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure ARIA attributes are not prohibited for an element's role",
"help": "Elements must only use permitted ARIA attributes",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-prohibited-attr?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "aria-prohibited-attr",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "ARIA attribute is allowed"
}
],
"impact": null,
"html": "<nav class=\"primary\" aria-label=\"Primary\">",
"target": [
"nav"
]
}
]
},
{
"id": "aria-required-attr",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure elements with ARIA roles have all required ARIA attributes",
"help": "Required ARIA attributes must be provided",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-required-attr?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "aria-required-attr",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "All required ARIA attributes are present"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<p id=\"form-msg\" class=\"note\" role=\"status\"></p>",
"target": [
"#form-msg"
]
}
]
},
{
"id": "aria-roles",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure all elements with a role attribute use a valid value",
"help": "ARIA roles used must conform to valid values",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-roles?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "invalidrole",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA role is valid"
},
{
"id": "abstractrole",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Abstract roles are not used"
},
{
"id": "unsupportedrole",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA role is supported"
}
],
"impact": null,
"html": "<p id=\"form-msg\" class=\"note\" role=\"status\"></p>",
"target": [
"#form-msg"
]
}
]
},
{
"id": "aria-valid-attr-value",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure all ARIA attributes have valid values",
"help": "ARIA attributes must conform to valid values",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-valid-attr-value?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "aria-valid-attr-value",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA attribute values are valid"
},
{
"id": "aria-errormessage",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "aria-errormessage exists and references elements visible to screen readers that use a supported aria-errormessage technique"
},
{
"id": "aria-level",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "aria-level values are valid"
}
],
"none": [],
"impact": null,
"html": "<nav class=\"primary\" aria-label=\"Primary\">",
"target": [
"nav"
]
}
]
},
{
"id": "aria-valid-attr",
"impact": null,
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure attributes that begin with aria- are valid ARIA attributes",
"help": "ARIA attributes must conform to valid names",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-valid-attr?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "aria-valid-attr",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "ARIA attribute name is valid"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<nav class=\"primary\" aria-label=\"Primary\">",
"target": [
"nav"
]
}
]
},
{
"id": "avoid-inline-spacing",
"impact": null,
"tags": [
"cat.structure",
"wcag21aa",
"wcag1412",
"EN-301-549",
"EN-9.1.4.12",
"ACT"
],
"description": "Ensure that text spacing set through style attributes can be adjusted with custom stylesheets",
"help": "Inline text spacing must be adjustable with custom stylesheets",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/avoid-inline-spacing?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "important-letter-spacing",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Letter-spacing in the style attribute is not set to !important, or meets the minimum"
},
{
"id": "important-word-spacing",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "word-spacing in the style attribute is not set to !important, or meets the minimum"
},
{
"id": "important-line-height",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "line-height in the style attribute is not set to !important, or meets the minimum"
}
],
"none": [],
"impact": null,
"html": "<div class=\"cta-row\" style=\"margin-top:1rem;\">\n <a class=\"btn copper\" href=\"#reservations\">Reserve a Seat</a>\n <a class=\"btn ghost-dark\" href=\"#order\">Start Order for class ingredients</a>\n </div>",
"target": [
"#classes > .cta-row"
]
}
]
},
{
"id": "button-name",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure buttons have discernible text",
"help": "Buttons must have discernible text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/button-name?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "button-has-visible-text",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Element has inner text that is visible to screen readers"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<button class=\"btn\" type=\"submit\">Estimate plate</button>",
"target": [
"#calc-form > .cta-row > button"
]
}
]
},
{
"id": "bypass",
"impact": null,
"tags": [
"cat.keyboard",
"wcag2a",
"wcag241",
"section508",
"section508.22.o",
"TTv5",
"TT9.a",
"EN-301-549",
"EN-9.2.4.1"
],
"description": "Ensure each page has at least one mechanism for a user to bypass navigation and jump straight to the content",
"help": "Page must have means to bypass repeated blocks",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/bypass?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "internal-link-present",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Valid skip link found"
},
{
"id": "header-present",
"data": null,
"relatedNodes": [
{
"html": "<h1>Cook with the season. Dine with intention.</h1>",
"target": [
"h1"
]
},
{
"html": "<h2>What the market is asking for this week</h2>",
"target": [
"#seasonal > h2"
]
},
{
"html": "<h3>Green garlic risotto with peas</h3>",
"target": [
".card:nth-child(1) > h3"
]
},
{
"html": "<h3>Lamb shoulder, anchovy, and herbs</h3>",
"target": [
".card:nth-child(2) > h3"
]
},
{
"html": "<h3>Chilled fennel broth, citrus oil</h3>",
"target": [
".card:nth-child(3) > h3"
]
},
{
"html": "<h3>Olive oil cake, roasted strawberries</h3>",
"target": [
".card:nth-child(4) > h3"
]
},
{
"html": "<h2>The small skills that change a whole dinner</h2>",
"target": [
"#technique > h2"
]
},
{
"html": "<h3>From fond to finish</h3>",
"target": [
".split > div > h3"
]
},
{
"html": "<h2>What is actually changing in the dining room</h2>",
"target": [
"#trends > h2"
]
},
{
"html": "<h3>Fermentation, quietly</h3>",
"target": [
".trend:nth-child(1) > h3"
]
},
{
"html": "<h3>The new hospitality test</h3>",
"target": [
".trend:nth-child(2) > h3"
]
},
{
"html": "<h2>Rooms worth crossing town for</h2>",
"target": [
"#reviews > h2"
]
},
{
"html": "<h3>Orchard Station</h3>",
"target": [
".review:nth-child(1) > h3"
]
},
{
"html": "<h3>Brine & Barley</h3>",
"target": [
".review:nth-child(2) > h3"
]
},
{
"html": "<h3>Little Provenance</h3>",
"target": [
".review:nth-child(3) > h3"
]
},
{
"html": "<h2>Stand at the bench with working cooks</h2>",
"target": [
"#classes > h2"
]
},
{
"html": "<h3>Knife & mise</h3>",
"target": [
".class-card:nth-child(1) > h3"
]
},
{
"html": "<h3>Sauces & emulsions</h3>",
"target": [
".class-card:nth-child(2) > h3"
]
},
{
"html": "<h3>Wine with the meal</h3>",
"target": [
".class-card:nth-child(3) > h3"
]
},
{
"html": "<h2>Longer reads for people who cook and people who book</h2>",
"target": [
"#stories > h2"
]
},
{
"html": "<h3>Counter today</h3>",
"target": [
".side-box:nth-child(1) > h3"
]
},
{
"html": "<h3>On the bench</h3>",
"target": [
".side-box:nth-child(2) > h3"
]
},
{
"html": "<h3>Keep these three</h3>",
"target": [
".side-box:nth-child(3) > h3"
]
},
{
"html": "<h2>Start an order for the week\u2019s menu</h2>",
"target": [
".wrap > h2"
]
},
{
"html": "<h2>A practical plate calculator</h2>",
"target": [
"#nutrition > h2"
]
},
{
"html": "<h2>What readers and students say</h2>",
"target": [
".wrap:nth-child(6) > section:nth-child(2) > h2"
]
},
{
"html": "<h2>Before you book, cook, or subscribe</h2>",
"target": [
"#faq > h2"
]
},
{
"html": "<h2>Request a table, a class seat, or a pantry start</h2>",
"target": [
"#reservations > h2"
]
},
{
"html": "<h2>Privacy</h2>",
"target": [
"#privacy > h2"
]
},
{
"html": "<h2>Terms</h2>",
"target": [
"#terms > h2"
]
},
{
"html": "<h4>Ember & Olive</h4>",
"target": [
"div:nth-child(1) > h4"
]
},
{
"html": "<h4>Explore</h4>",
"target": [
"div:nth-child(2) > h4"
]
},
{
"html": "<h4>House</h4>",
"target": [
"div:nth-child(3) > h4"
]
},
{
"html": "<h4>Social</h4>",
"target": [
"div:nth-child(4) > h4"
]
}
],
"impact": "serious",
"message": "Page has a heading"
},
{
"id": "landmark",
"data": null,
"relatedNodes": [
{
"html": "<main>",
"target": [
"main"
]
}
],
"impact": "serious",
"message": "Page has a landmark region"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<html lang=\"en\">",
"target": [
"html"
]
}
]
},
{
"id": "color-contrast",
"impact": "serious",
"tags": [
"cat.color",
"wcag2aa",
"wcag143",
"TTv5",
"TT13.c",
"EN-301-549",
"EN-9.1.4.3",
"ACT"
],
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
"help": "Elements must meet minimum color contrast ratio thresholds",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#1b1712",
"bgColor": "#fbf8f3",
"contrastRatio": 16.82,
"fontSize": "16.2pt (21.6px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "3:1",
"shadowColor": null
},
"relatedNodes": [],
"impact": "serious",
"message": "Element has sufficient color contrast of 16.82"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<strong>Ember & Olive</strong>",
"target": [
".brand > div > strong"
]
}
]
},
{
"id": "document-title",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag242",
"TTv5",
"TT12.a",
"EN-301-549",
"EN-9.2.4.2",
"ACT"
],
"description": "Ensure each HTML document contains a non-empty <title> element",
"help": "Documents must have <title> element to aid in navigation",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/document-title?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "doc-has-title",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Document has a non-empty <title> element"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<html lang=\"en\">",
"target": [
"html"
]
}
]
},
{
"id": "duplicate-id-aria",
"impact": null,
"tags": [
"cat.parsing",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure every id attribute value used in ARIA and in labels is unique",
"help": "IDs used in ARIA and labels must be unique",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/duplicate-id-aria?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "duplicate-id-aria",
"data": "protein",
"relatedNodes": [],
"impact": "critical",
"message": "Document has no elements referenced with ARIA or labels that share the same id attribute"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<input id=\"protein\" type=\"number\" min=\"0\" max=\"800\" value=\"160\" required=\"\">",
"target": [
"#protein"
]
}
]
},
{
"id": "form-field-multiple-labels",
"impact": null,
"tags": [
"cat.forms",
"wcag2a",
"wcag332",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.3.3.2"
],
"description": "Ensure form field does not have multiple label elements",
"help": "Form field must not have multiple label elements",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/form-field-multiple-labels?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "multiple-label",
"data": null,
"relatedNodes": [
{
"html": "<label for=\"protein\">Protein food (grams)</label>",
"target": [
"label[for=\"protein\"]"
]
}
],
"impact": "moderate",
"message": "Form field does not have multiple label elements"
}
],
"impact": null,
"html": "<input id=\"protein\" type=\"number\" min=\"0\" max=\"800\" value=\"160\" required=\"\">",
"target": [
"#protein"
]
}
]
},
{
"id": "html-has-lang",
"impact": null,
"tags": [
"cat.language",
"wcag2a",
"wcag311",
"TTv5",
"TT11.a",
"EN-301-549",
"EN-9.3.1.1",
"ACT"
],
"description": "Ensure every HTML document has a lang attribute",
"help": "<html> element must have a lang attribute",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/html-has-lang?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "has-lang",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "The <html> element has a lang attribute"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<html lang=\"en\">",
"target": [
"html"
]
}
]
},
{
"id": "html-lang-valid",
"impact": null,
"tags": [
"cat.language",
"wcag2a",
"wcag311",
"TTv5",
"TT11.a",
"EN-301-549",
"EN-9.3.1.1",
"ACT"
],
"description": "Ensure the lang attribute of the <html> element has a valid value",
"help": "<html> element must have a valid value for the lang attribute",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/html-lang-valid?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "valid-lang",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Value of lang attribute is included in the list of valid languages"
}
],
"impact": null,
"html": "<html lang=\"en\">",
"target": [
"html"
]
}
]
},
{
"id": "image-alt",
"impact": null,
"tags": [
"cat.text-alternatives",
"wcag2a",
"wcag111",
"section508",
"section508.22.a",
"TTv5",
"TT7.a",
"TT7.b",
"EN-301-549",
"EN-9.1.1.1",
"ACT"
],
"description": "Ensure <img> elements have alternative text or a role of none or presentation",
"help": "Images must have alternative text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/image-alt?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "has-alt",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Element has an alt attribute"
}
],
"all": [],
"none": [
{
"id": "alt-space-value",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Element has a valid alt attribute value"
}
],
"impact": null,
"html": "<img src=\"https://placehold.co/96x96/2e3b2c/f4efe6?text=E%26O&font=playfair+display\" alt=\"Ember and Olive monogram logo\">",
"target": [
"img[alt=\"Ember and Olive monogram logo\"]"
]
}
]
},
{
"id": "label",
"impact": null,
"tags": [
"cat.forms",
"wcag2a",
"wcag412",
"section508",
"section508.22.n",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure every form element has a label",
"help": "Form elements must have labels",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/label?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "explicit-label",
"data": {
"explicitLabel": "Protein food (grams)"
},
"relatedNodes": [
{
"html": "<label for=\"protein\">Protein food (grams)</label>",
"target": [
"label[for=\"protein\"]"
]
}
],
"impact": "critical",
"message": "Element has an explicit <label>"
}
],
"all": [],
"none": [
{
"id": "hidden-explicit-label",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Form element has a visible explicit <label>"
}
],
"impact": null,
"html": "<input id=\"protein\" type=\"number\" min=\"0\" max=\"800\" value=\"160\" required=\"\">",
"target": [
"#protein"
]
}
]
},
{
"id": "link-name",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag244",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.2.4.4",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure links have discernible text",
"help": "Links must have discernible text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/link-name?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "has-visible-text",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Element has text that is visible to screen readers"
}
],
"all": [],
"none": [
{
"id": "focusable-no-name",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Element is not in tab order or has accessible text"
}
],
"impact": null,
"html": "<a class=\"brand\" href=\"#top\">",
"target": [
".brand"
]
}
]
},
{
"id": "list",
"impact": null,
"tags": [
"cat.structure",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure that lists are structured correctly",
"help": "<ul> and <ol> must only directly contain <li>, <script> or <template> elements",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/list?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "only-listitems",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "List element only has direct children that are allowed inside <li> elements"
}
],
"impact": null,
"html": "<ul>",
"target": [
"div:nth-child(2) > ul"
]
}
]
},
{
"id": "listitem",
"impact": null,
"tags": [
"cat.structure",
"wcag2a",
"wcag131",
"EN-301-549",
"EN-9.1.3.1"
],
"description": "Ensure <li> elements are used semantically",
"help": "<li> elements must be contained in a <ul> or <ol>",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/listitem?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "listitem",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "List item has a <ul>, <ol> or role=\"list\" parent element"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<li><a href=\"#seasonal\">Seasonal Menus</a></li>",
"target": [
"div:nth-child(2) > ul > li:nth-child(1)"
]
}
]
},
{
"id": "meta-viewport",
"impact": null,
"tags": [
"cat.sensory-and-visual-cues",
"wcag2aa",
"wcag144",
"EN-301-549",
"EN-9.1.4.4",
"ACT"
],
"description": "Ensure <meta name=\"viewport\"> does not disable text scaling and zooming",
"help": "Zooming and scaling must not be disabled",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/meta-viewport?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "meta-viewport",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "<meta> tag does not disable zooming on mobile devices"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">",
"target": [
"meta[name=\"viewport\"]"
]
}
]
},
{
"id": "nested-interactive",
"impact": null,
"tags": [
"cat.keyboard",
"wcag2a",
"wcag412",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure interactive controls are not nested as they are not always announced by screen readers or can cause focus problems for assistive technologies",
"help": "Interactive controls must not be nested",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/nested-interactive?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "no-focusable-content",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Element does not have focusable descendants"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<img src=\"https://placehold.co/96x96/2e3b2c/f4efe6?text=E%26O&font=playfair+display\" alt=\"Ember and Olive monogram logo\">",
"target": [
"img[alt=\"Ember and Olive monogram logo\"]"
]
}
]
},
{
"id": "select-name",
"impact": null,
"tags": [
"cat.forms",
"wcag2a",
"wcag412",
"section508",
"section508.22.n",
"TTv5",
"TT5.c",
"EN-301-549",
"EN-9.4.1.2",
"ACT"
],
"description": "Ensure select element has an accessible name",
"help": "Select element must have an accessible name",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/select-name?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "explicit-label",
"data": {
"explicitLabel": "Plate style"
},
"relatedNodes": [
{
"html": "<label for=\"style\">Plate style</label>",
"target": [
"label[for=\"style\"]"
]
}
],
"impact": "critical",
"message": "Element has an explicit <label>"
}
],
"all": [],
"none": [
{
"id": "hidden-explicit-label",
"data": null,
"relatedNodes": [],
"impact": "critical",
"message": "Form element has a visible explicit <label>"
}
],
"impact": null,
"html": "<select id=\"style\">\n <option value=\"fish\">Fish or seafood</option>\n <option value=\"poultry\">Poultry</option>\n <option value=\"legume\">Legumes and vegetables</option>\n <option value=\"red\">Red meat, modest portion</option>\n </select>",
"target": [
"#style"
]
}
]
},
{
"id": "summary-name",
"impact": null,
"tags": [
"cat.name-role-value",
"wcag2a",
"wcag412",
"section508",
"section508.22.a",
"TTv5",
"TT6.a",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure summary elements have discernible text",
"help": "Summary elements must have discernible text",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/summary-name?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "has-visible-text",
"data": null,
"relatedNodes": [],
"impact": "serious",
"message": "Element has text that is visible to screen readers"
}
],
"all": [],
"none": [],
"impact": null,
"html": "<summary>Do the recipes assume professional equipment?</summary>",
"target": [
"details[open=\"\"] > summary"
]
}
]
},
{
"id": "target-size",
"impact": null,
"tags": [
"cat.sensory-and-visual-cues",
"wcag22aa",
"wcag258"
],
"description": "Ensure touch targets have sufficient size and space",
"help": "All touch targets must be 24px large, or leave sufficient space",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/target-size?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "target-size",
"data": {
"minSize": 24,
"width": 344.8,
"height": 69.8
},
"relatedNodes": [],
"impact": "serious",
"message": "Control has sufficient size (344.8px by 69.8px, should be at least 24px by 24px)"
},
{
"id": "target-offset",
"data": {
"closestOffset": 24,
"minOffset": 24
},
"relatedNodes": [],
"impact": "serious",
"message": "Target has sufficient space from its closest neighbors. Safe clickable space has a diameter of 24px which is at least 24px."
}
],
"all": [],
"none": [],
"impact": null,
"html": "<a class=\"brand\" href=\"#top\">",
"target": [
".brand"
]
}
]
}
],
"incomplete": [
{
"id": "aria-prohibited-attr",
"impact": "serious",
"tags": [
"cat.aria",
"wcag2a",
"wcag412",
"EN-301-549",
"EN-9.4.1.2"
],
"description": "Ensure ARIA attributes are not prohibited for an element's role",
"help": "Elements must only use permitted ARIA attributes",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/aria-prohibited-attr?application=axeAPI",
"nodes": [
{
"any": [],
"all": [],
"none": [
{
"id": "aria-prohibited-attr",
"data": {
"role": null,
"nodeName": "p",
"messageKey": "noRoleSingular",
"prohibited": [
"aria-label"
]
},
"relatedNodes": [],
"impact": "serious",
"message": "aria-label attribute is not well supported on a p with no valid role attribute."
}
],
"impact": "serious",
"html": "<p class=\"stars\" aria-label=\"4.5 out of 5\">\u2605\u2605\u2605\u2605\u2605</p>",
"target": [
".review:nth-child(1) > .stars[aria-label=\"4.5 out of 5\"]"
],
"failureSummary": "Fix all of the following:\n aria-label attribute is not well supported on a p with no valid role attribute."
}
]
},
{
"id": "color-contrast",
"impact": "serious",
"tags": [
"cat.color",
"wcag2aa",
"wcag143",
"TTv5",
"TT13.c",
"EN-301-549",
"EN-9.1.4.3",
"ACT"
],
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
"help": "Elements must meet minimum color contrast ratio thresholds",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "color-contrast",
"data": {
"fontSize": "13.4pt (17.92px)",
"fontWeight": "bold",
"messageKey": "pseudoContent",
"expectedContrastRatio": "4.5:1"
},
"relatedNodes": [
{
"html": "<section class=\"hero\" id=\"top\">",
"target": [
"#top"
]
}
],
"impact": "serious",
"message": "Element's background color could not be determined due to a pseudo element"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">Food & drink desk \u00b7 Portland & beyond</p>",
"target": [
".hero-inner > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element's background color could not be determined due to a pseudo element"
}
]
}
],
"violations": [
{
"id": "color-contrast",
"impact": "serious",
"tags": [
"cat.color",
"wcag2aa",
"wcag143",
"TTv5",
"TT13.c",
"EN-301-549",
"EN-9.1.4.3",
"ACT"
],
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
"help": "Elements must meet minimum color contrast ratio thresholds",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=axeAPI",
"nodes": [
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#b56a3c",
"bgColor": "#fbf8f3",
"contrastRatio": 3.89,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<body>",
"target": [
"body"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">Seasonal menus</p>",
"target": [
"#seasonal > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#ffffff",
"bgColor": "#b56a3c",
"contrastRatio": 4.12,
"fontSize": "11.4pt (15.2px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<a class=\"btn copper\" href=\"#order\">Order Now</a>",
"target": [
".copper.btn[href$=\"#order\"]"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.12 (foreground color: #ffffff, background color: #b56a3c, font size: 11.4pt (15.2px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<a class=\"btn copper\" href=\"#order\">Order Now</a>",
"target": [
".copper.btn[href$=\"#order\"]"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.12 (foreground color: #ffffff, background color: #b56a3c, font size: 11.4pt (15.2px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#b56a3c",
"bgColor": "#fbf8f3",
"contrastRatio": 3.89,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<body>",
"target": [
"body"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">Technique tutorials</p>",
"target": [
"#technique > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#b56a3c",
"bgColor": "#fbf8f3",
"contrastRatio": 3.89,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<body>",
"target": [
"body"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">Culinary trends</p>",
"target": [
"#trends > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#b56a3c",
"bgColor": "#fbf8f3",
"contrastRatio": 3.89,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<body>",
"target": [
"body"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">Restaurant reviews</p>",
"target": [
"#reviews > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#b56a3c",
"bgColor": "#fbf8f3",
"contrastRatio": 3.89,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<body>",
"target": [
"body"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">Cooking classes</p>",
"target": [
"#classes > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#ffffff",
"bgColor": "#b56a3c",
"contrastRatio": 4.12,
"fontSize": "11.4pt (15.2px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<a class=\"btn copper\" href=\"#reservations\">Reserve a Seat</a>",
"target": [
"#classes > .cta-row > .copper.btn[href$=\"#reservations\"]"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.12 (foreground color: #ffffff, background color: #b56a3c, font size: 11.4pt (15.2px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<a class=\"btn copper\" href=\"#reservations\">Reserve a Seat</a>",
"target": [
"#classes > .cta-row > .copper.btn[href$=\"#reservations\"]"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.12 (foreground color: #ffffff, background color: #b56a3c, font size: 11.4pt (15.2px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#b56a3c",
"bgColor": "#fbf8f3",
"contrastRatio": 3.89,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<body>",
"target": [
"body"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">From the journal</p>",
"target": [
"#stories > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#b56a3c",
"bgColor": "#fffdf9",
"contrastRatio": 4.05,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<div class=\"side-box\">",
"target": [
".side-box:nth-child(1)"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.05 (foreground color: #b56a3c, background color: #fffdf9, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">Daily specials</p>",
"target": [
".side-box:nth-child(1) > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.05 (foreground color: #b56a3c, background color: #fffdf9, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#b56a3c",
"bgColor": "#fffdf9",
"contrastRatio": 4.05,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<div class=\"side-box\">",
"target": [
".side-box:nth-child(2)"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.05 (foreground color: #b56a3c, background color: #fffdf9, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">Featured chefs</p>",
"target": [
".side-box:nth-child(2) > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.05 (foreground color: #b56a3c, background color: #fffdf9, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#b56a3c",
"bgColor": "#fffdf9",
"contrastRatio": 4.05,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<div class=\"side-box\">",
"target": [
".side-box:nth-child(3)"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.05 (foreground color: #b56a3c, background color: #fffdf9, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">Pantry note</p>",
"target": [
".side-box:nth-child(3) > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.05 (foreground color: #b56a3c, background color: #fffdf9, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#ffffff",
"bgColor": "#b56a3c",
"contrastRatio": 4.12,
"fontSize": "11.4pt (15.2px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<a class=\"btn copper\" href=\"#reservations\">Start Order</a>",
"target": [
".wrap > .cta-row > .copper.btn[href$=\"#reservations\"]"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.12 (foreground color: #ffffff, background color: #b56a3c, font size: 11.4pt (15.2px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<a class=\"btn copper\" href=\"#reservations\">Start Order</a>",
"target": [
".wrap > .cta-row > .copper.btn[href$=\"#reservations\"]"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.12 (foreground color: #ffffff, background color: #b56a3c, font size: 11.4pt (15.2px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#b56a3c",
"bgColor": "#fbf8f3",
"contrastRatio": 3.89,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<body>",
"target": [
"body"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">Nutrition resources</p>",
"target": [
"#nutrition > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#b56a3c",
"bgColor": "#fbf8f3",
"contrastRatio": 3.89,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<body>",
"target": [
"body"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">From the table</p>",
"target": [
".wrap:nth-child(6) > section:nth-child(2) > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#b56a3c",
"bgColor": "#fbf8f3",
"contrastRatio": 3.89,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<body>",
"target": [
"body"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">Questions</p>",
"target": [
"#faq > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#b56a3c",
"bgColor": "#fbf8f3",
"contrastRatio": 3.89,
"fontSize": "9.0pt (12px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<body>",
"target": [
"body"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<p class=\"eyebrow\">Reservations</p>",
"target": [
"#reservations > .eyebrow"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 3.89 (foreground color: #b56a3c, background color: #fbf8f3, font size: 9.0pt (12px), font weight: bold). Expected contrast ratio of 4.5:1"
},
{
"any": [
{
"id": "color-contrast",
"data": {
"fgColor": "#ffffff",
"bgColor": "#b56a3c",
"contrastRatio": 4.12,
"fontSize": "11.4pt (15.2px)",
"fontWeight": "bold",
"messageKey": null,
"expectedContrastRatio": "4.5:1",
"shadowColor": null
},
"relatedNodes": [
{
"html": "<button class=\"btn copper\" type=\"submit\">Reserve a Table</button>",
"target": [
"#reserve-form > .cta-row > button"
]
}
],
"impact": "serious",
"message": "Element has insufficient color contrast of 4.12 (foreground color: #ffffff, background color: #b56a3c, font size: 11.4pt (15.2px), font weight: bold). Expected contrast ratio of 4.5:1"
}
],
"all": [],
"none": [],
"impact": "serious",
"html": "<button class=\"btn copper\" type=\"submit\">Reserve a Table</button>",
"target": [
"#reserve-form > .cta-row > button"
],
"failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 4.12 (foreground color: #ffffff, background color: #b56a3c, font size: 11.4pt (15.2px), font weight: bold). Expected contrast ratio of 4.5:1"
}
]
}
],
"coverage": {
"contract": "main-document-vertical-scroll",
"complete": true,
"positions": [
{
"y": 0,
"height": 10087
},
{
"y": 576,
"height": 10087
},
{
"y": 1152,
"height": 10087
},
{
"y": 1728,
"height": 10087
},
{
"y": 2304,
"height": 10087
},
{
"y": 2880,
"height": 10087
},
{
"y": 3456,
"height": 10087
},
{
"y": 4032,
"height": 10087
},
{
"y": 4608,
"height": 10087
},
{
"y": 5184,
"height": 10087
},
{
"y": 5760,
"height": 10087
},
{
"y": 6336,
"height": 10087
},
{
"y": 6912,
"height": 10087
},
{
"y": 7488,
"height": 10087
},
{
"y": 8064,
"height": 10087
},
{
"y": 8640,
"height": 10087
},
{
"y": 9216,
"height": 10087
},
{
"y": 9367,
"height": 10087
}
],
"scans": 19,
"max_states": 512,
"settle_ms": 5000,
"page_timeout_seconds": 150,
"layout_stability": "consecutive 100ms size samples within one CSS pixel",
"animation_settling": "finite animations present when scroll resources are ready finish or are cancelled",
"interactive_states": "not exercised",
"horizontal_scroll": "not exercised"
}
}
System Prompt
You are a lead web developer at a top digital agency, tasked with creating a one-page website for a new client based on the given specifications, delivered as an HTML file. First non-whitespace char '<', last non-whitespace char '>'. Use the following services to generate placeholder images where needed:
- placehold.co (text): https://placehold.co/[{w}x{h}|{size}][/{bg-color}/{text-color}]?text={text}&font=[lato|lora|montserrat|noto sans|open sans|oswald|playfair display|poppins|pt sans|raleway|roboto|source sans|source sans pro]
- picsum.photos (photos): https://picsum.photos/[{w}/{h}|{size}]?[grayscale][&blur={1-10}]
- pravatar.cc (avatars): https://i.pravatar.cc/{size}?u={identifier}
Choose sizes appropriate to layout.
User Prompt
Create a **complete, polished, production-quality** primary web page for a new client in the "Food and Drink" sector.
Your goal is to generate the full HTML code for a page that is not just functional but also visually compelling, content-rich, and feels like a finished product ready for launch.
**Client & Category:**
- Industry: "Food and Drink"
- Description: Recipes, restaurant guides, cooking tips, and nutrition resources.
**Your Creative Task:**
1. **Invent:** Create a unique, professional-sounding site name and a strong tagline fitting the "Food and Drink" category.
2. **Define Page:** Determine the most effective primary page type (e.g., homepage, service landing page, category portal) to showcase this fictional entity.
3. **Design:** Develop an opinionated, modern, and professional layout. Make distinct choices about structure and flow.
**Content & Structure Requirements (Deliver a COMPLETE page):**
- **Overall:** The final page must feel substantial and complete, with realistic amounts of text (multiple paragraphs per section where appropriate, avoid single sentences), well-integrated placeholder images, and logical flow. It should look like a real website a business would proudly use.
- **HEADER:** Include the invented site name, tagline, a logo placeholder image, and a primary navigation bar. Ensure the navigation has **at least 5-7 clearly defined, relevant links** including: "Reservations", "Restaurant Reviews", "Cooking Classes".
- **MAIN CONTENT:** Structure this area with **at least 3-4 distinct, well-developed sections**.
- Address key topics relevant to the "Food and Drink" category. Consider themes similar to: "Seasonal Menus", "Technique Tutorials", "Culinary Trends".
- **Content Depth:** Populate each section with **substantial, realistic text** (multiple sentences/paragraphs). Use authentic industry language and terminology like: "umami", "gastronomy", "sommelier".
- **Visuals:** Integrate relevant placeholder images logically within the content sections.
- **Calls to Action:** Include clear and contextually relevant CTAs. Use strong verbs similar to: "View Menu", "Start Order", "Order Now".
- **ENGAGEMENT (Recommended):** Strongly consider incorporating **one meaningful interactive element** that would genuinely benefit a user in the "Food and Drink" sector. Ideas similar but not limited to: "nutrition calculator".
- **SIDEBAR (Optional):** If your design includes a sidebar, populate it with **useful, relevant content**. Ideas: "featured chefs", "daily specials", "chef interviews".
- **FOOTER:** Include a professional footer with invented contact details, copyright (current year), social media links, and standard links (Privacy, Terms).
- **MODERN WEB PATTERNS:** Include modern web patterns like testimonial cards, feature grids, or FAQ accordions where appropriate.