Here’s a tight, dev-focused QA pass on the FederalReserve.gov homepage markup you shared. I’ve prioritized concrete, high-impact fixes with drop-in snippets.


🔴 Real bugs / correctness

  1. Viewport meta syntax content="width=device-width, initial-scale=1.0, minimum-scale=1.0 maximum-scale=1.6, user-scalable=1"
    • Missing comma between minimum-scale and maximum-scale.
    • Use the standard value for user scaling:
    content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.6, user-scalable=yes"
  2. Open Graph type for homepage
    • og:type="article" is wrong for the root page; switch to website.
  3. Protocol-relative URLs
    • Search form uses action="//www.fedsearch.org/...". Force HTTPS to avoid mixed content:
    action="https://www.fedsearch.org/board_public/search"
  4. External links opened in new windows without rel
    • Footer badges (USA.gov, OpenGov) have target="_blank" but no rel. Add:
    rel="noopener noreferrer"

🟠 Accessibility (quick wins)

  1. “Here’s how you know” disclosure
    • The banner button doesn’t expose state. Add:
    <button type="button" class="custom-banner__button" aria-expanded="false" aria-controls="banner-content"> <span class="custom-banner__button-text">Here's how you know</span> <img id="caret-icon" …> </button>
    • In JS: toggle aria-expanded and an hidden attribute (or a CSS aria-[expanded] selector) on #banner-content.
  2. ARIA menu roles used on site nav
    • Primary nav uses role="menubar", role="menuitem", and submenus role="menu". Those roles require app-style roving tabindex & arrow-key behavior.
    • For a site nav, remove menu roles and rely on <nav><ul><li><a> semantics plus aria-expanded on the dropdown triggers. Example:
    <li class="dropdown"> <a href="/aboutthefed.htm" aria-haspopup="true" aria-expanded="false" id="aboutMenu">About the Fed</a> <ul aria-labelledby="aboutMenu" hidden> … </ul> </li>
    • JS: toggle hidden and aria-expanded.
  3. Icon images that are decorative
    • A number of icon <img> tags (e.g., caret, dot-gov/https icons, some card icons) should be alt="" + aria-hidden="true" and/or moved to background CSS to reduce verbosity. Keep meaningful ones with real alt text.
  4. Video accessibility
    • Brightcove player loads fine, but ensure captions are available and exposed. Add:
    <video … controls preload="metadata" playsinline aria-label="Federal Reserve video: [descriptive title]"></video>
    • Include a <track kind="captions" ...> if you have the caption file, or confirm Brightcove captions toggle is enabled.
    • Your SR-only keyboard help is great 👍. Wrap it in an aria-describedby offscreen ID referenced by the <video> for discoverability.
  5. Dates are not machine-readable
    • Render human dates with <time datetime="YYYY-MM-DD">…</time>. E.g., “Last Update: August 22, 2025”.

⚡ Performance (LCP/CLS)

  1. Hero media priority
  • For the topmost, above-fold imagery, add fetchpriority="high" and decoding="async" to the first visible hero image. Where you use background CSS, consider inlining a responsive <picture> instead (you already do <img> in the carousel).
  1. Intrinsic size placeholder
  • Where images don’t have explicit width/height, set width and height (or aspect-ratio) to avoid layout shifts. You already supply many width/height; keep it consistent on all large images (e.g., hmpg-function-banner-final.jpg).
  1. JavaScript payload
  • You load Modernizr, AngularJS 1.x, jQuery, Bootstrap, and many plugins. Audit for unused scripts and defer/async everything not required for first paint. You’re already deferring some (main.js as module) — keep pushing non-critical scripts to the end, defer’ed.
  1. Respect reduced motion
  • If the “lightbox” or dropdowns animate, disable transitions under @media (prefers-reduced-motion: reduce).

🔐 Security / privacy

  1. Strict CSP migration
  • You have a CF Zaraz nonced inline block. Multiple other inline scripts (jQuery init, Brightcove DOMContentLoaded, lightbox init) would be blocked under a strict CSP unless you add the nonce uniformly or move code to external files. Plan: adopt a single nonce for all inline <script> or externalize them.
  1. SRI & preconnect for third-party
  • Add rel="preconnect" crossorigin for Brightcove:
<link rel="preconnect" href="https://players.brightcove.net" crossorigin>
  • Add SRI where possible for static third-party scripts.

🔎 SEO polish

  1. Canonical
  • If you have a canonical, prefer the clean root (https://www.federalreserve.gov/) instead of /default.htm. If you must keep /default.htm, ensure consistent linking across the site.
  1. OpenGraph image alt
  • You already include og:image:alt 👍. Keep alt succinct and descriptive.

🧼 UI/UX misc

  1. Dropdowns & keyboard
  • Ensure Esc closes open menus and returns focus to the trigger. Arrow keys should move focus within open submenus if you keep ARIA menu patterns (but again, better to use simple list nav + aria-expanded).
  1. Back-to-top link
  • It points to href="#". Consider href="#top" with an actual id="top" sentinel to avoid browser jumping to document start unexpectedly, or use a button with JS scroll behavior and aria-label="Back to top" (you already have sr-only text).
  1. “Recent Developments” list
  • Good link text. Consider including <time> elements for each entry as noted above for better semantics.

Example patches (drop-ins)

Banner button a11y:

<button type="button"
        class="custom-banner__button"
        aria-expanded="false"
        aria-controls="banner-content">
  <span class="custom-banner__button-text">Here's how you know</span>
  <img id="caret-icon" class="custom-banner__caret" src="/images/expand_more.svg" alt="">
</button>
<div class="custom-banner__content" id="banner-content" hidden>…</div>
<script>
  const btn = document.querySelector('.custom-banner__button');
  const panel = document.getElementById('banner-content');
  btn?.addEventListener('click', () => {
    const open = btn.getAttribute('aria-expanded') === 'true';
    btn.setAttribute('aria-expanded', String(!open));
    panel.hidden = open;
  });
</script>

Nav roles cleanup (one item):

<li class="dropdown">
  <a href="/aboutthefed.htm"
     id="aboutMenu"
     aria-haspopup="true"
     aria-expanded="false">About<br>the Fed</a>
  <ul aria-labelledby="aboutMenu" hidden>
    …
  </ul>
</li>
<script>
  // Toggle hidden + aria-expanded on click/Enter/Space; close on Esc.
</script>

Meta tags:

<meta name="viewport"
      content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.6, user-scalable=yes">
<meta property="og:type" content="website">

HTTPS search action:

<form action="https://www.fedsearch.org/board_public/search" method="get" role="search">

Footer external links:

<a href="https://www.usa.gov/" target="_blank" rel="noopener noreferrer" title="Link to USA.gov">…</a>

Machine-readable update time:

<div class='lastUpdate' id="lastUpdate">
  Last Update: <time datetime="2025-08-22">August 22, 2025</time>
</div>

If you want, I can turn these into a small PR bundle: one template tweak for the header/nav + banner, a tiny script to manage aria-expanded/hidden, and a metadata partial update — all without changing visual design.