🔴 Real bugs / correctness
- 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-scaleandmaximum-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" - Missing comma between
- Open Graph type for homepage
og:type="article"is wrong for the root page; switch towebsite.
- Protocol-relative URLs
- Search form uses
action="//www.fedsearch.org/...". Force HTTPS to avoid mixed content:
action="https://www.fedsearch.org/board_public/search" - Search form uses
- External links opened in new windows without rel
- Footer badges (USA.gov, OpenGov) have
target="_blank"but norel. Add:
rel="noopener noreferrer" - Footer badges (USA.gov, OpenGov) have
🟠 Accessibility (quick wins)
- “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-expandedand anhiddenattribute (or a CSSaria-[expanded]selector) on#banner-content.
- ARIA menu roles used on site nav
- Primary nav uses
role="menubar",role="menuitem", and submenusrole="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 plusaria-expandedon 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
hiddenandaria-expanded.
- Primary nav uses
- Icon images that are decorative
- A number of icon
<img>tags (e.g., caret, dot-gov/https icons, some card icons) should bealt=""+aria-hidden="true"and/or moved to background CSS to reduce verbosity. Keep meaningful ones with realalttext.
- A number of icon
- 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-describedbyoffscreen ID referenced by the<video>for discoverability.
- Dates are not machine-readable
- Render human dates with
<time datetime="YYYY-MM-DD">…</time>. E.g., “Last Update: August 22, 2025”.
- Render human dates with
⚡ Performance (LCP/CLS)
- Hero media priority
- For the topmost, above-fold imagery, add
fetchpriority="high"anddecoding="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).
- Intrinsic size placeholder
- Where images don’t have explicit
width/height, setwidthandheight(oraspect-ratio) to avoid layout shifts. You already supply manywidth/height; keep it consistent on all large images (e.g.,hmpg-function-banner-final.jpg).
- 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.jsas module) — keep pushing non-critical scripts to the end,defer’ed.
- Respect reduced motion
- If the “lightbox” or dropdowns animate, disable transitions under
@media (prefers-reduced-motion: reduce).
🔐 Security / privacy
- 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 thenonceuniformly or move code to external files. Plan: adopt a single nonce for all inline<script>or externalize them.
- SRI & preconnect for third-party
- Add
rel="preconnect" crossoriginfor Brightcove:
<link rel="preconnect" href="https://players.brightcove.net" crossorigin>
- Add SRI where possible for static third-party scripts.
🔎 SEO polish
- 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.
- OpenGraph image alt
- You already include
og:image:alt👍. Keep alt succinct and descriptive.
🧼 UI/UX misc
- 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).
- Back-to-top link
- It points to
href="#". Considerhref="#top"with an actualid="top"sentinel to avoid browser jumping to document start unexpectedly, or use a button with JS scroll behavior andaria-label="Back to top"(you already have sr-only text).
- “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.