Project Shoehorn
.mustang-tree { position: relative; padding: 24px;
background: #faf9f6;
font-family: Georgia, "Times New Roman", serif; color: #333; }
.mustang-tree * { margin: 0; padding: 0; }
.mustang-tree h1 { font-size: 18px; font-weight: normal;
letter-spacing: .5px; color: #6d4aff; margin-bottom: 4px; }
.mustang-tree .sub { font-size: 12px; color: #999; font-style: italic;
margin-bottom: 12px; }
.mustang-tree #mt-census { font-size: 11px; color: #888; font-style: italic;
margin-bottom: 16px; border-top: 3px solid #6d4aff; padding-top: 4px; }
.mustang-tree #mt-search { display: block; margin-bottom: 16px;
padding: 6px 10px;
width: 260px; max-width: 100%;
font-family: Georgia, serif; font-size: 13px;
border: 1px solid #c8c4bd; border-radius: 5px; background: #fff;
outline: none; }
.mustang-tree #mt-search:focus { border-color: #6d4aff; }
.mustang-tree #mt-count { font-size: 11px; color: #777; margin-left: 10px;
font-style: italic; }
.mustang-tree .tree ul { display: flex; flex-direction: column;
justify-content: center; padding-left: 32px; list-style: none; }
.mustang-tree .tree li { position: relative; display: flex;
align-items: center; padding: 10px 0; }
.mustang-tree .tree li::before { content: ''; position: absolute;
left: -32px;
top: 50%; width: 32px; border-top: 2px solid #c8c4bd; }
.mustang-tree .tree li::after { content: ''; position: absolute;
left: -32px;
top: 50%; bottom: -50%; border-left: 2px solid #c8c4bd; }
.mustang-tree .tree li:last-child::after { bottom: 50%; }
.mustang-tree .tree li:only-child::after { display: none; }
.mustang-tree .tree > ul { padding-left: 0; }
.mustang-tree .tree > ul > li::before,
.mustang-tree .tree > ul > li::after { display: none; }
.mustang-tree li.collapsed > ul { display: none; }
.mustang-tree li.collapsed > .person .chev::after { content: '+'; }
.mustang-tree .person .chev::after { content: '-'; }
.mustang-tree .person { display: inline-flex; flex-direction: column;
min-width: 150px; max-width: 210px; padding: 4px 9px 4px 6px;
background: #fff; border: 1px solid #d8d4cc; border-radius: 5px;
box-shadow: 0 1px 2px rgba(0,0,0,.07); text-align: left;
flex-shrink: 0;
transition: opacity .2s, box-shadow .2s, border-color .2s,
background .2s; }
.mustang-tree .person:hover { border-color: #6d4aff; cursor: pointer;
box-shadow: 0 3px 10px rgba(0,0,0,.16); }
.mustang-tree .prow { display: flex; align-items: center; gap: 6px; }
.mustang-tree .person .nm { display: block; font-size: 12px;
line-height: 1.25; }
.mustang-tree .person .det { display: none; margin-top: 4px;
padding-top: 4px;
border-top: 1px solid #e5e1d8; font-size: 11px; color: #777;
font-style: italic; line-height: 1.4; }
.mustang-tree .person.open .det { display: block; }
.mustang-tree .person.open { max-width: 380px; background: #ece7ff; }
.mustang-tree .person .det .dd { display: block; }
.mustang-tree .person .det .ds { display: block; color: #999; }
.mustang-tree .det .species-info { display: flex; flex-wrap: wrap;
gap: 6px;
margin: 6px 0 0 0; align-items: baseline; }
.mustang-tree .det .thumbnail { width: 110px; height: 70px;
object-fit: cover;
border-radius: 4px; border: 1px solid #ccc;
box-shadow: 0 1px 3px rgba(0,0,0,.15); margin: 4px 0 0 0;
cursor: zoom-in; }
.mustang-tree .person .chev { display: inline-block; width: 16px;
height: 16px;
margin-left: 4px; line-height: 16px; text-align: center;
color: #6d4aff; font-size: 12px; background: #e9e6df;
border: 1px solid #d0ccc3; border-radius: 4px; cursor: pointer;
user-select: none; flex-shrink: 0; }
.mustang-tree .person .chev:hover { background: #6d4aff; color: #fff; }
.mustang-tree li.childless .chev { visibility: hidden; }
/* generation colors */
.mustang-tree .p-root { border-left: 5px solid #444; }
.mustang-tree .p-g1 { border-left: 5px solid #C9A227; }
.mustang-tree .p-g2 { border-left: 5px solid #8B5A2B; }
.mustang-tree .p-g3 { border-left: 5px solid #D2622A; }
.mustang-tree .p-g4 { border-left: 5px solid #2C7F7A; }
.mustang-tree .p-g5 { border-left: 5px solid #4A7BAB; }
.mustang-tree .p-g6 { border-left: 5px solid #6d4aff; }
.mustang-tree .p-g7 { border-left: 5px solid #9d47ff; }
.mustang-tree .p-probe { border-left: 5px dashed #aaa; }
/* timeline */
.mustang-tree .timeline { display: flex; align-items: center;
margin: 6px 0 0 0; font-size: 10px; color: #888; }
.mustang-tree .tl-lab { flex-shrink: 0; }
.mustang-tree .tl-track { flex: 1; height: 8px; margin: 0 8px;
position: relative;
background: #eceae4; border-radius: 4px; }
.mustang-tree .tl-fill { position: absolute; top: 0; height: 100%;
border-radius: 4px;
background: linear-gradient(to right, #6d4aff, #a994ff); }
.mustang-tree .tl-fill.ongoing::after { content: ''; position: absolute;
right: -4px; top: 0; width: 8px; height: 8px; border-radius: 50%;
background: #6d4aff;
animation: mt-tlpulse 1.6s ease-out infinite; }
@keyframes mt-tlpulse {
0% { box-shadow: 0 0 0 0 rgba(109,74,255,.6); }
100% { box-shadow: 0 0 0 10px rgba(109,74,255,0); } }
.mustang-tree .p-probe .tl-fill { background: #bbb; }
.mustang-tree .p-g1 .tl-fill {
background: linear-gradient(to right,#C9A227,#e6cf80);}
.mustang-tree .p-g2 .tl-fill {
background: linear-gradient(to right,#8B5A2B,#c49a68);}
.mustang-tree .p-g3 .tl-fill {
background: linear-gradient(to right,#D2622A,#eb9a6c);}
.mustang-tree .p-g4 .tl-fill {
background: linear-gradient(to right,#2C7F7A,#79bdb9);}
.mustang-tree .p-g5 .tl-fill {
background: linear-gradient(to right,#4A7BAB,#8fb4d2);}
.mustang-tree .p-g7 .tl-fill {
background: linear-gradient(to right,#9d47ff,#c9a6ff);}
.mustang-tree .dimmed { opacity: .18; }
.mustang-tree .lineage { opacity: 1 !important; background: #ece7ff;
border-color: #6d4aff;
box-shadow: 0 0 0 3px #6d4aff, 0 2px 8px rgba(0,0,0,.2);
font-weight: bold; }
.mustang-tree .person.hit { border-color: #6d4aff !important;
box-shadow: 0 0 0 3px rgba(109,74,255,.25); }
@keyframes mt-szpulse {
0% { box-shadow: 0 0 0 0 rgba(109,74,255,.55); }
70% { box-shadow: 0 0 0 14px rgba(109,74,255,0); }
100% { box-shadow: 0 0 0 14px rgba(109,74,255,0); } }
.mustang-tree .person.pulse { animation: mt-szpulse 1.2s ease-out 2; }
.mustang-tree #mt-peek { position: fixed; top: 0; left: 0;
display: none;
min-width: 180px; max-width: 260px; padding: 8px 11px;
background: #fff; border: 1px solid #d8d4cc;
border-left: 5px solid #6d4aff; border-radius: 5px;
box-shadow: 0 8px 24px rgba(0,0,0,.18); font-size: 12px;
pointer-events: none; z-index: 100; }
.mustang-tree #mt-peek .pn { display: block; font-size: 13px; }
.mustang-tree #mt-peek .pd { display: block; color: #777;
font-style: italic;
font-size: 11px; margin-top: 2px; }
.mustang-tree #mt-peek .thumb { display: block; width: 100%;
height: auto;
border-radius: 4px; margin-top: 6px;
box-shadow: 0 2px 6px rgba(0,0,0,.2); }
.mustang-tree .tree { box-shadow: 0 10px 40px rgba(0,0,0,.12);
background: #fff; padding: 18px; border-radius: 6px; }
.mustang-tree::before { content: ""; position: absolute; inset: 0;
pointer-events: none; z-index: 90;
box-shadow: inset 0 0 36px rgba(0,0,0,.16); }
.mustang-tree #mt-toggle-all { display: inline-block;
margin: 0 0 16px 0;
font: 600 13px/1.2 system-ui, sans-serif; color: #555;
background: #f2f2f2; border: 1px solid #ccc;
border-left: 4px solid #9c9c9c; border-radius: 14px;
padding: 6px 14px; cursor: pointer;
box-shadow: 0 1px 2px rgba(0,0,0,.08);
transition: background .15s, transform .15s; }
.mustang-tree #mt-toggle-all:hover { background: #e9e9e9;
transform: translateY(-1px); }
.mustang-tree #mt-lightbox { display: none; position: fixed; inset: 0;
background: rgba(0,0,0,.85); z-index: 200;
align-items: center; justify-content: center; cursor: pointer; }
.mustang-tree #mt-lightbox img { max-width: 90vw; max-height: 90vh;
border-radius: 8px; box-shadow: 0 4px 24px rgba(0,0,0,.4); }
.mustang-tree #mt-credits { margin-top: 28px; padding-top: 10px;
border-top: 1px solid #d8d4cc; font-size: 11px; color: #777;
font-style: italic; }
.mustang-tree #mt-credits a { color: #6d4aff; }
Ford Mustang — The Family Tree
Seven generations, one detour · click any card
for the story, click its photo for the full view
+ Expand All
Ford Mustang
First Generation
Shelby GT350 / GT500
Boss 302
Boss 429
Mach 1 (original)
Second Generation — Mustang II
Cobra II
King Cobra
Ford Probe — the detour
Third Generation — Fox Body
SVO
SVT Cobra (1993)
Fourth Generation — SN-95
Bullitt (2001)
Terminator Cobra
Fifth Generation — S197
Shelby GT500 (S197)
Boss 302 (2012)
Sixth Generation — S550
Shelby GT350 / GT500 (S550)
Mach 1 (revival)
Seventh Generation — S650
Dark Horse
Photography: Model photographs from
Wikimedia Commons contributors, used under
their respective free licenses. Individual photographer and
license credits are maintained for each image.
Sales data: Generation and annual U.S. unit
totals from CJ Pony Parts' Mustang sales
database.
History: Model-year spans and platform codes
per standard Mustang references. The Probe branch reflects the
widely reported late-1980s succession plan abandoned after
enthusiast protest.
Tree and text: Built with an open,
config-driven tree engine. Reuse welcome.
(function () {
var peek = document.getElementById('mt-peek');
var lightbox = document.getElementById('mt-lightbox');
var lightboxImg = lightbox.querySelector('img');
var people = Array.prototype.slice.call(
document.querySelectorAll('.mustang-tree .person'));
var Y0 = 1964, YN = 2026;
function detHTML(card) {
var html = '' + card.dataset.span + '';
if (card.dataset.code) html +=
'' + card.dataset.code + '';
if (card.dataset.units) html +=
'Units sold: ' +
card.dataset.units + '';
if (card.dataset.fact) html +=
'' + card.dataset.fact + '';
if (card.dataset.y1) {
var y1 = parseInt(card.dataset.y1, 10);
var ongoing = !card.dataset.y2;
var y2 = ongoing ? YN : parseInt(card.dataset.y2, 10);
var left = ((y1 - Y0) / (YN - Y0)) * 100;
var width = ((y2 - y1 + 1) / (YN - Y0)) * 100;
html += '' +
'' + y1 + '' +
'' +
'' + (ongoing ? 'now' : y2) + '' +
'';
}
if (card.dataset.thumb) {
html += '' +
'' +
'';
}
return html;
}
document.getElementById('mt-census').textContent =
'7 generations \u00B7 15 nameplates \u00B7 10,032,515 U.S. units ' +
'sold since 1964 \u00B7 in continuous production 62 years';
people.forEach(function (p) {
var li = p.closest('li');
if (!li.querySelector(':scope > ul')) li.classList.add('childless');
});
document.querySelectorAll('.mustang-tree .tree li').forEach(
function (li) {
if (li.querySelector(':scope > ul'))
li.classList.add('collapsed');
});
var rootLi = document.querySelector(
'.mustang-tree .tree > ul > li');
if (rootLi) rootLi.classList.remove('collapsed');
function show(card) {
peek.innerHTML =
'' + card.dataset.name + '' +
(card.dataset.code ?
'' + card.dataset.code + '' : '') +
'' + card.dataset.span + '';
if (card.dataset.thumb) {
peek.innerHTML += '';
}
peek.style.display = 'block';
var r = card.getBoundingClientRect();
var x = r.right + 10;
if (x + 260 > window.innerWidth)
x = r.left - 260;
peek.style.left = x + 'px';
peek.style.top = (r.top - 4) + 'px';
}
document.addEventListener('mouseover', function (e) {
var p = e.target.closest('.mustang-tree .person');
if (p) { show(p); } else { peek.style.display = 'none'; }
});
document.addEventListener('click', function (e) {
if (e.target.closest('#mt-lightbox')) {
lightbox.style.display = 'none';
return;
}
var thumb = e.target.closest('.lb-trigger');
if (thumb) {
lightboxImg.src = thumb.src;
lightbox.style.display = 'flex';
return;
}
var chev = e.target.closest('.mustang-tree .chev');
if (chev) {
e.stopPropagation();
chev.closest('li').classList.toggle('collapsed');
return;
}
var card = e.target.closest('.mustang-tree .person');
if (card) {
var open = card.classList.toggle('open');
if (open) card.querySelector('.det').innerHTML = detHTML(card);
people.forEach(function (p) { p.classList.remove('lineage'); });
var li = card.closest('li');
while (li && li.closest('.mustang-tree .tree')) {
var c = li.querySelector(':scope > .person');
if (c) c.classList.add('lineage');
li.classList.remove('collapsed');
li = li.parentElement ? li.parentElement.closest('li') : null;
}
return;
}
people.forEach(function (p) {
p.classList.remove('lineage'); p.classList.remove('open');
});
peek.style.display = 'none';
});
var box = document.getElementById('mt-search');
box.addEventListener('input', function () {
var q = box.value.trim().toLowerCase();
people.forEach(function (p) {
p.classList.remove('hit', 'pulse');
p.classList.toggle('dimmed',
q && p.dataset.name.toLowerCase().indexOf(q) === -1);
});
if (!q) {
document.getElementById('mt-count').textContent = '';
return;
}
var hits = 0, first = null;
people.forEach(function (p) {
if (p.dataset.name.toLowerCase().indexOf(q) !== -1) {
hits++; p.classList.add('hit');
if (!first) first = p;
var li = p.closest('li');
while ((li = li.parentElement) && li.classList)
li.classList.remove('collapsed');
}
});
document.getElementById('mt-count').textContent =
hits + (hits === 1 ? ' match' : ' matches');
if (first) {
setTimeout(function () {
first.scrollIntoView({ behavior: 'smooth', block: 'center' });
first.classList.add('pulse');
setTimeout(function () {
first.classList.remove('pulse');
}, 2600);
}, 90);
}
});
(function () {
var btn = document.getElementById('mt-toggle-all');
if (!btn) return;
var lis = Array.prototype.slice.call(
document.querySelectorAll('.mustang-tree .tree li'));
var isOpen = function (li) {
return !!li.querySelector(':scope > ul') &&
!li.classList.contains('collapsed');
};
var refresh = function () {
btn.textContent = lis.some(isOpen) ?
'\u2212 Collapse All' : '+ Expand All';
};
btn.addEventListener('click', function () {
var anyOpen = lis.some(isOpen);
lis.forEach(function (li) {
if (!li.querySelector(':scope > ul')) return;
li.classList.toggle('collapsed', anyOpen);
});
refresh();
});
refresh();
})();
})();