[object Object]

← back to Paul Conrad Cartoons Shadowman

Add verified cartoon images, topic tags, and a full nav bar

7995bcdc17c40e2b82e562aaad04dd4ee879aa54 · 2026-09-24 13:28:17 -0700 · Steve Abrams

- Sourced 11 new verified cartoon images: all 10 Library of Congress items
  via loc.gov's own full-resolution service derivatives (visually confirmed
  against each item's cataloged title/subject), plus one more (Nast 1982
  homage) via Spartacus Educational. Reused 6 already-verified images as
  clearly-labeled representative images for the 3 Pulitzer-year and 3
  archive-collection-summary records (year-of-work awards and finding aids
  name no single cartoon). 25 of 38 records now show a verified image
  (up from 8); the remaining 13 documented cartoons have no digitized copy
  found anywhere free and show an honest "no verified image found" placeholder
  linking to the citation source.
- Added a topics[] array to all 38 records (Nixon/Watergate, Vietnam War,
  Civil Rights, Nuclear Arms & Cold War, Reagan Era, Iran-Contra, Space Race,
  Gun Politics, Media & Press, Economy, Religion, LA/California, and more),
  shown as chips on cards and in the modal.
- Rebuilt the header into a sticky top nav: wordmark, section links
  (Cartoons / Pulitzers / Library of Congress / Archives / Bio), a
  horizontally-scrollable topic-chip row with live counts, a search box,
  and a decade quick-jump (50s-00s). Bio opens in the existing modal.
  Added a Topic A-Z sort option; all choices persist to localStorage.
  Collapses to a hamburger menu at mobile widths with no horizontal
  page scroll (verified at 390px).
- artifact/ (the metadata-only shareable build) is untouched.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V29xaoBwcFwJyR4KC43ptn

Files touched

Diff

commit 7995bcdc17c40e2b82e562aaad04dd4ee879aa54
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Sep 24 13:28:17 2026 -0700

    Add verified cartoon images, topic tags, and a full nav bar
    
    - Sourced 11 new verified cartoon images: all 10 Library of Congress items
      via loc.gov's own full-resolution service derivatives (visually confirmed
      against each item's cataloged title/subject), plus one more (Nast 1982
      homage) via Spartacus Educational. Reused 6 already-verified images as
      clearly-labeled representative images for the 3 Pulitzer-year and 3
      archive-collection-summary records (year-of-work awards and finding aids
      name no single cartoon). 25 of 38 records now show a verified image
      (up from 8); the remaining 13 documented cartoons have no digitized copy
      found anywhere free and show an honest "no verified image found" placeholder
      linking to the citation source.
    - Added a topics[] array to all 38 records (Nixon/Watergate, Vietnam War,
      Civil Rights, Nuclear Arms & Cold War, Reagan Era, Iran-Contra, Space Race,
      Gun Politics, Media & Press, Economy, Religion, LA/California, and more),
      shown as chips on cards and in the modal.
    - Rebuilt the header into a sticky top nav: wordmark, section links
      (Cartoons / Pulitzers / Library of Congress / Archives / Bio), a
      horizontally-scrollable topic-chip row with live counts, a search box,
      and a decade quick-jump (50s-00s). Bio opens in the existing modal.
      Added a Topic A-Z sort option; all choices persist to localStorage.
      Collapses to a hamburger menu at mobile widths with no horizontal
      page scroll (verified at 390px).
    - artifact/ (the metadata-only shareable build) is untouched.
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01V29xaoBwcFwJyR4KC43ptn
---
 .gitignore                                      |   1 +
 data/cartoons.json                              | 357 +++++++++++++++++-------
 public/app.js                                   | 213 ++++++++++++--
 public/img/loc-barroom-1989.jpg                 | Bin 0 -> 163616 bytes
 public/img/loc-black-teen-unemployment-1977.jpg | Bin 0 -> 211831 bytes
 public/img/loc-death-row-1991.jpg               | Bin 0 -> 43583 bytes
 public/img/loc-disarmament-1961.jpg             | Bin 0 -> 210940 bytes
 public/img/loc-herblock-2000.jpg                | Bin 0 -> 85161 bytes
 public/img/loc-inheritance-1990.jpg             | Bin 0 -> 126861 bytes
 public/img/loc-naked-truth-1987.jpg             | Bin 0 -> 125972 bytes
 public/img/loc-nra-pacifier-1982.jpg            | Bin 0 -> 117818 bytes
 public/img/loc-sl-hud-1989.jpg                  | Bin 0 -> 87031 bytes
 public/img/loc-southamerica-1959.jpg            | Bin 0 -> 101159 bytes
 public/img/nast-affixing-blame-1982.jpg         | Bin 0 -> 38144 bytes
 public/index.html                               |  38 ++-
 public/style.css                                | 193 ++++++++++++-
 16 files changed, 659 insertions(+), 143 deletions(-)

diff --git a/.gitignore b/.gitignore
index 1924158..69e7414 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@ tmp/
 dist/
 build/
 .next/
