← back to CelebritySignatures
wear: map worn-shot by EXACT signer name, not surname — kills wrong-celebrity collisions
ced4cca3e7c69ce6960e7ce7a5132b7faa8846f5 · 2026-09-09 17:15:27 -0700 · Steve
Surname auto-detect would show campaign-adams.jpg (John Quincy Adams) on all 10
other Adams pages (John/Samuel/Abigail...), Napoleon's shot on Napoleon III,
Hugo's on Hugo Grotius, Louis XIV's on France Prešeren, etc. — the WRONG person's
editorial photo. Replaced with an exact full-name→slug map of the definitive
top-50 (+ existing); anyone not listed shows the normal garment mockup. Still
probes the file (may not be generated yet) and self-surfaces as shots land.
Verified: Darwin/Napoleon show, Abigail Adams/Napoleon III show nothing, 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit ced4cca3e7c69ce6960e7ce7a5132b7faa8846f5
Author: Steve <steve@designerwallcoverings.com>
Date: Wed Sep 9 17:15:27 2026 -0700
wear: map worn-shot by EXACT signer name, not surname — kills wrong-celebrity collisions
Surname auto-detect would show campaign-adams.jpg (John Quincy Adams) on all 10
other Adams pages (John/Samuel/Abigail...), Napoleon's shot on Napoleon III,
Hugo's on Hugo Grotius, Louis XIV's on France Prešeren, etc. — the WRONG person's
editorial photo. Replaced with an exact full-name→slug map of the definitive
top-50 (+ existing); anyone not listed shows the normal garment mockup. Still
probes the file (may not be generated yet) and self-surfaces as shots land.
Verified: Darwin/Napoleon show, Abigail Adams/Napoleon III show nothing, 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
public/wear.html | 59 ++++++++++++++++++++------------------------------------
1 file changed, 21 insertions(+), 38 deletions(-)
diff --git a/public/wear.html b/public/wear.html
index 29e86e9..a6c6a2e 100644
--- a/public/wear.html
+++ b/public/wear.html
@@ -223,30 +223,15 @@ const INK_PRESETS = [
{ id:'white', label:'White', hex:'#ffffff' },
];
// Editorial "worn" shots — the celebrity seated in the full Signature Edit
-// (AI-generated, named /assets/campaign-<slug>.jpg by the campaign pipeline).
-// Rather than hardcode a name→file map (which wouldn't pick up newly generated
-// shots), AUTO-DETECT: derive candidate slugs from the person's name and probe
-// which campaign-<slug>.jpg actually exists. Handles the naming quirks — some
-// files are keyed on the surname (darwin, napoleon), some on a joined full
-// surname (vangogh), some on a first name (frida). A few explicit overrides
-// pin the non-obvious existing files.
-const LIFESTYLE_OVERRIDE = { 'vincent van gogh':'vangogh', 'frida kahlo':'frida' };
-function lifestyleCandidates(name){
- // Fold accents first (Velázquez→velazquez, Molière→moliere, Dürer→durer) so
- // the slug matches the pipeline's transliterated campaign-<slug>.jpg filenames,
- // THEN drop anything non-alphabetic.
- const n = (name || '').toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g,'').replace(/[^a-z ]/g,'').trim();
- if (!n) return [];
- const cands = [];
- if (LIFESTYLE_OVERRIDE[n]) cands.push(LIFESTYLE_OVERRIDE[n]);
- const parts = n.split(/\s+/).filter(Boolean);
- if (parts.length){
- cands.push(parts[parts.length-1]); // surname (darwin, lincoln, shakespeare)
- if (parts.length >= 2) cands.push(parts.slice(-2).join('')); // joined last two (vangogh)
- cands.push(parts.join('')); // full name joined (leonardodavinci)
- cands.push(parts[0]); // first name (frida)
- }
- return [...new Set(cands)].filter(Boolean);
+// (AI-generated, /assets/campaign-<slug>.jpg). Keyed on the signer's EXACT name,
+// NOT a surname guess: a surname match would wrongly show, e.g., John Quincy
+// Adams's photo on all 10 other "Adams" pages, or Napoleon's on Napoleon III.
+// This map is the definitive top-50 (+ existing); anyone not listed shows the
+// normal garment mockup. Generated from the ranked list; extend when the
+// pipeline adds a signer.
+const LIFESTYLE_MAP = {"william shakespeare":"shakespeare","leonardo da vinci":"davinci","abraham lincoln":"lincoln","napoleon":"napoleon","johann wolfgang von goethe":"goethe","charles darwin":"darwin","george washington":"washington","galileo galilei":"galilei","victor hugo":"hugo","vincent van gogh":"vangogh","michelangelo":"michelangelo","martin luther":"luther","voltaire":"voltaire","fyodor dostoyevsky":"dostoyevsky","friedrich nietzsche":"nietzsche","rené descartes":"descartes","miguel de cervantes":"cervantes","charles dickens":"dickens","hans christian andersen":"andersen","alexander pushkin":"pushkin","edgar allan poe":"poe","molière":"moliere","oscar wilde":"wilde","lord byron":"byron","benjamin franklin":"franklin","louis pasteur":"pasteur","rembrandt":"rembrandt","richard wagner":"wagner","raphael":"raphael","georg wilhelm friedrich hegel":"hegel","alfred nobel":"nobel","francis bacon":"bacon","albrecht dürer":"durer","louis xiv of france":"france","friedrich schiller":"schiller","francisco goya":"goya","charles baudelaire":"baudelaire","geoffrey chaucer":"chaucer","katsushika hokusai":"hokusai","alexandre dumas":"dumas","honoré de balzac":"balzac","peter paul rubens":"rubens","heinrich heine":"heine","john quincy adams":"adams","diego velázquez":"velazquez","william blake":"blake","jonathan swift":"swift","montesquieu":"montesquieu","gustave flaubert":"flaubert","frida kahlo":"frida","albert einstein":"einstein","mark twain":"twain","pablo picasso":"picasso"};
+function lifestyleSlug(name){
+ return LIFESTYLE_MAP[(name || '').toLowerCase().trim()] || null;
}
// Toggle the modal's left visual between the editorial "worn" shot and the
// interactive garment mockup.
@@ -261,22 +246,20 @@ function setLifeView(mode){
}
function applyLifestyle(){
const shot = document.getElementById('lifestyleShot'), tog = document.getElementById('lifestyleToggle');
- // Default to the garment mockup; probe for a worn shot and switch in if found.
+ // Default to the garment mockup; switch to the worn shot only if this EXACT
+ // signer is mapped AND the file exists (it may not be generated yet).
tog.hidden = true; shot.hidden = true; shot.removeAttribute('src'); setLifeView('garment');
const sig = state.sig;
- const cands = lifestyleCandidates(sig && sig.full_name);
- (function tryNext(i){
- if (i >= cands.length || state.sig !== sig) return;
- const url = `/assets/campaign-${cands[i]}.jpg`;
- const probe = new Image();
- probe.onload = () => {
- if (state.sig !== sig) return; // signer changed while probing
- shot.src = url; shot.alt = `${sig.full_name} in the Signature Edit`;
- tog.hidden = false; setLifeView('worn'); // lead with the editorial shot
- };
- probe.onerror = () => tryNext(i + 1);
- probe.src = url;
- })(0);
+ const slug = lifestyleSlug(sig && sig.full_name);
+ if (!slug) return;
+ const url = `/assets/campaign-${slug}.jpg`;
+ const probe = new Image();
+ probe.onload = () => {
+ if (state.sig !== sig) return; // signer changed while loading
+ shot.src = url; shot.alt = `${sig.full_name} in the Signature Edit`;
+ tog.hidden = false; setLifeView('worn');
+ };
+ probe.src = url;
}
// Top-level HTML-attribute escape (the autocomplete's own `esc` is scoped to
// that block, so the grid renderer needs its own).
← a0253a8 wear: 43 worn editorial campaign shots for top-signer roster
·
back to CelebritySignatures
·
wear: map Michelangelo Buonarroti → campaign-michelangelo.jp cb3ba6f →