1) Accessibility & motion-safety (top win)
Respect “Reduce Motion” and stop the hero carousel
<style>
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; transition: none !important; }
.featured .featured-slider { animation: none !important; }
}
</style>
<script>
// Pause the slider if the user prefers reduced motion
(function () {
var m = window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)');
function maybePause() {
var $ = window.jQuery;
if (!($ && $('.featured-slider').slick)) return;
if (m && m.matches) {
$('.featured-slider').slick('slickPause')
.slick('slickSetOption','autoplay',false,true);
var btn = document.getElementById('play-pause-button');
if (btn) { btn.classList.add('paused'); btn.setAttribute('aria-label','Play'); }
}
}
document.addEventListener('DOMContentLoaded', maybePause);
if (m) m.addEventListener('change', maybePause);
}());
</script>
Landmark labeling (screen reader clarity)
<nav class="header-menu" aria-labelledby="header-menu-button" aria-label="Primary"></nav>
<nav class="breadcrumbs-wrapper" aria-label="Breadcrumb">…</nav>
<nav class="horizontal-scrolling-navigation-wrapper" aria-label="Programs & services">…</nav>
<footer class="footer" role="contentinfo" aria-label="Site footer">…</footer>
<section class="featured" aria-label="Featured items">…</section>
<section class="trending" aria-label="Trending">…</section>
<section class="your-library" aria-label="Your Library">…</section>
<section class="public-domain" aria-label="Free to Use and Reuse: Teachers and Students">…</section>
Search form: unique, explicit label on the input
(You already provide a visible label; keep it tied to the input via for/id.)
<label for="search" class="screen-readers-only">Search the Library of Congress</label>
<input type="search" id="search" name="q" … />
2) LCP / Core Web Vitals: make the hero image “priority”
Your LCP is almost certainly the first slide image. Hint it to the browser:
<link rel="preload" as="image"
href="/static/home/images/featured/nbf/2025-natbookfest2_1200x560.jpg"
fetchpriority="high" imagesrcset="/static/home/images/featured/nbf/2025-natbookfest2_1200x560.jpg 1x">
Also add fetchpriority="high" on that <img> itself:
<img src="/static/home/images/featured/nbf/2025-natbookfest2_1200x560.jpg"
alt="Library of Congress National Book Festival 25-year multi-color graphic"
fetchpriority="high">
(Keep loading="lazy" on below-the-fold images; you already do this in “Trending”.)
3) Head/meta correctness & SEO polish
- Fix canonical (use link, not meta; use https; full domain):
<link rel="canonical" href="https://www.loc.gov/">
og:typeshould bewebsitefor a homepage:
<meta property="og:type" content="website">
- Add structured data with on-site search action:
<script type="application/ld+json">
{
"@context":"https://schema.org",
"@type":"WebSite",
"name":"Library of Congress",
"url":"https://www.loc.gov/",
"potentialAction":{
"@type":"SearchAction",
"target":"https://www.loc.gov/search/?q={search_term_string}",
"query-input":"required name=search_term_string"
}
}
</script>
- Resource hints for critical domains:
<link rel="preconnect" href="https://www.loc.gov" crossorigin>
<link rel="preconnect" href="https://cdn.loc.gov" crossorigin>
<link rel="preconnect" href="https://assets.adobedtm.com" crossorigin>
<link rel="preconnect" href="https://media.loc.gov" crossorigin>
4) Script loading & performance
You’re loading jQuery 1.8.2 (2012) synchronously and relying on .live() (deprecated since 1.9). Two safe options:
Option A (quick): keep versions, avoid blocking render
<script src="/static/js/lib/jquery-1.8.2.js" defer></script>
<!-- move inline jQuery code blocks *after* this script, also with defer -->
<script defer>jQuery(function($){ /* existing handlers */ });</script>
Why:
deferqueues parsing until after HTML, preserving execution order among deferred scripts, improving FCP/LCP.
Option B (better): upgrade to jQuery 3.x and replace .live() with .on()
Example conversions:
// BEFORE
$('.header-logo a').live('click', handler);
// AFTER
$(document).on('click', '.header-logo a', handler);
// BEFORE
$('.header-menu').live('hover', over, out);
// AFTER (hover shortcut preserved)
$('.header-menu').on('mouseenter', function(e){ over.call(this,e); })
.on('mouseleave', function(e){ out.call(this,e); });
(Do a global find for .live( across header, breadcrumbs, menu, search, footer bindings.)
Passive listeners (scroll/drag) for smoother scrolling
You can safely switch some to passive:
window.addEventListener('scroll', onScroll, {passive:true});
horizontalScrollingNavigation.addEventListener('scroll', onScroll, {passive:true});
5) Security hygiene
- Add
rel="noopener noreferrer"to everytarget="_blank":
<a href="https://library-of-congress-shop.myshopify.com/" target="_blank" rel="noopener noreferrer">Shop …</a>
- Consider a Content-Security-Policy header (at least script/style nonces for inline blocks) on the server side. It will also help rein in third-party tags.
- Use HTTPS everywhere (you still have a few
http:///protocol-relative references in Open Graph & elsewhere).
6) Video player a11y & perf niceties
- Add
controlslist="nodownload"if desired andplaysinlinefor mobile:
<video controls preload="metadata" playsinline controlslist="nodownload" …>
- Poster already present (good). Keep captions (
<track>)—great for a11y. - For users with reduced motion, the script above doesn’t auto-play; your player already requires user interaction to play, which is good.
7) Minor accessibility/content refinements
- Ensure unique link text when repeating “Read more / Learn more” patterns—yours are already mostly descriptive; keep it that way.
- Social icons already have
alt—good. Make sure the visible label (e.g., title) matches what screen readers announce meaningfully. - The “Back to top” button already sets focus to
#top—👍.
8) Fonts & CLS
- You preload fonts (great). In your CSS, ensure
font-display:swap;on the@font-facerules to avoid FOIT. - You’re setting width/height on most images and using aspect-ratio for tiles—good for CLS.
Paste-ready micro-patch bundle
Canonical + OG type
<link rel="canonical" href="https://www.loc.gov/">
<meta property="og:type" content="website">
Resource hints
<link rel="preconnect" href="https://www.loc.gov" crossorigin>
<link rel="preconnect" href="https://cdn.loc.gov" crossorigin>
<link rel="preconnect" href="https://assets.adobedtm.com" crossorigin>
<link rel="preconnect" href="https://media.loc.gov" crossorigin>
Hero preload
<link rel="preload" as="image"
href="/static/home/images/featured/nbf/2025-natbookfest2_1200x560.jpg"
fetchpriority="high">
Reduced motion + slider pause (from §1).
Safer external links (pattern):
<a href="https://newsroom.loc.gov/…" target="_blank" rel="noopener noreferrer">…</a>
If you’d like, I can provide a small PR-style diff (head block + aria labels + defer + reduced-motion script + external link rels) sized to this exact file so you can drop it in with minimal churn.