+shots/
diff --git a/data/cartoons.json b/data/cartoons.json
index 41d9b76..38ede02 100644
--- a/data/cartoons.json
+++ b/data/cartoons.json
@@ -1,5 +1,5 @@
 {
-  "generated_note": "Paul Conrad (1924-2010) research catalog. Compiled 2026-09-24 from pulitzer.org, Library of Congress, The Pop History Dig, Encyclopedia.com, Wikipedia, Spartacus Educational, Toons Mag, the 2010 AP obituary, and the OAC/Huntington, Syracuse, and Wichita State finding aids. RIGHTS: no public-domain/open-license Conrad cartoon image exists; all works are copyright Los Angeles Times or the Conrad estate. The 8 locally-shown thumbnails are low-res retrospective reproductions displayed for PRIVATE reference only, each credited; every other record links out to view at the holding source.",
+  "generated_note": "Paul Conrad (1924-2010) research catalog. Compiled 2026-09-24 from pulitzer.org, Library of Congress, The Pop History Dig, Encyclopedia.com, Wikipedia, Spartacus Educational, Toons Mag, the 2010 AP obituary, and the OAC/Huntington, Syracuse, and Wichita State finding aids. Updated 2026-09-24 (image pass): all 10 Library of Congress items were digitized via loc.gov's own full-resolution derivatives (v/r service files, ~800-1024px), downloaded and visually verified against each item's cataloged title/subject; one additional documented cartoon ('Affixing Blame for Our Economic Problems', 1982) was verified via Spartacus Educational; the 3 Pulitzer-year and 3 archive-collection-summary records show a clearly-labeled REPRESENTATIVE cartoon from the matching era/collection, reusing an already-verified image (year-of-work Pulitzers and finding aids name no single cartoon, so none is the literal prize-winning or catalogued work). 25 of 38 records now show a verified image; the remaining 13 documented cartoons (no digitized copy located anywhere free) show a 'no verified image found' placeholder linking to the citation source. RIGHTS: no public-domain/open-license Conrad cartoon image exists; all works are copyright Los Angeles Times, Denver Post, or the Conrad estate; every image here is a low-res reproduction shown for PRIVATE, non-published reference only, each credited to its source.",
   "bio": {
     "name": "Paul Francis Conrad",
     "born": "1924-06-27, Cedar Rapids, Iowa",
@@ -19,11 +19,16 @@
       "subject": "Body of editorial cartooning during the prior year. Citation (verbatim): \"For his editorial cartooning during the past year.\" The prize is a year-of-work award; no single cartoon is named.",
       "award": "Pulitzer Prize for Editorial Cartooning 1964",
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
-      "image_source": null,
-      "rights_note": "Official Pulitzer winner page names no specific cartoon and displays no image.",
-      "citation_url": "https://www.pulitzer.org/winners/paul-conrad"
+      "image": "img/loc-disarmament-1961.jpg",
+      "image_url": "https://tile.loc.gov/storage-services/service/pnp/ppmsca/09400/09425v.jpg",
+      "image_source": "Library of Congress",
+      "rights_note": "REPRESENTATIVE IMAGE — not the specific prize-winning work (the 1964 Pulitzer is a year-of-work citation naming no single cartoon). Shown: Conrad's 1961 Denver Post Cold War disarmament cartoon, the closest verified image from his Denver Post years.",
+      "citation_url": "https://www.pulitzer.org/winners/paul-conrad",
+      "topics": [
+        "Awards & Career",
+        "Denver Post Era"
+      ],
+      "representative": true
     },
     {
       "id": "pulitzer-1971",
@@ -33,11 +38,17 @@
       "subject": "Body of editorial cartooning during 1970 (Nixon era, Vietnam War). Year-of-work award; no single cartoon named.",
       "award": "Pulitzer Prize for Editorial Cartooning 1971",
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
-      "image_source": null,
-      "rights_note": "No specific cartoon named; no official image.",
-      "citation_url": "https://www.pulitzer.org/winners/paul-conrad"
+      "image": "img/phone-company-1972.jpg",
+      "image_url": "https://pophistorydig.com/wp-content/uploads/2011/05/Phone-Company-300.jpg",
+      "image_source": "The Pop History Dig",
+      "rights_note": "REPRESENTATIVE IMAGE — not the specific prize-winning work (the 1971 Pulitzer is a year-of-work citation for 1970 Nixon/Vietnam-era cartooning, naming no single cartoon). Shown: Conrad's 1972 Nixon/Watergate cartoon, the closest verified image from that era.",
+      "citation_url": "https://www.pulitzer.org/winners/paul-conrad",
+      "topics": [
+        "Awards & Career",
+        "Nixon/Watergate",
+        "Vietnam War"
+      ],
+      "representative": true
     },
     {
       "id": "pulitzer-1984",
@@ -47,13 +58,19 @@
       "subject": "Body of editorial cartooning during the prior year (Reagan-era themes: homelessness, nuclear arms, corporate/political power). Year-of-work award; no single cartoon named.",
       "award": "Pulitzer Prize for Editorial Cartooning 1984",
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
-      "image_source": null,
-      "rights_note": "No specific cartoon named; no official image displayed.",
-      "citation_url": "https://www.pulitzer.org/winners/paul-conrad"
+      "image": "img/reagan-american-gothic-1986.jpg",
+      "image_url": "https://pophistorydig.com/wp-content/uploads/2011/05/1986-Reagan-1-260.jpg",
+      "image_source": "The Pop History Dig",
+      "rights_note": "REPRESENTATIVE IMAGE — not the specific prize-winning work (the 1984 Pulitzer is a year-of-work citation for Reagan-era cartooning, naming no single cartoon). Shown: Conrad's 1986 Reagan 'American Gothic' cartoon, the closest verified image from that era.",
+      "citation_url": "https://www.pulitzer.org/winners/paul-conrad",
+      "topics": [
+        "Awards & Career",
+        "Reagan Era",
+        "Economy",
+        "Nuclear Arms & Cold War"
+      ],
+      "representative": true
     },
-
     {
       "id": "obit-phone-company-1972",
       "title": "He says he's from the phone company…",
@@ -66,7 +83,10 @@
       "image_url": "https://pophistorydig.com/wp-content/uploads/2011/05/Phone-Company-300.jpg",
       "image_source": "The Pop History Dig",
       "rights_note": "© Los Angeles Times / Conrad estate. Low-res reproduction shown for private reference only; view in context at the source.",
-      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/"
+      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/",
+      "topics": [
+        "Nixon/Watergate"
+      ]
     },
     {
       "id": "obit-worst-enemy-1973",
@@ -80,7 +100,10 @@
       "image_url": "https://pophistorydig.com/wp-content/uploads/2011/05/Worst-Enemy-370.jpg",
       "image_source": "The Pop History Dig",
       "rights_note": "© Los Angeles Times / Conrad estate. Low-res reproduction shown for private reference only.",
-      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/"
+      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/",
+      "topics": [
+        "Nixon/Watergate"
+      ]
     },
     {
       "id": "obit-spiders-web-1973",
@@ -94,7 +117,10 @@
       "image_url": "https://pophistorydig.com/wp-content/uploads/2011/05/Nixon-Spiders-Web333.jpg",
       "image_source": "The Pop History Dig",
       "rights_note": "© Los Angeles Times / Conrad estate. Low-res reproduction shown for private reference only.",
-      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/"
+      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/",
+      "topics": [
+        "Nixon/Watergate"
+      ]
     },
     {
       "id": "obit-come-get-me-1974",
@@ -108,7 +134,10 @@
       "image_url": "https://pophistorydig.com/wp-content/uploads/2011/05/Come-Get-Me-310.jpg",
       "image_source": "The Pop History Dig",
       "rights_note": "© Los Angeles Times / Conrad estate. Low-res reproduction shown for private reference only.",
-      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/"
+      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/",
+      "topics": [
+        "Nixon/Watergate"
+      ]
     },
     {
       "id": "obit-lbj-hubert-1968",
@@ -122,7 +151,12 @@
       "image_url": "https://pophistorydig.com/wp-content/uploads/2011/05/1968-LBJ-w-Hubert280.jpg",
       "image_source": "The Pop History Dig",
       "rights_note": "© Los Angeles Times / Conrad estate. Low-res reproduction shown for private reference only.",
-      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/"
+      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/",
+      "topics": [
+        "Vietnam War",
+        "Elections & Campaigns",
+        "Presidency"
+      ]
     },
     {
       "id": "obit-reagan-gothic-1986",
@@ -136,7 +170,11 @@
       "image_url": "https://pophistorydig.com/wp-content/uploads/2011/05/1986-Reagan-1-260.jpg",
       "image_source": "The Pop History Dig",
       "rights_note": "© Los Angeles Times / Conrad estate. Low-res reproduction shown for private reference only.",
-      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/"
+      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/",
+      "topics": [
+        "Reagan Era",
+        "Economy"
+      ]
     },
     {
       "id": "obit-clinton-horn-1994",
@@ -150,7 +188,11 @@
       "image_url": "https://pophistorydig.com/wp-content/uploads/2011/05/Clinton-elephant-300.jpg",
       "image_source": "The Pop History Dig",
       "rights_note": "© Los Angeles Times / Conrad estate. Low-res reproduction shown for private reference only.",
-      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/"
+      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/",
+      "topics": [
+        "Clinton Era",
+        "GOP/Republican Party"
+      ]
     },
     {
       "id": "obit-palin-2008",
@@ -164,7 +206,11 @@
       "image_url": "https://pophistorydig.com/wp-content/uploads/2011/05/2008-Palin-260.jpg",
       "image_source": "The Pop History Dig",
       "rights_note": "© Conrad estate. Low-res reproduction shown for private reference only.",
-      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/"
+      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-political-cartoons/",
+      "topics": [
+        "GOP/Republican Party",
+        "Elections & Campaigns"
+      ]
     },
     {
       "id": "obit-cuckoos-nest-1974",
@@ -178,7 +224,11 @@
       "image_url": null,
       "image_source": null,
       "rights_note": "Described in the 2010 Associated Press obituary; no rights-clear image located.",
-      "citation_url": "https://www.nevadaappeal.com/news/2010/sep/05/pulitzer-winning-cartoonist-paul-conrad-dies-at-86/"
+      "citation_url": "https://www.nevadaappeal.com/news/2010/sep/05/pulitzer-winning-cartoonist-paul-conrad-dies-at-86/",
+      "topics": [
+        "Nixon/Watergate"
+      ],
+      "image_status": "not_found"
     },
     {
       "id": "obit-nixon-cross-1974",
@@ -192,7 +242,12 @@
       "image_url": null,
       "image_source": null,
       "rights_note": "Described in Wikipedia and the LOC LCIB profile; no rights-clear image located.",
-      "citation_url": "https://en.wikipedia.org/wiki/Paul_Conrad"
+      "citation_url": "https://en.wikipedia.org/wiki/Paul_Conrad",
+      "topics": [
+        "Nixon/Watergate",
+        "Religion"
+      ],
+      "image_status": "not_found"
     },
     {
       "id": "obit-yorty-1969",
@@ -206,7 +261,12 @@
       "image_url": null,
       "image_source": null,
       "rights_note": "Described in Wikipedia and the Toons Mag profile.",
-      "citation_url": "https://en.wikipedia.org/wiki/Paul_Conrad"
+      "citation_url": "https://en.wikipedia.org/wiki/Paul_Conrad",
+      "topics": [
+        "LA/California",
+        "Media & Press"
+      ],
+      "image_status": "not_found"
     },
     {
       "id": "obit-apollo1-1967",
@@ -220,7 +280,11 @@
       "image_url": null,
       "image_source": null,
       "rights_note": "Described in the Encyclopedia.com entry.",
-      "citation_url": "https://www.encyclopedia.com/humanities/encyclopedias-almanacs-transcripts-and-maps/conrad-paul"
+      "citation_url": "https://www.encyclopedia.com/humanities/encyclopedias-almanacs-transcripts-and-maps/conrad-paul",
+      "topics": [
+        "Space Race"
+      ],
+      "image_status": "not_found"
     },
     {
       "id": "obit-apollo11-1969",
@@ -234,7 +298,11 @@
       "image_url": null,
       "image_source": null,
       "rights_note": "Described in the Encyclopedia.com entry.",
-      "citation_url": "https://www.encyclopedia.com/humanities/encyclopedias-almanacs-transcripts-and-maps/conrad-paul"
+      "citation_url": "https://www.encyclopedia.com/humanities/encyclopedias-almanacs-transcripts-and-maps/conrad-paul",
+      "topics": [
+        "Space Race"
+      ],
+      "image_status": "not_found"
     },
     {
       "id": "obit-moratorium-1969",
@@ -248,7 +316,11 @@
       "image_url": null,
       "image_source": null,
       "rights_note": "Described in the Encyclopedia.com entry (year given; exact day uncertain).",
-      "citation_url": "https://www.encyclopedia.com/humanities/encyclopedias-almanacs-transcripts-and-maps/conrad-paul"
+      "citation_url": "https://www.encyclopedia.com/humanities/encyclopedias-almanacs-transcripts-and-maps/conrad-paul",
+      "topics": [
+        "Vietnam War"
+      ],
+      "image_status": "not_found"
     },
     {
       "id": "obit-burro-denver",
@@ -262,7 +334,12 @@
       "image_url": null,
       "image_source": null,
       "rights_note": "Described in the Encyclopedia.com entry.",
-      "citation_url": "https://www.encyclopedia.com/humanities/encyclopedias-almanacs-transcripts-and-maps/conrad-paul"
+      "citation_url": "https://www.encyclopedia.com/humanities/encyclopedias-almanacs-transcripts-and-maps/conrad-paul",
+      "topics": [
+        "Media & Press",
+        "Denver Post Era"
+      ],
+      "image_status": "not_found"
     },
     {
       "id": "obit-nast-1982",
@@ -272,11 +349,15 @@
       "subject": "After Thomas Nast's 1871 'Who Stole the People's Money?' ring cartoon — Reagan-era economy / passing the blame",
       "award": null,
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
-      "image_source": null,
-      "rights_note": "Described in the Spartacus Educational profile.",
-      "citation_url": "https://spartacus-educational.com/ARTconrad.htm"
+      "image": "img/nast-affixing-blame-1982.jpg",
+      "image_url": "https://spartacus-educational.com/ARTconrad.jpg",
+      "image_source": "Spartacus Educational",
+      "rights_note": "© Los Angeles Times / Conrad estate. Low-res reproduction (401x451) shown for private reference only; verified by visual inspection — matches the captioned 'Affixing Blame for Our Economic Problems' (30 Sept 1982), Conrad's homage to Thomas Nast's 1871 Tammany Ring cartoon.",
+      "citation_url": "https://spartacus-educational.com/ARTconrad.htm",
+      "topics": [
+        "Economy",
+        "Reagan Era"
+      ]
     },
     {
       "id": "obit-reagan-selfportrait-1984",
@@ -290,7 +371,12 @@
       "image_url": null,
       "image_source": null,
       "rights_note": "Described in the Library of Congress LCIB profile.",
-      "citation_url": "https://www.loc.gov/loc/lcib/9910/conrad.html"
+      "citation_url": "https://www.loc.gov/loc/lcib/9910/conrad.html",
+      "topics": [
+        "Reagan Era",
+        "Elections & Campaigns"
+      ],
+      "image_status": "not_found"
     },
     {
       "id": "obit-littlerock-1958",
@@ -304,7 +390,12 @@
       "image_url": null,
       "image_source": null,
       "rights_note": "Listed in The Pop History Dig retrospective.",
-      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-enemies-list/"
+      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-enemies-list/",
+      "topics": [
+        "Civil Rights",
+        "Denver Post Era"
+      ],
+      "image_status": "not_found"
     },
     {
       "id": "obit-lbj-blankcheck-1964",
@@ -318,7 +409,12 @@
       "image_url": null,
       "image_source": null,
       "rights_note": "Listed in The Pop History Dig retrospective.",
-      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-enemies-list/"
+      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-enemies-list/",
+      "topics": [
+        "Vietnam War",
+        "Presidency"
+      ],
+      "image_status": "not_found"
     },
     {
       "id": "obit-ford-pardon-1974",
@@ -332,7 +428,12 @@
       "image_url": null,
       "image_source": null,
       "rights_note": "Listed in The Pop History Dig retrospective.",
-      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-enemies-list/"
+      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-enemies-list/",
+      "topics": [
+        "Nixon/Watergate",
+        "Presidency"
+      ],
+      "image_status": "not_found"
     },
     {
       "id": "obit-richard-ii-1973",
@@ -346,7 +447,11 @@
       "image_url": null,
       "image_source": null,
       "rights_note": "Listed in The Pop History Dig retrospective.",
-      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-enemies-list/"
+      "citation_url": "https://pophistorydig.com/topics/tag/paul-conrad-enemies-list/",
+      "topics": [
+        "Nixon/Watergate"
+      ],
+      "image_status": "not_found"
     },
     {
       "id": "obit-popepaulvi-1977",
@@ -360,9 +465,12 @@
       "image_url": null,
       "image_source": null,
       "rights_note": "Described in the Toons Mag profile.",
-      "citation_url": "https://www.toonsmag.com/paul-conrad/"
+      "citation_url": "https://www.toonsmag.com/paul-conrad/",
+      "topics": [
+        "Religion"
+      ],
+      "image_status": "not_found"
     },
-
     {
       "id": "loc-sl-hud-1989",
       "title": "S&L's and HUD",
@@ -371,11 +479,15 @@
       "subject": "Savings & Loan / HUD scandals vs. Teapot Dome; pot-calling-kettle-black",
       "award": null,
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
+      "image": "img/loc-sl-hud-1989.jpg",
+      "image_url": "https://tile.loc.gov/storage-services/service/pnp/cph/3c30000/3c36000/3c36100/3c36115v.jpg",
       "image_source": "Library of Congress",
-      "rights_note": "May be restricted: Copyright 1989, The Los Angeles Times. LOC holds a digitized copy — view via the catalog link; not embedded here.",
-      "citation_url": "https://www.loc.gov/item/2016685149/"
+      "rights_note": "© Los Angeles Times / Conrad estate (Denver Post for pre-1964 work). Digitized reproduction from the Library of Congress Prints & Photographs Online Catalog, shown low-res for private research reference only — verified by visual inspection against the LOC catalog description. LOC states it does not own rights and cannot license use; view the official record at the citation link before any other use.",
+      "citation_url": "https://www.loc.gov/item/2016685149/",
+      "topics": [
+        "Economy",
+        "Government Scandal"
+      ]
     },
     {
       "id": "loc-death-row-1991",
@@ -385,11 +497,14 @@
       "subject": "Six Supreme Court justices in a row; capital punishment",
       "award": null,
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
+      "image": "img/loc-death-row-1991.jpg",
+      "image_url": "https://tile.loc.gov/storage-services/service/pnp/cph/3c20000/3c21000/3c21900/3c21940r.jpg",
       "image_source": "Library of Congress",
-      "rights_note": "May be restricted: Copyright 1991, The Los Angeles Times. LOC holds a digitized copy — view via the catalog link.",
-      "citation_url": "https://www.loc.gov/item/2016685127/"
+      "rights_note": "© Los Angeles Times / Conrad estate (Denver Post for pre-1964 work). Digitized reproduction from the Library of Congress Prints & Photographs Online Catalog, shown low-res for private research reference only — verified by visual inspection against the LOC catalog description. LOC states it does not own rights and cannot license use; view the official record at the citation link before any other use.",
+      "citation_url": "https://www.loc.gov/item/2016685127/",
+      "topics": [
+        "Judiciary & Courts"
+      ]
     },
     {
       "id": "loc-disarmament-1961",
@@ -399,11 +514,15 @@
       "subject": "Cold War disarmament posturing",
       "award": null,
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
+      "image": "img/loc-disarmament-1961.jpg",
+      "image_url": "https://tile.loc.gov/storage-services/service/pnp/ppmsca/09400/09425v.jpg",
       "image_source": "Library of Congress",
-      "rights_note": "Rights status not evaluated by LOC — treat as non-embeddable.",
-      "citation_url": "https://www.loc.gov/item/2005685912/"
+      "rights_note": "© Los Angeles Times / Conrad estate (Denver Post for pre-1964 work). Digitized reproduction from the Library of Congress Prints & Photographs Online Catalog, shown low-res for private research reference only — verified by visual inspection against the LOC catalog description. LOC states it does not own rights and cannot license use; view the official record at the citation link before any other use.",
+      "citation_url": "https://www.loc.gov/item/2005685912/",
+      "topics": [
+        "Nuclear Arms & Cold War",
+        "Denver Post Era"
+      ]
     },
     {
       "id": "loc-herblock-2000",
@@ -413,11 +532,14 @@
       "subject": "Caricature of cartoonist Herblock as George Washington",
       "award": null,
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
+      "image": "img/loc-herblock-2000.jpg",
+      "image_url": "https://tile.loc.gov/storage-services/service/pnp/ppmsc/03400/03417v.jpg",
       "image_source": "Library of Congress",
-      "rights_note": "Publication may be restricted — treat as non-embeddable.",
-      "citation_url": "https://www.loc.gov/item/00652290/"
+      "rights_note": "© Los Angeles Times / Conrad estate (Denver Post for pre-1964 work). Digitized reproduction from the Library of Congress Prints & Photographs Online Catalog, shown low-res for private research reference only — verified by visual inspection against the LOC catalog description. LOC states it does not own rights and cannot license use; view the official record at the citation link before any other use.",
+      "citation_url": "https://www.loc.gov/item/00652290/",
+      "topics": [
+        "Media & Press"
+      ]
     },
     {
       "id": "loc-inheritance-1990",
@@ -427,11 +549,15 @@
       "subject": "Deficit / generational debt",
       "award": null,
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
+      "image": "img/loc-inheritance-1990.jpg",
+      "image_url": "https://tile.loc.gov/storage-services/service/pnp/cph/3g10000/3g13000/3g13000/3g13017v.jpg",
       "image_source": "Library of Congress",
-      "rights_note": "May be restricted: Copyright 1990, Los Angeles Times.",
-      "citation_url": "https://www.loc.gov/item/2016685135/"
+      "rights_note": "© Los Angeles Times / Conrad estate (Denver Post for pre-1964 work). Digitized reproduction from the Library of Congress Prints & Photographs Online Catalog, shown low-res for private research reference only — verified by visual inspection against the LOC catalog description. LOC states it does not own rights and cannot license use; view the official record at the citation link before any other use.",
+      "citation_url": "https://www.loc.gov/item/2016685135/",
+      "topics": [
+        "Reagan Era",
+        "Economy"
+      ]
     },
     {
       "id": "loc-nra-pacifier-1982",
@@ -441,11 +567,14 @@
       "subject": "Gun politics / NRA",
       "award": null,
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
+      "image": "img/loc-nra-pacifier-1982.jpg",
+      "image_url": "https://tile.loc.gov/storage-services/service/pnp/cph/3c30000/3c33000/3c33000/3c33005v.jpg",
       "image_source": "Library of Congress",
-      "rights_note": "May be restricted: Copyright 1982, The Los Angeles Times.",
-      "citation_url": "https://www.loc.gov/item/2016685176/"
+      "rights_note": "© Los Angeles Times / Conrad estate (Denver Post for pre-1964 work). Digitized reproduction from the Library of Congress Prints & Photographs Online Catalog, shown low-res for private research reference only — verified by visual inspection against the LOC catalog description. LOC states it does not own rights and cannot license use; view the official record at the citation link before any other use.",
+      "citation_url": "https://www.loc.gov/item/2016685176/",
+      "topics": [
+        "Gun Politics"
+      ]
     },
     {
       "id": "loc-southamerica-1959",
@@ -455,11 +584,16 @@
       "subject": "Foreign-relations / South America policy",
       "award": null,
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
+      "image": "img/loc-southamerica-1959.jpg",
+      "image_url": "https://tile.loc.gov/storage-services/service/pnp/acd/2a07000/2a07600/2a07662r.jpg",
       "image_source": "Library of Congress",
-      "rights_note": "May be restricted — no affirmative open statement; treat as non-embeddable.",
-      "citation_url": "https://www.loc.gov/item/2016680206/"
+      "rights_note": "© Los Angeles Times / Conrad estate (Denver Post for pre-1964 work). Digitized reproduction from the Library of Congress Prints & Photographs Online Catalog, shown low-res for private research reference only — verified by visual inspection against the LOC catalog description. LOC states it does not own rights and cannot license use; view the official record at the citation link before any other use.",
+      "citation_url": "https://www.loc.gov/item/2016680206/",
+      "topics": [
+        "Foreign Policy",
+        "Media & Press",
+        "Denver Post Era"
+      ]
     },
     {
       "id": "loc-barroom-1989",
@@ -469,11 +603,15 @@
       "subject": "Political commentary (1989)",
       "award": null,
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
+      "image": "img/loc-barroom-1989.jpg",
+      "image_url": "https://tile.loc.gov/storage-services/service/pnp/cph/3c30000/3c32000/3c32800/3c32804v.jpg",
       "image_source": "Library of Congress",
-      "rights_note": "May be restricted: Copyright 1989, The Los Angeles Times.",
-      "citation_url": "https://www.loc.gov/item/2016685150/"
+      "rights_note": "© Los Angeles Times / Conrad estate (Denver Post for pre-1964 work). Digitized reproduction from the Library of Congress Prints & Photographs Online Catalog, shown low-res for private research reference only — verified by visual inspection against the LOC catalog description. LOC states it does not own rights and cannot license use; view the official record at the citation link before any other use.",
+      "citation_url": "https://www.loc.gov/item/2016685150/",
+      "topics": [
+        "Civil Rights",
+        "Judiciary & Courts"
+      ]
     },
     {
       "id": "loc-naked-truth-1987",
@@ -483,11 +621,15 @@
       "subject": "Political commentary (1987)",
       "award": null,
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
+      "image": "img/loc-naked-truth-1987.jpg",
+      "image_url": "https://tile.loc.gov/storage-services/service/pnp/cph/3c30000/3c33000/3c33900/3c33940v.jpg",
       "image_source": "Library of Congress",
-      "rights_note": "May be restricted: Copyright 1987, The Los Angeles Times.",
-      "citation_url": "https://www.loc.gov/item/2016685157/"
+      "rights_note": "© Los Angeles Times / Conrad estate (Denver Post for pre-1964 work). Digitized reproduction from the Library of Congress Prints & Photographs Online Catalog, shown low-res for private research reference only — verified by visual inspection against the LOC catalog description. LOC states it does not own rights and cannot license use; view the official record at the citation link before any other use.",
+      "citation_url": "https://www.loc.gov/item/2016685157/",
+      "topics": [
+        "Iran-Contra",
+        "Foreign Policy"
+      ]
     },
     {
       "id": "loc-black-teen-unemployment-1977",
@@ -497,13 +639,16 @@
       "subject": "Black youth unemployment",
       "award": null,
       "record_type": "documented",
-      "image": null,
-      "image_url": null,
+      "image": "img/loc-black-teen-unemployment-1977.jpg",
+      "image_url": "https://tile.loc.gov/storage-services/service/pnp/cph/3g10000/3g13000/3g13000/3g13019v.jpg",
       "image_source": "Library of Congress",
-      "rights_note": "May be restricted: Copyright 1977, Los Angeles Times.",
-      "citation_url": "https://www.loc.gov/item/2016685134/"
+      "rights_note": "© Los Angeles Times / Conrad estate (Denver Post for pre-1964 work). Digitized reproduction from the Library of Congress Prints & Photographs Online Catalog, shown low-res for private research reference only — verified by visual inspection against the LOC catalog description. LOC states it does not own rights and cannot license use; view the official record at the citation link before any other use.",
+      "citation_url": "https://www.loc.gov/item/2016685134/",
+      "topics": [
+        "Civil Rights",
+        "Economy"
+      ]
     },
-
     {
       "id": "coll-huntington",
       "title": "Paul Conrad Papers — The Huntington Library",
@@ -513,11 +658,15 @@
       "award": null,
       "record_type": "collection-summary",
       "extent": "272.41 linear feet (285 boxes). Identifier mssCON 1-12360. Cartoons in Boxes 1-106 + oversize 107-167, ~40-50 per box, each foldered.",
-      "image": null,
-      "image_url": null,
-      "image_source": null,
-      "rights_note": "No explicit access restriction stated. Preferred citation: '[item]. Paul Conrad Papers, The Huntington Library, San Marino, California.'",
-      "citation_url": "https://oac.cdlib.org/findaid/ark:/13030/c8z03dxd/"
+      "image": "img/nixon-spiders-web-1973.jpg",
+      "image_url": "https://pophistorydig.com/wp-content/uploads/2011/05/Nixon-Spiders-Web333.jpg",
+      "image_source": "The Pop History Dig",
+      "rights_note": "REPRESENTATIVE IMAGE — the Huntington holds ~285 boxes of Conrad originals (1959-2003); this is a verified Conrad Watergate-era cartoon shown to represent the collection's character, not a specific catalogued item from this finding aid.",
+      "citation_url": "https://oac.cdlib.org/findaid/ark:/13030/c8z03dxd/",
+      "topics": [
+        "Archive Collection"
+      ],
+      "representative": true
     },
     {
       "id": "coll-syracuse",
@@ -528,11 +677,15 @@
       "award": null,
       "record_type": "collection-summary",
       "extent": "~10 boxes; reported ~1,000+ original cartoons. Not stated in linear feet.",
-      "image": null,
-      "image_url": null,
-      "image_source": null,
-      "rights_note": "No access restriction noted in the guide.",
-      "citation_url": "https://library.syracuse.edu/digital/guides/c/conrad_p.htm"
+      "image": "img/worst-enemy-1973.jpg",
+      "image_url": "https://pophistorydig.com/wp-content/uploads/2011/05/Worst-Enemy-370.jpg",
+      "image_source": "The Pop History Dig",
+      "rights_note": "REPRESENTATIVE IMAGE — Syracuse holds 1,000+ original LA Times-era cartoons (bulk 1963-1969); this is a verified Conrad cartoon from that broad era shown to represent the collection's character, not a specific catalogued item from this finding aid.",
+      "citation_url": "https://library.syracuse.edu/digital/guides/c/conrad_p.htm",
+      "topics": [
+        "Archive Collection"
+      ],
+      "representative": true
     },
     {
       "id": "coll-wichita",
@@ -543,11 +696,15 @@
       "award": null,
       "record_type": "collection-summary",
       "extent": "2 linear feet. Identifier MS-90-18.",
-      "image": null,
-      "image_url": null,
-      "image_source": null,
-      "rights_note": "Literary rights NOT granted to Wichita State; permission to examine is not authorization to publish. Some items off-site (48h retrieval).",
-      "citation_url": "https://archivesspace.wichita.edu/repositories/3/resources/166"
+      "image": "img/lbj-hubert-1968.jpg",
+      "image_url": "https://pophistorydig.com/wp-content/uploads/2011/05/1968-LBJ-w-Hubert280.jpg",
+      "image_source": "The Pop History Dig",
+      "rights_note": "REPRESENTATIVE IMAGE — Wichita's collection covers exactly 1968-1971; this is a verified 1968 Conrad cartoon shown to represent the collection's character, not a specific catalogued item from this finding aid.",
+      "citation_url": "https://archivesspace.wichita.edu/repositories/3/resources/166",
+      "topics": [
+        "Archive Collection"
+      ],
+      "representative": true
     }
   ]
 }
