<div class="infographic-jshist">
<style>
.infographic-jshist {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', monospace;
max-width: 880px;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-jshist[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
}
.infographic-jshist * { box-sizing: border-box; }
.infographic-jshist .ig-inner { padding: 0 clamp(1.25rem, 5vw, 3rem) 2.5rem; }
.infographic-jshist .ig-header { padding-top: 2rem; margin-bottom: 2rem; text-align: center; }
.infographic-jshist .ig-eyebrow {
font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase;
color: var(--accent); font-weight: 600;
}
.infographic-jshist .ig-title {
font-family: var(--display-font); font-size: clamp(1.8rem, 5vw, 2.6rem);
margin: 0.4rem 0 0.5rem; font-weight: 600;
}
.infographic-jshist .ig-sub { color: var(--ink-soft); font-size: 0.95rem; max-width: 46ch; margin: 0 auto; }
.infographic-jshist .timeline { position: relative; padding-left: 2rem; border-left: 2px solid var(--line); margin-top: 1rem; }
.infographic-jshist .timeline-entry { position: relative; margin-bottom: 0; }
.infographic-jshist .timeline-entry-btn {
all: unset; display: block; width: 100%; cursor: pointer; padding: 0.9rem 0;
}
.infographic-jshist .timeline-entry::before {
content: ""; position: absolute; left: -2.44rem; top: 1.15rem;
width: 10px; height: 10px; border-radius: 50%; background: var(--accent);
transition: transform 0.15s;
}
.infographic-jshist .timeline-entry.is-open::before { transform: scale(1.5); }
.infographic-jshist .entry-head { display: flex; align-items: baseline; gap: 0.75rem; flex-wrap: wrap; }
.infographic-jshist .date { font-family: var(--display-font); color: var(--accent); font-size: 1.25rem; font-weight: 600; min-width: 3.4rem; }
.infographic-jshist .headline { font-weight: 600; font-size: 1rem; }
.infographic-jshist .chevron { margin-left: auto; color: var(--ink-soft); transition: transform 0.2s; font-size: 0.85rem; }
.infographic-jshist .timeline-entry.is-open .chevron { transform: rotate(180deg); }
.infographic-jshist .entry-detail {
display: grid; grid-template-rows: 0fr; overflow: hidden; transition: grid-template-rows 0.25s ease;
}
.infographic-jshist .entry-detail > div { overflow: hidden; }
.infographic-jshist .timeline-entry.is-open .entry-detail { grid-template-rows: 1fr; }
.infographic-jshist .entry-body {
padding: 0.15rem 0 1rem; font-size: 0.9rem; color: var(--ink-soft); line-height: 1.5;
}
.infographic-jshist .entry-tag {
display: inline-block; margin-top: 0.5rem; font-size: 0.72rem; font-family: var(--mono-font);
background: var(--accent-soft); color: var(--accent); padding: 0.15rem 0.5rem;
}
.infographic-jshist .ig-footer {
margin-top: 1.75rem; padding-top: 1.25rem; border-top: 1px solid var(--line);
font-size: 0.85rem; color: var(--ink-soft); text-align: center;
}
.infographic-jshist .ig-footer strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-jshist *, .infographic-jshist *::before, .infographic-jshist *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<div class="ig-header">
<div class="ig-eyebrow">Origins & Evolution</div>
<h2 class="ig-title">The History of JavaScript</h2>
<p class="ig-sub">From a 10-day prototype to the language that runs everywhere. Click any entry to expand.</p>
</div>
<div class="timeline" id="jsTimeline">
<div class="timeline-entry" data-idx="0">
<button class="timeline-entry-btn">
<div class="entry-head">
<span class="date">1995</span>
<span class="headline">Built in 10 days</span>
<span class="chevron">▾</span>
</div>
</button>
<div class="entry-detail"><div class="entry-body">
Brendan Eich wrote it at Netscape to make web pages interactive. It went through three names before shipping: Mocha, then LiveScript, then JavaScript.
<span class="entry-tag">Netscape</span>
</div></div>
</div>
<div class="timeline-entry" data-idx="1">
<button class="timeline-entry-btn">
<div class="entry-head">
<span class="date">1995</span>
<span class="headline">The name game</span>
<span class="chevron">▾</span>
</div>
</button>
<div class="entry-detail"><div class="entry-body">
Netscape and Sun Microsystems picked "JavaScript" for marketing — riding on Java's popularity, despite the two languages barely being related.
<span class="entry-tag">Netscape + Sun</span>
</div></div>
</div>
<div class="timeline-entry" data-idx="2">
<button class="timeline-entry-btn">
<div class="entry-head">
<span class="date">1996</span>
<span class="headline">Ships in Navigator 2.0</span>
<span class="chevron">▾</span>
</div>
</button>
<div class="entry-detail"><div class="entry-body">
JavaScript debuts as a client-side scripting language running directly in the browser.
<span class="entry-tag">Browser era begins</span>
</div></div>
</div>
<div class="timeline-entry" data-idx="3">
<button class="timeline-entry-btn">
<div class="entry-head">
<span class="date">1997</span>
<span class="headline">Standardized as ECMAScript</span>
<span class="chevron">▾</span>
</div>
</button>
<div class="entry-detail"><div class="entry-body">
To stop browser vendors from forking the language, ECMA International standardizes it — giving us the official name "ECMAScript" (ES).
<span class="entry-tag">ECMA International</span>
</div></div>
</div>
<div class="timeline-entry" data-idx="4">
<button class="timeline-entry-btn">
<div class="entry-head">
<span class="date">2009</span>
<span class="headline">ES5 lands</span>
<span class="chevron">▾</span>
</div>
</button>
<div class="entry-detail"><div class="entry-body">
Adds JSON support and strict mode. Widely adopted across browsers — the stable baseline for years.
<span class="entry-tag">JSON · strict mode</span>
</div></div>
</div>
<div class="timeline-entry" data-idx="5">
<button class="timeline-entry-btn">
<div class="entry-head">
<span class="date">2015</span>
<span class="headline">ES6 / ES2015 — the big one</span>
<span class="chevron">▾</span>
</div>
</button>
<div class="entry-detail"><div class="entry-body">
A major overhaul: <code>let</code>/<code>const</code>, arrow functions, classes, promises, and modules. Most modern JS idioms trace back here.
<span class="entry-tag">let · const · classes · promises</span>
</div></div>
</div>
<div class="timeline-entry" data-idx="6">
<button class="timeline-entry-btn">
<div class="entry-head">
<span class="date">2010s</span>
<span class="headline">Frameworks take over</span>
<span class="chevron">▾</span>
</div>
</button>
<div class="entry-detail"><div class="entry-body">
Angular, React, and Vue reshape frontend development around components and reactive state.
<span class="entry-tag">Angular · React · Vue</span>
</div></div>
</div>
<div class="timeline-entry" data-idx="7">
<button class="timeline-entry-btn">
<div class="entry-head">
<span class="date">Today</span>
<span class="headline">Runs everywhere</span>
<span class="chevron">▾</span>
</div>
</button>
<div class="entry-detail"><div class="entry-body">
Browsers, servers (Node.js), mobile, desktop, IoT, and even ML — one language, nearly every runtime.
<span class="entry-tag">Node · mobile · desktop · IoT · ML</span>
</div></div>
</div>
</div>
<div class="ig-footer">
<strong>30 years, one language.</strong> From a 10-day sketch to the most widely deployed programming language on Earth.
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-jshist')
|| document.querySelector('.infographic-jshist');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
document.querySelectorAll('.infographic-jshist .timeline-entry').forEach(entry => {
entry.querySelector('.timeline-entry-btn').addEventListener('click', () => {
const wasOpen = entry.classList.contains('is-open');
document.querySelectorAll('.infographic-jshist .timeline-entry').forEach(e => e.classList.remove('is-open'));
if (!wasOpen) entry.classList.add('is-open');
});
});
})();
</script>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});