MoonshotAI Kimi K3.1 Pro – Food and Drink

via Moonshot AI · Generated

  • AIMAC Debt 5.27
  • Cost $0.54
  • Total Violations 31
  • HTML Size 145 KB
  • Em Dashes 14

Screenshot

View MoonshotAI Kimi K3.1 Pro Food and Drink page View Live Page

Accessibility Issues Found

31 Serious

  • color-contrast serious 31 instances

    Elements must meet minimum color contrast ratio thresholds

    Example HTML <em>what’s in season.</em>

Artifacts

View Generated HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="Savor & Sage brings together rigorously tested seasonal recipes, independent restaurant reviews, practical meal plans, and kitchen wisdom for curious cooks.">
  <meta name="theme-color" content="#173f35">
  <title>Savor &amp; Sage — Seasonal Recipes, Restaurant Guides &amp; Kitchen Wisdom</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=DM+Sans:wght@400;500;600;700&amp;family=Fraunces:opsz,wght@9..144,500;9..144,600;9..144,700&amp;display=swap" rel="stylesheet">

  <script>document.documentElement.classList.add('js');</script>

  <style>
    :root {
      --forest: #173f35;
      --forest-deep: #102e27;
      --forest-soft: #28594a;
      --ink: #20312b;
      --muted: #66736c;
      --cream: #f8f5ed;
      --paper: #fffdf8;
      --sage: #e3eadf;
      --sage-deep: #cbd9c5;
      --terracotta: #e6784b;
      --terracotta-soft: #f3ded0;
      --gold: #d8ad5f;
      --line: #dcded4;
      --white: #ffffff;
      --shadow-sm: 0 8px 28px rgba(23, 63, 53, 0.08);
      --shadow-lg: 0 24px 70px rgba(23, 63, 53, 0.16);
      --radius-sm: 12px;
      --radius-md: 20px;
      --radius-lg: 30px;
      --font-body: "DM Sans", sans-serif;
      --font-display: "Fraunces", Georgia, serif;
      --container: 1200px;
    }

    *,
    *::before,
    *::after {
      box-sizing: border-box;
    }

    html {
      scroll-behavior: smooth;
      scroll-padding-top: 110px;
    }

    body {
      margin: 0;
      overflow-x: hidden;
      background: var(--cream);
      color: var(--ink);
      font-family: var(--font-body);
      font-size: 16px;
      line-height: 1.7;
      -webkit-font-smoothing: antialiased;
    }

    body.modal-open {
      overflow: hidden;
    }

    img {
      display: block;
      width: 100%;
      max-width: 100%;
    }

    a {
      color: inherit;
      text-decoration: none;
    }

    button,
    input,
    select,
    textarea {
      color: inherit;
      font: inherit;
    }

    button {
      cursor: pointer;
    }

    button,
    input,
    select {
      border-radius: 0;
    }

    h1,
    h2,
    h3,
    h4,
    p {
      margin-top: 0;
    }

    h1,
    h2,
    h3,
    h4 {
      color: var(--forest);
      font-family: var(--font-display);
      font-weight: 600;
      line-height: 1.08;
      letter-spacing: -0.035em;
    }

    h2 {
      margin-bottom: 22px;
      font-size: clamp(2.35rem, 4vw, 4rem);
    }

    h3 {
      font-size: 1.55rem;
    }

    p:last-child {
      margin-bottom: 0;
    }

    [hidden] {
      display: none !important;
    }

    ::selection {
      background: var(--terracotta-soft);
      color: var(--forest-deep);
    }

    :focus-visible {
      outline: 3px solid var(--terracotta);
      outline-offset: 4px;
    }

    .container {
      width: min(var(--container), calc(100% - 48px));
      margin-inline: auto;
    }

    .section {
      padding: 108px 0;
    }

    .section-paper {
      background: var(--paper);
    }

    .visually-hidden {
      position: absolute !important;
      width: 1px !important;
      height: 1px !important;
      padding: 0 !important;
      margin: -1px !important;
      overflow: hidden !important;
      clip: rect(0, 0, 0, 0) !important;
      white-space: nowrap !important;
      border: 0 !important;
    }

    .skip-link {
      position: fixed;
      z-index: 9999;
      top: 12px;
      left: 12px;
      padding: 12px 18px;
      transform: translateY(-160%);
      border-radius: 8px;
      background: var(--paper);
      color: var(--forest);
      font-weight: 700;
      transition: transform 180ms ease;
    }

    .skip-link:focus {
      transform: translateY(0);
    }

    .eyebrow {
      display: inline-flex;
      align-items: center;
      gap: 10px;
      margin-bottom: 20px;
      color: var(--forest-soft);
      font-size: 0.73rem;
      font-weight: 700;
      letter-spacing: 0.16em;
      line-height: 1.4;
      text-transform: uppercase;
    }

    .eyebrow::before {
      width: 28px;
      height: 1px;
      background: currentColor;
      content: "";
    }

    .eyebrow.no-line::before {
      display: none;
    }

    .button {
      display: inline-flex;
      min-height: 50px;
      align-items: center;
      justify-content: center;
      gap: 10px;
      padding: 13px 22px;
      border: 1px solid transparent;
      border-radius: 999px;
      font-size: 0.9rem;
      font-weight: 700;
      line-height: 1.2;
      text-align: center;
      transition: transform 180ms ease, background 180ms ease, border-color 180ms ease, color 180ms ease, box-shadow 180ms ease;
    }

    .button:hover {
      transform: translateY(-2px);
    }

    .button-primary {
      background: var(--terracotta);
      color: var(--forest-deep);
      box-shadow: 0 8px 22px rgba(184, 87, 45, 0.17);
    }

    .button-primary:hover {
      background: #ef875a;
      box-shadow: 0 12px 28px rgba(184, 87, 45, 0.24);
    }

    .button-dark {
      background: var(--forest);
      color: var(--white);
    }

    .button-dark:hover {
      background: var(--forest-soft);
    }

    .button-light {
      background: var(--cream);
      color: var(--forest);
    }

    .button-light:hover {
      background: var(--white);
    }

    .button-outline {
      border-color: #b8c1b9;
      background: transparent;
      color: var(--forest);
    }

    .button-outline:hover {
      border-color: var(--forest);
      background: rgba(23, 63, 53, 0.04);
    }

    .button-outline-light {
      border-color: rgba(255, 255, 255, 0.36);
      background: transparent;
      color: var(--cream);
    }

    .button-outline-light:hover {
      border-color: var(--cream);
      background: rgba(255, 255, 255, 0.07);
    }

    .text-link {
      display: inline-flex;
      align-items: center;
      gap: 9px;
      padding: 0;
      border: 0;
      border-bottom: 1px solid #9eaaa2;
      background: none;
      color: var(--forest);
      font-size: 0.88rem;
      font-weight: 700;
      line-height: 1.9;
      transition: gap 180ms ease, border-color 180ms ease;
    }

    .text-link:hover {
      gap: 14px;
      border-color: var(--terracotta);
    }

    .announcement {
      position: relative;
      z-index: 60;
      background: var(--forest-deep);
      color: #e9eee7;
      font-size: 0.77rem;
    }

    .announcement .container {
      display: flex;
      min-height: 38px;
      align-items: center;
      justify-content: space-between;
      gap: 24px;
    }

    .announcement p {
      margin: 0;
    }

    .announcement a {
      color: #f4bb91;
      font-weight: 700;
      white-space: nowrap;
    }

    .site-header {
      position: sticky;
      z-index: 50;
      top: 0;
      border-bottom: 1px solid transparent;
      background: rgba(248, 245, 237, 0.94);
      backdrop-filter: blur(16px);
      transition: border-color 180ms ease, box-shadow 180ms ease;
    }

    .site-header.scrolled {
      border-color: rgba(23, 63, 53, 0.1);
      box-shadow: 0 8px 28px rgba(23, 63, 53, 0.06);
    }

    .header-inner {
      position: relative;
      display: flex;
      min-height: 84px;
      align-items: center;
      justify-content: space-between;
      gap: 24px;
    }

    .brand {
      display: inline-flex;
      flex: 0 0 auto;
      align-items: center;
      gap: 11px;
    }

    .brand-mark {
      width: 46px;
      height: 46px;
      flex: 0 0 auto;
      border-radius: 50%;
      box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.15);
    }

    .brand-copy {
      display: flex;
      flex-direction: column;
      line-height: 1;
    }

    .brand-name {
      color: var(--forest);
      font-family: var(--font-display);
      font-size: 1.38rem;
      font-weight: 700;
      letter-spacing: -0.04em;
    }

    .brand-tagline {
      margin-top: 7px;
      color: var(--muted);
      font-size: 0.59rem;
      font-weight: 700;
      letter-spacing: 0.08em;
      text-transform: uppercase;
    }

    .primary-nav {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 21px;
    }

    .nav-link {
      position: relative;
      padding: 9px 0;
      color: #40554b;
      font-size: 0.78rem;
      font-weight: 600;
      white-space: nowrap;
    }

    .nav-link::after {
      position: absolute;
      right: 0;
      bottom: 2px;
      left: 0;
      height: 2px;
      transform: scaleX(0);
      transform-origin: right;
      background: var(--terracotta);
      content: "";
      transition: transform 180ms ease;
    }

    .nav-link:hover::after,
    .nav-link.active::after {
      transform: scaleX(1);
      transform-origin: left;
    }

    .nav-link.active {
      color: var(--forest);
    }

    .header-actions {
      display: flex;
      flex: 0 0 auto;
      align-items: center;
      gap: 12px;
    }

    .header-cta {
      min-height: 43px;
      padding: 11px 18px;
      font-size: 0.78rem;
    }

    .menu-toggle {
      display: none;
      width: 44px;
      height: 44px;
      padding: 11px;
      border: 1px solid var(--line);
      border-radius: 50%;
      background: transparent;
    }

    .menu-toggle span {
      display: block;
      width: 100%;
      height: 2px;
      margin: 4px 0;
      background: var(--forest);
      transition: transform 180ms ease, opacity 180ms ease;
    }

    .menu-toggle[aria-expanded="true"] span:nth-child(1) {
      transform: translateY(6px) rotate(45deg);
    }

    .menu-toggle[aria-expanded="true"] span:nth-child(2) {
      opacity: 0;
    }

    .menu-toggle[aria-expanded="true"] span:nth-child(3) {
      transform: translateY(-6px) rotate(-45deg);
    }

    .hero {
      position: relative;
      padding: 66px 0 76px;
    }

    .hero::before {
      position: absolute;
      z-index: -1;
      top: 10%;
      left: -180px;
      width: 420px;
      height: 420px;
      border: 1px solid rgba(23, 63, 53, 0.08);
      border-radius: 50%;
      content: "";
    }

    .hero-grid {
      display: grid;
      align-items: center;
      grid-template-columns: minmax(0, 1.04fr) minmax(380px, 0.86fr);
      gap: clamp(50px, 7vw, 100px);
    }

    .hero h1 {
      max-width: 690px;
      margin-bottom: 28px;
      font-size: clamp(3.5rem, 6.4vw, 6.15rem);
      line-height: 0.96;
    }

    .hero h1 em {
      color: var(--terracotta);
      font-weight: 500;
    }

    .hero-intro {
      max-width: 610px;
      margin-bottom: 30px;
      color: #52645a;
      font-size: 1.06rem;
      line-height: 1.8;
    }

    .hero-actions {
      display: flex;
      flex-wrap: wrap;
      gap: 12px;
      margin-bottom: 36px;
    }

    .hero-proof {
      display: flex;
      align-items: center;
      gap: 16px;
    }

    .avatar-stack {
      display: flex;
      padding-left: 8px;
    }

    .avatar-stack img {
      width: 39px;
      height: 39px;
      margin-left: -8px;
      border: 3px solid var(--cream);
      border-radius: 50%;
      object-fit: cover;
    }

    .proof-copy {
      color: var(--muted);
      font-size: 0.77rem;
      line-height: 1.5;
    }

    .proof-copy strong {
      display: block;
      color: var(--forest);
      font-size: 0.84rem;
    }

    .hero-visual {
      position: relative;
      max-width: 520px;
      margin-left: auto;
      padding: 0 14px 20px 0;
    }

    .hero-arch {
      position: relative;
      overflow: hidden;
      aspect-ratio: 0.82;
      border-radius: 250px 250px 26px 26px;
      background: var(--sage-deep);
      box-shadow: var(--shadow-lg);
    }

    .hero-arch img {
      height: 100%;
      object-fit: cover;
    }

    .hero-arch::after {
      position: absolute;
      inset: 0;
      background: linear-gradient(to top, rgba(10, 36, 29, 0.25), transparent 45%);
      content: "";
      pointer-events: none;
    }

    .floating-recipe {
      position: absolute;
      z-index: 2;
      right: -26px;
      bottom: 0;
      width: 245px;
      padding: 20px 22px;
      border: 1px solid rgba(23, 63, 53, 0.09);
      border-radius: 17px;
      background: var(--paper);
      box-shadow: var(--shadow-lg);
    }

    .floating-recipe .mini-label {
      display: block;
      margin-bottom: 7px;
      color: var(--terracotta);
      font-size: 0.63rem;
      font-weight: 700;
      letter-spacing: 0.14em;
      text-transform: uppercase;
    }

    .floating-recipe strong {
      display: block;
      margin-bottom: 6px;
      color: var(--forest);
      font-family: var(--font-display);
      font-size: 1.15rem;
      line-height: 1.2;
    }

    .floating-recipe span:last-child {
      color: var(--muted);
      font-size: 0.75rem;
    }

    .issue-stamp {
      position: absolute;
      z-index: 2;
      top: 17%;
      left: -36px;
      display: grid;
      width: 88px;
      height: 88px;
      place-items: center;
      transform: rotate(-10deg);
      border: 1px solid rgba(23, 63, 53, 0.22);
      border-radius: 50%;
      background: var(--cream);
      color: var(--forest);
      font-size: 0.58rem;
      font-weight: 700;
      letter-spacing: 0.1em;
      line-height: 1.5;
      text-align: center;
      text-transform: uppercase;
    }

    .stat-band {
      border-top: 1px solid var(--line);
      border-bottom: 1px solid var(--line);
      background: rgba(255, 253, 248, 0.5);
    }

    .stats-grid {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
    }

    .stat {
      padding: 26px 30px;
      border-right: 1px solid var(--line);
      text-align: center;
    }

    .stat:first-child {
      border-left: 1px solid var(--line);
    }

    .stat strong {
      display: block;
      margin-bottom: 3px;
      color: var(--forest);
      font-family: var(--font-display);
      font-size: 1.75rem;
      line-height: 1.2;
    }

    .stat span {
      color: var(--muted);
      font-size: 0.71rem;
      font-weight: 600;
      letter-spacing: 0.06em;
      text-transform: uppercase;
    }

    .section-heading {
      margin-bottom: 42px;
    }

    .section-heading.split {
      display: grid;
      align-items: end;
      grid-template-columns: minmax(0, 1fr) minmax(300px, 0.7fr);
      gap: 60px;
    }

    .section-heading h2 {
      max-width: 700px;
      margin-bottom: 0;
    }

    .section-intro {
      color: var(--muted);
      font-size: 0.98rem;
      line-height: 1.8;
    }

    .section-intro p {
      margin-bottom: 14px;
    }

    .filter-bar {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 20px;
      margin-bottom: 28px;
    }

    .filters {
      display: flex;
      flex-wrap: wrap;
      gap: 9px;
    }

    .filter-button {
      padding: 9px 16px;
      border: 1px solid var(--line);
      border-radius: 999px;
      background: transparent;
      color: var(--muted);
      font-size: 0.76rem;
      font-weight: 700;
      transition: background 180ms ease, color 180ms ease, border-color 180ms ease;
    }

    .filter-button:hover,
    .filter-button.is-active {
      border-color: var(--forest);
      background: var(--forest);
      color: var(--white);
    }

    .filter-status {
      margin: 0;
      color: var(--muted);
      font-size: 0.75rem;
      white-space: nowrap;
    }

    .recipe-grid {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 28px;
    }

    .recipe-card {
      overflow: hidden;
      border: 1px solid var(--line);
      border-radius: var(--radius-md);
      background: var(--paper);
      transition: transform 220ms ease, box-shadow 220ms ease;
    }

    .recipe-card:hover {
      transform: translateY(-5px);
      box-shadow: var(--shadow-sm);
    }

    .recipe-media {
      position: relative;
      overflow: hidden;
      aspect-ratio: 1.72;
      background: var(--sage);
    }

    .recipe-media img {
      height: 100%;
      object-fit: cover;
      transition: transform 500ms ease;
    }

    .recipe-card:hover .recipe-media img {
      transform: scale(1.035);
    }

    .recipe-badge {
      position: absolute;
      top: 16px;
      left: 16px;
      padding: 7px 11px;
      border-radius: 999px;
      background: rgba(255, 253, 248, 0.94);
      color: var(--forest);
      font-size: 0.65rem;
      font-weight: 700;
      letter-spacing: 0.08em;
      text-transform: uppercase;
    }

    .save-recipe {
      position: absolute;
      top: 14px;
      right: 14px;
      display: grid;
      width: 38px;
      height: 38px;
      place-items: center;
      border: 0;
      border-radius: 50%;
      background: rgba(255, 253, 248, 0.94);
      color: var(--forest);
      transition: transform 180ms ease, background 180ms ease, color 180ms ease;
    }

    .save-recipe:hover {
      transform: scale(1.08);
    }

    .save-recipe[aria-pressed="true"] {
      background: var(--terracotta);
      color: var(--forest-deep);
    }

    .save-recipe svg {
      width: 17px;
      height: 17px;
    }

    .save-recipe[aria-pressed="true"] svg {
      fill: currentColor;
    }

    .recipe-content {
      padding: 25px 27px 26px;
    }

    .recipe-meta {
      display: flex;
      flex-wrap: wrap;
      gap: 8px 18px;
      margin-bottom: 12px;
      color: var(--muted);
      font-size: 0.7rem;
      font-weight: 600;
      letter-spacing: 0.03em;
    }

    .recipe-meta span {
      display: inline-flex;
      align-items: center;
      gap: 7px;
    }

    .recipe-meta span::before {
      width: 4px;
      height: 4px;
      border-radius: 50%;
      background: var(--terracotta);
      content: "";
    }

    .recipe-content h3 {
      margin-bottom: 12px;
      font-size: 1.8rem;
    }

    .recipe-content p {
      min-height: 78px;
      margin-bottom: 20px;
      color: var(--muted);
      font-size: 0.87rem;
      line-height: 1.75;
    }

    .recipe-lab {
      position: relative;
      overflow: hidden;
      background: var(--forest);
      color: #dfe8df;
    }

    .recipe-lab::before {
      position: absolute;
      top: -200px;
      right: -180px;
      width: 520px;
      height: 520px;
      border: 1px solid rgba(255, 255, 255, 0.08);
      border-radius: 50%;
      content: "";
    }

    .recipe-lab .section-heading {
      position: relative;
    }

    .recipe-lab h2,
    .recipe-lab h3 {
      color: var(--cream);
    }

    .recipe-lab .eyebrow {
      color: #f0ae83;
    }

    .recipe-lab .section-intro {
      color: #baccc0;
    }

    .lab-workspace {
      position: relative;
      display: grid;
      overflow: hidden;
      grid-template-columns: minmax(0, 0.88fr) minmax(0, 1.12fr);
      border-radius: var(--radius-lg);
      background: var(--paper);
      box-shadow: 0 30px 80px rgba(3, 20, 15, 0.24);
      color: var(--ink);
    }

    .control-panel {
      padding: 42px;
      background: #e8ede3;
    }

    .control-panel h3,
    .ingredient-panel h3 {
      color: var(--forest);
    }

    .field-label,
    .control-label {
      display: block;
      margin-bottom: 8px;
      color: var(--forest);
      font-size: 0.7rem;
      font-weight: 700;
      letter-spacing: 0.1em;
      text-transform: uppercase;
    }

    .recipe-select {
      width: 100%;
      min-height: 52px;
      padding: 12px 42px 12px 15px;
      border: 1px solid #bdc9bb;
      border-radius: 10px;
      background: var(--paper);
      color: var(--forest);
      font-weight: 700;
    }

    .recipe-description {
      margin: 19px 0;
      color: #596b60;
      font-size: 0.87rem;
      line-height: 1.75;
    }

    .lab-meta {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      margin-bottom: 28px;
    }

    .lab-meta span {
      padding: 6px 10px;
      border: 1px solid #c6d0c2;
      border-radius: 999px;
      color: var(--forest-soft);
      font-size: 0.68rem;
      font-weight: 600;
    }

    .serving-row {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 20px;
      padding: 21px 0;
      border-top: 1px solid #cbd4c7;
      border-bottom: 1px solid #cbd4c7;
    }

    .serving-row .control-label {
      margin-bottom: 3px;
    }

    .serving-row small {
      color: var(--muted);
      font-size: 0.72rem;
    }

    .serving-stepper {
      display: flex;
      flex: 0 0 auto;
      align-items: center;
      overflow: hidden;
      border: 1px solid #b9c5b6;
      border-radius: 999px;
      background: var(--paper);
    }

    .serving-stepper button {
      width: 40px;
      height: 42px;
      border: 0;
      background: transparent;
      color: var(--forest);
      font-size: 1.25rem;
    }

    .serving-stepper button:hover {
      background: var(--sage);
    }

    .serving-stepper output {
      min-width: 82px;
      color: var(--forest);
      font-size: 0.8rem;
      font-weight: 700;
      text-align: center;
    }

    .unit-row {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 20px;
      margin: 22px 0;
    }

    .unit-row .control-label {
      margin: 0;
    }

    .unit-toggle {
      display: flex;
      padding: 3px;
      border-radius: 999px;
      background: #d7dfd2;
    }

    .unit-toggle button {
      padding: 7px 13px;
      border: 0;
      border-radius: 999px;
      background: transparent;
      color: var(--muted);
      font-size: 0.7rem;
      font-weight: 700;
    }

    .unit-toggle button.is-active {
      background: var(--paper);
      box-shadow: 0 2px 8px rgba(23, 63, 53, 0.09);
      color: var(--forest);
    }

    .chef-note {
      margin: 22px 0;
      padding: 17px 18px;
      border-left: 3px solid var(--terracotta);
      background: rgba(255, 253, 248, 0.62);
    }

    .chef-note strong {
      display: block;
      margin-bottom: 5px;
      color: var(--forest);
      font-size: 0.75rem;
    }

    .chef-note p {
      color: var(--muted);
      font-size: 0.76rem;
      line-height: 1.65;
    }

    .method-title {
      margin-bottom: 12px;
      color: var(--forest);
      font-family: var(--font-body);
      font-size: 0.72rem;
      font-weight: 700;
      letter-spacing: 0.1em;
      text-transform: uppercase;
    }

    .method-list {
      margin: 0;
      padding-left: 21px;
      color: var(--muted);
      font-size: 0.76rem;
      line-height: 1.65;
    }

    .method-list li {
      margin-bottom: 9px;
      padding-left: 4px;
    }

    .method-list li::marker {
      color: var(--terracotta);
      font-weight: 700;
    }

    .ingredient-panel {
      padding: 42px 46px;
      background: var(--paper);
    }

    .ingredient-heading {
      display: flex;
      align-items: start;
      justify-content: space-between;
      gap: 20px;
      margin-bottom: 19px;
    }

    .ingredient-heading h3 {
      margin-bottom: 5px;
      font-size: 2rem;
    }

    .ingredient-heading p {
      color: var(--muted);
      font-size: 0.74rem;
    }

    .prep-count {
      padding: 7px 10px;
      border-radius: 999px;
      background: var(--sage);
      color: var(--forest);
      font-size: 0.68rem;
      font-weight: 700;
      white-space: nowrap;
    }

    .progress-track {
      overflow: hidden;
      height: 4px;
      margin-bottom: 18px;
      border-radius: 999px;
      background: #e8e9e1;
    }

    .progress-bar {
      width: 0;
      height: 100%;
      border-radius: inherit;
      background: var(--terracotta);
      transition: width 200ms ease;
    }

    .ingredient-list {
      margin: 0;
      padding: 0;
      list-style: none;
    }

    .ingredient-list li {
      border-bottom: 1px solid #e6e6df;
    }

    .ingredient-list label {
      display: flex;
      align-items: flex-start;
      gap: 12px;
      padding: 14px 0;
      cursor: pointer;
      font-size: 0.82rem;
      line-height: 1.5;
    }

    .ingredient-list input {
      width: 17px;
      height: 17px;
      flex: 0 0 auto;
      margin: 3px 0 0;
      accent-color: var(--forest);
    }

    .ingredient-amount {
      min-width: 80px;
      color: var(--forest);
      font-weight: 700;
    }

    .ingredient-name {
      color: #53645a;
      transition: opacity 180ms ease;
    }

    .ingredient-list input:checked ~ .ingredient-amount,
    .ingredient-list input:checked ~ .ingredient-name {
      opacity: 0.42;
      text-decoration: line-through;
    }

    .lab-actions {
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
      margin-top: 27px;
    }

    .lab-actions .button {
      min-height: 44px;
      padding: 11px 17px;
      font-size: 0.76rem;
    }

    .noscript-note {
      padding: 14px;
      background: var(--terracotta-soft);
      color: var(--forest);
      font-size: 0.8rem;
    }

    .trends-layout {
      display: grid;
      align-items: start;
      grid-template-columns: minmax(0, 0.88fr) minmax(0, 1.12fr);
      gap: clamp(45px, 7vw, 90px);
    }

    .trend-photo {
      position: sticky;
      top: 120px;
    }

    .trend-photo-frame {
      position: relative;
      overflow: hidden;
      aspect-ratio: 0.9;
      border-radius: 180px 180px 18px 18px;
      background: var(--sage);
    }

    .trend-photo-frame img {
      height: 100%;
      object-fit: cover;
    }

    .trend-photo figcaption {
      display: flex;
      justify-content: space-between;
      gap: 20px;
      padding-top: 14px;
      color: var(--muted);
      font-size: 0.69rem;
    }

    .trend-intro {
      margin-bottom: 32px;
      color: var(--muted);
      font-size: 0.96rem;
      line-height: 1.8;
    }

    .trend-intro p {
      margin-bottom: 16px;
    }

    .trend-item {
      display: grid;
      padding: 27px 0;
      border-top: 1px solid var(--line);
      grid-template-columns: 45px 1fr;
      gap: 15px;
    }

    .trend-item:last-of-type {
      border-bottom: 1px solid var(--line);
    }

    .trend-number {
      padding-top: 5px;
      color: var(--terracotta);
      font-family: var(--font-display);
      font-size: 1.1rem;
    }

    .trend-item h3 {
      margin-bottom: 10px;
      font-size: 1.65rem;
    }

    .trend-item p {
      margin-bottom: 0;
      color: var(--muted);
      font-size: 0.86rem;
      line-height: 1.75;
    }

    .trend-link {
      margin-top: 28px;
    }

    .spotlight {
      position: relative;
      background: #efe5d6;
    }

    .spotlight-grid {
      display: grid;
      align-items: center;
      grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
      gap: clamp(48px, 8vw, 100px);
    }

    .spotlight-media {
      position: relative;
      padding: 0 0 30px 30px;
    }

    .spotlight-media::before {
      position: absolute;
      bottom: 0;
      left: 0;
      width: 68%;
      height: 72%;
      border-radius: var(--radius-md);
      background: var(--forest);
      content: "";
    }

    .spotlight-media img {
      position: relative;
      aspect-ratio: 0.93;
      border-radius: var(--radius-md);
      object-fit: cover;
      box-shadow: var(--shadow-lg);
    }

    .season-badge {
      position: absolute;
      right: -22px;
      bottom: 3px;
      width: 160px;
      padding: 17px;
      transform: rotate(3deg);
      border-radius: 12px;
      background: var(--terracotta);
      color: var(--forest-deep);
      box-shadow: var(--shadow-sm);
    }

    .season-badge small {
      display: block;
      font-size: 0.61rem;
      font-weight: 700;
      letter-spacing: 0.12em;
      text-transform: uppercase;
    }

    .season-badge strong {
      font-family: var(--font-display);
      font-size: 1.2rem;
    }

    .spotlight-copy > p {
      color: #5d685f;
      font-size: 0.94rem;
      line-height: 1.85;
    }

    .pairing-label {
      margin: 25px 0 10px;
      color: var(--forest);
      font-size: 0.68rem;
      font-weight: 700;
      letter-spacing: 0.12em;
      text-transform: uppercase;
    }

    .pairing-list {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      margin-bottom: 26px;
    }

    .pairing-list span {
      padding: 7px 12px;
      border: 1px solid #c9bca8;
      border-radius: 999px;
      color: var(--forest-soft);
      font-size: 0.72rem;
      font-weight: 600;
    }

    .prep-steps {
      display: grid;
      margin: 27px 0 30px;
      grid-template-columns: repeat(3, 1fr);
      gap: 12px;
    }

    .prep-step {
      padding-top: 14px;
      border-top: 1px solid #c9bca8;
    }

    .prep-step strong {
      display: block;
      margin-bottom: 5px;
      color: var(--forest);
      font-size: 0.75rem;
    }

    .prep-step span {
      display: block;
      color: var(--muted);
      font-size: 0.69rem;
      line-height: 1.55;
    }

    .spotlight-actions {
      display: flex;
      flex-wrap: wrap;
      gap: 11px;
    }

    .review-standard {
      margin-top: 16px;
    }

    .review-standard summary {
      display: inline-flex;
      align-items: center;
      gap: 7px;
      color: var(--forest);
      cursor: pointer;
      font-size: 0.76rem;
      font-weight: 700;
    }

    .review-standard p {
      max-width: 420px;
      margin-top: 12px;
      color: var(--muted);
      font-size: 0.76rem;
      line-height: 1.65;
    }

    .restaurant-grid {
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 24px;
    }

    .restaurant-card {
      display: flex;
      overflow: hidden;
      flex-direction: column;
      border: 1px solid var(--line);
      border-radius: var(--radius-md);
      background: var(--paper);
    }

    .restaurant-media {
      position: relative;
      overflow: hidden;
      aspect-ratio: 1.35;
      background: var(--sage);
    }

    .restaurant-media img {
      height: 100%;
      object-fit: cover;
      transition: transform 500ms ease;
    }

    .restaurant-card:hover .restaurant-media img {
      transform: scale(1.035);
    }

    .city-tag {
      position: absolute;
      top: 15px;
      left: 15px;
      padding: 6px 10px;
      border-radius: 999px;
      background: rgba(16, 46, 39, 0.9);
      color: var(--white);
      font-size: 0.62rem;
      font-weight: 700;
      letter-spacing: 0.1em;
      text-transform: uppercase;
    }

    .review-score {
      position: absolute;
      right: 15px;
      bottom: -22px;
      display: grid;
      width: 58px;
      height: 58px;
      place-items: center;
      border: 4px solid var(--paper);
      border-radius: 50%;
      background: var(--terracotta);
      color: var(--forest-deep);
      font-family: var(--font-display);
      font-size: 1.05rem;
      font-weight: 700;
    }

    .restaurant-content {
      display: flex;
      flex: 1;
      flex-direction: column;
      padding: 28px 25px 25px;
    }

    .restaurant-content h3 {
      margin-bottom: 6px;
      font-size: 1.8rem;
    }

    .restaurant-meta {
      margin-bottom: 16px;
      color: var(--terracotta);
      font-size: 0.66rem;
      font-weight: 700;
      letter-spacing: 0.08em;
      text-transform: uppercase;
    }

    .restaurant-summary {
      color: var(--muted);
      font-size: 0.84rem;
      line-height: 1.75;
    }

    .order-note {
      margin: 17px 0;
      padding: 12px 14px;
      border-radius: 9px;
      background: var(--sage);
      color: var(--forest-soft);
      font-size: 0.73rem;
      line-height: 1.55;
    }

    .order-note strong {
      color: var(--forest);
    }

    .review-more {
      margin-bottom: 20px;
      border-top: 1px solid var(--line);
      border-bottom: 1px solid var(--line);
    }

    .review-more summary {
      padding: 12px 0;
      color: var(--forest);
      cursor: pointer;
      font-size: 0.75rem;
      font-weight: 700;
    }

    .review-more p {
      padding-bottom: 14px;
      color: var(--muted);
      font-size: 0.76rem;
      line-height: 1.7;
    }

    .restaurant-content .button {
      width: 100%;
      margin-top: auto;
    }

    .meal-plan-section {
      background: var(--sage);
    }

    .plan-grid {
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 22px;
    }

    .plan-card {
      position: relative;
      display: flex;
      min-height: 100%;
      flex-direction: column;
      padding: 31px;
      border: 1px solid #c6d2c1;
      border-radius: var(--radius-md);
      background: rgba(255, 253, 248, 0.68);
    }

    .plan-card.featured {
      border-color: var(--forest);
      background: var(--forest);
      color: #dbe6dc;
    }

    .plan-card.featured h3,
    .plan-card.featured .plan-features strong {
      color: var(--cream);
    }

    .plan-ribbon {
      position: absolute;
      top: 22px;
      right: 22px;
      padding: 5px 9px;
      border-radius: 999px;
      background: var(--terracotta);
      color: var(--forest-deep);
      font-size: 0.58rem;
      font-weight: 700;
      letter-spacing: 0.08em;
      text-transform: uppercase;
    }

    .plan-number {
      display: block;
      margin-bottom: 25px;
      color: var(--terracotta);
      font-family: var(--font-display);
      font-size: 1rem;
    }

    .plan-card h3 {
      max-width: 250px;
      margin-bottom: 14px;
      font-size: 1.9rem;
    }

    .plan-card > p {
      margin-bottom: 20px;
      color: var(--muted);
      font-size: 0.83rem;
      line-height: 1.75;
    }

    .plan-card.featured > p {
      color: #baccc0;
    }

    .plan-features {
      margin: 0 0 25px;
      padding: 0;
      list-style: none;
    }

    .plan-features li {
      padding: 9px 0;
      border-top: 1px solid rgba(102, 115, 108, 0.22);
      color: var(--muted);
      font-size: 0.75rem;
    }

    .plan-card.featured .plan-features li {
      border-color: rgba(255, 255, 255, 0.13);
      color: #c6d5ca;
    }

    .plan-features strong {
      color: var(--forest);
    }

    .plan-card .button {
      width: 100%;
      margin-top: auto;
    }

    .nutrition-note {
      display: grid;
      align-items: start;
      margin-top: 26px;
      padding: 24px 27px;
      border: 1px solid #c6d2c1;
      border-radius: var(--radius-md);
      background: rgba(255, 253, 248, 0.5);
      grid-template-columns: 45px 1fr;
      gap: 18px;
    }

    .nutrition-icon {
      display: grid;
      width: 43px;
      height: 43px;
      place-items: center;
      border-radius: 50%;
      background: var(--forest);
      color: var(--cream);
      font-family: var(--font-display);
      font-size: 1.15rem;
    }

    .nutrition-note h3 {
      margin-bottom: 6px;
      font-family: var(--font-body);
      font-size: 0.85rem;
      letter-spacing: 0;
    }

    .nutrition-note p {
      color: var(--muted);
      font-size: 0.77rem;
      line-height: 1.7;
    }

    .testimonial-grid {
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 24px;
    }

    .quote-card {
      display: flex;
      flex-direction: column;
      padding: 30px;
      border: 1px solid var(--line);
      border-radius: var(--radius-md);
      background: var(--paper);
    }

    .quote-mark {
      height: 34px;
      color: var(--terracotta);
      font-family: var(--font-display);
      font-size: 3.4rem;
      line-height: 1;
    }

    .quote-card blockquote {
      flex: 1;
      margin: 16px 0 26px;
      color: #465b50;
      font-family: var(--font-display);
      font-size: 1.16rem;
      line-height: 1.55;
    }

    .quote-author {
      display: flex;
      align-items: center;
      gap: 13px;
    }

    .quote-author img {
      width: 47px;
      height: 47px;
      border-radius: 50%;
      object-fit: cover;
    }

    .quote-author strong {
      display: block;
      color: var(--forest);
      font-size: 0.79rem;
    }

    .quote-author span {
      display: block;
      color: var(--muted);
      font-size: 0.68rem;
    }

    .blog-grid {
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 26px;
    }

    .article-card {
      display: flex;
      flex-direction: column;
    }

    .article-image {
      overflow: hidden;
      aspect-ratio: 1.45;
      margin-bottom: 21px;
      border-radius: var(--radius-md);
      background: var(--sage);
    }

    .article-image img {
      height: 100%;
      object-fit: cover;
      transition: transform 500ms ease;
    }

    .article-card:hover .article-image img {
      transform: scale(1.04);
    }

    .article-kicker {
      display: flex;
      justify-content: space-between;
      gap: 15px;
      margin-bottom: 10px;
      color: var(--terracotta);
      font-size: 0.65rem;
      font-weight: 700;
      letter-spacing: 0.08em;
      text-transform: uppercase;
    }

    .article-kicker span:last-child {
      color: var(--muted);
      letter-spacing: 0;
      text-transform: none;
    }

    .article-card h3 {
      margin-bottom: 11px;
      font-size: 1.65rem;
      line-height: 1.15;
    }

    .article-card p {
      flex: 1;
      margin-bottom: 18px;
      color: var(--muted);
      font-size: 0.82rem;
      line-height: 1.75;
    }

    .article-card .text-link {
      align-self: flex-start;
    }

    .faq-layout {
      display: grid;
      align-items: start;
      grid-template-columns: minmax(260px, 0.7fr) minmax(0, 1.3fr);
      gap: clamp(50px, 8vw, 110px);
    }

    .faq-intro {
      position: sticky;
      top: 120px;
    }

    .faq-intro p {
      color: var(--muted);
      font-size: 0.9rem;
      line-height: 1.8;
    }

    .faq-contact {
      margin-top: 24px;
      color: var(--forest);
      font-size: 0.8rem;
      font-weight: 700;
    }

    .faq-list {
      border-top: 1px solid var(--line);
    }

    .faq-item {
      border-bottom: 1px solid var(--line);
    }

    .faq-item summary {
      position: relative;
      padding: 24px 48px 24px 0;
      color: var(--forest);
      cursor: pointer;
      font-family: var(--font-display);
      font-size: 1.28rem;
      font-weight: 600;
      line-height: 1.35;
      list-style: none;
    }

    .faq-item summary::-webkit-details-marker {
      display: none;
    }

    .faq-item summary::before,
    .faq-item summary::after {
      position: absolute;
      top: 34px;
      right: 6px;
      width: 16px;
      height: 1px;
      background: var(--forest);
      content: "";
      transition: transform 180ms ease;
    }

    .faq-item summary::after {
      transform: rotate(90deg);
    }

    .faq-item[open] summary::after {
      transform: rotate(0);
    }

    .faq-item p {
      max-width: 690px;
      padding: 0 40px 24px 0;
      color: var(--muted);
      font-size: 0.86rem;
      line-height: 1.8;
    }

    .newsletter-section {
      padding: 0 0 100px;
      background: var(--paper);
    }

    .newsletter-card {
      position: relative;
      display: grid;
      overflow: hidden;
      align-items: center;
      padding: clamp(38px, 6vw, 70px);
      border-radius: var(--radius-lg);
      background: var(--forest);
      color: #c6d5ca;
      grid-template-columns: minmax(0, 0.9fr) minmax(340px, 1.1fr);
      gap: 60px;
    }

    .newsletter-card::after {
      position: absolute;
      right: -120px;
      bottom: -180px;
      width: 390px;
      height: 390px;
      border: 1px solid rgba(255, 255, 255, 0.1);
      border-radius: 50%;
      content: "";
      pointer-events: none;
    }

    .newsletter-copy {
      position: relative;
      z-index: 1;
    }

    .newsletter-copy .eyebrow {
      color: #f0ae83;
    }

    .newsletter-copy h2 {
      color: var(--cream);
      font-size: clamp(2.25rem, 3.8vw, 3.5rem);
    }

    .newsletter-copy p {
      font-size: 0.88rem;
      line-height: 1.8;
    }

    .newsletter-form-wrap {
      position: relative;
      z-index: 1;
    }

    .newsletter-fields {
      display: grid;
      grid-template-columns: 1fr 0.8fr;
      gap: 10px;
    }

    .newsletter-fields input,
    .newsletter-fields select {
      width: 100%;
      min-height: 52px;
      padding: 12px 15px;
      border: 1px solid rgba(255, 255, 255, 0.26);
      border-radius: 9px;
      background: rgba(255, 255, 255, 0.08);
      color: var(--white);
      font-size: 0.8rem;
    }

    .newsletter-fields input::placeholder {
      color: #b7c8bc;
    }

    .newsletter-fields select option {
      background: var(--forest);
      color: var(--white);
    }

    .newsletter-form .button {
      width: 100%;
      margin-top: 11px;
    }

    .newsletter-consent {
      margin-top: 12px;
      color: #aebfb3;
      font-size: 0.66rem;
      line-height: 1.6;
    }

    .inline-legal {
      padding: 0;
      border: 0;
      border-bottom: 1px solid currentColor;
      background: transparent;
      color: inherit;
      font-size: inherit;
    }

    .plan-hint,
    .form-status {
      margin-top: 12px;
      padding: 10px 12px;
      border-radius: 8px;
      background: rgba(255, 255, 255, 0.09);
      color: #e6eee6;
      font-size: 0.72rem;
    }

    .site-footer {
      padding: 70px 0 24px;
      background: var(--forest-deep);
      color: #aebfb3;
    }

    .footer-grid {
      display: grid;
      padding-bottom: 52px;
      grid-template-columns: 1.5fr 0.7fr 0.8fr 1fr;
      gap: 50px;
    }

    .site-footer .brand-name {
      color: var(--cream);
    }

    .site-footer .brand-tagline {
      color: #9eb2a4;
    }

    .footer-about p {
      max-width: 340px;
      margin: 21px 0;
      font-size: 0.78rem;
      line-height: 1.8;
    }

    .social-links {
      display: flex;
      flex-wrap: wrap;
      gap: 9px;
    }

    .social-links a {
      padding: 7px 11px;
      border: 1px solid rgba(255, 255, 255, 0.16);
      border-radius: 999px;
      color: #d7e2d8;
      font-size: 0.66rem;
      font-weight: 600;
      transition: border-color 180ms ease, background 180ms ease;
    }

    .social-links a:hover {
      border-color: var(--terracotta);
      background: rgba(255, 255, 255, 0.05);
    }

    .footer-column h3 {
      margin-bottom: 18px;
      color: var(--cream);
      font-family: var(--font-body);
      font-size: 0.7rem;
      font-weight: 700;
      letter-spacing: 0.12em;
      text-transform: uppercase;
    }

    .footer-links {
      margin: 0;
      padding: 0;
      list-style: none;
    }

    .footer-links li {
      margin-bottom: 10px;
    }

    .footer-links a,
    .footer-links button {
      padding: 0;
      border: 0;
      background: none;
      color: #aebfb3;
      font-size: 0.76rem;
      text-align: left;
      transition: color 180ms ease;
    }

    .footer-links a:hover,
    .footer-links button:hover {
      color: var(--terracotta);
    }

    .footer-contact address {
      margin-bottom: 18px;
      font-size: 0.76rem;
      font-style: normal;
      line-height: 1.8;
    }

    .footer-contact a {
      display: block;
      margin-bottom: 8px;
      color: #d7e2d8;
      font-size: 0.75rem;
    }

    .footer-bottom {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 25px;
      padding-top: 22px;
      border-top: 1px solid rgba(255, 255, 255, 0.12);
      font-size: 0.66rem;
    }

    .footer-bottom p {
      margin: 0;
    }

    .legal-links {
      display: flex;
      flex-wrap: wrap;
      gap: 18px;
    }

    .legal-links button {
      padding: 0;
      border: 0;
      background: none;
      color: #aebfb3;
      font-size: 0.66rem;
    }

    .legal-links button:hover {
      color: var(--white);
    }

    dialog {
      max-height: calc(100vh - 40px);
      padding: 0;
      overflow: auto;
      border: 0;
      border-radius: var(--radius-md);
      background: var(--paper);
      box-shadow: 0 30px 100px rgba(3, 20, 15, 0.35);
      color: var(--ink);
    }

    dialog::backdrop {
      background: rgba(9, 28, 23, 0.72);
      backdrop-filter: blur(5px);
    }

    dialog[open] {
      animation: dialog-in 200ms ease both;
    }

    @keyframes dialog-in {
      from {
        transform: translateY(15px) scale(0.98);
        opacity: 0;
      }
      to {
        transform: translateY(0) scale(1);
        opacity: 1;
      }
    }

    .dialog-close {
      position: absolute;
      z-index: 4;
      top: 15px;
      right: 15px;
      display: grid;
      width: 38px;
      height: 38px;
      place-items: center;
      border: 1px solid var(--line);
      border-radius: 50%;
      background: rgba(255, 253, 248, 0.94);
      color: var(--forest);
      font-size: 1.4rem;
      line-height: 1;
    }

    .tutorial-dialog {
      width: min(780px, calc(100% - 32px));
    }

    .tutorial-image {
      aspect-ratio: 1.9;
      background: var(--sage);
    }

    .tutorial-image img {
      height: 100%;
      object-fit: cover;
    }

    .dialog-body {
      padding: 34px 38px 38px;
    }

    .dialog-body .eyebrow {
      margin-bottom: 12px;
    }

    .dialog-body h2 {
      margin-bottom: 14px;
      font-size: 2.25rem;
    }

    .dialog-body > p {
      color: var(--muted);
      font-size: 0.88rem;
      line-height: 1.8;
    }

    .tutorial-topline {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 20px;
      margin-bottom: 16px;
      color: var(--muted);
      font-size: 0.69rem;
      font-weight: 700;
      letter-spacing: 0.08em;
      text-transform: uppercase;
    }

    .tutorial-dots {
      display: flex;
      gap: 6px;
    }

    .tutorial-dot {
      width: 26px;
      height: 5px;
      padding: 0;
      border: 0;
      border-radius: 999px;
      background: var(--line);
    }

    .tutorial-dot[aria-current="step"] {
      background: var(--terracotta);
    }

    .tutorial-nav {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 15px;
      margin-top: 25px;
    }

    .tutorial-nav .button:disabled {
      cursor: not-allowed;
      opacity: 0.4;
      transform: none;
    }

    .reservation-dialog {
      width: min(610px, calc(100% - 32px));
    }

    .reservation-dialog .dialog-body {
      padding: 42px;
    }

    .reservation-dialog .dialog-body > p {
      margin-bottom: 25px;
    }

    .form-grid {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 16px;
    }

    .form-field {
      display: flex;
      flex-direction: column;
      gap: 6px;
    }

    .form-field.full {
      grid-column: 1 / -1;
    }

    .form-field label {
      color: var(--forest);
      font-size: 0.7rem;
      font-weight: 700;
    }

    .form-field input,
    .form-field select {
      width: 100%;
      min-height: 47px;
      padding: 10px 12px;
      border: 1px solid var(--line);
      border-radius: 8px;
      background: var(--white);
      color: var(--ink);
      font-size: 0.8rem;
    }

    .reservation-form .button {
      width: 100%;
      margin-top: 21px;
    }

    .form-fine-print {
      margin-top: 12px !important;
      margin-bottom: 0 !important;
      font-size: 0.67rem !important;
      text-align: center;
    }

    .reservation-success {
      padding: 25px 0 5px;
      text-align: center;
    }

    .success-icon {
      display: grid;
      width: 64px;
      height: 64px;
      margin: 0 auto 20px;
      place-items: center;
      border-radius: 50%;
      background: var(--sage);
      color: var(--forest);
      font-size: 1.7rem;
      font-weight: 700;
    }

    .reservation-success h3 {
      font-size: 2rem;
    }

    .reservation-success p {
      color: var(--muted);
      font-size: 0.85rem;
    }

    .confirmation-code {
      display: inline-block;
      margin: 6px 0 22px;
      padding: 8px 13px;
      border-radius: 8px;
      background: var(--sage);
      color: var(--forest);
      font-size: 0.72rem;
      font-weight: 700;
      letter-spacing: 0.08em;
    }

    .article-dialog {
      width: min(800px, calc(100% - 32px));
    }

    .article-dialog-image {
      aspect-ratio: 2;
      background: var(--sage);
    }

    .article-dialog-image img {
      height: 100%;
      object-fit: cover;
    }

    .article-dialog-content {
      max-width: 670px;
      margin: 0 auto;
      padding: 38px 42px 48px;
    }

    .article-dialog-content h2 {
      font-size: clamp(2.1rem, 4vw, 3.2rem);
    }

    .article-dialog-content .article-body {
      color: #53645a;
      font-size: 0.93rem;
      line-height: 1.9;
    }

    .article-body p {
      margin-bottom: 20px;
    }

    .article-body p:first-child::first-letter {
      float: left;
      margin: 7px 8px 0 0;
      color: var(--terracotta);
      font-family: var(--font-display);
      font-size: 3.8rem;
      line-height: 0.75;
    }

    .article-signoff {
      margin-top: 30px;
      padding-top: 18px;
      border-top: 1px solid var(--line);
      color: var(--forest);
      font-size: 0.75rem;
      font-weight: 700;
    }

    .legal-dialog {
      width: min(650px, calc(100% - 32px));
    }

    .legal-dialog .dialog-body {
      padding: 44px;
    }

    .legal-content {
      color: var(--muted);
      font-size: 0.82rem;
      line-height: 1.8;
    }

    .legal-content h3 {
      margin: 25px 0 8px;
      font-family: var(--font-body);
      font-size: 0.85rem;
      letter-spacing: 0;
    }

    .toast {
      position: fixed;
      z-index: 200;
      right: 24px;
      bottom: 24px;
      max-width: min(380px, calc(100% - 48px));
      padding: 14px 18px;
      transform: translateY(20px);
      border: 1px solid rgba(255, 255, 255, 0.15);
      border-radius: 12px;
      background: var(--forest-deep);
      box-shadow: var(--shadow-lg);
      color: var(--white);
      font-size: 0.78rem;
      opacity: 0;
      pointer-events: none;
      transition: opacity 180ms ease, transform 180ms ease;
    }

    .toast.show {
      transform: translateY(0);
      opacity: 1;
    }

    .back-to-top {
      position: fixed;
      z-index: 35;
      right: 22px;
      bottom: 22px;
      display: grid;
      width: 45px;
      height: 45px;
      place-items: center;
      transform: translateY(20px);
      border: 1px solid var(--line);
      border-radius: 50%;
      background: var(--paper);
      box-shadow: var(--shadow-sm);
      color: var(--forest);
      opacity: 0;
      pointer-events: none;
      transition: opacity 180ms ease, transform 180ms ease;
    }

    .back-to-top.visible {
      transform: translateY(0);
      opacity: 1;
      pointer-events: auto;
    }

    .js .reveal {
      transform: translateY(24px);
      opacity: 0;
      transition: opacity 650ms ease, transform 650ms ease;
    }

    .js .reveal.is-visible {
      transform: translateY(0);
      opacity: 1;
    }

    @media (max-width: 1140px) {
      .primary-nav {
        gap: 15px;
      }

      .nav-link {
        font-size: 0.72rem;
      }

      .header-cta {
        display: none;
      }

      .hero-grid {
        gap: 55px;
      }

      .floating-recipe {
        right: -8px;
      }
    }

    @media (max-width: 960px) {
      .section {
        padding: 88px 0;
      }

      .menu-toggle {
        display: block;
      }

      .primary-nav {
        position: absolute;
        top: calc(100% + 8px);
        right: 0;
        left: 0;
        display: none;
        align-items: stretch;
        padding: 18px;
        border: 1px solid var(--line);
        border-radius: 16px;
        background: var(--paper);
        box-shadow: var(--shadow-lg);
      }

      .primary-nav.is-open {
        display: flex;
        flex-direction: column;
        gap: 2px;
      }

      .primary-nav .nav-link {
        padding: 11px 12px;
        border-radius: 8px;
        font-size: 0.86rem;
      }

      .primary-nav .nav-link:hover {
        background: var(--sage);
      }

      .primary-nav .nav-link::after {
        display: none;
      }

      .hero-grid {
        grid-template-columns: 1fr;
      }

      .hero-copy {
        max-width: 760px;
      }

      .hero-visual {
        width: min(100%, 590px);
        max-width: none;
        margin: 10px auto 0;
      }

      .hero-arch {
        aspect-ratio: 1.05;
        border-radius: 220px 220px 24px 24px;
      }

      .section-heading.split {
        align-items: start;
        grid-template-columns: 1fr;
        gap: 24px;
      }

      .section-intro {
        max-width: 730px;
      }

      .lab-workspace {
        grid-template-columns: 1fr;
      }

      .control-panel,
      .ingredient-panel {
        padding: 38px;
      }

      .trends-layout,
      .spotlight-grid {
        grid-template-columns: 1fr;
      }

      .trend-photo {
        position: static;
        max-width: 650px;
      }

      .trend-photo-frame {
        aspect-ratio: 1.4;
        border-radius: var(--radius-md);
      }

      .spotlight-media {
        max-width: 670px;
      }

      .spotlight-media img {
        aspect-ratio: 1.35;
      }

      .restaurant-grid,
      .plan-grid,
      .testimonial-grid {
        grid-template-columns: 1fr;
      }

      .restaurant-card {
        display: grid;
        grid-template-columns: 0.8fr 1.2fr;
      }

      .restaurant-media {
        height: 100%;
        aspect-ratio: auto;
      }

      .plan-card {
        min-height: auto;
      }

      .newsletter-card {
        grid-template-columns: 1fr;
        gap: 30px;
      }

      .footer-grid {
        grid-template-columns: 1.4fr 1fr 1fr;
      }

      .footer-contact {
        grid-column: 2 / -1;
      }
    }

    @media (max-width: 740px) {
      .container {
        width: min(var(--container), calc(100% - 32px));
      }

      .announcement .container {
        justify-content: center;
        text-align: center;
      }

      .announcement p {
        display: none;
      }

      .header-inner {
        min-height: 74px;
      }

      .brand-mark {
        width: 42px;
        height: 42px;
      }

      .brand-name {
        font-size: 1.25rem;
      }

      .brand-tagline {
        font-size: 0.53rem;
      }

      .hero {
        padding: 48px 0 60px;
      }

      .hero h1 {
        font-size: clamp(3.15rem, 13vw, 4.8rem);
      }

      .hero-intro {
        font-size: 0.96rem;
      }

      .issue-stamp {
        left: -8px;
        width: 76px;
        height: 76px;
      }

      .floating-recipe {
        right: 0;
        width: 220px;
      }

      .stats-grid {
        grid-template-columns: repeat(2, 1fr);
      }

      .stat {
        border-bottom: 1px solid var(--line);
      }

      .stat:nth-child(odd) {
        border-left: 1px solid var(--line);
      }

      .stat:nth-child(even) {
        border-right: 1px solid var(--line);
      }

      .stat:nth-last-child(-n+2) {
        border-bottom: 0;
      }

      .recipe-grid,
      .blog-grid {
        grid-template-columns: 1fr;
      }

      .filter-bar {
        align-items: flex-start;
        flex-direction: column;
      }

      .recipe-content p {
        min-height: auto;
      }

      .control-panel,
      .ingredient-panel {
        padding: 28px 24px;
      }

      .serving-row {
        align-items: flex-start;
        flex-direction: column;
      }

      .ingredient-amount {
        min-width: 68px;
      }

      .spotlight-media {
        padding: 0 0 20px 20px;
      }

      .season-badge {
        right: 0;
      }

      .prep-steps {
        grid-template-columns: 1fr;
        gap: 18px;
      }

      .restaurant-card {
        display: flex;
      }

      .restaurant-media {
        height: auto;
        aspect-ratio: 1.4;
      }

      .faq-layout {
        grid-template-columns: 1fr;
        gap: 35px;
      }

      .faq-intro {
        position: static;
      }

      .newsletter-fields {
        grid-template-columns: 1fr;
      }

      .footer-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 38px 25px;
      }

      .footer-about {
        grid-column: 1 / -1;
      }

      .footer-contact {
        grid-column: auto;
      }

      .footer-bottom {
        align-items: flex-start;
        flex-direction: column;
      }

      .form-grid {
        grid-template-columns: 1fr;
      }

      .form-field.full {
        grid-column: auto;
      }

      .dialog-body,
      .reservation-dialog .dialog-body,
      .legal-dialog .dialog-body {
        padding: 34px 24px;
      }

      .article-dialog-content {
        padding: 32px 25px 38px;
      }
    }

    @media (max-width: 440px) {
      .brand-tagline {
        display: none;
      }

      .hero-actions .button,
      .spotlight-actions .button {
        width: 100%;
      }

      .hero-proof {
        align-items: flex-start;
        flex-direction: column;
      }

      .floating-recipe {
        position: relative;
        right: auto;
        bottom: auto;
        width: calc(100% - 28px);
        margin: -45px auto 0;
      }

      .issue-stamp {
        top: 10px;
      }

      .stat {
        padding: 21px 12px;
      }

      .stat strong {
        font-size: 1.5rem;
      }

      .stat span {
        font-size: 0.6rem;
      }

      .newsletter-card {
        padding: 32px 23px;
      }

      .footer-grid {
        grid-template-columns: 1fr;
      }

      .footer-about,
      .footer-contact {
        grid-column: auto;
      }

      .unit-row {
        align-items: flex-start;
        flex-direction: column;
      }

      .tutorial-nav {
        align-items: stretch;
        flex-direction: column-reverse;
      }
    }

    @media (prefers-reduced-motion: reduce) {
      html {
        scroll-behavior: auto;
      }

      *,
      *::before,
      *::after {
        scroll-behavior: auto !important;
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
      }

      .js .reveal {
        transform: none;
        opacity: 1;
      }
    }
  </style>