diff --git a/public/app.js b/public/app.js
index 102661d..ef2568d 100644
--- a/public/app.js
+++ b/public/app.js
@@ -1,13 +1,18 @@
 // Paul Conrad Cartoons — private catalog viewer.
 // Loads /api/cartoons, renders a filterable/sortable grid with a density slider,
-// both persisted to localStorage. No server-side state beyond the static dataset.
+// a topic-chip + section + decade nav, and a detail modal. Choices persist to localStorage.
+// No server-side state beyond the static dataset.
 
 const LS_SORT = 'pcc:sort';
 const LS_DENSITY = 'pcc:density';
 const LS_FILTERS = 'pcc:filters';
 
 let ALL = [];
-let filters = { year: null, publication: null, award: null, subject: null, recordType: null };
+let BIO = null;
+let filters = {
+  year: null, publication: null, award: null, subject: null, recordType: null,
+  topic: null, section: 'all', decade: null,
+};
 
 function safeGetLS(key, fallback) {
   try {
@@ -25,23 +30,43 @@ function yearOf(rec) {
   return m ? m[0] : 'Unknown';
 }
 
+function decadeOf(rec) {
+  const y = parseInt(rec.year, 10);
+  if (!y) return null;
+  return String(Math.floor(y / 10) * 10);
+}
+
 function normalizeRecords(raw) {
-  return raw.map((r, i) => ({
-    id: r.id || `pc-${i}`,
-    title: r.title || 'Untitled',
-    date: r.date || r.date_range || null,
-    year: yearOf(r),
-    publication: r.publication || null,
-    subject: r.subject || null,
-    award: r.award || null,
-    record_type: r.record_type || 'documented',
-    extent: r.extent || null,
-    image: r.image || null,          // local downloaded path, preferred for display
-    image_url: r.image_url || null,  // external legitimate source, fallback
-    image_source: r.image_source || null,
-    rights_note: r.rights_note || null,
-    citation_url: r.citation_url || null,
-  }));
+  return raw.map((r, i) => {
+    const year = yearOf(r);
+    return {
+      id: r.id || `pc-${i}`,
+      title: r.title || 'Untitled',
+      date: r.date || r.date_range || null,
+      year,
+      decade: (() => { const y = parseInt(year, 10); return y ? String(Math.floor(y / 10) * 10) : null; })(),
+      publication: r.publication || null,
+      subject: r.subject || null,
+      award: r.award || null,
+      record_type: r.record_type || 'documented',
+      extent: r.extent || null,
+      topics: Array.isArray(r.topics) ? r.topics : [],
+      image: r.image || null,          // local downloaded path, preferred for display
+      image_url: r.image_url || null,  // external legitimate source, fallback
+      image_source: r.image_source || null,
+      image_status: r.image_status || null, // 'not_found' when no image exists anywhere
+      representative: !!r.representative,
+      rights_note: r.rights_note || null,
+      citation_url: r.citation_url || null,
+    };
+  });
+}
+
+function sectionOf(rec) {
+  if (rec.id.startsWith('pulitzer-')) return 'pulitzers';
+  if (rec.id.startsWith('loc-')) return 'loc';
+  if (rec.id.startsWith('coll-')) return 'archives';
+  return 'cartoons';
 }
 
 function buildFacet(records, field) {
@@ -54,6 +79,14 @@ function buildFacet(records, field) {
   return [...counts.entries()].sort((a, b) => b[1] - a[1] || String(a[0]).localeCompare(String(b[0])));
 }
 
+function buildTopicCounts(records) {
+  const counts = new Map();
+  for (const r of records) {
+    for (const t of r.topics) counts.set(t, (counts.get(t) || 0) + 1);
+  }
+  return [...counts.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));
+}
+
 function applyFilters(records) {
   const q = document.getElementById('search').value.trim().toLowerCase();
   return records.filter(r => {
@@ -62,8 +95,11 @@ function applyFilters(records) {
     if (filters.award && r.award !== filters.award) return false;
     if (filters.subject && r.subject !== filters.subject) return false;
     if (filters.recordType && r.record_type !== filters.recordType) return false;
+    if (filters.topic && !r.topics.includes(filters.topic)) return false;
+    if (filters.decade && r.decade !== filters.decade) return false;
+    if (filters.section && filters.section !== 'all' && filters.section !== 'bio' && sectionOf(r) !== filters.section) return false;
     if (q) {
-      const hay = [r.title, r.subject, r.publication, r.award, r.date].filter(Boolean).join(' ').toLowerCase();
+      const hay = [r.title, r.subject, r.publication, r.award, r.date, ...(r.topics || [])].filter(Boolean).join(' ').toLowerCase();
       if (!hay.includes(q)) return false;
     }
     return true;
@@ -76,6 +112,7 @@ function sortRecords(records, mode) {
     case 'year-asc': return arr.sort((a, b) => (a.year > b.year ? 1 : -1));
     case 'year-desc': return arr.sort((a, b) => (a.year < b.year ? 1 : -1));
     case 'title-az': return arr.sort((a, b) => a.title.localeCompare(b.title));
+    case 'topic-az': return arr.sort((a, b) => (a.topics[0] || 'zzz').localeCompare(b.topics[0] || 'zzz') || a.title.localeCompare(b.title));
     case 'award-first': return arr.sort((a, b) => (b.award ? 1 : 0) - (a.award ? 1 : 0));
     case 'newest':
     default: return arr; // natural/dataset order = "Newest"-equivalent default
@@ -89,7 +126,7 @@ function renderFacetGroup(containerId, field, label) {
     const activeKey = field === 'record_type' ? 'recordType' : field;
     const isActive = filters[activeKey] === val;
     return `<div class="filter-row${isActive ? ' active' : ''}" data-field="${field}" data-value="${encodeURIComponent(val)}">
-      <span>${val === 'documented' ? 'Documented cartoon' : val === 'collection-summary' ? 'Archive collection' : val}</span>
+      <span>${val === 'documented' ? 'Documented cartoon' : val === 'collection-summary' ? 'Archive collection' : escapeHtml(val)}</span>
       <span class="count">${count}</span>
     </div>`;
   }).join('');
@@ -114,20 +151,60 @@ function renderFilters() {
   renderFacetGroup('facet-recordtype', 'record_type', 'Record Type');
 }
 
+function renderTopicRow() {
+  const el = document.getElementById('topic-row');
+  const counts = buildTopicCounts(ALL);
+  const totalCount = ALL.length;
+  const allChip = `<button type="button" class="topic-chip${!filters.topic ? ' active' : ''}" data-topic="">All <span class="chip-count">${totalCount}</span></button>`;
+  const chips = counts.map(([topic, count]) => {
+    const isActive = filters.topic === topic;
+    return `<button type="button" class="topic-chip${isActive ? ' active' : ''}" data-topic="${encodeURIComponent(topic)}">${escapeHtml(topic)} <span class="chip-count">${count}</span></button>`;
+  }).join('');
+  el.innerHTML = allChip + chips;
+  el.querySelectorAll('.topic-chip').forEach(chip => {
+    chip.addEventListener('click', () => {
+      const t = chip.dataset.topic ? decodeURIComponent(chip.dataset.topic) : null;
+      filters.topic = (filters.topic === t) ? null : t;
+      safeSetLS(LS_FILTERS, filters);
+      renderAll();
+    });
+  });
+}
+
+function renderSectionLinks() {
+  document.querySelectorAll('#section-links button[data-section]').forEach(btn => {
+    btn.classList.toggle('active', filters.section === btn.dataset.section);
+  });
+}
+
+function renderDecadeJump() {
+  document.querySelectorAll('#decade-jump button[data-decade]').forEach(btn => {
+    btn.classList.toggle('active', filters.decade === btn.dataset.decade);
+  });
+}
+
 function cardHtml(r) {
   const img = r.image || r.image_url;
-  const thumb = img
-    ? `<img src="${img}" alt="${escapeHtml(r.title)}" loading="lazy">`
-    : `<div class="no-img">Not digitized —<br>see archive citation</div>`;
+  let thumb;
+  if (img) {
+    thumb = `<img src="${img}" alt="${escapeHtml(r.title)}" loading="lazy">`;
+  } else if (r.image_status === 'not_found') {
+    thumb = `<div class="no-img no-img-notfound">No verified image found —<br>view at source</div>`;
+  } else {
+    thumb = `<div class="no-img">Not digitized —<br>see archive citation</div>`;
+  }
   const badges = [
     `<span class="badge ${r.record_type}">${r.record_type === 'documented' ? 'Documented' : 'Archive'}</span>`,
-    r.award ? `<span class="badge award">Pulitzer</span>` : ''
+    r.award ? `<span class="badge award">Pulitzer</span>` : '',
+    r.representative ? `<span class="badge representative">Representative image</span>` : '',
   ].join('');
+  const topicChips = r.topics.slice(0, 3).map(t => `<span class="topic-tag">${escapeHtml(t)}</span>`).join('');
   return `<div class="card" data-id="${r.id}">
     <div class="thumb">${thumb}</div>
     <div class="body">
       <div class="title">${escapeHtml(r.title)}</div>
       <div class="meta">${escapeHtml(r.date || r.year || '')}${r.publication ? ' · ' + escapeHtml(r.publication) : ''}</div>
+      <div class="topics">${topicChips}</div>
       <div class="badges">${badges}</div>
     </div>
   </div>`;
@@ -152,6 +229,9 @@ function renderGrid() {
 
 function renderAll() {
   renderFilters();
+  renderTopicRow();
+  renderSectionLinks();
+  renderDecadeJump();
   renderGrid();
 }
 
@@ -159,11 +239,20 @@ function openModal(id) {
   const r = ALL.find(x => x.id === id);
   if (!r) return;
   const img = r.image || r.image_url;
+  const topicChips = r.topics.map(t => `<span class="topic-tag modal-topic-tag">${escapeHtml(t)}</span>`).join('');
+  let imgBlock = '';
+  if (img) {
+    const repBadge = r.representative ? `<div class="modal-rep-note">Representative image — see the credit note below.</div>` : '';
+    imgBlock = `<img class="modal-img" src="${img}" alt="${escapeHtml(r.title)}">${repBadge}`;
+  } else if (r.image_status === 'not_found') {
+    imgBlock = `<div class="modal-no-img">No verified image found for this cartoon.${r.citation_url ? ` <a href="${r.citation_url}" target="_blank" rel="noopener noreferrer">View at source →</a>` : ''}</div>`;
+  }
   document.getElementById('modal-body').innerHTML = `
     <button class="close-x" id="modal-close">&times;</button>
     <h2>${escapeHtml(r.title)}</h2>
     <div class="modal-meta">${escapeHtml(r.date || r.year || '')}${r.publication ? ' · ' + escapeHtml(r.publication) : ''}</div>
-    ${img ? `<img class="modal-img" src="${img}" alt="${escapeHtml(r.title)}">` : ''}
+    <div class="topics modal-topics">${topicChips}</div>
+    ${imgBlock}
     <dl>
       <dt>Subject</dt><dd>${escapeHtml(r.subject || '—')}</dd>
       <dt>Award</dt><dd>${escapeHtml(r.award || '—')}</dd>
@@ -177,8 +266,73 @@ function openModal(id) {
   document.getElementById('modal-backdrop').classList.add('open');
   document.getElementById('modal-close').addEventListener('click', closeModal);
 }
+
+function openBioModal() {
+  if (!BIO) return;
+  document.getElementById('modal-body').innerHTML = `
+    <button class="close-x" id="modal-close">&times;</button>
+    <h2>${escapeHtml(BIO.name || 'Paul Conrad')}</h2>
+    <div class="modal-meta">${escapeHtml(BIO.born || '')} — ${escapeHtml(BIO.died || '')}</div>
+    <dl>
+      <dt>Education</dt><dd>${escapeHtml(BIO.education || '—')}</dd>
+      <dt>Career</dt><dd>${escapeHtml(BIO.career || '—')}</dd>
+      <dt>Honors</dt><dd>${escapeHtml(BIO.honors || '—')}</dd>
+      <dt>Family</dt><dd>${escapeHtml(BIO.family || '—')}</dd>
+      <dt>Citation</dt><dd>${BIO.citation_url ? `<a href="${BIO.citation_url}" target="_blank" rel="noopener noreferrer">${escapeHtml(BIO.citation_url)}</a>` : '—'}</dd>
+    </dl>
+  `;
+  document.getElementById('modal-backdrop').classList.add('open');
+  document.getElementById('modal-close').addEventListener('click', closeModal);
+}
+
 function closeModal() { document.getElementById('modal-backdrop').classList.remove('open'); }
 
+function closeMobileNav() {
+  document.getElementById('topnav').classList.remove('nav-open');
+  document.getElementById('hamburger').setAttribute('aria-expanded', 'false');
+}
+
+function initNav() {
+  document.getElementById('hamburger').addEventListener('click', () => {
+    const nav = document.getElementById('topnav');
+    const isOpen = nav.classList.toggle('nav-open');
+    document.getElementById('hamburger').setAttribute('aria-expanded', String(isOpen));
+  });
+
+  document.getElementById('wordmark').addEventListener('click', (e) => {
+    e.preventDefault();
+    filters.section = 'all';
+    safeSetLS(LS_FILTERS, filters);
+    renderAll();
+    closeMobileNav();
+  });
+
+  document.querySelectorAll('#section-links button[data-section]').forEach(btn => {
+    btn.addEventListener('click', () => {
+      const section = btn.dataset.section;
+      if (section === 'bio') {
+        openBioModal();
+        closeMobileNav();
+        return;
+      }
+      filters.section = section;
+      safeSetLS(LS_FILTERS, filters);
+      renderAll();
+      closeMobileNav();
+    });
+  });
+
+  document.querySelectorAll('#decade-jump button[data-decade]').forEach(btn => {
+    btn.addEventListener('click', () => {
+      const d = btn.dataset.decade;
+      filters.decade = (filters.decade === d) ? null : d;
+      safeSetLS(LS_FILTERS, filters);
+      renderAll();
+      closeMobileNav();
+    });
+  });
+}
+
 function initControls() {
   const sortEl = document.getElementById('sort');
   sortEl.value = safeGetLS(LS_SORT, 'year-asc');
@@ -195,7 +349,7 @@ function initControls() {
 
   document.getElementById('search').addEventListener('input', renderGrid);
   document.getElementById('clear-filters').addEventListener('click', () => {
-    filters = { year: null, publication: null, award: null, subject: null, recordType: null };
+    filters = { year: null, publication: null, award: null, subject: null, recordType: null, topic: null, section: 'all', decade: null };
     safeSetLS(LS_FILTERS, filters);
     document.getElementById('search').value = '';
     renderAll();
@@ -205,13 +359,18 @@ function initControls() {
     if (e.target.id === 'modal-backdrop') closeModal();
   });
   document.addEventListener('keydown', (e) => { if (e.key === 'Escape') closeModal(); });
+
+  initNav();
 }
 
 async function boot() {
-  filters = safeGetLS(LS_FILTERS, filters);
+  const savedFilters = safeGetLS(LS_FILTERS, filters);
+  filters = { ...filters, ...savedFilters };
+  if (!filters.section) filters.section = 'all';
   const res = await fetch('/api/cartoons');
   const raw = await res.json();
   ALL = normalizeRecords(raw.records || raw);
+  BIO = raw.bio || null;
   initControls();
   renderAll();
 }
diff --git a/public/img/loc-barroom-1989.jpg b/public/img/loc-barroom-1989.jpg
new file mode 100644
index 0000000..5bd18ac
Binary files /dev/null and b/public/img/loc-barroom-1989.jpg differ
diff --git a/public/img/loc-black-teen-unemployment-1977.jpg b/public/img/loc-black-teen-unemployment-1977.jpg
new file mode 100644
index 0000000..0b4d5d4
Binary files /dev/null and b/public/img/loc-black-teen-unemployment-1977.jpg differ
diff --git a/public/img/loc-death-row-1991.jpg b/public/img/loc-death-row-1991.jpg
new file mode 100644
index 0000000..328d485
Binary files /dev/null and b/public/img/loc-death-row-1991.jpg differ
diff --git a/public/img/loc-disarmament-1961.jpg b/public/img/loc-disarmament-1961.jpg
new file mode 100644
index 0000000..4cf1ecf
Binary files /dev/null and b/public/img/loc-disarmament-1961.jpg differ
diff --git a/public/img/loc-herblock-2000.jpg b/public/img/loc-herblock-2000.jpg
new file mode 100644
index 0000000..e0973cb
Binary files /dev/null and b/public/img/loc-herblock-2000.jpg differ
diff --git a/public/img/loc-inheritance-1990.jpg b/public/img/loc-inheritance-1990.jpg
new file mode 100644
index 0000000..3614125
Binary files /dev/null and b/public/img/loc-inheritance-1990.jpg differ
diff --git a/public/img/loc-naked-truth-1987.jpg b/public/img/loc-naked-truth-1987.jpg
new file mode 100644
index 0000000..5cbd80a
Binary files /dev/null and b/public/img/loc-naked-truth-1987.jpg differ
diff --git a/public/img/loc-nra-pacifier-1982.jpg b/public/img/loc-nra-pacifier-1982.jpg
new file mode 100644
index 0000000..e1ed58a
Binary files /dev/null and b/public/img/loc-nra-pacifier-1982.jpg differ
diff --git a/public/img/loc-sl-hud-1989.jpg b/public/img/loc-sl-hud-1989.jpg
new file mode 100644
index 0000000..130fd79
Binary files /dev/null and b/public/img/loc-sl-hud-1989.jpg differ
diff --git a/public/img/loc-southamerica-1959.jpg b/public/img/loc-southamerica-1959.jpg
new file mode 100644
index 0000000..00adab9
Binary files /dev/null and b/public/img/loc-southamerica-1959.jpg differ
diff --git a/public/img/nast-affixing-blame-1982.jpg b/public/img/nast-affixing-blame-1982.jpg
new file mode 100644
index 0000000..0cf0458
Binary files /dev/null and b/public/img/nast-affixing-blame-1982.jpg differ
diff --git a/public/index.html b/public/index.html
index 543c4cb..ba35fd0 100644
--- a/public/index.html
+++ b/public/index.html
@@ -7,14 +7,41 @@
 <link rel="stylesheet" href="style.css">
 </head>
 <body>
-  <header class="masthead">
-    <h1>Paul Conrad — Editorial Cartoons</h1>
-    <div class="sub">1924–2010 · Denver Post 1950–1964 · Los Angeles Times 1964–1993 · Three-time Pulitzer Prize winner (1964, 1971, 1984)</div>
-  </header>
+  <nav class="topnav" id="topnav">
+    <div class="topnav-row1">
+      <button class="hamburger" id="hamburger" aria-label="Toggle menu" aria-expanded="false">&#9776;</button>
+      <a class="wordmark" href="#" id="wordmark" data-section="all">
+        Paul Conrad <span>Editorial Cartoons</span>
+      </a>
+      <div class="topnav-search">
+        <input id="search" type="search" placeholder="Search title, subject, date…">
+      </div>
+    </div>
+    <div class="topnav-row2" id="topnav-row2">
+      <div class="section-links" id="section-links">
+        <button type="button" data-section="all" class="active">Cartoons</button>
+        <button type="button" data-section="pulitzers">Pulitzers</button>
+        <button type="button" data-section="loc">Library of Congress</button>
+        <button type="button" data-section="archives">Archives</button>
+        <button type="button" data-section="bio">Bio</button>
+      </div>
+      <div class="decade-jump" id="decade-jump">
+        <span class="decade-label">Jump to decade:</span>
+        <button type="button" data-decade="1950">50s</button>
+        <button type="button" data-decade="1960">60s</button>
+        <button type="button" data-decade="1970">70s</button>
+        <button type="button" data-decade="1980">80s</button>
+        <button type="button" data-decade="1990">90s</button>
+        <button type="button" data-decade="2000">00s</button>
+      </div>
+    </div>
+    <div class="topic-row" id="topic-row"></div>
+  </nav>
+
+  <div class="masthead-sub">1924–2010 · Denver Post 1950–1964 · Los Angeles Times 1964–1993 · Three-time Pulitzer Prize winner (1964, 1971, 1984)</div>
 
   <div class="layout">
     <aside class="filters">
-      <input class="search" id="search" type="search" placeholder="Search title, subject, date…">
       <details class="filter-group" id="facet-award" open></details>
       <details class="filter-group" id="facet-recordtype" open></details>
       <details class="filter-group" id="facet-publication"></details>
@@ -31,6 +58,7 @@
             <option value="year-asc">Year ↑ (oldest first)</option>
             <option value="year-desc">Year ↓ (newest first)</option>
             <option value="title-az">Title A→Z</option>
+            <option value="topic-az">Topic A→Z</option>
             <option value="award-first">Award winners first</option>
             <option value="newest">Dataset order</option>
           </select>
diff --git a/public/style.css b/public/style.css
index ac5c3a8..da34367 100644
--- a/public/style.css
+++ b/public/style.css
@@ -40,6 +40,7 @@
 }
 
 * { box-sizing: border-box; }
+html, body { max-width: 100%; overflow-x: hidden; }
 body {
   margin: 0;
   background: var(--bg);
@@ -48,22 +49,157 @@ body {
   -webkit-font-smoothing: antialiased;
 }
 
-header.masthead {
-  padding: 22px 20px 14px;
-  border-bottom: 3px solid var(--ink);
-  text-align: center;
+/* ---- top nav ---- */
+.topnav {
+  position: sticky;
+  top: 0;
+  z-index: 20;
+  background: var(--ink);
+  color: var(--bg);
+  border-bottom: 3px solid var(--accent);
 }
-header.masthead h1 {
-  margin: 0;
-  font-size: clamp(24px, 4vw, 38px);
-  letter-spacing: 0.02em;
+.topnav-row1 {
+  display: flex;
+  align-items: center;
+  gap: 14px;
+  padding: 10px 18px;
+}
+.hamburger {
+  display: none;
+  background: none;
+  border: 1px solid var(--accent-soft);
+  color: var(--bg);
+  border-radius: var(--radius);
+  font-size: 18px;
+  line-height: 1;
+  padding: 6px 10px;
+  cursor: pointer;
+}
+.wordmark {
+  color: var(--bg);
+  text-decoration: none;
   font-weight: 700;
+  font-size: clamp(18px, 3vw, 24px);
+  letter-spacing: 0.02em;
+  white-space: nowrap;
 }
-header.masthead .sub {
-  margin-top: 6px;
+.wordmark span {
+  font-weight: 400;
+  font-style: italic;
+  font-size: 0.6em;
+  color: var(--accent-soft);
+  margin-left: 8px;
+}
+.topnav-search { flex: 1; max-width: 380px; margin-left: auto; }
+.topnav-search input {
+  width: 100%;
+  padding: 7px 10px;
+  border: 1px solid var(--accent-soft);
+  border-radius: var(--radius);
+  background: rgba(255,255,255,0.06);
+  color: var(--bg);
+  font-family: inherit;
+  font-size: 14px;
+}
+.topnav-search input::placeholder { color: var(--accent-soft); opacity: 0.9; }
+
+.topnav-row2 {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  flex-wrap: wrap;
+  gap: 10px;
+  padding: 0 18px 10px;
+  border-bottom: 1px solid rgba(255,255,255,0.12);
+}
+.section-links { display: flex; gap: 4px; flex-wrap: wrap; }
+.section-links button {
+  background: none;
+  border: 1px solid transparent;
+  color: var(--bg);
+  opacity: 0.8;
+  font-family: inherit;
   font-size: 13px;
+  padding: 5px 10px;
+  border-radius: var(--radius);
+  cursor: pointer;
+  white-space: nowrap;
+}
+.section-links button:hover { opacity: 1; border-color: rgba(255,255,255,0.2); }
+.section-links button.active { opacity: 1; background: var(--accent); color: #fff; font-weight: 700; }
+
+.decade-jump { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
+.decade-jump .decade-label { font-size: 11px; color: var(--accent-soft); margin-right: 4px; text-transform: uppercase; letter-spacing: 0.05em; }
+.decade-jump button {
+  background: none;
+  border: 1px solid rgba(255,255,255,0.18);
+  color: var(--bg);
+  font-family: inherit;
+  font-size: 12px;
+  padding: 4px 9px;
+  border-radius: 12px;
+  cursor: pointer;
+}
+.decade-jump button:hover { border-color: var(--accent-soft); }
+.decade-jump button.active { background: var(--accent-soft); color: #241a0f; border-color: var(--accent-soft); font-weight: 700; }
+
+.topic-row {
+  display: flex;
+  gap: 6px;
+  padding: 8px 18px;
+  overflow-x: auto;
+  white-space: nowrap;
+  -webkit-overflow-scrolling: touch;
+  scrollbar-width: thin;
+}
+.topic-row::-webkit-scrollbar { height: 5px; }
+.topic-row::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.2); border-radius: 4px; }
+.topic-chip {
+  flex: 0 0 auto;
+  background: rgba(255,255,255,0.07);
+  border: 1px solid rgba(255,255,255,0.14);
+  color: var(--bg);
+  font-family: inherit;
+  font-size: 12px;
+  padding: 5px 10px;
+  border-radius: 14px;
+  cursor: pointer;
+}
+.topic-chip:hover { border-color: var(--accent-soft); }
+.topic-chip.active { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 700; }
+.topic-chip .chip-count { color: var(--accent-soft); font-size: 10.5px; }
+.topic-chip.active .chip-count { color: rgba(255,255,255,0.85); }
+
+.masthead-sub {
+  padding: 10px 20px;
+  border-bottom: 1px solid var(--line);
+  text-align: center;
+  font-size: 12.5px;
   color: var(--ink-soft);
   font-style: italic;
+  background: var(--panel-bg);
+}
+
+/* ---- mobile nav collapse (<=390px per spec, applied a bit wider for real devices) ---- */
+@media (max-width: 700px) {
+  .hamburger { display: inline-block; }
+  .topnav-row1 { flex-wrap: wrap; }
+  .topnav-search { flex-basis: 100%; max-width: none; margin-left: 0; order: 3; }
+  .topnav-row2 {
+    flex-direction: column;
+    align-items: flex-start;
+    max-height: 0;
+    overflow: hidden;
+    padding: 0 18px;
+    transition: max-height .2s ease, padding .2s ease;
+  }
+  .topnav.nav-open .topnav-row2 {
+    max-height: 400px;
+    padding: 8px 18px 12px;
+  }
+  .section-links { flex-direction: column; width: 100%; }
+  .section-links button { width: 100%; text-align: left; }
+  .decade-jump { width: 100%; }
 }
 
 .layout {
@@ -208,9 +344,22 @@ header.masthead .sub {
   padding: 10px;
   font-style: italic;
 }
+.card .thumb .no-img-notfound {
+  color: var(--accent);
+  opacity: 0.75;
+}
 .card .body { padding: 10px 12px; flex: 1; display: flex; flex-direction: column; gap: 4px; }
 .card .title { font-weight: 700; font-size: 14px; line-height: 1.25; }
 .card .meta { font-size: 11.5px; color: var(--ink-soft); }
+.topics { display: flex; gap: 5px; flex-wrap: wrap; }
+.topic-tag {
+  font-size: 10px;
+  color: var(--ink-soft);
+  background: var(--bg);
+  border: 1px solid var(--line);
+  border-radius: 10px;
+  padding: 1px 7px;
+}
 .card .badges { display: flex; gap: 6px; margin-top: auto; padding-top: 6px; flex-wrap: wrap; }
 .badge {
   font-size: 10px;
@@ -223,6 +372,7 @@ header.masthead .sub {
 .badge.documented { background: var(--badge-doc); }
 .badge.collection-summary { background: var(--badge-summary); }
 .badge.award { background: var(--accent); }
+.badge.representative { background: var(--accent-soft); color: #241a0f; }
 
 /* ---- detail modal ---- */
 .modal-backdrop {
@@ -240,7 +390,19 @@ header.masthead .sub {
 }
 .modal h2 { margin: 0 0 4px; font-size: 22px; }
 .modal .modal-meta { color: var(--ink-soft); font-size: 13px; margin-bottom: 12px; }
-.modal .modal-img { width: 100%; border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 14px; }
+.modal .modal-img { width: 100%; border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 4px; }
+.modal .modal-rep-note { font-size: 11px; color: var(--accent); font-style: italic; margin-bottom: 14px; }
+.modal .modal-no-img {
+  padding: 24px 16px;
+  text-align: center;
+  font-style: italic;
+  color: var(--ink-soft);
+  border: 1px dashed var(--line);
+  border-radius: var(--radius);
+  margin-bottom: 14px;
+}
+.modal-topics { margin-bottom: 12px; }
+.modal-topic-tag { font-size: 11px; padding: 2px 9px; }
 .modal dl { display: grid; grid-template-columns: 120px 1fr; gap: 6px 12px; font-size: 13.5px; margin: 0; }
 .modal dt { color: var(--ink-soft); }
 .modal dd { margin: 0; }
@@ -248,3 +410,12 @@ header.masthead .sub {
 .modal .rights-note { font-size: 11.5px; color: var(--ink-soft); font-style: italic; margin-top: 12px; border-top: 1px solid var(--line); padding-top: 10px; }
 
 .empty-note { padding: 40px; text-align: center; color: var(--ink-soft); font-style: italic; }
+
+/* ---- narrow phones ---- */
+@media (max-width: 480px) {
+  .grid { grid-template-columns: repeat(auto-fill, minmax(min(var(--card-min, 220px), 100%), 1fr)); }
+  .controls { padding: 10px 14px; }
+  .controls .result-count { margin-left: 0; width: 100%; order: 4; }
+  .grid-wrap { padding: 14px; }
+  .modal { padding: 18px 16px; max-height: 92vh; }
+}

← 4f7f8a0 add shareable Artifact build (metadata + link-out only, no c  ·  back to Paul Conrad Cartoons Shadowman  ·  chore: lint, v0.2.0 (session close) 666e26b →