</head>

<body>
  <a class="skip-link" href="#main-content">Skip to main content</a>

  <div class="announcement">
    <div class="container">
      <p>The Seasonal Edit is here: 18 bright, brothy, crisp things to cook now.</p>
      <a href="#recipes">Explore the collection <span aria-hidden="true">→</span></a>
    </div>
  </div>

  <header class="site-header" id="siteHeader">
    <div class="container header-inner">
      <a class="brand" href="#top" aria-label="Savor and Sage home">
        <img class="brand-mark" src="https://placehold.co/72x72/173F35/F8F3E8?text=S%26S&amp;font=montserrat" width="72" height="72" alt="Savor and Sage monogram">
        <span class="brand-copy">
          <span class="brand-name">Savor &amp; Sage</span>
          <span class="brand-tagline">Cook seasonally. Eat joyfully.</span>
        </span>
      </a>

      <nav class="primary-nav" id="primaryNav" aria-label="Primary navigation">
        <a class="nav-link" href="#recipes">Recipes</a>
        <a class="nav-link" href="#seasonal">Seasonal</a>
        <a class="nav-link" href="#restaurants">Restaurant Reviews</a>
        <a class="nav-link" href="#meal-plans">Meal Plans</a>
        <a class="nav-link" href="#guides">Kitchen Guides</a>
        <a class="nav-link" href="#blog">Blog</a>
      </nav>

      <div class="header-actions">
        <a class="button button-dark header-cta" href="#recipe-lab">Open Recipe Lab</a>
        <button class="menu-toggle" id="menuToggle" type="button" aria-label="Open navigation" aria-controls="primaryNav" aria-expanded="false">
          <span></span>
          <span></span>
          <span></span>
        </button>
      </div>
    </div>
  </header>

  <main id="main-content">
    <section class="hero" id="top">
      <div class="container hero-grid">
        <div class="hero-copy reveal">
          <span class="eyebrow">Recipes · Restaurants · Real kitchen wisdom</span>
          <h1>Good cooking starts with <em>what’s in season.</em></h1>
          <p class="hero-intro">
            Savor &amp; Sage is an independent table for curious cooks. From a Tuesday skillet to a dining room worth traveling for, we test the recipes, do the mise en place, and tell you what actually works—without the fuss, filler, or fifteen-step detours.
          </p>
          <div class="hero-actions">
            <a class="button button-primary" href="#recipes">Find tonight’s recipe <span aria-hidden="true">→</span></a>
            <a class="button button-outline" href="#recipe-lab">Scale a recipe</a>
          </div>
          <div class="hero-proof">
            <div class="avatar-stack" aria-hidden="true">
              <img src="https://i.pravatar.cc/80?u=savor-maya" alt="" width="80" height="80">
              <img src="https://i.pravatar.cc/80?u=savor-theo" alt="" width="80" height="80">
              <img src="https://i.pravatar.cc/80?u=savor-lena" alt="" width="80" height="80">
            </div>
            <div class="proof-copy">
              <strong>4.9 out of 5 from our cooking community</strong>
              Tested, tasted, and loved by 120,000+ curious home cooks.
            </div>
          </div>
        </div>

        <div class="hero-visual reveal">
          <div class="hero-arch">
            <img src="https://picsum.photos/seed/savor-sage-table/1000/1200" alt="A beautifully set seasonal dinner table" width="1000" height="1200" fetchpriority="high">
          </div>
          <div class="issue-stamp">Issue No. 04<br>The Spring<br>Table</div>
          <a class="floating-recipe recipe-open" href="#recipe-lab" data-recipe="salmon">
            <span class="mini-label">Editor’s pick · Open recipe</span>
            <strong>Charred Citrus Salmon</strong>
            <span>25 minutes · crisp skin, glossy reduction</span>
          </a>
        </div>
      </div>
    </section>

    <div class="stat-band" aria-label="Savor and Sage at a glance">
      <div class="container stats-grid">
        <div class="stat"><strong>48</strong><span>Seasonal recipes tested</span></div>
        <div class="stat"><strong>2×</strong><span>Every recipe re-tested</span></div>
        <div class="stat"><strong>32</strong><span>Independent restaurant visits</span></div>
        <div class="stat"><strong>100%</strong><span>Ad-free editorial judgment</span></div>
      </div>
    </div>

    <section class="section" id="recipes">
      <div class="container">
        <div class="section-heading split reveal">
          <div>
            <span class="eyebrow">01 · The Seasonal Edit</span>
            <h2>A little brighter.<br>A little greener.</h2>
          </div>
          <div class="section-intro">
            <p>Our spring collection leans into snap, acidity, and soft herbs: crisp-skinned salmon, brothy grains, and vegetables that need little more than a hot pan. Every dish is tested with standard home equipment and supermarket ingredients.</p>
            <p>Use the filters to find your pace, then open any recipe in our Recipe Lab to adjust the yield without doing dinner-party arithmetic.</p>
          </div>
        </div>

        <div class="filter-bar reveal">
          <div class="filters" role="group" aria-label="Filter recipes">
            <button class="filter-button is-active" type="button" data-filter="all" aria-pressed="true">All recipes</button>
            <button class="filter-button" type="button" data-filter="quick" aria-pressed="false">Under 30 minutes</button>
            <button class="filter-button" type="button" data-filter="vegetarian" aria-pressed="false">Vegetarian</button>
            <button class="filter-button" type="button" data-filter="weekend" aria-pressed="false">Weekend projects</button>
          </div>
          <p class="filter-status" id="filterStatus" role="status">Showing 4 seasonal recipes</p>
        </div>

        <div class="recipe-grid">
          <article class="recipe-card reveal" data-category="quick">
            <div class="recipe-media">
              <img src="https://picsum.photos/seed/savor-citrus-salmon/900/620" alt="Charred citrus salmon with herbs" width="900" height="620" loading="lazy" decoding="async">
              <span class="recipe-badge">Most cooked</span>
              <button class="save-recipe" type="button" data-save="salmon" aria-label="Save Charred Citrus Salmon" aria-pressed="false">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><path d="M6 3.5h12v17l-6-4-6 4z"/></svg>
              </button>
            </div>
            <div class="recipe-content">
              <div class="recipe-meta"><span>25 min</span><span>Pescatarian</span><span>4.9 / 5</span></div>
              <h3>Charred Citrus Salmon</h3>
              <p>Caramelized orange, white miso, and a quick pan reduction make a glossy sauce for crisp-skinned salmon. A shower of dill and mint keeps the finish lively.</p>
              <a class="text-link recipe-open" href="#recipe-lab" data-recipe="salmon">Open &amp; scale recipe <span aria-hidden="true">→</span></a>
            </div>
          </article>

          <article class="recipe-card reveal" data-category="vegetarian weekend">
            <div class="recipe-media">
              <img src="https://picsum.photos/seed/savor-asparagus-risotto/900/620" alt="Creamy asparagus risotto with lemon" width="900" height="620" loading="lazy" decoding="async">
              <span class="recipe-badge">Seasonal favorite</span>
              <button class="save-recipe" type="button" data-save="risotto" aria-label="Save Asparagus and Lemon Risotto" aria-pressed="false">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><path d="M6 3.5h12v17l-6-4-6 4z"/></svg>
              </button>
            </div>
            <div class="recipe-content">
              <div class="recipe-meta"><span>45 min</span><span>Vegetarian</span><span>4.8 / 5</span></div>
              <h3>Asparagus &amp; Lemon Risotto</h3>
              <p>We blanch the tips separately, then use the stems to enrich the stock. The result is loose, glossy risotto with clean asparagus flavor—not a stodgy green mound.</p>
              <a class="text-link recipe-open" href="#recipe-lab" data-recipe="risotto">Open &amp; scale recipe <span aria-hidden="true">→</span></a>
            </div>
          </article>

          <article class="recipe-card reveal" data-category="quick vegetarian">
            <div class="recipe-media">
              <img src="https://picsum.photos/seed/savor-pea-pasta/900/620" alt="Spring pea pasta with ricotta and mint" width="900" height="620" loading="lazy" decoding="async">
              <span class="recipe-badge">Weeknight hero</span>
              <button class="save-recipe" type="button" data-save="pasta" aria-label="Save Spring Pea and Ricotta Pasta" aria-pressed="false">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><path d="M6 3.5h12v17l-6-4-6 4z"/></svg>
              </button>
            </div>
            <div class="recipe-content">
              <div class="recipe-meta"><span>20 min</span><span>Vegetarian</span><span>4.9 / 5</span></div>
              <h3>Spring Pea &amp; Ricotta Pasta</h3>
              <p>Sweet peas, lemon, and ricotta become a silky sauce with a ladle of starchy pasta water. Frozen peas work beautifully, making this a year-round pantry fallback.</p>
              <a class="text-link recipe-open" href="#recipe-lab" data-recipe="pasta">Open &amp; scale recipe <span aria-hidden="true">→</span></a>
            </div>
          </article>

          <article class="recipe-card reveal" data-category="vegetarian weekend">
            <div class="recipe-media">
              <img src="https://picsum.photos/seed/savor-mushroom-buns/900/620" alt="Miso mushroom steam buns with crisp cabbage" width="900" height="620" loading="lazy" decoding="async">
              <span class="recipe-badge">Cook with friends</span>
              <button class="save-recipe" type="button" data-save="buns" aria-label="Save Miso Mushroom Steam Buns" aria-pressed="false">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><path d="M6 3.5h12v17l-6-4-6 4z"/></svg>
              </button>
            </div>
            <div class="recipe-content">
              <div class="recipe-meta"><span>75 min</span><span>Plant-based option</span><span>4.7 / 5</span></div>
              <h3>Miso Mushroom Steam Buns</h3>
              <p>Deeply browned mushrooms are glazed with miso and mirin, then tucked into pillowy buns with sesame cabbage. Make the filling ahead and steam to order.</p>
              <a class="text-link recipe-open" href="#recipe-lab" data-recipe="buns">Open &amp; scale recipe <span aria-hidden="true">→</span></a>
            </div>
          </article>
        </div>
      </div>
    </section>

    <section class="section recipe-lab" id="recipe-lab">
      <div class="container">
        <div class="section-heading split reveal">
          <div>
            <span class="eyebrow">02 · Interactive Recipe Lab</span>
            <h2>Your recipe,<br>recalculated.</h2>
          </div>
          <div class="section-intro">
            <p>Cooking for two instead of six? Choose a dish, set your serving count, and switch between US and metric measurements. We’ll scale every ingredient while keeping the method grounded in practical pan sizes and timing.</p>
            <p>Check items off as you complete your mise en place, then copy the finished list for your market run.</p>
          </div>
        </div>

        <div class="lab-workspace reveal">
          <div class="control-panel">
            <label class="field-label" for="recipeSelect">Choose a recipe</label>
            <select class="recipe-select" id="recipeSelect">
              <option value="salmon">Charred Citrus Salmon</option>
              <option value="risotto">Asparagus &amp; Lemon Risotto</option>
              <option value="pasta">Spring Pea &amp; Ricotta Pasta</option>
              <option value="buns">Miso Mushroom Steam Buns</option>
            </select>

            <p class="recipe-description" id="recipeDescription">Crisp-skinned salmon with caramelized citrus, soft herbs, and a quick miso pan reduction.</p>

            <div class="lab-meta">
              <span id="recipeTime">25 minutes</span>
              <span id="recipeLevel">Confident beginner</span>
              <span id="recipeNutrition">≈ 540 kcal · 39 g protein</span>
            </div>

            <div class="serving-row">
              <div>
                <span class="control-label">Adjust the yield</span>
                <small>Scale from 1 to 12 servings</small>
              </div>
              <div class="serving-stepper">
                <button type="button" id="decreaseServings" aria-label="Decrease servings">−</button>
                <output id="servingOutput" for="decreaseServings increaseServings" aria-live="polite">4 servings</output>
                <button type="button" id="increaseServings" aria-label="Increase servings">+</button>
              </div>
            </div>

            <div class="unit-row">
              <span class="control-label">Measurement system</span>
              <div class="unit-toggle" role="group" aria-label="Measurement system">
                <button class="is-active" type="button" data-unit="us" aria-pressed="true">US cups</button>
                <button type="button" data-unit="metric" aria-pressed="false">Metric</button>
              </div>
            </div>

            <div class="chef-note">
              <strong>Chef’s note</strong>
              <p id="recipeNote">Dry the salmon thoroughly and leave it undisturbed in the pan. For larger yields, sear in batches rather than crowding and steaming the fillets.</p>
            </div>

            <h3 class="method-title">Method at a glance</h3>
            <ol class="method-list" id="methodList">
              <li>Season and dry the salmon; mix the citrus glaze.</li>
              <li>Sear skin-side down until crisp, then turn and char the citrus.</li>
              <li>Build the reduction in the pan and spoon over the fish.</li>
            </ol>
          </div>

          <div class="ingredient-panel">
            <div class="ingredient-heading">
              <div>
                <h3>Ingredients</h3>
                <p id="yieldLabel">For 4 servings · US measurements</p>
              </div>
              <span class="prep-count" id="prepCount">0 / 7 prepped</span>
            </div>

            <div class="progress-track" aria-hidden="true"><div class="progress-bar" id="prepProgress"></div></div>

            <noscript><p class="noscript-note">Enable JavaScript to scale ingredients automatically. The base recipe below remains available.</p></noscript>

            <ul class="ingredient-list" id="ingredientList">
              <li><label><input type="checkbox"><span class="ingredient-amount">4</span><span class="ingredient-name">salmon fillets, about 6 oz / 170 g each</span></label></li>
              <li><label><input type="checkbox"><span class="ingredient-amount">2</span><span class="ingredient-name">oranges, one sliced and one juiced</span></label></li>
              <li><label><input type="checkbox"><span class="ingredient-amount">2 tbsp</span><span class="ingredient-name">white miso</span></label></li>
              <li><label><input type="checkbox"><span class="ingredient-amount">1 tbsp</span><span class="ingredient-name">honey</span></label></li>
              <li><label><input type="checkbox"><span class="ingredient-amount">2 tbsp</span><span class="ingredient-name">soy sauce</span></label></li>
              <li><label><input type="checkbox"><span class="ingredient-amount">1 tbsp</span><span class="ingredient-name">rice vinegar</span></label></li>
              <li><label><input type="checkbox"><span class="ingredient-amount">½ cup</span><span class="ingredient-name">soft herbs, such as dill and mint</span></label></li>
            </ul>

            <div class="lab-actions">
              <button class="button button-dark" id="copyIngredients" type="button">Copy ingredient list</button>
              <button class="button button-outline" id="printRecipe" type="button">Print recipe</button>
            </div>
          </div>
        </div>
      </div>
    </section>

    <section class="section section-paper" id="guides">
      <div class="container">
        <div class="section-heading split reveal">
          <div>
            <span class="eyebrow">03 · Culinary Trends &amp; Kitchen Guides</span>
            <h2>The modern plate is loosening up.</h2>
          </div>
          <div class="section-intro">
            <p>Our editors spend a lot of time in restaurant kitchens, but the most useful trends are the ones that survive the trip home. These three shifts make everyday food more expressive—not more complicated.</p>
          </div>
        </div>

        <div class="trends-layout">
          <figure class="trend-photo reveal">
            <div class="trend-photo-frame">
              <img src="https://picsum.photos/seed/savor-kitchen-field-notes/900/1000" alt="A cook composing a colorful seasonal plate" width="900" height="1000" loading="lazy" decoding="async">
            </div>
            <figcaption><span>Field notes from the Savor &amp; Sage test kitchen</span><span>Guide 018</span></figcaption>
          </figure>

          <div class="trend-content reveal">
            <div class="trend-intro">
              <p>Trend chasing is rarely a useful route to better cooking. Technique is. Learn how a chef builds acidity, uses negative space in plating, or organizes a cutting board, and you can apply that thinking to everything from a lunch bowl to a long Sunday lunch.</p>
              <p>Here is what we are borrowing from professional kitchens right now, with practical ways to make each idea work at home.</p>
            </div>

            <article class="trend-item">
              <span class="trend-number">01</span>
              <div>
                <h3>Acid is the new finishing salt</h3>
                <p>Verjus, pickled fruit, and quick shallot reductions are replacing one-note lemon finishes. The lesson is to season in layers: salt early, then add a measured splash of acidity just before serving to lift fat and sharpen aromatics without making the dish taste sour.</p>
              </div>
            </article>

            <article class="trend-item">
              <span class="trend-number">02</span>
              <div>
                <h3>Plating leaves room to breathe</h3>
                <p>The towering, tweezed plate is giving way to generous shapes and intentional negative space. At home, use a wide bowl, place the protein slightly off-center, and spoon sauce around rather than over it; the contrast preserves crisp textures and makes color do the work.</p>
              </div>
            </article>

            <article class="trend-item">
              <span class="trend-number">03</span>
              <div>
                <h3>Mise en place gets a second life</h3>
                <p>Herb stems become oil, onion ends fortify stock, and citrus peels infuse finishing salt. This is not about saving every scrap; it is about organizing prep so flavorful trimmings go straight into a labeled container before the cutting board gets crowded.</p>
              </div>
            </article>

            <a class="text-link trend-link" href="#blog">Explore the editors’ field notes <span aria-hidden="true">→</span></a>
          </div>
        </div>
      </div>
    </section>

    <section class="section spotlight" id="seasonal">
      <div class="container spotlight-grid">
        <div class="spotlight-media reveal">
          <img src="https://picsum.photos/seed/savor-asparagus-market/900/1000" alt="Fresh asparagus at a seasonal produce market" width="900" height="1000" loading="lazy" decoding="async">
          <div class="season-badge"><small>Peak season</small><strong>April — June</strong></div>
        </div>

        <div class="spotlight-copy reveal">
          <span class="eyebrow">04 · Ingredient Spotlight</span>
          <h2>Asparagus,<br>after the snap.</h2>
          <p>Good asparagus should squeak faintly when rubbed together, with tight tips and cut ends that still look moist. Thickness is a preference, not a quality mark: slender spears are excellent raw or quickly blistered, while thick spears develop remarkable sweetness over high heat.</p>
          <p>Instead of snapping every spear, trim one to find the tender point and cut the bunch to match. Save the peels and woody ends for vegetable stock. For a simple plating, nestle the spears over lemony crème fraîche and finish with a spoonful of brown-butter reduction and toasted seeds.</p>

          <div class="pairing-label">Natural pairings</div>
          <div class="pairing-list" aria-label="Asparagus flavor pairings">
            <span>Brown butter</span><span>Preserved lemon</span><span>Egg yolk</span><span>White miso</span><span>Tarragon</span>
          </div>

          <div class="prep-steps">
            <div class="prep-step"><strong>01 · Choose</strong><span>Look for firm stalks, closed tips, and no woody shriveling at the base.</span></div>
            <div class="prep-step"><strong>02 · Store</strong><span>Stand the bunch in an inch of water, cover loosely, and refrigerate.</span></div>
            <div class="prep-step"><strong>03 · Cook hot</strong><span>Use a wide pan and avoid crowding so the spears char before they soften.</span></div>
          </div>

          <div class="spotlight-actions">
            <button class="button button-dark" id="openTutorial" type="button">Watch tutorial <span aria-hidden="true">▶</span></button>
            <a class="button button-outline recipe-open" href="#recipe-lab" data-recipe="risotto">Cook the risotto</a>
          </div>
        </div>
      </div>
    </section>

    <section class="section" id="restaurants">
      <div class="container">
        <div class="section-heading split reveal">
          <div>
            <span class="eyebrow">05 · Restaurant Reviews</span>
            <h2>Worth the reservation.</h2>
          </div>
          <div class="section-intro">
            <p>We book anonymously, pay for every meal, and return when a kitchen seems to be having an off night. Our reviews consider cooking, hospitality, room, and value—not social-media hype.</p>
            <details class="review-standard">
              <summary>How we score a restaurant</summary>
              <p>Food accounts for 50% of the score, service for 25%, atmosphere for 15%, and value for 10%. Ratings reflect the restaurant’s own ambitions: a neighborhood counter is not judged against a tasting-menu dining room.</p>
            </details>
          </div>
        </div>

        <div class="restaurant-grid">
          <article class="restaurant-card reveal">
            <div class="restaurant-media">
              <img src="https://picsum.photos/seed/savor-juniper-rye/800/620" alt="The dining room at Juniper and Rye" width="800" height="620" loading="lazy" decoding="async">
              <span class="city-tag">New York</span>
              <span class="review-score" aria-label="Score 4.8 out of 5">4.8</span>
            </div>
            <div class="restaurant-content">
              <h3>Juniper &amp; Rye</h3>
              <div class="restaurant-meta">Seasonal American · Fort Greene · $$$</div>
              <p class="restaurant-summary">A relaxed, intelligent neighborhood restaurant where wood smoke is used as seasoning rather than spectacle. The room hums, service is unforced, and the vegetable dishes routinely steal the table’s attention.</p>
              <div class="order-note"><strong>Order this:</strong> ember-roasted carrots, rye cavatelli, and the olive-oil cake with preserved citrus.</div>
              <details class="review-more">
                <summary>Read our full verdict</summary>
                <p>The cavatelli is a lesson in restraint: chewy rye pasta, sweet spring onions, and just enough aged cheese to round the pan juices. On a second visit, the roast chicken arrived with impeccably crisp skin and a glossy jus that tasted properly reduced rather than merely enriched. Book the counter if you enjoy watching a calm kitchen work.</p>
              </details>
              <button class="button button-dark reserve-button" type="button" data-restaurant="Juniper & Rye">Make Reservation</button>
            </div>
          </article>

          <article class="restaurant-card reveal">
            <div class="restaurant-media">
              <img src="https://picsum.photos/seed/savor-kado-chicago/800/620" alt="A refined dinner service at Kado" width="800" height="620" loading="lazy" decoding="async">
              <span class="city-tag">Chicago</span>
              <span class="review-score" aria-label="Score 4.7 out of 5">4.7</span>
            </div>
            <div class="restaurant-content">
              <h3>Kado</h3>
              <div class="restaurant-meta">Japanese Listening Bar · West Loop · $$$</div>
              <p class="restaurant-summary">Precise Japanese drinking snacks meet a serious vinyl collection and exceptionally warm service. Kado understands that pacing matters as much as plating; nothing arrives before you are ready for it.</p>
              <div class="order-note"><strong>Order this:</strong> sesame tofu, binchotan mushrooms, and the seasonal highball with shiso.</div>
              <details class="review-more">
                <summary>Read our full verdict</summary>
                <p>The menu rewards sharing but avoids the usual chaos of small-plates dining. Mushrooms carry a clean charcoal aroma, while the hand rolls are assembled to preserve the nori’s snap. Music is present but never prevents conversation. Go before 7 p.m. for the quietest room, or lean into the later energy with a seat near the bar.</p>
              </details>
              <button class="button button-dark reserve-button" type="button" data-restaurant="Kado">Make Reservation</button>
            </div>
          </article>

          <article class="restaurant-card reveal">
            <div class="restaurant-media">
              <img src="https://picsum.photos/seed/savor-loma-los-angeles/800/620" alt="Coastal dishes served at Loma" width="800" height="620" loading="lazy" decoding="async">
              <span class="city-tag">Los Angeles</span>
              <span class="review-score" aria-label="Score 4.9 out of 5">4.9</span>
            </div>
            <div class="restaurant-content">
              <h3>Loma</h3>
              <div class="restaurant-meta">Coastal Mexican · Los Feliz · $$</div>
              <p class="restaurant-summary">Bright seafood, house-nixtamalized tortillas, and salsas with real depth make Loma the table we keep recommending. It is casual enough for Tuesday and distinctive enough for an occasion.</p>
              <div class="order-note"><strong>Order this:</strong> kampachi tostada, charcoal octopus, and a cooling jicama salad.</div>
              <details class="review-more">
                <summary>Read our full verdict</summary>
                <p>Loma’s tortillas have the aroma and supple structure that only fresh masa delivers. The octopus is tender at the center with properly crisp edges, set over a restrained black-garlic reduction. Prices remain fair for the quality, though prime weekend reservations disappear quickly. The shaded patio is our first choice at lunch.</p>
              </details>
              <button class="button button-dark reserve-button" type="button" data-restaurant="Loma">Make Reservation</button>
            </div>
          </article>
        </div>
      </div>
    </section>

    <section class="section meal-plan-section" id="meal-plans">
      <div class="container">
        <div class="section-heading split reveal">
          <div>
            <span class="eyebrow">06 · Meal Plans With Breathing Room</span>
            <h2>A calmer week starts with a better plan.</h2>
          </div>
          <div class="section-intro">
            <p>Our meal plans are built around overlapping ingredients, deliberate leftovers, and one completely free night. Each includes a consolidated grocery list, prep sequence, substitutions, and per-serving nutrition estimates.</p>
            <p>Choose a free sample plan below. We’ll send the five-day menu and Sunday mise en place checklist straight to your inbox.</p>
          </div>
        </div>

        <div class="plan-grid">
          <article class="plan-card reveal">
            <span class="plan-number">Plan 01</span>
            <h3>The Plant-Forward Week</h3>
            <p>Five colorful dinners built around beans, grains, and peak produce. Protein is varied across the week, with dairy-free swaps wherever they make culinary sense.</p>
            <ul class="plan-features">
              <li><strong>On the menu:</strong> miso mushrooms</li>
              <li>Green farro with lemon tahini</li>
              <li>Crispy bean and cabbage tostadas</li>
              <li><strong>Prep commitment:</strong> 40 minutes Sunday</li>
            </ul>
            <a class="button button-outline plan-select" href="#newsletter" data-plan="plant" data-name="The Plant-Forward Week">Get the free plan</a>
          </article>

          <article class="plan-card featured reveal">
            <span class="plan-ribbon">Most popular</span>
            <span class="plan-number">Plan 02</span>
            <h3>The Weeknight Reset</h3>
            <p>Five low-friction dinners, each ready in 30 minutes or less. Smart prep carries forward without making Wednesday feel like Monday reheated.</p>
            <ul class="plan-features">
              <li><strong>On the menu:</strong> citrus salmon</li>
              <li>Spring pea and ricotta pasta</li>
              <li>Ginger chicken lettuce cups</li>
              <li><strong>Prep commitment:</strong> 25 minutes Sunday</li>
            </ul>
            <a class="button button-primary plan-select" href="#newsletter" data-plan="weeknight" data-name="The Weeknight Reset">Get the free plan</a>
          </article>

          <article class="plan-card reveal">
            <span class="plan-number">Plan 03</span>
            <h3>The Weekend Host</h3>
            <p>A generous three-course menu for six with a realistic cooking timeline. Most components can be prepared ahead, leaving only final searing and plating.</p>
            <ul class="plan-features">
              <li><strong>On the menu:</strong> whipped ricotta</li>
              <li>Herb-roasted chicken with pan jus</li>
              <li>Olive-oil cake and citrus salad</li>
              <li><strong>Prep commitment:</strong> 90 minutes, split up</li>
            </ul>
            <a class="button button-outline plan-select" href="#newsletter" data-plan="hosting" data-name="The Weekend Host">Get the free plan</a>
          </article>
        </div>

        <aside class="nutrition-note reveal">
          <div class="nutrition-icon" aria-hidden="true">N</div>
          <div>
            <h3>Nutrition information, without the noise</h3>
            <p>Our nutrition editors use standard USDA ingredient data to estimate calories, protein, fiber, sodium, and common allergens per serving. These figures are practical guides, not medical advice; individual needs vary, and anyone managing a health condition should consult a qualified clinician or registered dietitian.</p>
          </div>
        </aside>
      </div>
    </section>

    <section class="section section-paper" aria-labelledby="community-title">
      <div class="container">
        <div class="section-heading split reveal">
          <div>
            <span class="eyebrow">Notes From Our Tables</span>
            <h2 id="community-title">Cooked here.<br>Shared everywhere.</h2>
          </div>
          <div class="section-intro">
            <p>The best measure of a recipe is not how it looks under studio lights, but what happens in a real kitchen after a long day. Here is what members of our community have been cooking, adapting, and passing along.</p>
          </div>
        </div>

        <div class="testimonial-grid">
          <article class="quote-card reveal">
            <span class="quote-mark" aria-hidden="true">“</span>
            <blockquote>The Recipe Lab is the first scaler I trust. I made the risotto for nine, and the liquid ratios still worked. Even my father-in-law asked for the recipe.</blockquote>
            <div class="quote-author">
              <img src="https://i.pravatar.cc/96?u=savor-community-nina" alt="Portrait of Nina R." width="96" height="96" loading="lazy">
              <div><strong>Nina R.</strong><span>Home cook · Portland</span></div>
            </div>
          </article>

          <article class="quote-card reveal">
            <span class="quote-mark" aria-hidden="true">“</span>
            <blockquote>The reviews tell me where to sit and what to order, but also why a dish works. Loma lived up to every word—and the tortillas really are that good.</blockquote>
            <div class="quote-author">
              <img src="https://i.pravatar.cc/96?u=savor-community-marcus" alt="Portrait of Marcus T." width="96" height="96" loading="lazy">
              <div><strong>Marcus T.</strong><span>Weekend traveler · Austin</span></div>
            </div>
          </article>

          <article class="quote-card reveal">
            <span class="quote-mark" aria-hidden="true">“</span>
            <blockquote>I finally stopped treating meal prep as a second shift. The Weeknight Reset gives us structure, but the free night keeps it feeling like real life.</blockquote>
            <div class="quote-author">
              <img src="https://i.pravatar.cc/96?u=savor-community-elena" alt="Portrait of Elena S." width="96" height="96" loading="lazy">
              <div><strong>Elena S.</strong><span>Parent &amp; meal planner · Chicago</span></div>
            </div>
          </article>
        </div>
      </div>
    </section>

    <section class="section" id="blog">
      <div class="container">
        <div class="section-heading split reveal">
          <div>
            <span class="eyebrow">07 · From The Blog</span>
            <h2>Stories for curious appetites.</h2>
          </div>
          <div class="section-intro">
            <p>Technique deep dives, market reporting, and the small decisions that make food taste more considered. No hot takes for the sake of heat—just useful, closely observed food writing.</p>
          </div>
        </div>

        <div class="blog-grid">
          <article class="article-card reveal">
            <div class="article-image">
              <img src="https://picsum.photos/seed/savor-pan-sauce/800/560" alt="A pan sauce being finished in a skillet" width="800" height="560" loading="lazy" decoding="async">
            </div>
            <div class="article-kicker"><span>Technique</span><span>6 min read</span></div>
            <h3>The Five-Minute Pan Sauce</h3>
            <p>Those browned bits left after searing are not a mess; they are your head start. Learn to turn fond, stock, and a knob of butter into a glossy reduction.</p>
            <button class="text-link article-open" type="button" data-article="pan-sauce">Read the story <span aria-hidden="true">→</span></button>
          </article>

          <article class="article-card reveal">
            <div class="article-image">
              <img src="https://picsum.photos/seed/savor-market-without-list/800/560" alt="An abundant farmers market produce display" width="800" height="560" loading="lazy" decoding="async">
            </div>
            <div class="article-kicker"><span>Market Notes</span><span>8 min read</span></div>
            <h3>Shop the Market Without a List</h3>
            <p>A flexible framework for buying what looks best, avoiding an expensive pile of good intentions, and turning market finds into three realistic meals.</p>
            <button class="text-link article-open" type="button" data-article="market">Read the story <span aria-hidden="true">→</span></button>
          </article>

          <article class="article-card reveal">
            <div class="article-image">
              <img src="https://picsum.photos/seed/savor-season-in-layers/800/560" alt="A cook seasoning vegetables during preparation" width="800" height="560" loading="lazy" decoding="async">
            </div>
            <div class="article-kicker"><span>Kitchen Science</span><span>5 min read</span></div>
            <h3>How to Salt in Layers</h3>
            <p>Seasoning at the end can only do so much. We look at when salt penetrates, when it draws moisture, and why your pasta water should not taste like the sea.</p>
            <button class="text-link article-open" type="button" data-article="salt">Read the story <span aria-hidden="true">→</span></button>
          </article>
        </div>
      </div>
    </section>

    <section class="section section-paper" aria-labelledby="faq-title">
      <div class="container faq-layout">
        <div class="faq-intro reveal">
          <span class="eyebrow">Good Questions</span>
          <h2 id="faq-title">Before you tie your apron.</h2>
          <p>From substitutions to scoring restaurants, here are the practical details behind Savor &amp; Sage. If your question is more specific, our small editorial team reads every note.</p>
          <a class="faq-contact" href="mailto:hello@savorandsage.com">Ask us at hello@savorandsage.com →</a>
        </div>

        <div class="faq-list reveal">
          <details class="faq-item">
            <summary>Can I really scale every recipe?</summary>
            <p>The Recipe Lab scales ingredient quantities from one to twelve servings, but cooking is not purely mathematical. Pan size, evaporation, and batching may change the timing. Our chef’s notes flag those moments—for example, searing salmon in batches or using a wider pot for a larger risotto yield.</p>
          </details>
          <details class="faq-item">
            <summary>How are your recipes tested?</summary>
            <p>A recipe developer drafts each formula, a second cook tests it without verbal guidance, and an editor checks measurements, timing, and substitutions. We use standard home ovens and widely available equipment. Reader feedback often leads to another test and a clearer note.</p>
          </details>
          <details class="faq-item">
            <summary>Do you accommodate allergies and dietary needs?</summary>
            <p>Recipes include common allergen flags and tested substitutions where a swap preserves the dish. Because shared kitchens and ingredient formulations vary, always check labels and cross-contact risks. Our nutrition information is general guidance, not a substitute for individualized medical or dietetic care.</p>
          </details>
          <details class="faq-item">
            <summary>Do restaurants pay to be reviewed?</summary>
            <p>No. We do not accept paid placements, comped review meals, or advance approval of our coverage. Reservations are made anonymously whenever possible, and our editorial team pays the bill. Advertising, when present, is clearly labeled and kept separate from reviews.</p>
          </details>
          <details class="faq-item">
            <summary>What arrives with a meal plan?</summary>
            <p>You receive a menu, consolidated grocery list, storage guidance, and a chronological prep checklist. Each plan includes at least one flexible night and suggests ways to use leftovers deliberately. You can adapt serving sizes in the Recipe Lab before copying your list.</p>
          </details>
        </div>
      </div>
    </section>

    <section class="newsletter-section" id="newsletter" aria-labelledby="newsletter-title">
      <div class="container">
        <div class="newsletter-card reveal">
          <div class="newsletter-copy">
            <span class="eyebrow">The Thursday Table</span>
            <h2 id="newsletter-title">The best thing in your inbox on Thursday.</h2>
            <p>One seasonal recipe, one genuinely useful technique, and one restaurant worth knowing. Plus first access to new meal plans and market guides. Thoughtful, concise, and free.</p>
          </div>

          <div class="newsletter-form-wrap">
            <form class="newsletter-form" id="newsletterForm">
              <div class="newsletter-fields">
                <div>
                  <label class="visually-hidden" for="newsletterEmail">Email address</label>
                  <input id="newsletterEmail" name="email" type="email" autocomplete="email" placeholder="Your email address" required>
                </div>
                <div>
                  <label class="visually-hidden" for="newsletterInterest">Choose your newsletter or meal plan</label>
                  <select id="newsletterInterest" name="interest">
                    <option value="weekly">Weekly newsletter</option>
                    <option value="weeknight">Weeknight Reset plan</option>
                    <option value="plant">Plant-Forward Week plan</option>
                    <option value="hosting">Weekend Host plan</option>
                  </select>
                </div>
              </div>
              <button class="button button-primary" id="newsletterSubmit" type="submit">Send me something delicious</button>
              <p class="newsletter-consent">No spam, no inbox avalanche. Unsubscribe anytime. By subscribing, you agree to our <button class="inline-legal" type="button" data-legal="privacy">Privacy Policy</button>.</p>
              <p class="plan-hint" id="planHint" hidden></p>
              <p class="form-status" id="newsletterStatus" role="status" hidden></p>
            </form>
          </div>
        </div>
      </div>
    </section>
  </main>

  <footer class="site-footer">
    <div class="container">
      <div class="footer-grid">
        <div class="footer-about">
          <a class="brand" href="#top" aria-label="Savor and Sage home">
            <img class="brand-mark" src="https://placehold.co/72x72/F8F3E8/173F35?text=S%26S&amp;font=montserrat" width="72" height="72" alt="Savor and Sage monogram" loading="lazy">
            <span class="brand-copy">
              <span class="brand-name">Savor &amp; Sage</span>
              <span class="brand-tagline">Cook seasonally. Eat joyfully.</span>
            </span>
          </a>
          <p>Independent recipes, restaurant guides, cooking techniques, and nutrition resources for people who want to eat well and cook with a little more confidence.</p>
          <div class="social-links" aria-label="Social media">
            <a href="https://www.instagram.com/" target="_blank" rel="noopener noreferrer" aria-label="Savor and Sage on Instagram">Instagram</a>
            <a href="https://www.pinterest.com/" target="_blank" rel="noopener noreferrer" aria-label="Savor and Sage on Pinterest">Pinterest</a>
            <a href="https://www.youtube.com/" target="_blank" rel="noopener noreferrer" aria-label="Savor and Sage on YouTube">YouTube</a>
            <a href="https://www.tiktok.com/" target="_blank" rel="noopener noreferrer" aria-label="Savor and Sage on TikTok">TikTok</a>
          </div>
        </div>

        <div class="footer-column">
          <h3>Explore</h3>
          <ul class="footer-links">
            <li><a href="#recipes">Seasonal Recipes</a></li>
            <li><a href="#recipe-lab">Recipe Lab</a></li>
            <li><a href="#meal-plans">Meal Plans</a></li>
            <li><a href="#restaurants">Restaurant Reviews</a></li>
            <li><a href="#guides">Kitchen Guides</a></li>
            <li><a href="#blog">Blog</a></li>
          </ul>
        </div>

        <div class="footer-column">
          <h3>Our Kitchen</h3>
          <ul class="footer-links">
            <li><a href="#guides">Editorial Standards</a></li>
            <li><a href="#restaurants">Review Policy</a></li>
            <li><a href="#meal-plans">Nutrition Approach</a></li>
            <li><a href="#newsletter">Newsletter</a></li>
            <li><a href="mailto:careers@savorandsage.com">Work With Us</a></li>
            <li><button type="button" data-legal="accessibility">Accessibility</button></li>
          </ul>
        </div>

        <div class="footer-column footer-contact">
          <h3>Visit &amp; Write</h3>
          <address>118 Market Lane, Suite 4<br>Portland, OR 97205<br>Monday–Friday, 9 a.m.–5 p.m. PT</address>
          <a href="mailto:hello@savorandsage.com">hello@savorandsage.com</a>
          <a href="tel:+15035550148">+1 (503) 555-0148</a>
        </div>
      </div>

      <div class="footer-bottom">
        <p>© <span id="currentYear">2025</span> Savor &amp; Sage Media. All rights reserved. Made with care in Portland.</p>
        <div class="legal-links">
          <button type="button" data-legal="privacy">Privacy</button>
          <button type="button" data-legal="terms">Terms</button>
          <button type="button" data-legal="cookies">Cookie Policy</button>
        </div>
      </div>
    </div>
  </footer>

  <dialog class="tutorial-dialog" id="tutorialDialog" aria-labelledby="tutorialTitle">
    <button class="dialog-close" type="button" data-close-dialog aria-label="Close tutorial">&times;</button>
    <div class="tutorial-image">
      <img id="tutorialImage" src="https://picsum.photos/seed/asparagus-trim-tutorial/1000/540" alt="Trimming asparagus on a cutting board" width="1000" height="540">
    </div>
    <div class="dialog-body">
      <div class="tutorial-topline">
        <span id="tutorialProgress">Step 1 of 3 · Interactive tutorial</span>
        <div class="tutorial-dots" aria-label="Tutorial steps">
          <button class="tutorial-dot" type="button" data-step="0" aria-label="Go to step 1" aria-current="step"></button>
          <button class="tutorial-dot" type="button" data-step="1" aria-label="Go to step 2"></button>
          <button class="tutorial-dot" type="button" data-step="2" aria-label="Go to step 3"></button>
        </div>
      </div>
      <h2 id="tutorialTitle">Trim with intention</h2>
      <p id="tutorialText">Bend one spear until it naturally snaps, then line it up with the bunch and trim the remaining ends to the same point. Keep the trimmings for stock, but skip the woody ends if they are dry or hollow.</p>
      <div class="tutorial-nav">
        <button class="button button-outline" id="tutorialPrev" type="button" disabled>Previous step</button>
        <button class="button button-dark" id="tutorialNext" type="button">Next step</button>
      </div>
    </div>
  </dialog>

  <dialog class="reservation-dialog" id="reservationDialog" aria-labelledby="reservationTitle">
    <button class="dialog-close" type="button" data-close-dialog aria-label="Close reservation form">&times;</button>
    <div class="dialog-body">
      <div id="reservationFormView">
        <span class="eyebrow">Your table awaits</span>
        <h2 id="reservationTitle">Request a reservation</h2>
        <p>Choose your preferred date and time. The restaurant will confirm availability directly by email.</p>
        <form class="reservation-form" id="reservationForm">
          <div class="form-grid">
            <div class="form-field full">
              <label for="reservationRestaurant">Restaurant</label>
              <select id="reservationRestaurant" name="restaurant" required>
                <option value="Juniper & Rye">Juniper &amp; Rye · New York</option>
                <option value="Kado">Kado · Chicago</option>
                <option value="Loma">Loma · Los Angeles</option>
              </select>
            </div>
            <div class="form-field">
              <label for="reservationDate">Date</label>
              <input id="reservationDate" name="date" type="date" required>
            </div>
            <div class="form-field">
              <label for="reservationTime">Preferred time</label>
              <select id="reservationTime" name="time" required>
                <option value="5:30 PM">5:30 PM</option>
                <option value="6:00 PM">6:00 PM</option>
                <option value="6:30 PM">6:30 PM</option>
                <option value="7:00 PM" selected>7:00 PM</option>
                <option value="7:30 PM">7:30 PM</option>
                <option value="8:00 PM">8:00 PM</option>
                <option value="8:30 PM">8:30 PM</option>
              </select>
            </div>
            <div class="form-field">
              <label for="reservationGuests">Party size</label>
              <select id="reservationGuests" name="guests" required>
                <option value="1">1 guest</option>
                <option value="2" selected>2 guests</option>
                <option value="3">3 guests</option>
                <option value="4">4 guests</option>
                <option value="5">5 guests</option>
                <option value="6">6 guests</option>
                <option value="7+">7+ guests</option>
              </select>
            </div>
            <div class="form-field">
              <label for="reservationName">Name</label>
              <input id="reservationName" name="name" type="text" autocomplete="name" placeholder="Full name" required>
            </div>
            <div class="form-field full">
              <label for="reservationEmail">Email address</label>
              <input id="reservationEmail" name="email" type="email" autocomplete="email" placeholder="you@example.com" required>
            </div>
          </div>
          <button class="button button-primary" type="submit">Make Reservation</button>
          <p class="form-fine-print">This is a reservation request, not an instant confirmation. For parties of seven or more, the restaurant may contact you for additional details.</p>
        </form>
      </div>

      <div class="reservation-success" id="reservationSuccess" hidden>
        <div class="success-icon" aria-hidden="true">✓</div>
        <h3>Request received.</h3>
        <p id="reservationSuccessText"></p>
        <span class="confirmation-code" id="confirmationCode"></span>
        <br>
        <button class="button button-dark" type="button" data-close-dialog>Done</button>
      </div>
    </div>
  </dialog>

  <dialog class="article-dialog" id="articleDialog" aria-labelledby="articleDialogTitle">
    <button class="dialog-close" type="button" data-close-dialog aria-label="Close article">&times;</button>
    <div class="article-dialog-image"><img id="articleDialogImage" src="https://picsum.photos/seed/savor-pan-sauce/1000/500" alt="" width="1000" height="500"></div>
    <article class="article-dialog-content">
      <span class="eyebrow" id="articleDialogKicker">Technique · 6 min read</span>
      <h2 id="articleDialogTitle">The Five-Minute Pan Sauce</h2>
      <div class="article-body" id="articleDialogBody"></div>
      <div class="article-signoff">Filed from the Savor &amp; Sage test kitchen · Cook well, waste less.</div>
    </article>
  </dialog>

  <dialog class="legal-dialog" id="legalDialog" aria-labelledby="legalDialogTitle">
    <button class="dialog-close" type="button" data-close-dialog aria-label="Close legal information">&times;</button>
    <div class="dialog-body">
      <span class="eyebrow">Savor &amp; Sage</span>
      <h2 id="legalDialogTitle">Privacy Policy</h2>
      <div class="legal-content" id="legalDialogBody"></div>
    </div>
  </dialog>

  <div class="toast" id="toast" role="status" aria-live="polite"></div>

  <button class="back-to-top" id="backToTop" type="button" aria-label="Back to top">↑</button>

  <script>
    document.addEventListener('DOMContentLoaded', function () {
      const $ = (selector, scope = document) => scope.querySelector(selector);
      const $$ = (selector, scope = document) => Array.from(scope.querySelectorAll(selector));

      const toast = $('#toast');
      let toastTimer;

      function showToast(message) {
        clearTimeout(toastTimer);
        toast.textContent = message;
        toast.classList.add('show');
        toastTimer = setTimeout(() => toast.classList.remove('show'), 3200);
      }

      $('#currentYear').textContent = new Date().getFullYear();

      const siteHeader = $('#siteHeader');
      const backToTop = $('#backToTop');

      function handleScroll() {
        siteHeader.classList.toggle('scrolled', window.scrollY > 18);
        backToTop.classList.toggle('visible', window.scrollY > 850);
        toast.classList.toggle('show', toast.classList.contains('show') && window.scrollY < 850 ? true : toast.classList.contains('show'));
      }

      window.addEventListener('scroll', handleScroll, { passive: true });
      handleScroll();

      backToTop.addEventListener('click', () => {
        window.scrollTo({ top: 0, behavior: 'smooth' });
      });

      const menuToggle = $('#menuToggle');
      const primaryNav = $('#primaryNav');

      function closeMenu() {
        primaryNav.classList.remove('is-open');
        menuToggle.setAttribute('aria-expanded', 'false');
        menuToggle.setAttribute('aria-label', 'Open navigation');
      }

      menuToggle.addEventListener('click', () => {
        const open = menuToggle.getAttribute('aria-expanded') === 'true';
        primaryNav.classList.toggle('is-open', !open);
        menuToggle.setAttribute('aria-expanded', String(!open));
        menuToggle.setAttribute('aria-label', open ? 'Open navigation' : 'Close navigation');
      });

      $$('.nav-link', primaryNav).forEach(link => link.addEventListener('click', closeMenu));

      document.addEventListener('click', event => {
        if (primaryNav.classList.contains('is-open') && !siteHeader.contains(event.target)) closeMenu();
      });

      document.addEventListener('keydown', event => {
        if (event.key === 'Escape') closeMenu();
      });

      window.addEventListener('resize', () => {
        if (window.innerWidth > 960) closeMenu();
      });

      const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
      const revealItems = $$('.reveal');

      if (!reducedMotion && 'IntersectionObserver' in window) {
        const revealObserver = new IntersectionObserver(entries => {
          entries.forEach(entry => {
            if (entry.isIntersecting) {
              entry.target.classList.add('is-visible');
              revealObserver.unobserve(entry.target);
            }
          });
        }, { threshold: 0.09, rootMargin: '0px 0px -35px' });

        revealItems.forEach(item => revealObserver.observe(item));
      } else {
        revealItems.forEach(item => item.classList.add('is-visible'));
      }

      if ('IntersectionObserver' in window) {
        const navLinks = $$('.nav-link', primaryNav);
        const observedSections = navLinks.map(link => $(link.getAttribute('href'))).filter(Boolean);
        const sectionObserver = new IntersectionObserver(entries => {
          entries.forEach(entry => {
            if (entry.isIntersecting) {
              navLinks.forEach(link => {
                const active = link.getAttribute('href') === '#' + entry.target.id;
                link.classList.toggle('active', active);
                if (active) link.setAttribute('aria-current', 'location');
                else link.removeAttribute('aria-current');
              });
            }
          });
        }, { rootMargin: '-30% 0px -60% 0px', threshold: 0 });

        observedSections.forEach(section => sectionObserver.observe(section));
      }

      const filterButtons = $$('.filter-button');
      const recipeCards = $$('.recipe-card');
      const filterStatus = $('#filterStatus');

      filterButtons.forEach(button => {
        button.addEventListener('click', () => {
          const filter = button.dataset.filter;
          let visibleCount = 0;

          filterButtons.forEach(item => {
            const active = item === button;
            item.classList.toggle('is-active', active);
            item.setAttribute('aria-pressed', String(active));
          });

          recipeCards.forEach(card => {
            const categories = card.dataset.category.split(' ');
            const visible = filter === 'all' || categories.includes(filter);
            card.hidden = !visible;
            if (visible) visibleCount++;
          });

          filterStatus.textContent = `Showing ${visibleCount} seasonal recipe${visibleCount === 1 ? '' : 's'}`;
        });
      });

      let savedRecipes = [];
      try {
        savedRecipes = JSON.parse(localStorage.getItem('savorSageSaved') || '[]');
        if (!Array.isArray(savedRecipes)) savedRecipes = [];
      } catch (error) {
        savedRecipes = [];
      }

      $$('.save-recipe').forEach(button => {
        const slug = button.dataset.save;
        button.setAttribute('aria-pressed', String(savedRecipes.includes(slug)));

        button.addEventListener('click', () => {
          const isSaved = button.getAttribute('aria-pressed') === 'true';
          button.setAttribute('aria-pressed', String(!isSaved));

          if (isSaved) savedRecipes = savedRecipes.filter(item => item !== slug);
          else if (!savedRecipes.includes(slug)) savedRecipes.push(slug);

          try {
            localStorage.setItem('savorSageSaved', JSON.stringify(savedRecipes));
          } catch (error) {
            // Saving remains available for this session when storage is blocked.
          }

          const recipeName = button.getAttribute('aria-label').replace(/^Save\s+/, '');
          showToast(isSaved ? `${recipeName} removed from saved recipes.` : `${recipeName} saved for later.`);
        });
      });

      const recipes = {
        salmon: {
          title: 'Charred Citrus Salmon',
          base: 4,
          time: '25 minutes',
          level: 'Confident beginner',
          nutrition: '≈ 540 kcal · 39 g protein',
          description: 'Crisp-skinned salmon with caramelized citrus, soft herbs, and a quick miso pan reduction.',
          note: 'Dry the salmon thoroughly and leave it undisturbed in the pan. For larger yields, sear in batches rather than crowding and steaming the fillets.',
          ingredients: [
            { us: 4, metric: 4, usUnit: '', metricUnit: '', name: 'salmon fillets, about 6 oz / 170 g each' },
            { us: 2, metric: 2, usUnit: '', metricUnit: '', name: 'oranges, one sliced and one juiced' },
            { us: 2, metric: 34, usUnit: 'tbsp', metricUnit: 'g', name: 'white miso' },
            { us: 1, metric: 20, usUnit: 'tbsp', metricUnit: 'g', name: 'honey' },
            { us: 2, metric: 30, usUnit: 'tbsp', metricUnit: 'ml', name: 'soy sauce' },
            { us: 1, metric: 15, usUnit: 'tbsp', metricUnit: 'ml', name: 'rice vinegar' },
            { us: 0.5, metric: 15, usUnit: 'cup', metricUnit: 'g', name: 'soft herbs, such as dill and mint' }
          ],
          steps: [
            'Season and dry the salmon; mix the citrus glaze.',
            'Sear skin-side down until crisp, then turn and char the citrus.',
            'Build the reduction in the pan and spoon over the fish.'
          ]
        },
        risotto: {
          title: 'Asparagus & Lemon Risotto',
          base: 4,
          time: '45 minutes',
          level: 'Intermediate',
          nutrition: '≈ 510 kcal · 15 g protein',
          description: 'Loose, lemony risotto with asparagus two ways, Parmesan, and a clean vegetable stock.',
          note: 'The finished risotto should ripple when the pan is shaken. Hold back a little stock; larger batches can need slightly less liquid per portion because there is less evaporation.',
          ingredients: [
            { us: 1.5, metric: 300, usUnit: 'cup', metricUnit: 'g', name: 'Arborio rice' },
            { us: 5, metric: 1.2, usUnit: 'cup', metricUnit: 'L', name: 'warm vegetable stock, plus more as needed' },
            { us: 1, metric: 450, usUnit: 'lb', metricUnit: 'g', name: 'asparagus, tips and stems separated' },
            { us: 0.5, metric: 120, usUnit: 'cup', metricUnit: 'ml', name: 'dry white wine' },
            { us: 0.5, metric: 50, usUnit: 'cup', metricUnit: 'g', name: 'finely grated Parmesan' },
            { us: 2, metric: 30, usUnit: 'tbsp', metricUnit: 'g', name: 'cold unsalted butter, cubed' },
            { us: 1, metric: 1, usUnit: '', metricUnit: '', name: 'unwaxed lemon, zested and juiced' }
          ],
          steps: [
            'Simmer the asparagus stems in stock; blanch and chill the tips.',
            'Toast the rice, deglaze with wine, and add warm stock gradually.',
            'Mantecare with butter and Parmesan; fold in asparagus and lemon.'
          ]
        },
        pasta: {
          title: 'Spring Pea & Ricotta Pasta',
          base: 4,
          time: '20 minutes',
          level: 'Easy',
          nutrition: '≈ 480 kcal · 18 g protein',
          description: 'A fast, silky pasta with sweet peas, lemony ricotta, garlic, and torn mint.',
          note: 'Reserve more pasta water than you think you need. Ricotta thickens as it sits, so loosen the sauce just before plating and serve in warmed bowls.',
          ingredients: [
            { us: 12, metric: 340, usUnit: 'oz', metricUnit: 'g', name: 'short pasta, such as rigatoni or shells' },
            { us: 2, metric: 300, usUnit: 'cup', metricUnit: 'g', name: 'frozen or fresh sweet peas' },
            { us: 2, metric: 30, usUnit: 'tbsp', metricUnit: 'ml', name: 'extra-virgin olive oil' },
            { us: 2, metric: 2, usUnit: '', metricUnit: '', name: 'garlic cloves, finely grated' },
            { us: 0.5, metric: 120, usUnit: 'cup', metricUnit: 'g', name: 'whole-milk ricotta' },
            { us: 1, metric: 1, usUnit: '', metricUnit: '', name: 'unwaxed lemon, zested and juiced' },
            { us: 0.25, metric: 10, usUnit: 'cup', metricUnit: 'g', name: 'tender mint leaves, torn' }
          ],
          steps: [
            'Boil the pasta in well-salted water; add peas for the final two minutes.',
            'Warm garlic in olive oil, then whisk ricotta with pasta water and lemon.',
            'Toss everything off the heat until glossy; finish with mint and black pepper.'
          ]
        },
        buns: {
          title: 'Miso Mushroom Steam Buns',
          base: 4,
          time: '75 minutes',
          level: 'Weekend project',
          nutrition: '≈ 430 kcal · 13 g protein',
          description: 'Pillowy buns filled with deeply browned miso mushrooms, sesame cabbage, and fresh herbs.',
          note: 'Brown the mushrooms in batches so their moisture evaporates quickly. The glaze should coat them lightly; a long reduction will make the filling salty and sticky.',
          ingredients: [
            { us: 8, metric: 8, usUnit: '', metricUnit: '', name: 'frozen or fresh bao buns' },
            { us: 1.5, metric: 680, usUnit: 'lb', metricUnit: 'g', name: 'mixed mushrooms, thickly sliced' },
            { us: 2, metric: 35, usUnit: 'tbsp', metricUnit: 'g', name: 'white or yellow miso' },
            { us: 1, metric: 15, usUnit: 'tbsp', metricUnit: 'ml', name: 'soy sauce or tamari' },
            { us: 1, metric: 15, usUnit: 'tbsp', metricUnit: 'ml', name: 'mirin' },
            { us: 2, metric: 10, usUnit: 'tsp', metricUnit: 'ml', name: 'toasted sesame oil' },
            { us: 2, metric: 150, usUnit: 'cup', metricUnit: 'g', name: 'finely shredded cabbage' }
          ],
          steps: [
            'Brown mushrooms in batches, then combine with miso, soy, and mirin.',
            'Steam the buns until puffed and toss cabbage with sesame oil.',
            'Fill, garnish with herbs, and serve immediately while the buns are soft.'
          ]
        }
      };

      const recipeSelect = $('#recipeSelect');
      const servingOutput = $('#servingOutput');
      const ingredientList = $('#ingredientList');
      let currentRecipeKey = 'salmon';
      let currentServings = recipes.salmon.base;
      let currentUnit = 'us';

      function formatQuantity(value, unit) {
        if (unit === 'g' || unit === 'ml') {
          const step = value >= 250 ? 10 : value >= 50 ? 5 : 1;
          return String(Math.max(step, Math.round(value / step) * step));
        }

        if (unit === 'L') {
          return String(Math.round(value * 10) / 10);
        }

        const rounded = Math.max(0.25, Math.round(value * 4) / 4);
        const whole = Math.floor(rounded);
        const fraction = Math.round((rounded - whole) * 4);
        const fractions = { 1: '¼', 2: '½', 3: '¾' };

        if (fraction === 0) return String(whole);
        if (whole === 0) return fractions[fraction];
        return `${whole}${fractions[fraction]}`;
      }

      function getIngredientParts(ingredient) {
        const recipe = recipes[currentRecipeKey];
        const rawAmount = currentUnit === 'metric' ? ingredient.metric : ingredient.us;
        const scaledAmount = rawAmount * currentServings / recipe.base;
        let unit = currentUnit === 'metric' ? ingredient.metricUnit : ingredient.usUnit;

        if (unit === 'cup') unit = Math.abs(scaledAmount - 1) < 0.001 ? 'cup' : 'cups';

        return {
          quantity: formatQuantity(scaledAmount, unit),
          unit,
          amount: `${formatQuantity(scaledAmount, unit)}${unit ? ' ' + unit : ''}`,
          name: ingredient.name
        };
      }

      function updatePrepProgress() {
        const boxes = $$('input[type="checkbox"]', ingredientList);
        const checked = boxes.filter(box => box.checked).length;
        $('#prepCount').textContent = `${checked} / ${boxes.length} prepped`;
        $('#prepProgress').style.width = boxes.length ? `${checked / boxes.length * 100}%` : '0%';
      }

      function renderIngredients(preserveChecks = false) {
        const checkedIndexes = preserveChecks
          ? $$('input[type="checkbox"]', ingredientList).map((box, index) => box.checked ? index : -1).filter(index => index >= 0)
          : [];

        const recipe = recipes[currentRecipeKey];
        ingredientList.innerHTML = recipe.ingredients.map((ingredient, index) => {
          const parts = getIngredientParts(ingredient);
          const checked = checkedIndexes.includes(index) ? ' checked' : '';
          return `<li><label><input type="checkbox"${checked}><span class="ingredient-amount">${parts.amount}</span><span class="ingredient-name">${parts.name}</span></label></li>`;
        }).join('');

        $('#yieldLabel').textContent = `For ${currentServings} serving${currentServings === 1 ? '' : 's'} · ${currentUnit === 'metric' ? 'Metric' : 'US'} measurements`;
        updatePrepProgress();
      }

      function renderRecipe() {
        const recipe = recipes[currentRecipeKey];
        recipeSelect.value = currentRecipeKey;
        $('#recipeDescription').textContent = recipe.description;
        $('#recipeTime').textContent = recipe.time;
        $('#recipeLevel').textContent = recipe.level;
        $('#recipeNutrition').textContent = recipe.nutrition;
        $('#recipeNote').textContent = recipe.note;
        servingOutput.textContent = `${currentServings} serving${currentServings === 1 ? '' : 's'}`;
        $('#methodList').innerHTML = recipe.steps.map(step => `<li>${step}</li>`).join('');
        renderIngredients(false);
      }

      function changeServings(delta) {
        const next = Math.min(12, Math.max(1, currentServings + delta));
        if (next === currentServings) {
          showToast(next === 12 ? 'The Recipe Lab scales up to 12 servings.' : 'The minimum yield is 1 serving.');
          return;
        }
        currentServings = next;
        servingOutput.textContent = `${currentServings} serving${currentServings === 1 ? '' : 's'}`;
        renderIngredients(true);
      }

      $('#decreaseServings').addEventListener('click', () => changeServings(-1));
      $('#increaseServings').addEventListener('click', () => changeServings(1));

      recipeSelect.addEventListener('change', () => {
        currentRecipeKey = recipeSelect.value;
        currentServings = recipes[currentRecipeKey].base;
        renderRecipe();
      });

      $$('.unit-toggle button').forEach(button => {
        button.addEventListener('click', () => {
          currentUnit = button.dataset.unit;
          $$('.unit-toggle button').forEach(item => {
            const active = item === button;
            item.classList.toggle('is-active', active);
            item.setAttribute('aria-pressed', String(active));
          });
          renderIngredients(true);
        });
      });

      ingredientList.addEventListener('change', updatePrepProgress);

      $$('.recipe-open').forEach(link => {
        link.addEventListener('click', () => {
          const key = link.dataset.recipe;
          if (!recipes[key]) return;
          currentRecipeKey = key;
          currentServings = recipes[key].base;
          renderRecipe();
        });
      });

      function ingredientTextLines() {
        return recipes[currentRecipeKey].ingredients.map(ingredient => {
          const parts = getIngredientParts(ingredient);
          return `${parts.amount} ${parts.name}`;
        });
      }

      async function copyText(text) {
        if (navigator.clipboard && window.isSecureContext) {
          await navigator.clipboard.writeText(text);
          return;
        }

        const textarea = document.createElement('textarea');
        textarea.value = text;
        textarea.style.position = 'fixed';
        textarea.style.opacity = '0';
        document.body.appendChild(textarea);
        textarea.select();
        const successful = document.execCommand('copy');
        textarea.remove();
        if (!successful) throw new Error('Copy failed');
      }

      $('#copyIngredients').addEventListener('click', async () => {
        const recipe = recipes[currentRecipeKey];
        const text = `${recipe.title}\n${currentServings} serving${currentServings === 1 ? '' : 's'}\n\n${ingredientTextLines().map(line => '• ' + line).join('\n')}\n\nFrom Savor & Sage`;
        const button = $('#copyIngredients');

        try {
          await copyText(text);
          const original = button.textContent;
          button.textContent = 'Copied to clipboard';
          showToast('Ingredient list copied. Your market run just got easier.');
          setTimeout(() => { button.textContent = original; }, 2200);
        } catch (error) {
          showToast('Could not access the clipboard. Select the ingredients and copy them manually.');
        }
      });

      function escapeHTML(value) {
        return String(value).replace(/[&<>"']/g, character => ({
          '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;'
        })[character]);
      }

      $('#printRecipe').addEventListener('click', () => {
        const recipe = recipes[currentRecipeKey];
        const printWindow = window.open('', '_blank', 'width=760,height=860');

        if (!printWindow) {
          showToast('Allow pop-ups to open the print-friendly recipe.');
          return;
        }

        const ingredients = ingredientTextLines().map(line => `<li>${escapeHTML(line)}</li>`).join('');
        const steps = recipe.steps.map(step => `<li>${escapeHTML(step)}</li>`).join('');

        printWindow.document.write(`<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>${escapeHTML(recipe.title)} — Savor & Sage</title><style>body{max-width:700px;margin:45px auto;padding:0 24px;color:#20312b;font:15px/1.7 Arial,sans-serif}h1,h2{font-family:Georgia,serif;color:#173f35}h1{font-size:38px;line-height:1.1}h2{margin-top:30px;font-size:22px}ul,ol{padding-left:22px}li{margin-bottom:8px}.meta{padding-bottom:18px;border-bottom:1px solid #ccc;color:#66736c}.note{padding:14px;background:#f1f3ec}.footer{margin-top:35px;padding-top:15px;border-top:1px solid #ccc;font-size:12px;color:#66736c}@media print{body{margin:0}}</style></head><body><h1>${escapeHTML(recipe.title)}</h1><p>${escapeHTML(recipe.description)}</p><p class="meta">${currentServings} serving${currentServings === 1 ? '' : 's'} · ${escapeHTML(recipe.time)} · ${escapeHTML(recipe.level)}<br>${escapeHTML(recipe.nutrition)} per serving</p><h2>Ingredients</h2><ul>${ingredients}</ul><h2>Method</h2><ol>${steps}</ol><p class="note"><strong>Chef’s note:</strong> ${escapeHTML(recipe.note)}</p><p class="footer">Savor & Sage · Cook seasonally. Eat joyfully.</p></body></html>`);
        printWindow.document.close();
        printWindow.focus();
        setTimeout(() => printWindow.print(), 300);
      });

      renderRecipe();

      function openDialog(dialog) {
        if (typeof dialog.showModal === 'function') dialog.showModal();
        else dialog.setAttribute('open', '');
        document.body.classList.add('modal-open');
      }

      function closeDialog(dialog) {
        if (typeof dialog.close === 'function') dialog.close();
        else dialog.removeAttribute('open');
      }

      $$('dialog').forEach(dialog => {
        dialog.addEventListener('close', () => {
          if (!$('dialog[open]')) document.body.classList.remove('modal-open');
        });

        dialog.addEventListener('click', event => {
          const rect = dialog.getBoundingClientRect();
          const outside = event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom;
          if (outside) closeDialog(dialog);
        });
      });

      $$('[data-close-dialog]').forEach(button => {
        button.addEventListener('click', () => closeDialog(button.closest('dialog')));
      });

      const tutorialDialog = $('#tutorialDialog');
      const tutorialSteps = [
        {
          title: 'Trim with intention',
          text: 'Bend one spear until it naturally snaps, then line it up with the bunch and trim the remaining ends to the same point. Keep the trimmings for stock, but skip the woody ends if they are dry or hollow.',
          image: 'https://picsum.photos/seed/asparagus-trim-tutorial/1000/540',
          alt: 'Trimming asparagus on a cutting board'
        },
        {
          title: 'Build a hot, wide pan',
          text: 'Heat a heavy skillet until a drop of water skitters across it. Add a thin film of oil and arrange the spears in one layer. Leave them alone for two minutes so they blister before turning; crowding will trap steam and soften the exterior.',
          image: 'https://picsum.photos/seed/asparagus-hot-pan/1000/540',
          alt: 'Asparagus spears blistering in a wide skillet'
        },
        {
          title: 'Finish with acid and texture',
          text: 'Season with salt, add a small knob of butter, and remove the pan from the heat. Finish with lemon zest, a measured squeeze of juice, and toasted seeds. Add acid off the heat to preserve its aroma and keep the spears vividly green.',
          image: 'https://picsum.photos/seed/asparagus-finish-plating/1000/540',
          alt: 'Finished asparagus plated with lemon and toasted seeds'
        }
      ];
      let tutorialIndex = 0;

      function renderTutorialStep() {
        const step = tutorialSteps[tutorialIndex];
        $('#tutorialTitle').textContent = step.title;
        $('#tutorialText').textContent = step.text;
        $('#tutorialImage').src = step.image;
        $('#tutorialImage').alt = step.alt;
        $('#tutorialProgress').textContent = `Step ${tutorialIndex + 1} of ${tutorialSteps.length} · Interactive tutorial`;
        $('#tutorialPrev').disabled = tutorialIndex === 0;
        $('#tutorialNext').textContent = tutorialIndex === tutorialSteps.length - 1 ? 'Finish tutorial' : 'Next step';

        $$('.tutorial-dot').forEach((dot, index) => {
          if (index === tutorialIndex) dot.setAttribute('aria-current', 'step');
          else dot.removeAttribute('aria-current');
        });
      }

      $('#openTutorial').addEventListener('click', () => {
        tutorialIndex = 0;
        renderTutorialStep();
        openDialog(tutorialDialog);
      });

      $('#tutorialPrev').addEventListener('click', () => {
        if (tutorialIndex > 0) {
          tutorialIndex--;
          renderTutorialStep();
        }
      });

      $('#tutorialNext').addEventListener('click', () => {
        if (tutorialIndex < tutorialSteps.length - 1) {
          tutorialIndex++;
          renderTutorialStep();
        } else {
          closeDialog(tutorialDialog);
          showToast('Tutorial complete. Your asparagus is ready for the pan.');
        }
      });

      $$('.tutorial-dot').forEach(dot => {
        dot.addEventListener('click', () => {
          tutorialIndex = Number(dot.dataset.step);
          renderTutorialStep();
        });
      });

      const reservationDialog = $('#reservationDialog');
      const reservationForm = $('#reservationForm');
      const reservationDate = $('#reservationDate');
      const localToday = new Date();
      localToday.setMinutes(localToday.getMinutes() - localToday.getTimezoneOffset());
      reservationDate.min = localToday.toISOString().split('T')[0];

      $$('.reserve-button').forEach(button => {
        button.addEventListener('click', () => {
          $('#reservationRestaurant').value = button.dataset.restaurant;
          $('#reservationFormView').hidden = false;
          $('#reservationSuccess').hidden = true;

          if (!reservationDate.value) {
            const tomorrow = new Date();
            tomorrow.setDate(tomorrow.getDate() + 1);
            tomorrow.setMinutes(tomorrow.getMinutes() - tomorrow.getTimezoneOffset());
            reservationDate.value = tomorrow.toISOString().split('T')[0];
          }

          openDialog(reservationDialog);
        });
      });

      reservationForm.addEventListener('submit', event => {
        event.preventDefault();
        const data = new FormData(reservationForm);
        const date = new Date(`${data.get('date')}T12:00:00`);
        const formattedDate = new Intl.DateTimeFormat('en-US', { weekday: 'long', month: 'long', day: 'numeric' }).format(date);
        const reference = 'SS-' + Math.random().toString(36).slice(2, 7).toUpperCase();

        $('#reservationSuccessText').textContent = `${data.get('restaurant')} has received your request for ${data.get('guests')} ${data.get('guests') === '1' ? 'guest' : 'guests'} on ${formattedDate} at ${data.get('time')}. A confirmation will be sent to ${data.get('email')}.`;
        $('#confirmationCode').textContent = `Request ${reference}`;
        $('#reservationFormView').hidden = true;
        $('#reservationSuccess').hidden = false;
      });

      reservationDialog.addEventListener('close', () => {
        setTimeout(() => {
          reservationForm.reset();
          reservationDate.value = '';
          $('#reservationFormView').hidden = false;
          $('#reservationSuccess').hidden = true;
        }, 200);
      });

      const articles = {
        'pan-sauce': {
          title: 'The Five-Minute Pan Sauce',
          kicker: 'Technique · 6 min read',
          image: 'https://picsum.photos/seed/savor-pan-sauce/1000/500',
          alt: 'A glossy pan sauce being whisked in a skillet',
          paragraphs: [
            'The best part of a seared chicken thigh may be what stays in the pan. Those mahogany fragments—called fond—are concentrated juices and proteins that have browned against the metal. Once you know how to release them, a restaurant-worthy sauce is rarely more than five minutes away.',
            'Start by pouring off excess fat, leaving about a tablespoon along with the fond. Add a finely chopped shallot over medium heat and stir just until translucent. If the fond is getting darker too quickly, lower the heat; burned fond turns bitter, and no amount of butter will rescue it.',
            'Deglaze with a splash of wine, stock, or even water, scraping with a wooden spoon. Let the liquid reduce by about half, then add enough stock to surround rather than drown your main ingredient. Simmer until the sauce coats a spoon lightly. This is a reduction: flavor becomes concentrated as water evaporates.',
            'Take the pan off the heat before swirling in cold butter, a piece at a time. The sauce should turn glossy, not greasy. Taste before salting, especially if your stock was seasoned. Finish with lemon juice or vinegar, then spoon around your plating so crisp skin stays crisp.'
          ]
        },
        market: {
          title: 'Shop the Market Without a List',
          kicker: 'Market Notes · 8 min read',
          image: 'https://picsum.photos/seed/savor-market-without-list/1000/500',
          alt: 'Seasonal produce arranged at a farmers market',
          paragraphs: [
            'A rigid shopping list can be a disadvantage at the farmers market. The spinach may be tired, the first strawberries may cost more than dinner, and the farmer with the best-looking fennel may not have appeared on your plan. Shopping well begins with a framework rather than a fixed set of ingredients.',
            'Walk the entire market before buying anything. Look for produce that seems abundant, not merely photogenic; abundance often means peak flavor and a better price. Choose one anchor vegetable, one leafy green, one aromatic such as spring onions or herbs, and something that brings acidity. Add protein or a cooked grain from your pantry later.',
            'Think in three overlapping meals before you reach the register. A bunch of asparagus might become a frittata, a risotto garnish, and a quick side with brown butter. Herbs can season all three, but only if you store them properly when you get home. This is household mise en place: organize the week before the week organizes you.',
            'Finally, leave room for one unreasonable purchase—the vegetable you cannot identify or the cheese with no place in your plan. Curiosity is part of cooking. Ask the grower how they use it, buy a modest amount, and let that ingredient teach you something new.'
          ]
        },
        salt: {
          title: 'How to Salt in Layers',
          kicker: 'Kitchen Science · 5 min read',
          image: 'https://picsum.photos/seed/savor-season-in-layers/1000/500',
          alt: 'A cook seasoning vegetables during preparation',
          paragraphs: [
            'Salt does more than make food taste salty. Used at the right moment, it changes texture, draws out moisture, softens bitterness, and helps aromatics release their fragrance. A final sprinkle can improve a dish, but it cannot fully replicate seasoning built throughout the cooking process.',
            'For vegetables headed into a hot pan, season just before cooking unless a recipe specifically calls for salting ahead. Early salting draws water to the surface, which can delay browning. Eggplant and cabbage are exceptions when you deliberately want to remove moisture; give them time, then pat or squeeze them dry.',
            'Pasta water should taste pleasantly seasoned, not aggressively briny. The exact amount depends on the salt’s crystal size, which is why a pinch is not a reliable universal measure. Taste the water, reserve a cup before draining, and remember that the starchy liquid will also season your sauce.',
            'Finish with a clean, bright salt only when the texture matters. Flaky salt on a tomato salad or chocolate cookie provides small bursts rather than uniform seasoning. Taste after resting, after reduction, and again after adding acid. Good seasoning is a sequence of small decisions, not one dramatic gesture.'
          ]
        }
      };

      const articleDialog = $('#articleDialog');

      $$('.article-open').forEach(button => {
        button.addEventListener('click', () => {
          const article = articles[button.dataset.article];
          if (!article) return;
          $('#articleDialogTitle').textContent = article.title;
          $('#articleDialogKicker').textContent = article.kicker;
          $('#articleDialogImage').src = article.image;
          $('#articleDialogImage').alt = article.alt;
          $('#articleDialogBody').innerHTML = article.paragraphs.map(paragraph => `<p>${paragraph}</p>`).join('');
          articleDialog.scrollTop = 0;
          openDialog(articleDialog);
        });
      });

      const legalContent = {
        privacy: {
          title: 'Privacy Policy',
          body: '<p>Savor & Sage collects only the information needed to provide the services you request, such as an email address for a newsletter or contact details for a reservation request. We do not sell personal information.</p><h3>How we use information</h3><p>Information is used to deliver requested content, respond to messages, maintain site security, and understand aggregate readership trends. Newsletter consent can be withdrawn at any time using the unsubscribe link.</p><h3>Your choices</h3><p>You may request access, correction, or deletion of your information by emailing privacy@savorandsage.com. Reservation details are governed by the relevant restaurant’s own privacy practices once your request is transmitted.</p>'
        },
        terms: {
          title: 'Terms of Use',
          body: '<p>By using Savor & Sage, you agree to use the site lawfully and to evaluate recipes, nutrition estimates, and restaurant information using your own judgment. Content is provided for general informational purposes.</p><h3>Recipes and health</h3><p>Cooking times and results vary with equipment and ingredients. Follow safe food-handling practices and account for allergies and individual dietary needs. Nutrition information is estimated and is not medical advice.</p><h3>Editorial content</h3><p>Articles, recipes, photography, and branding are protected by applicable intellectual-property laws. You may print recipes for personal use; republication or commercial redistribution requires written permission.</p>'
        },
        cookies: {
          title: 'Cookie Policy',
          body: '<p>Savor & Sage uses essential browser storage to remember practical preferences such as saved recipes. We aim to keep tracking minimal and do not use saved-recipe data to build advertising profiles.</p><h3>Analytics and embedded services</h3><p>Privacy-respecting aggregate analytics may help us understand which guides are useful. External font, image, or social-media services may receive technical request information under their own policies.</p><h3>Managing storage</h3><p>You can clear saved data through your browser settings. Doing so may remove saved recipes and other preferences, but the rest of the site will remain available.</p>'
        },
        accessibility: {
          title: 'Accessibility Commitment',
          body: '<p>Savor & Sage is designed for readers using keyboards, screen readers, zoom, reduced-motion settings, and a range of screen sizes. We regularly review contrast, semantic structure, labels, focus states, and interaction patterns.</p><h3>Ongoing improvements</h3><p>Accessibility is an ongoing editorial and engineering practice. If a recipe control, review, document, or other feature creates a barrier, we want to know.</p><h3>Contact us</h3><p>Email accessibility@savorandsage.com with the page, issue, and assistive technology you are using. We will make reasonable efforts to provide the information in an accessible format and address the underlying problem.</p>'
        }
      };

      const legalDialog = $('#legalDialog');

      $$('[data-legal]').forEach(button => {
        button.addEventListener('click', () => {
          const content = legalContent[button.dataset.legal];
          if (!content) return;
          $('#legalDialogTitle').textContent = content.title;
          $('#legalDialogBody').innerHTML = content.body;
          openDialog(legalDialog);
        });
      });

      const faqItems = $$('.faq-item');
      faqItems.forEach(item => {
        item.addEventListener('toggle', () => {
          if (item.open) faqItems.forEach(other => {
            if (other !== item) other.open = false;
          });
        });
      });

      $$('.plan-select').forEach(link => {
        link.addEventListener('click', () => {
          $('#newsletterInterest').value = link.dataset.plan;
          const hint = $('#planHint');
          hint.textContent = `${link.dataset.name} is selected. Enter your email above and we’ll send the menu, grocery list, and prep checklist.`;
          hint.hidden = false;
        });
      });

      $('#newsletterForm').addEventListener('submit', event => {
        event.preventDefault();
        const email = $('#newsletterEmail').value.trim();
        const interestText = $('#newsletterInterest').selectedOptions[0].textContent;
        const status = $('#newsletterStatus');

        status.textContent = `You’re on the list, ${email}. ${interestText} is headed your way—look out for a confirmation email.`;
        status.hidden = false;
        $('#newsletterSubmit').textContent = 'You’re subscribed';
        $('#newsletterSubmit').disabled = true;
      });
    });
  </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:15:23.949Z",
  "url": "https://benchmark.aimac.invalid/5b6793a81874369622fe354aede69d988b1743b6e272814055442d584ecb6675.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-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": "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": []
    },
    {
      "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": "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": "<a class=\"brand\" href=\"#top\" aria-label=\"Savor and Sage home\">",
          "target": [
            ".header-inner > .brand[href$=\"#top\"][aria-label=\"Savor and Sage home\"]"
          ]
        }
      ]
    },
    {
      "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": "<a class=\"brand\" href=\"#top\" aria-label=\"Savor and Sage home\">",
          "target": [
            ".header-inner > .brand[href$=\"#top\"][aria-label=\"Savor and Sage home\"]"
          ]
        }
      ]
    },
    {
      "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": "<div class=\"filters\" role=\"group\" aria-label=\"Filter recipes\">",
          "target": [
            ".filters"
          ]
        }
      ]
    },
    {
      "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-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": [
        {
          "any": [],
          "all": [
            {
              "id": "focusable-modal-open",
              "data": null,
              "relatedNodes": [],
              "impact": "serious",
              "message": "No focusable elements while a modal is open"
            },
            {
              "id": "focusable-disabled",
              "data": null,
              "relatedNodes": [],
              "impact": "serious",
              "message": "No focusable elements contained within element"
            },
            {
              "id": "focusable-not-tabbable",
              "data": null,
              "relatedNodes": [],
              "impact": "serious",
              "message": "No focusable elements contained within element"
            }
          ],
          "none": [],
          "impact": null,
          "html": "<span aria-hidden=\"true\">\u2192</span>",
          "target": [
            ".container > a[href$=\"#recipes\"] > span[aria-hidden=\"true\"]"
          ]
        }
      ]
    },
    {
      "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": "<a class=\"brand\" href=\"#top\" aria-label=\"Savor and Sage home\">",
          "target": [
            ".header-inner > .brand[href$=\"#top\"][aria-label=\"Savor and Sage home\"]"
          ]
        }
      ]
    },
    {
      "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": "<div class=\"filters\" role=\"group\" aria-label=\"Filter recipes\">",
          "target": [
            ".filters"
          ]
        }
      ]
    },
    {
      "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": "<div class=\"filters\" role=\"group\" aria-label=\"Filter recipes\">",
          "target": [
            ".filters"
          ]
        }
      ]
    },
    {
      "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": "<a class=\"brand\" href=\"#top\" aria-label=\"Savor and Sage home\">",
          "target": [
            ".header-inner > .brand[href$=\"#top\"][aria-label=\"Savor and Sage home\"]"
          ]
        }
      ]
    },
    {
      "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": "<a class=\"brand\" href=\"#top\" aria-label=\"Savor and Sage home\">",
          "target": [
            ".header-inner > .brand[href$=\"#top\"][aria-label=\"Savor and Sage home\"]"
          ]
        }
      ]
    },
    {
      "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": [
        {
          "any": [],
          "all": [
            {
              "id": "autocomplete-valid",
              "data": null,
              "relatedNodes": [],
              "impact": "serious",
              "message": "the autocomplete attribute is correctly formatted"
            }
          ],
          "none": [],
          "impact": null,
          "html": "<input id=\"newsletterEmail\" name=\"email\" type=\"email\" autocomplete=\"email\" placeholder=\"Your email address\" required=\"\">",
          "target": [
            "#newsletterEmail"
          ]
        }
      ]
    },
    {
      "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=\"filter-button is-active\" type=\"button\" data-filter=\"all\" aria-pressed=\"true\">All recipes</button>",
          "target": [
            "button[data-filter=\"all\"]"
          ]
        }
      ]
    },
    {
      "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>Good cooking starts with <em>what\u2019s in season.</em></h1>",
                  "target": [
                    "h1"
                  ]
                },
                {
                  "html": "<h2>A little brighter.<br>A little greener.</h2>",
                  "target": [
                    "#recipes > .container > .section-heading.split.reveal > div:nth-child(1) > h2"
                  ]
                },
                {
                  "html": "<h3>Charred Citrus Salmon</h3>",
                  "target": [
                    "article[data-category=\"quick\"] > .recipe-content > h3"
                  ]
                },
                {
                  "html": "<h3>Asparagus &amp; Lemon Risotto</h3>",
                  "target": [
                    ".recipe-card[data-category=\"vegetarian weekend\"]:nth-child(2) > .recipe-content > h3"
                  ]
                },
                {
                  "html": "<h3>Spring Pea &amp; Ricotta Pasta</h3>",
                  "target": [
                    "article[data-category=\"quick vegetarian\"] > .recipe-content > h3"
                  ]
                },
                {
                  "html": "<h3>Miso Mushroom Steam Buns</h3>",
                  "target": [
                    ".recipe-card[data-category=\"vegetarian weekend\"]:nth-child(4) > .recipe-content > h3"
                  ]
                },
                {
                  "html": "<h2>Your recipe,<br>recalculated.</h2>",
                  "target": [
                    "#recipe-lab > .container > .section-heading.split.reveal > div:nth-child(1) > h2"
                  ]
                },
                {
                  "html": "<h3 class=\"method-title\">Method at a glance</h3>",
                  "target": [
                    ".method-title"
                  ]
                },
                {
                  "html": "<h3>Ingredients</h3>",
                  "target": [
                    ".ingredient-heading > div > h3"
                  ]
                },
                {
                  "html": "<h2>The modern plate is loosening up.</h2>",
                  "target": [
                    "#guides > .container > .section-heading.split.reveal > div:nth-child(1) > h2"
                  ]
                },
                {
                  "html": "<h3>Acid is the new finishing salt</h3>",
                  "target": [
                    ".trend-item:nth-child(2) > div > h3"
                  ]
                },
                {
                  "html": "<h3>Plating leaves room to breathe</h3>",
                  "target": [
                    ".trend-item:nth-child(3) > div > h3"
                  ]
                },
                {
                  "html": "<h3>Mise en place gets a second life</h3>",
                  "target": [
                    ".trend-item:nth-child(4) > div > h3"
                  ]
                },
                {
                  "html": "<h2>Asparagus,<br>after the snap.</h2>",
                  "target": [
                    ".spotlight-copy > h2"
                  ]
                },
                {
                  "html": "<h2>Worth the reservation.</h2>",
                  "target": [
                    "#restaurants > .container > .section-heading.split.reveal > div:nth-child(1) > h2"
                  ]
                },
                {
                  "html": "<h3>Juniper &amp; Rye</h3>",
                  "target": [
                    ".restaurant-card:nth-child(1) > .restaurant-content > h3"
                  ]
                },
                {
                  "html": "<h3>Kado</h3>",
                  "target": [
                    ".restaurant-card:nth-child(2) > .restaurant-content > h3"
                  ]
                },
                {
                  "html": "<h3>Loma</h3>",
                  "target": [
                    ".restaurant-card:nth-child(3) > .restaurant-content > h3"
                  ]
                },
                {
                  "html": "<h2>A calmer week starts with a better plan.</h2>",
                  "target": [
                    "#meal-plans > .container > .section-heading.split.reveal > div:nth-child(1) > h2"
                  ]
                },
                {
                  "html": "<h3>The Plant-Forward Week</h3>",
                  "target": [
                    ".plan-card:nth-child(1) > h3"
                  ]
                },
                {
                  "html": "<h3>The Weeknight Reset</h3>",
                  "target": [
                    ".featured > h3"
                  ]
                },
                {
                  "html": "<h3>The Weekend Host</h3>",
                  "target": [
                    ".plan-card:nth-child(3) > h3"
                  ]
                },
                {
                  "html": "<h3>Nutrition information, without the noise</h3>",
                  "target": [
                    "aside > div:nth-child(2) > h3"
                  ]
                },
                {
                  "html": "<h2 id=\"community-title\">Cooked here.<br>Shared everywhere.</h2>",
                  "target": [
                    "#community-title"
                  ]
                },
                {
                  "html": "<h2>Stories for curious appetites.</h2>",
                  "target": [
                    "#blog > .container > .section-heading.split.reveal > div:nth-child(1) > h2"
                  ]
                },
                {
                  "html": "<h3>The Five-Minute Pan Sauce</h3>",
                  "target": [
                    ".article-card:nth-child(1) > h3"
                  ]
                },
                {
                  "html": "<h3>Shop the Market Without a List</h3>",
                  "target": [
                    ".article-card:nth-child(2) > h3"
                  ]
                },
                {
                  "html": "<h3>How to Salt in Layers</h3>",
                  "target": [
                    ".article-card:nth-child(3) > h3"
                  ]
                },
                {
                  "html": "<h2 id=\"faq-title\">Before you tie your apron.</h2>",
                  "target": [
                    "#faq-title"
                  ]
                },
                {
                  "html": "<h2 id=\"newsletter-title\">The best thing in your inbox on Thursday.</h2>",
                  "target": [
                    "#newsletter-title"
                  ]
                },
                {
                  "html": "<h3>Explore</h3>",
                  "target": [
                    ".footer-column:nth-child(2) > h3"
                  ]
                },
                {
                  "html": "<h3>Our Kitchen</h3>",
                  "target": [
                    ".footer-column:nth-child(3) > h3"
                  ]
                },
                {
                  "html": "<h3>Visit &amp; Write</h3>",
                  "target": [
                    ".footer-contact > h3"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Page has a heading"
            },
            {
              "id": "landmark",
              "data": null,
              "relatedNodes": [
                {
                  "html": "<main id=\"main-content\">",
                  "target": [
                    "#main-content"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Page has a landmark region"
            }
          ],
          "all": [],
          "none": [],
          "impact": null,
          "html": "<html lang=\"en\" class=\"js\">",
          "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": "#e9eee7",
                "bgColor": "#102e27",
                "contrastRatio": 12.37,
                "fontSize": "9.2pt (12.32px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [],
              "impact": "serious",
              "message": "Element has sufficient color contrast of 12.37"
            }
          ],
          "all": [],
          "none": [],
          "impact": null,
          "html": "<p>The Seasonal Edit is here: 18 bright, brothy, crisp things to cook now.</p>",
          "target": [
            ".container > p"
          ]
        }
      ]
    },
    {
      "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\" class=\"js\">",
          "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": "primaryNav",
              "relatedNodes": [],
              "impact": "critical",
              "message": "Document has no elements referenced with ARIA or labels that share the same id attribute"
            }
          ],
          "all": [],
          "none": [],
          "impact": null,
          "html": "<nav class=\"primary-nav\" id=\"primaryNav\" aria-label=\"Primary navigation\">",
          "target": [
            "#primaryNav"
          ]
        }
      ]
    },
    {
      "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 class=\"field-label\" for=\"recipeSelect\">Choose a recipe</label>",
                  "target": [
                    ".field-label"
                  ]
                }
              ],
              "impact": "moderate",
              "message": "Form field does not have multiple label elements"
            }
          ],
          "impact": null,
          "html": "<select class=\"recipe-select\" id=\"recipeSelect\">",
          "target": [
            "#recipeSelect"
          ]
        }
      ]
    },
    {
      "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\" class=\"js\">",
          "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\" class=\"js\">",
          "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 class=\"brand-mark\" src=\"https://placehold.co/72x72/173F35/F8F3E8?text=S%26S&amp;font=montserrat\" width=\"72\" height=\"72\" alt=\"Savor and Sage monogram\">",
          "target": [
            ".header-inner > .brand[href$=\"#top\"][aria-label=\"Savor and Sage home\"] > .brand-mark[width=\"72\"][height=\"72\"]"
          ]
        }
      ]
    },
    {
      "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": "implicit-label",
              "data": {
                "implicitLabel": "4salmon fillets, about 6 oz / 170 g each"
              },
              "relatedNodes": [
                {
                  "html": "<label><input type=\"checkbox\"><span class=\"ingredient-amount\">4</span><span class=\"ingredient-name\">salmon fillets, about 6 oz / 170 g each</span></label>",
                  "target": [
                    "li:nth-child(1) > label"
                  ]
                }
              ],
              "impact": "critical",
              "message": "Element has an implicit (wrapped) <label>"
            }
          ],
          "all": [],
          "none": [
            {
              "id": "hidden-explicit-label",
              "data": null,
              "relatedNodes": [],
              "impact": "critical",
              "message": "Form element has a visible explicit <label>"
            }
          ],
          "impact": null,
          "html": "<input type=\"checkbox\">",
          "target": [
            "li:nth-child(1) > label > input[type=\"checkbox\"]"
          ]
        }
      ]
    },
    {
      "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=\"skip-link\" href=\"#main-content\">Skip to main content</a>",
          "target": [
            ".skip-link"
          ]
        }
      ]
    },
    {
      "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": "<ol class=\"method-list\" id=\"methodList\"><li>Season and dry the salmon; mix the citrus glaze.</li><li>Sear skin-side down until crisp, then turn and char the citrus.</li><li>Build the reduction in the pan and spoon over the fish.</li></ol>",
          "target": [
            "#methodList"
          ]
        }
      ]
    },
    {
      "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>Season and dry the salmon; mix the citrus glaze.</li>",
          "target": [
            "#methodList > 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 class=\"brand-mark\" src=\"https://placehold.co/72x72/173F35/F8F3E8?text=S%26S&amp;font=montserrat\" width=\"72\" height=\"72\" alt=\"Savor and Sage monogram\">",
          "target": [
            ".header-inner > .brand[href$=\"#top\"][aria-label=\"Savor and Sage home\"] > .brand-mark[width=\"72\"][height=\"72\"]"
          ]
        }
      ]
    },
    {
      "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": null,
              "relatedNodes": [
                {
                  "html": "<label class=\"field-label\" for=\"recipeSelect\">Choose a recipe</label>",
                  "target": [
                    ".field-label"
                  ]
                }
              ],
              "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 class=\"recipe-select\" id=\"recipeSelect\">",
          "target": [
            "#recipeSelect"
          ]
        }
      ]
    },
    {
      "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>How we score a restaurant</summary>",
          "target": [
            ".review-standard > 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": 198.8,
                "height": 51.2
              },
              "relatedNodes": [],
              "impact": "serious",
              "message": "Control has sufficient size (198.8px by 51.2px, 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=\"skip-link\" href=\"#main-content\">Skip to main content</a>",
          "target": [
            ".skip-link"
          ]
        }
      ]
    }
  ],
  "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": "div",
                "messageKey": "noRoleSingular",
                "prohibited": [
                  "aria-label"
                ]
              },
              "relatedNodes": [],
              "impact": "serious",
              "message": "aria-label attribute is not well supported on a div with no valid role attribute."
            }
          ],
          "impact": "serious",
          "html": "<div class=\"stat-band\" aria-label=\"Savor and Sage at a glance\">",
          "target": [
            ".stat-band"
          ],
          "failureSummary": "Fix all of the following:\n  aria-label attribute is not well supported on a div 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": {
                "messageKey": "nonBmp"
              },
              "relatedNodes": [],
              "impact": "serious",
              "message": "Element content contains only non-text characters"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span aria-hidden=\"true\">\u2192</span>",
          "target": [
            ".container > a[href$=\"#recipes\"] > span[aria-hidden=\"true\"]"
          ],
          "failureSummary": "Fix any of the following:\n  Element content contains only non-text characters"
        }
      ]
    },
    {
      "id": "link-in-text-block",
      "impact": "serious",
      "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": [
        {
          "any": [
            {
              "id": "link-in-text-block",
              "data": {
                "messageKey": "bgOverlap"
              },
              "relatedNodes": [
                {
                  "html": "<div class=\"footer-about\">",
                  "target": [
                    ".footer-about"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element's contrast ratio could not be determined because of element overlap"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<a class=\"brand\" href=\"#top\" aria-label=\"Savor and Sage home\">",
          "target": [
            ".footer-about > .brand[href$=\"#top\"][aria-label=\"Savor and Sage home\"]"
          ],
          "failureSummary": "Fix any of the following:\n  Element's contrast ratio could not be determined because of element overlap"
        }
      ]
    }
  ],
  "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": "#e6784b",
                "bgColor": "#f8f5ed",
                "contrastRatio": 2.69,
                "fontSize": "61.4pt (81.92px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "3:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<body>",
                  "target": [
                    "body"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.69 (foreground color: #e6784b, background color: #f8f5ed, font size: 61.4pt (81.92px), font weight: normal). Expected contrast ratio of 3:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<em>what\u2019s in season.</em>",
          "target": [
            "em"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.69 (foreground color: #e6784b, background color: #f8f5ed, font size: 61.4pt (81.92px), font weight: normal). Expected contrast ratio of 3:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#fffdf8",
                "contrastRatio": 2.88,
                "fontSize": "7.6pt (10.08px)",
                "fontWeight": "bold",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<a class=\"floating-recipe recipe-open\" href=\"#recipe-lab\" data-recipe=\"salmon\">\n            <span class=\"mini-label\">Editor\u2019s pick \u00b7 Open recipe</span>\n            <strong>Charred Citrus Salmon</strong>\n            <span>25 minutes \u00b7 crisp skin, glossy reduction</span>\n          </a>",
                  "target": [
                    ".floating-recipe"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.6pt (10.08px), font weight: bold). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span class=\"mini-label\">Editor\u2019s pick \u00b7 Open recipe</span>",
          "target": [
            ".mini-label"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.6pt (10.08px), font weight: bold). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#eaeae2",
                "contrastRatio": 4.1,
                "fontSize": "7.1pt (9.44px)",
                "fontWeight": "bold",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<header class=\"site-header scrolled\" id=\"siteHeader\">",
                  "target": [
                    "#siteHeader"
                  ]
                },
                {
                  "html": "<section class=\"section recipe-lab\" id=\"recipe-lab\">",
                  "target": [
                    "#recipe-lab"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 4.1 (foreground color: #66736c, background color: #eaeae2, font size: 7.1pt (9.44px), font weight: bold). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span class=\"brand-tagline\">Cook seasonally. Eat joyfully.</span>",
          "target": [
            ".header-inner > .brand[href$=\"#top\"][aria-label=\"Savor and Sage home\"] > .brand-copy > .brand-tagline"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 4.1 (foreground color: #66736c, background color: #eaeae2, font size: 7.1pt (9.44px), font weight: bold). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#e8ede3",
                "contrastRatio": 4.16,
                "fontSize": "8.6pt (11.52px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<div class=\"control-panel\">",
                  "target": [
                    ".control-panel"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 4.16 (foreground color: #66736c, background color: #e8ede3, font size: 8.6pt (11.52px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<small>Scale from 1 to 12 servings</small>",
          "target": [
            "div:nth-child(1) > small"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 4.16 (foreground color: #66736c, background color: #e8ede3, font size: 8.6pt (11.52px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#d7dfd2",
                "contrastRatio": 3.63,
                "fontSize": "8.4pt (11.2px)",
                "fontWeight": "bold",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<div class=\"unit-toggle\" role=\"group\" aria-label=\"Measurement system\">\n                <button class=\"is-active\" type=\"button\" data-unit=\"us\" aria-pressed=\"true\">US cups</button>\n                <button type=\"button\" data-unit=\"metric\" aria-pressed=\"false\">Metric</button>\n              </div>",
                  "target": [
                    ".unit-toggle"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 3.63 (foreground color: #66736c, background color: #d7dfd2, font size: 8.4pt (11.2px), font weight: bold). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<button type=\"button\" data-unit=\"metric\" aria-pressed=\"false\">Metric</button>",
          "target": [
            "button[data-unit=\"metric\"]"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 3.63 (foreground color: #66736c, background color: #d7dfd2, font size: 8.4pt (11.2px), font weight: bold). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#e8ede3",
                "contrastRatio": 4.16,
                "fontSize": "9.1pt (12.16px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<div class=\"control-panel\">",
                  "target": [
                    ".control-panel"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 4.16 (foreground color: #66736c, background color: #e8ede3, font size: 9.1pt (12.16px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<li>Season and dry the salmon; mix the citrus glaze.</li>",
          "target": [
            "#methodList > li:nth-child(1)"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 4.16 (foreground color: #66736c, background color: #e8ede3, font size: 9.1pt (12.16px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#e8ede3",
                "contrastRatio": 4.16,
                "fontSize": "9.1pt (12.16px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<div class=\"control-panel\">",
                  "target": [
                    ".control-panel"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 4.16 (foreground color: #66736c, background color: #e8ede3, font size: 9.1pt (12.16px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<li>Sear skin-side down until crisp, then turn and char the citrus.</li>",
          "target": [
            "#methodList > li:nth-child(2)"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 4.16 (foreground color: #66736c, background color: #e8ede3, font size: 9.1pt (12.16px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#e8ede3",
                "contrastRatio": 4.16,
                "fontSize": "9.1pt (12.16px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<div class=\"control-panel\">",
                  "target": [
                    ".control-panel"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 4.16 (foreground color: #66736c, background color: #e8ede3, font size: 9.1pt (12.16px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<li>Build the reduction in the pan and spoon over the fish.</li>",
          "target": [
            "#methodList > li:nth-child(3)"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 4.16 (foreground color: #66736c, background color: #e8ede3, font size: 9.1pt (12.16px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#fffdf8",
                "contrastRatio": 2.88,
                "fontSize": "13.2pt (17.6px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<section class=\"section section-paper\" id=\"guides\">",
                  "target": [
                    "#guides"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 13.2pt (17.6px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span class=\"trend-number\">01</span>",
          "target": [
            ".trend-item:nth-child(2) > .trend-number"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 13.2pt (17.6px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#fffdf8",
                "contrastRatio": 2.88,
                "fontSize": "13.2pt (17.6px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<section class=\"section section-paper\" id=\"guides\">",
                  "target": [
                    "#guides"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 13.2pt (17.6px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span class=\"trend-number\">02</span>",
          "target": [
            ".trend-item:nth-child(3) > .trend-number"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 13.2pt (17.6px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#fffdf8",
                "contrastRatio": 2.88,
                "fontSize": "13.2pt (17.6px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<section class=\"section section-paper\" id=\"guides\">",
                  "target": [
                    "#guides"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 13.2pt (17.6px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span class=\"trend-number\">03</span>",
          "target": [
            ".trend-item:nth-child(4) > .trend-number"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 13.2pt (17.6px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#efe5d6",
                "contrastRatio": 3.97,
                "fontSize": "8.3pt (11.04px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<section class=\"section spotlight\" id=\"seasonal\">",
                  "target": [
                    "#seasonal"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 3.97 (foreground color: #66736c, background color: #efe5d6, font size: 8.3pt (11.04px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span>Look for firm stalks, closed tips, and no woody shriveling at the base.</span>",
          "target": [
            ".prep-step:nth-child(1) > span"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 3.97 (foreground color: #66736c, background color: #efe5d6, font size: 8.3pt (11.04px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#efe5d6",
                "contrastRatio": 3.97,
                "fontSize": "8.3pt (11.04px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<section class=\"section spotlight\" id=\"seasonal\">",
                  "target": [
                    "#seasonal"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 3.97 (foreground color: #66736c, background color: #efe5d6, font size: 8.3pt (11.04px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span>Stand the bunch in an inch of water, cover loosely, and refrigerate.</span>",
          "target": [
            ".prep-step:nth-child(2) > span"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 3.97 (foreground color: #66736c, background color: #efe5d6, font size: 8.3pt (11.04px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#efe5d6",
                "contrastRatio": 3.97,
                "fontSize": "8.3pt (11.04px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<section class=\"section spotlight\" id=\"seasonal\">",
                  "target": [
                    "#seasonal"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 3.97 (foreground color: #66736c, background color: #efe5d6, font size: 8.3pt (11.04px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span>Use a wide pan and avoid crowding so the spears char before they soften.</span>",
          "target": [
            ".prep-step:nth-child(3) > span"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 3.97 (foreground color: #66736c, background color: #efe5d6, font size: 8.3pt (11.04px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#fffdf8",
                "contrastRatio": 2.88,
                "fontSize": "7.9pt (10.56px)",
                "fontWeight": "bold",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<article class=\"restaurant-card reveal is-visible\">",
                  "target": [
                    ".restaurant-card.is-visible:nth-child(1)"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.9pt (10.56px), font weight: bold). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<div class=\"restaurant-meta\">Seasonal American \u00b7 Fort Greene \u00b7 $$$</div>",
          "target": [
            ".restaurant-card.is-visible:nth-child(1) > .restaurant-content > .restaurant-meta"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.9pt (10.56px), font weight: bold). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#fffdf8",
                "contrastRatio": 2.88,
                "fontSize": "7.9pt (10.56px)",
                "fontWeight": "bold",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<article class=\"restaurant-card reveal is-visible\">",
                  "target": [
                    ".restaurant-card.is-visible:nth-child(2)"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.9pt (10.56px), font weight: bold). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<div class=\"restaurant-meta\">Japanese Listening Bar \u00b7 West Loop \u00b7 $$$</div>",
          "target": [
            ".restaurant-card.is-visible:nth-child(2) > .restaurant-content > .restaurant-meta"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.9pt (10.56px), font weight: bold). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#fffdf8",
                "contrastRatio": 2.88,
                "fontSize": "7.9pt (10.56px)",
                "fontWeight": "bold",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<article class=\"restaurant-card reveal is-visible\">",
                  "target": [
                    ".restaurant-card.is-visible:nth-child(3)"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.9pt (10.56px), font weight: bold). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<div class=\"restaurant-meta\">Coastal Mexican \u00b7 Los Feliz \u00b7 $$</div>",
          "target": [
            ".restaurant-card.is-visible:nth-child(3) > .restaurant-content > .restaurant-meta"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.9pt (10.56px), font weight: bold). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#fffdf8",
                "contrastRatio": 2.88,
                "fontSize": "7.9pt (10.56px)",
                "fontWeight": "bold",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<article class=\"restaurant-card reveal is-visible\">",
                  "target": [
                    ".restaurant-card:nth-child(1)"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.9pt (10.56px), font weight: bold). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<div class=\"restaurant-meta\">Seasonal American \u00b7 Fort Greene \u00b7 $$$</div>",
          "target": [
            ".restaurant-card:nth-child(1) > .restaurant-content > .restaurant-meta"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.9pt (10.56px), font weight: bold). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#fffdf8",
                "contrastRatio": 2.88,
                "fontSize": "7.9pt (10.56px)",
                "fontWeight": "bold",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<article class=\"restaurant-card reveal is-visible\">",
                  "target": [
                    ".restaurant-card:nth-child(2)"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.9pt (10.56px), font weight: bold). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<div class=\"restaurant-meta\">Japanese Listening Bar \u00b7 West Loop \u00b7 $$$</div>",
          "target": [
            ".restaurant-card:nth-child(2) > .restaurant-content > .restaurant-meta"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.9pt (10.56px), font weight: bold). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#fffdf8",
                "contrastRatio": 2.88,
                "fontSize": "7.9pt (10.56px)",
                "fontWeight": "bold",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<article class=\"restaurant-card reveal is-visible\">",
                  "target": [
                    ".restaurant-card:nth-child(3)"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.9pt (10.56px), font weight: bold). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<div class=\"restaurant-meta\">Coastal Mexican \u00b7 Los Feliz \u00b7 $$</div>",
          "target": [
            ".restaurant-card:nth-child(3) > .restaurant-content > .restaurant-meta"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.88 (foreground color: #e6784b, background color: #fffdf8, font size: 7.9pt (10.56px), font weight: bold). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#e3eadf",
                "contrastRatio": 4.03,
                "fontSize": "11.8pt (15.68px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<section class=\"section meal-plan-section\" id=\"meal-plans\">",
                  "target": [
                    "#meal-plans"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 4.03 (foreground color: #66736c, background color: #e3eadf, font size: 11.8pt (15.68px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<p>Our meal plans are built around overlapping ingredients, deliberate leftovers, and one completely free night. Each includes a consolidated grocery list, prep sequence, substitutions, and per-serving nutrition estimates.</p>",
          "target": [
            "#meal-plans > .container > .section-heading.split.is-visible > .section-intro > p:nth-child(1)"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 4.03 (foreground color: #66736c, background color: #e3eadf, font size: 11.8pt (15.68px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#e3eadf",
                "contrastRatio": 4.03,
                "fontSize": "11.8pt (15.68px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<section class=\"section meal-plan-section\" id=\"meal-plans\">",
                  "target": [
                    "#meal-plans"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 4.03 (foreground color: #66736c, background color: #e3eadf, font size: 11.8pt (15.68px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<p>Choose a free sample plan below. We\u2019ll send the five-day menu and Sunday mise en place checklist straight to your inbox.</p>",
          "target": [
            "#meal-plans > .container > .section-heading.split.is-visible > .section-intro > p:nth-child(2)"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 4.03 (foreground color: #66736c, background color: #e3eadf, font size: 11.8pt (15.68px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#f6f7f0",
                "contrastRatio": 2.72,
                "fontSize": "12.0pt (16px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<article class=\"plan-card reveal is-visible\">",
                  "target": [
                    ".plan-card:nth-child(1)"
                  ]
                },
                {
                  "html": "<section class=\"section meal-plan-section\" id=\"meal-plans\">",
                  "target": [
                    "#meal-plans"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.72 (foreground color: #e6784b, background color: #f6f7f0, font size: 12.0pt (16px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span class=\"plan-number\">Plan 01</span>",
          "target": [
            ".plan-card:nth-child(1) > .plan-number"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.72 (foreground color: #e6784b, background color: #f6f7f0, font size: 12.0pt (16px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#173f35",
                "contrastRatio": 3.97,
                "fontSize": "12.0pt (16px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<article class=\"plan-card featured reveal is-visible\">",
                  "target": [
                    ".featured"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 3.97 (foreground color: #e6784b, background color: #173f35, font size: 12.0pt (16px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span class=\"plan-number\">Plan 02</span>",
          "target": [
            ".featured > .plan-number"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 3.97 (foreground color: #e6784b, background color: #173f35, font size: 12.0pt (16px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#f6f7f0",
                "contrastRatio": 2.72,
                "fontSize": "12.0pt (16px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<article class=\"plan-card reveal is-visible\">",
                  "target": [
                    ".plan-card:nth-child(3)"
                  ]
                },
                {
                  "html": "<section class=\"section meal-plan-section\" id=\"meal-plans\">",
                  "target": [
                    "#meal-plans"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.72 (foreground color: #e6784b, background color: #f6f7f0, font size: 12.0pt (16px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span class=\"plan-number\">Plan 03</span>",
          "target": [
            ".plan-card:nth-child(3) > .plan-number"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.72 (foreground color: #e6784b, background color: #f6f7f0, font size: 12.0pt (16px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#f1f4ec",
                "contrastRatio": 4.46,
                "fontSize": "9.2pt (12.32px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<aside class=\"nutrition-note reveal is-visible\">",
                  "target": [
                    "aside"
                  ]
                },
                {
                  "html": "<section class=\"section meal-plan-section\" id=\"meal-plans\">",
                  "target": [
                    "#meal-plans"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 4.46 (foreground color: #66736c, background color: #f1f4ec, font size: 9.2pt (12.32px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<p>",
          "target": [
            "aside > div:nth-child(2) > p"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 4.46 (foreground color: #66736c, background color: #f1f4ec, font size: 9.2pt (12.32px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#f8f5ed",
                "contrastRatio": 2.69,
                "fontSize": "7.8pt (10.4px)",
                "fontWeight": "bold",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<body>",
                  "target": [
                    "body"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.69 (foreground color: #e6784b, background color: #f8f5ed, font size: 7.8pt (10.4px), font weight: bold). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span>Technique</span>",
          "target": [
            ".article-card:nth-child(1) > .article-kicker > span:nth-child(1)"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.69 (foreground color: #e6784b, background color: #f8f5ed, font size: 7.8pt (10.4px), font weight: bold). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#f8f5ed",
                "contrastRatio": 2.69,
                "fontSize": "7.8pt (10.4px)",
                "fontWeight": "bold",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<body>",
                  "target": [
                    "body"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.69 (foreground color: #e6784b, background color: #f8f5ed, font size: 7.8pt (10.4px), font weight: bold). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span>Market Notes</span>",
          "target": [
            ".article-card:nth-child(2) > .article-kicker > span:nth-child(1)"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.69 (foreground color: #e6784b, background color: #f8f5ed, font size: 7.8pt (10.4px), font weight: bold). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#e6784b",
                "bgColor": "#f8f5ed",
                "contrastRatio": 2.69,
                "fontSize": "7.8pt (10.4px)",
                "fontWeight": "bold",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<body>",
                  "target": [
                    "body"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 2.69 (foreground color: #e6784b, background color: #f8f5ed, font size: 7.8pt (10.4px), font weight: bold). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<span>Kitchen Science</span>",
          "target": [
            ".article-card:nth-child(3) > .article-kicker > span:nth-child(1)"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 2.69 (foreground color: #e6784b, background color: #f8f5ed, font size: 7.8pt (10.4px), font weight: bold). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#e3eadf",
                "contrastRatio": 4.03,
                "fontSize": "11.8pt (15.68px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<section class=\"section meal-plan-section\" id=\"meal-plans\">",
                  "target": [
                    "#meal-plans"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 4.03 (foreground color: #66736c, background color: #e3eadf, font size: 11.8pt (15.68px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<p>Our meal plans are built around overlapping ingredients, deliberate leftovers, and one completely free night. Each includes a consolidated grocery list, prep sequence, substitutions, and per-serving nutrition estimates.</p>",
          "target": [
            "#meal-plans > .container > .section-heading.split.reveal > .section-intro > p:nth-child(1)"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 4.03 (foreground color: #66736c, background color: #e3eadf, font size: 11.8pt (15.68px), font weight: normal). Expected contrast ratio of 4.5:1"
        },
        {
          "any": [
            {
              "id": "color-contrast",
              "data": {
                "fgColor": "#66736c",
                "bgColor": "#e3eadf",
                "contrastRatio": 4.03,
                "fontSize": "11.8pt (15.68px)",
                "fontWeight": "normal",
                "messageKey": null,
                "expectedContrastRatio": "4.5:1",
                "shadowColor": null
              },
              "relatedNodes": [
                {
                  "html": "<section class=\"section meal-plan-section\" id=\"meal-plans\">",
                  "target": [
                    "#meal-plans"
                  ]
                }
              ],
              "impact": "serious",
              "message": "Element has insufficient color contrast of 4.03 (foreground color: #66736c, background color: #e3eadf, font size: 11.8pt (15.68px), font weight: normal). Expected contrast ratio of 4.5:1"
            }
          ],
          "all": [],
          "none": [],
          "impact": "serious",
          "html": "<p>Choose a free sample plan below. We\u2019ll send the five-day menu and Sunday mise en place checklist straight to your inbox.</p>",
          "target": [
            "#meal-plans > .container > .section-heading.split.reveal > .section-intro > p:nth-child(2)"
          ],
          "failureSummary": "Fix any of the following:\n  Element has insufficient color contrast of 4.03 (foreground color: #66736c, background color: #e3eadf, font size: 11.8pt (15.68px), font weight: normal). Expected contrast ratio of 4.5:1"
        }
      ]
    }
  ],
  "coverage": {
    "contract": "main-document-vertical-scroll",
    "complete": true,
    "positions": [
      {
        "y": 0,
        "height": 11786
      },
      {
        "y": 576,
        "height": 11786
      },
      {
        "y": 1152,
        "height": 11786
      },
      {
        "y": 1728,
        "height": 11786
      },
      {
        "y": 2304,
        "height": 11786
      },
      {
        "y": 2880,
        "height": 11786
      },
      {
        "y": 3456,
        "height": 11786
      },
      {
        "y": 4032,
        "height": 11786
      },
      {
        "y": 4608,
        "height": 11786
      },
      {
        "y": 5184,
        "height": 11786
      },
      {
        "y": 5760,
        "height": 11786
      },
      {
        "y": 6336,
        "height": 11786
      },
      {
        "y": 6912,
        "height": 11786
      },
      {
        "y": 7488,
        "height": 11786
      },
      {
        "y": 8064,
        "height": 11786
      },
      {
        "y": 8640,
        "height": 11786
      },
      {
        "y": 9216,
        "height": 11786
      },
      {
        "y": 9792,
        "height": 11786
      },
      {
        "y": 10368,
        "height": 11786
      },
      {
        "y": 10944,
        "height": 11786
      },
      {
        "y": 11066,
        "height": 11786
      }
    ],
    "scans": 22,
    "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: "Blog", "Meal Plans", "Restaurant Reviews".
-   **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: "Culinary Trends", "Seasonal Menus", "Ingredient Spotlight".
    -   **Content Depth:** Populate each section with **substantial, realistic text** (multiple sentences/paragraphs). Use authentic industry language and terminology like: "mise en place", "plating", "reduction".
    -   **Visuals:** Integrate relevant placeholder images logically within the content sections.
    -   **Calls to Action:** Include clear and contextually relevant CTAs. Use strong verbs similar to: "Make Reservation", "Start Order", "Watch Tutorial".
-   **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: "recipe calculator".
-   **SIDEBAR (Optional):** If your design includes a sidebar, populate it with **useful, relevant content**. Ideas: "cooking tips", "daily specials", "restaurant picks".
-   **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.