<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>History of AWS</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,500;0,6..72,600;1,6..72,500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
.infographic-awshistory {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--display-font: 'Newsreader', Georgia, serif;
--body-font: 'Inter', system-ui, sans-serif;
background: var(--paper);
color: var(--ink);
font-family: var(--body-font);
max-width: 880px;
margin: 0 auto;
padding: clamp(1.25rem, 5vw, 3rem);
box-sizing: border-box;
}
.infographic-awshistory[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #13171F;
--paper-alt: #1c2029;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
}
.infographic-awshistory * { box-sizing: border-box; }
.infographic-awshistory h1 {
font-family: var(--display-font);
font-weight: 600;
font-size: clamp(1.4rem, 3.6vw, 1.9rem);
margin: 0 0 0.3rem;
letter-spacing: -0.01em;
}
.infographic-awshistory .subhead {
color: var(--ink-soft);
font-size: 0.92rem;
margin: 0 0 1.9rem;
max-width: 62ch;
line-height: 1.55;
}
.infographic-awshistory .timeline {
position: relative;
padding-left: 2.1rem;
border-left: 2px solid var(--line);
}
.infographic-awshistory .entry {
position: relative;
padding-bottom: 1.6rem;
}
.infographic-awshistory .entry:last-child { padding-bottom: 0; }
.infographic-awshistory .entry::before {
content: "";
position: absolute;
left: -2.53rem;
top: 0.35rem;
width: 11px; height: 11px;
border-radius: 50%;
background: var(--paper);
border: 2px solid var(--accent);
transition: transform 0.15s, background 0.15s;
}
.infographic-awshistory .entry.is-open::before {
background: var(--accent);
transform: scale(1.25);
}
.infographic-awshistory .entry-head {
background: none;
border: none;
width: 100%;
text-align: left;
padding: 0;
font: inherit;
cursor: pointer;
color: var(--ink);
display: flex;
align-items: baseline;
gap: 0.7rem;
flex-wrap: wrap;
}
.infographic-awshistory .entry-date {
font-family: var(--display-font);
font-weight: 600;
color: var(--accent);
font-size: 0.95rem;
white-space: nowrap;
}
.infographic-awshistory .entry-title {
font-weight: 600;
font-size: 0.98rem;
}
.infographic-awshistory .entry-detail {
display: none;
margin-top: 0.5rem;
font-size: 0.86rem;
color: var(--ink-soft);
line-height: 1.55;
max-width: 58ch;
}
.infographic-awshistory .entry.is-open .entry-detail { display: block; }
.infographic-awshistory .badge {
display: inline-block;
font-size: 0.68rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.03em;
color: var(--accent);
background: var(--accent-soft);
border-radius: 5px;
padding: 0.12rem 0.45rem;
margin-left: 0.1rem;
}
.infographic-awshistory .footline {
margin-top: 1.7rem;
padding-top: 1.1rem;
border-top: 1px solid var(--line);
font-size: 0.88rem;
color: var(--ink-soft);
font-style: italic;
}
.infographic-awshistory .footline strong { color: var(--ink); font-style: normal; }
@media (prefers-reduced-motion: reduce) {
.infographic-awshistory * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}
</style>
</head>
<body>
<div class="infographic-awshistory">
<h1>π From internal tool to global cloud - History</h1>
<p class="subhead">AWS didn't start as a product β it started as the infrastructure Amazon built to run its own e-commerce business at scale, then opened up to everyone else. Click a milestone to expand it.</p>
<div class="timeline" id="timeline">
<div class="entry" data-i="0">
<button class="entry-head">
<span class="entry-date">Jul 2002</span>
<span class="entry-title">Amazon Web Services launches internally</span>
</button>
<div class="entry-detail">Built first for Amazon's own developers β a private toolkit, not yet a public service.</div>
</div>
<div class="entry" data-i="1">
<button class="entry-head">
<span class="entry-date">Nov 2004</span>
<span class="entry-title">Amazon SQS goes public</span>
</button>
<div class="entry-detail">Simple Queue Service becomes AWS's first offering opened up to outside developers.</div>
</div>
<div class="entry" data-i="2">
<button class="entry-head">
<span class="entry-date">Mar 14, 2006</span>
<span class="entry-title">Amazon S3 launches <span class="badge">Storage</span></span>
</button>
<div class="entry-detail">Simple Storage Service β pay-as-you-go object storage that's still an AWS cornerstone today.</div>
</div>
<div class="entry" data-i="3">
<button class="entry-head">
<span class="entry-date">Aug 2006</span>
<span class="entry-title">Amazon EC2 launches <span class="badge">Compute</span></span>
</button>
<div class="entry-detail">Elastic Compute Cloud rents out virtual servers on demand β the moment "cloud compute" became real.</div>
</div>
<div class="entry" data-i="4">
<button class="entry-head">
<span class="entry-date">Sep 2007</span>
<span class="entry-title">AWS Startup Challenge launches</span>
</button>
<div class="entry-detail">AWS starts courting startups directly, seeding the ecosystem that now runs on it.</div>
</div>
</div>
<p class="footline">Two decades later, <strong>millions of applications run on AWS worldwide</strong> β from the same building blocks laid down here.</p>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-awshistory')
|| document.querySelector('.infographic-awshistory');
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-awshistory .entry-head').forEach(head => {
head.addEventListener('click', () => {
const entry = head.closest('.entry');
const wasOpen = entry.classList.contains('is-open');
document.querySelectorAll('.infographic-awshistory .entry').forEach(e => e.classList.remove('is-open'));
if (!wasOpen) entry.classList.add('is-open');
});
});
// open first entry by default so the page isn't fully collapsed on load
document.querySelector('.infographic-awshistory .entry')?.classList.add('is-open');
})();
</script>
</body>
</html>.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!');
});<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AWS: Services Behind the Scenes</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,500;0,6..72,600;1,6..72,500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
.infographic-awsusecases {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--display-font: 'Newsreader', Georgia, serif;
--body-font: 'Inter', system-ui, sans-serif;
background: var(--paper);
color: var(--ink);
font-family: var(--body-font);
max-width: 880px;
margin: 0 auto;
padding: clamp(1.25rem, 5vw, 3rem);
box-sizing: border-box;
}
.infographic-awsusecases[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #13171F;
--paper-alt: #1c2029;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
}
.infographic-awsusecases * { box-sizing: border-box; }
.infographic-awsusecases h1 {
font-family: var(--display-font);
font-weight: 600;
font-size: clamp(1.4rem, 3.6vw, 1.9rem);
margin: 0 0 0.3rem;
letter-spacing: -0.01em;
}
.infographic-awsusecases .subhead {
color: var(--ink-soft);
font-size: 0.92rem;
margin: 0 0 1.8rem;
max-width: 62ch;
line-height: 1.55;
}
.infographic-awsusecases .section-label {
font-size: 0.72rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--ink-soft);
margin: 0 0 0.7rem;
}
/* use case tag grid */
.infographic-awsusecases .usecases {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-bottom: 2rem;
}
.infographic-awsusecases .usecase-tag {
font-size: 0.82rem;
font-weight: 500;
padding: 0.45rem 0.8rem;
border-radius: 20px;
background: var(--paper-alt);
border: 1px solid var(--line);
color: var(--ink-soft);
transition: opacity 0.15s, background 0.15s, border-color 0.15s, color 0.15s, transform 0.15s;
}
.infographic-awsusecases .usecases.filtered .usecase-tag {
opacity: 0.3;
}
.infographic-awsusecases .usecases.filtered .usecase-tag.is-match {
opacity: 1;
background: var(--accent-soft);
border-color: var(--accent);
color: var(--accent);
transform: translateY(-1px);
}
/* service chips */
.infographic-awsusecases .services {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.7rem;
}
@media (max-width: 640px) {
.infographic-awsusecases .services { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 420px) {
.infographic-awsusecases .services { grid-template-columns: 1fr; }
}
.infographic-awsusecases .service-chip {
background: var(--paper-alt);
border: 1px solid var(--line);
border-top: 3px solid transparent;
border-radius: 10px;
padding: 0.85rem 0.9rem;
text-align: left;
cursor: pointer;
font: inherit;
color: var(--ink);
transition: border-color 0.15s, background 0.15s;
}
.infographic-awsusecases .service-chip.is-active {
border-color: var(--accent);
background: var(--paper);
}
.infographic-awsusecases .service-name {
font-weight: 700;
font-size: 0.88rem;
display: block;
}
.infographic-awsusecases .service-cat {
font-size: 0.76rem;
color: var(--ink-soft);
display: block;
margin-top: 0.15rem;
}
.infographic-awsusecases .service-chip.is-active .service-cat { color: var(--accent); }
.infographic-awsusecases .summary {
margin-top: 1.1rem;
min-height: 1.4em;
font-size: 0.86rem;
color: var(--ink-soft);
line-height: 1.5;
}
.infographic-awsusecases .summary strong { color: var(--accent); }
@media (prefers-reduced-motion: reduce) {
.infographic-awsusecases * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}
</style>
</head>
<body>
<div class="infographic-awsusecases">
<h1>π AWS is already running your apps - Use Cases</h1>
<p class="subhead">Stream a video, open an app, call an API β there's a good chance AWS is working quietly underneath. Click a service below to see what it powers.</p>
<p class="section-label">Where it shows up</p>
<div class="usecases" id="usecases">
<span class="usecase-tag" data-tags="ec2,cloudfront">Website & web app hosting</span>
<span class="usecase-tag" data-tags="s3">Data storage & backups</span>
<span class="usecase-tag" data-tags="sagemaker,dynamodb">Big data analytics</span>
<span class="usecase-tag" data-tags="sagemaker">Machine learning & AI</span>
<span class="usecase-tag" data-tags="ec2,lambda,dynamodb">Mobile app backends</span>
<span class="usecase-tag" data-tags="lambda">Serverless applications</span>
<span class="usecase-tag" data-tags="s3">Disaster recovery</span>
<span class="usecase-tag" data-tags="ec2">DevOps & CI/CD</span>
<span class="usecase-tag" data-tags="ec2,dynamodb">Gaming platforms</span>
<span class="usecase-tag" data-tags="lambda,dynamodb">IoT systems</span>
<span class="usecase-tag" data-tags="s3,cloudfront">Media & video streaming</span>
</div>
<p class="section-label">Core services</p>
<div class="services" id="services">
<button class="service-chip" data-service="ec2">
<span class="service-name">Amazon EC2</span>
<span class="service-cat">β Compute</span>
</button>
<button class="service-chip" data-service="s3">
<span class="service-name">Amazon S3</span>
<span class="service-cat">β Storage</span>
</button>
<button class="service-chip" data-service="lambda">
<span class="service-name">AWS Lambda</span>
<span class="service-cat">β Serverless</span>
</button>
<button class="service-chip" data-service="sagemaker">
<span class="service-name">Amazon SageMaker</span>
<span class="service-cat">β Machine Learning</span>
</button>
<button class="service-chip" data-service="dynamodb">
<span class="service-name">Amazon DynamoDB</span>
<span class="service-cat">β Database</span>
</button>
<button class="service-chip" data-service="cloudfront">
<span class="service-name">Amazon CloudFront</span>
<span class="service-cat">β Content Delivery</span>
</button>
</div>
<p class="summary" id="summary">Click a service to see the use cases it powers.</p>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-awsusecases')
|| document.querySelector('.infographic-awsusecases');
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');
const usecasesEl = document.getElementById('usecases');
const tags = usecasesEl.querySelectorAll('.usecase-tag');
const chips = document.querySelectorAll('.service-chip');
const summary = document.getElementById('summary');
chips.forEach(chip => {
chip.addEventListener('click', () => {
const wasActive = chip.classList.contains('is-active');
chips.forEach(c => c.classList.remove('is-active'));
if (wasActive) {
usecasesEl.classList.remove('filtered');
tags.forEach(t => t.classList.remove('is-match'));
summary.innerHTML = 'Click a service to see the use cases it powers.';
return;
}
chip.classList.add('is-active');
const service = chip.dataset.service;
usecasesEl.classList.add('filtered');
const matched = [];
tags.forEach(t => {
const isMatch = t.dataset.tags.split(',').includes(service);
t.classList.toggle('is-match', isMatch);
if (isMatch) matched.push(t.textContent.trim());
});
const name = chip.querySelector('.service-name').textContent;
summary.innerHTML = `<strong>${name}</strong> powers: ${matched.join(', ')}.`;
});
});
})();
</script>
</body>
</html>.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!');
});<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AWS Global Infrastructure</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,500;0,6..72,600;1,6..72,500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
.infographic-awsinfra {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--charge: #c2760c;
--charge-soft: #fbeed9;
--error: #c0392b;
--error-soft: #fbe9e7;
--display-font: 'Newsreader', Georgia, serif;
--body-font: 'Inter', system-ui, sans-serif;
background: var(--paper);
color: var(--ink);
font-family: var(--body-font);
max-width: 880px;
margin: 0 auto;
padding: clamp(1.25rem, 5vw, 3rem);
box-sizing: border-box;
}
.infographic-awsinfra[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #13171F;
--paper-alt: #1c2029;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--charge: #e0a13f;
--charge-soft: #3a2e14;
--error: #e57373;
--error-soft: #3a2222;
}
.infographic-awsinfra * { box-sizing: border-box; }
.infographic-awsinfra h1 {
font-family: var(--display-font);
font-weight: 600;
font-size: clamp(1.4rem, 3.6vw, 1.9rem);
margin: 1.5rem 0 0.3rem;
letter-spacing: -0.01em;
}
.infographic-awsinfra .subhead {
color: var(--ink-soft);
font-size: 0.92rem;
margin: 0 0 1.6rem;
max-width: 66ch;
line-height: 1.55;
}
.infographic-awsinfra .section-label {
font-size: 0.72rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--accent);
margin: 2.4rem 0 0.4rem;
}
.infographic-awsinfra .section-label:first-of-type { margin-top: 0; }
.infographic-awsinfra .section-intro {
font-size: 0.87rem;
color: var(--ink-soft);
line-height: 1.55;
margin: 0 0 1rem;
max-width: 64ch;
}
.infographic-awsinfra .connector-note {
font-size: 0.78rem;
color: var(--ink-soft);
font-style: italic;
margin-top: 0.7rem;
}
.infographic-awsinfra .connector-note strong { color: var(--accent); font-style: normal; }
/* ---- latency demo ---- */
.infographic-awsinfra .latency-demo {
background: var(--paper-alt);
border: 1px solid var(--line);
border-radius: 10px;
padding: 1.4rem 1.2rem 1.2rem;
}
.infographic-awsinfra .track { position: relative; height: 64px; margin: 1.6rem 0 0.6rem; }
.infographic-awsinfra .track-line {
position: absolute; top: 50%; left: 6%; right: 6%; height: 2px;
background: var(--line); transform: translateY(-50%);
}
.infographic-awsinfra .track-line .fill {
position: absolute; top: 0; left: 0; height: 100%;
background: var(--charge); width: 100%;
transition: width 0.5s ease, background 0.5s ease;
}
.infographic-awsinfra .node {
position: absolute; top: 50%; transform: translate(-50%, -50%);
display: flex; flex-direction: column; align-items: center; gap: 0.3rem;
}
.infographic-awsinfra .node .dot { width: 16px; height: 16px; border-radius: 50%; background: var(--ink); border: 2px solid var(--paper-alt); }
.infographic-awsinfra .node .lbl { font-size: 0.72rem; font-weight: 600; color: var(--ink-soft); white-space: nowrap; }
.infographic-awsinfra .node.user { left: 6%; }
.infographic-awsinfra .node.origin { left: 94%; }
.infographic-awsinfra .node.origin .dot { background: var(--accent); }
.infographic-awsinfra .node.edge { left: 6%; opacity: 0; transition: left 0.5s ease, opacity 0.4s ease; pointer-events: none; }
.infographic-awsinfra .node.edge .dot { background: var(--accent); }
.infographic-awsinfra .latency-demo.is-cached .node.edge { left: 28%; opacity: 1; }
.infographic-awsinfra .latency-demo.is-cached .track-line .fill { width: 22%; background: var(--accent); }
.infographic-awsinfra .latency-readout {
display: flex; align-items: center; justify-content: space-between;
flex-wrap: wrap; gap: 0.8rem; margin-top: 1.2rem;
}
.infographic-awsinfra .latency-badge { font-family: var(--display-font); font-weight: 600; font-size: 1.1rem; color: var(--charge); transition: color 0.3s ease; }
.infographic-awsinfra .latency-demo.is-cached .latency-badge { color: var(--accent); }
.infographic-awsinfra .latency-badge .tag { font-family: var(--body-font); font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; display: block; color: var(--ink-soft); }
.infographic-awsinfra .demo-btn {
font: inherit; font-size: 0.82rem; font-weight: 600;
background: var(--paper); border: 1px solid var(--accent); color: var(--accent);
border-radius: 8px; padding: 0.55rem 1rem; cursor: pointer;
transition: background 0.15s, color 0.15s;
}
.infographic-awsinfra .latency-demo.is-cached .demo-btn { background: var(--accent); color: var(--paper); }
/* ---- comparison ---- */
.infographic-awsinfra .compare {
display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
background: var(--line); border: 1px solid var(--line); border-radius: 10px; overflow: hidden;
}
@media (max-width: 560px) { .infographic-awsinfra .compare { grid-template-columns: 1fr; } }
.infographic-awsinfra .compare-col {
background: var(--paper); padding: 1.1rem 1.1rem 1.2rem; cursor: pointer;
border-top: 3px solid transparent; transition: background 0.15s, border-color 0.15s;
}
.infographic-awsinfra .compare-col.is-highlighted { background: var(--accent-soft); border-top-color: var(--accent); }
.infographic-awsinfra .compare-title { font-family: var(--display-font); font-weight: 600; font-size: 1rem; margin: 0 0 0.2rem; }
.infographic-awsinfra .compare-sub { font-size: 0.76rem; color: var(--ink-soft); margin: 0 0 0.8rem; }
.infographic-awsinfra .compare-col ul { margin: 0; padding-left: 1.05rem; font-size: 0.85rem; color: var(--ink-soft); line-height: 1.65; }
.infographic-awsinfra .compare-col.is-highlighted ul { color: var(--ink); }
.infographic-awsinfra .compare-col strong { color: var(--ink); }
/* ---- tag rows (goals / factors / properties / used-by) ---- */
.infographic-awsinfra .tag-row { display: flex; flex-wrap: wrap; gap: 0.55rem; }
.infographic-awsinfra .tag-chip {
font-size: 0.82rem; font-weight: 600; padding: 0.5rem 0.9rem;
border-radius: 20px; background: var(--accent-soft); color: var(--accent);
}
.infographic-awsinfra .tag-chip.outline {
background: var(--paper); border: 1px solid var(--line); color: var(--ink-soft); font-weight: 500;
}
/* ---- region cards ---- */
.infographic-awsinfra .regions { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.7rem; margin-top: 1rem; }
@media (max-width: 620px) { .infographic-awsinfra .regions { grid-template-columns: 1fr; } }
.infographic-awsinfra .region-card {
background: var(--paper-alt); border: 1px solid var(--line); border-radius: 10px;
padding: 0.9rem 1rem; text-align: left; cursor: pointer; font: inherit; color: var(--ink);
border-top: 3px solid transparent; transition: border-color 0.15s, background 0.15s;
}
.infographic-awsinfra .region-card.is-active { border-color: var(--accent); background: var(--paper); }
.infographic-awsinfra .region-name { font-weight: 700; font-size: 0.86rem; display: block; }
.infographic-awsinfra .region-loc { font-size: 0.76rem; color: var(--ink-soft); display: block; margin-top: 0.15rem; }
.infographic-awsinfra .latency-gauge {
margin-top: 1rem; padding: 0.8rem 1rem; background: var(--paper-alt); border-radius: 10px;
display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap;
}
.infographic-awsinfra .gauge-label { font-size: 0.78rem; color: var(--ink-soft); font-weight: 600; }
.infographic-awsinfra .gauge-track { flex: 1; min-width: 140px; height: 8px; border-radius: 4px; background: var(--line); position: relative; overflow: hidden; }
.infographic-awsinfra .gauge-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 20%; background: var(--accent); transition: width 0.4s ease, background 0.4s ease; border-radius: 4px; }
.infographic-awsinfra .gauge-readout { font-size: 0.8rem; font-weight: 700; color: var(--ink); min-width: 8ch; }
/* ---- AZ failover ---- */
.infographic-awsinfra .az-demo { background: var(--paper-alt); border: 1px solid var(--line); border-radius: 10px; padding: 1.3rem 1.2rem 1.2rem; }
.infographic-awsinfra .az-region-box {
border: 1.5px dashed var(--line); border-radius: 10px; padding: 1.2rem 1rem 1rem;
display: flex; justify-content: space-around; gap: 0.8rem; flex-wrap: wrap; position: relative;
}
.infographic-awsinfra .az-region-label {
position: absolute; top: -0.7rem; left: 1rem; background: var(--paper-alt);
padding: 0 0.5rem; font-size: 0.72rem; font-weight: 700; color: var(--ink-soft); text-transform: uppercase; letter-spacing: 0.04em;
}
.infographic-awsinfra .az-box {
flex: 1 1 90px; text-align: center; padding: 0.9rem 0.5rem; border-radius: 8px;
background: var(--paper); border: 2px solid var(--accent); transition: border-color 0.35s, background 0.35s, opacity 0.35s;
}
.infographic-awsinfra .az-box .az-name { font-weight: 700; font-size: 0.82rem; }
.infographic-awsinfra .az-box .az-status { font-size: 0.72rem; color: var(--accent); margin-top: 0.2rem; font-weight: 600; }
.infographic-awsinfra .az-box.is-down { border-color: var(--error); opacity: 0.5; }
.infographic-awsinfra .az-box.is-down .az-status { color: var(--error); }
.infographic-awsinfra .az-box.is-boosted { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.infographic-awsinfra .az-readout {
margin-top: 1.1rem; font-size: 0.85rem; color: var(--ink-soft); line-height: 1.5; min-height: 1.4em;
}
.infographic-awsinfra .az-readout strong { color: var(--ink); }
.infographic-awsinfra .az-readout.status-ok strong.status-word { color: var(--accent); }
.infographic-awsinfra .az-readout.status-down strong.status-word { color: var(--error); }
.infographic-awsinfra .az-btn {
margin-top: 1rem; font: inherit; font-size: 0.82rem; font-weight: 600;
background: var(--paper); border: 1px solid var(--error); color: var(--error);
border-radius: 8px; padding: 0.5rem 0.95rem; cursor: pointer;
}
.infographic-awsinfra .az-demo.is-down .az-btn { background: var(--error); color: var(--paper); }
/* ---- edge flow ---- */
.infographic-awsinfra .flow { display: flex; gap: 1.5rem; flex-wrap: wrap; align-items: stretch; margin-top: 1rem; }
.infographic-awsinfra .flow-step {
flex: 1 1 180px; background: var(--paper-alt); border: 1px solid var(--line); border-radius: 10px;
padding: 1.1rem; position: relative; cursor: pointer;
}
.infographic-awsinfra .flow-step .num { font-family: var(--display-font); color: var(--accent); font-size: 1.3rem; }
.infographic-awsinfra .flow-step::after {
content: "β"; position: absolute; right: -1.85rem; top: 50%; transform: translateY(-50%);
color: var(--line); font-size: 1.4rem;
}
.infographic-awsinfra .flow-step:last-child::after { content: none; }
.infographic-awsinfra .flow-step .step-title { font-weight: 600; font-size: 0.88rem; margin-top: 0.2rem; }
.infographic-awsinfra .flow-step .step-detail { display: none; margin-top: 0.55rem; font-size: 0.8rem; color: var(--ink-soft); line-height: 1.5; }
.infographic-awsinfra .flow-step.is-open .step-detail { display: block; }
.infographic-awsinfra .flow-step.is-open { border-color: var(--accent); }
@media (max-width: 640px) {
.infographic-awsinfra .flow { flex-direction: column; }
.infographic-awsinfra .flow-step::after { content: "β"; right: 50%; top: auto; bottom: -1.9rem; transform: translateX(50%); }
}
.infographic-awsinfra .flow-result { margin-top: 1.2rem; font-size: 0.88rem; color: var(--ink-soft); font-style: italic; }
.infographic-awsinfra .flow-result strong { color: var(--accent); font-style: normal; }
@media (prefers-reduced-motion: reduce) {
.infographic-awsinfra * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}
</style>
</head>
<body>
<div class="infographic-awsinfra" id="awsInfraRoot">
<h1>π AWS Global Infrastructure</h1>
<p class="subhead">A user in Nairobi requesting a site hosted in Europe pays for that distance in latency. AWS closes the gap with a layered footprint: Regions, then Availability Zones inside each Region, then Edge Locations reaching past both.</p>
<p class="section-label">The problem: distance</p>
<div class="latency-demo" id="latencyDemo">
<div class="track">
<div class="track-line"><div class="fill"></div></div>
<div class="node user"><span class="dot"></span><span class="lbl">Nairobi user</span></div>
<div class="node edge"><span class="dot"></span><span class="lbl">CloudFront edge</span></div>
<div class="node origin"><span class="dot"></span><span class="lbl">EU origin server</span></div>
</div>
<div class="latency-readout">
<div class="latency-badge"><span class="tag" id="latencyTag">Direct to origin</span><span id="latencyValue">High latency</span></div>
<button class="demo-btn" id="cdnToggle">Add a CloudFront edge location</button>
</div>
</div>
<p class="section-label">Two kinds of services</p>
<div class="compare" id="compare">
<div class="compare-col" data-col="global">
<p class="compare-title">Global services</p>
<p class="compare-sub">One instance, works from anywhere</p>
<ul>
<li><strong>IAM</strong> β identity & access management</li>
<li><strong>Route 53</strong> β DNS service</li>
<li><strong>CloudFront</strong> β content delivery network</li>
<li><strong>WAF</strong> β web application firewall</li>
</ul>
</div>
<div class="compare-col" data-col="regional">
<p class="compare-title">Region-scoped services</p>
<p class="compare-sub">Deployed per region, closer to users</p>
<ul>
<li><strong>EC2</strong> β infrastructure as a service</li>
<li><strong>Elastic Beanstalk</strong> β platform as a service</li>
<li><strong>Lambda</strong> β function as a service</li>
<li><strong>Rekognition</strong> β software as a service</li>
</ul>
</div>
</div>
<p class="section-label">What this buys you</p>
<div class="tag-row">
<span class="tag-chip">π Global reach</span>
<span class="tag-chip">β‘ Low latency</span>
<span class="tag-chip">π Enterprise security</span>
<span class="tag-chip">π§± Fault tolerance</span>
<span class="tag-chip">π Elastic scalability</span>
</div>
<h1>πΊ Regions</h1>
<p class="section-intro">A Region is a specific geographic location β a country or area β holding a cluster of AWS data centers. Each one is fully isolated from every other Region, runs region-specific services, and exists to satisfy compliance and reliability needs. Click an example to see roughly how far it sits from our Nairobi user.</p>
<div class="regions" id="regions">
<button class="region-card" data-latency="60">
<span class="region-name">US East</span>
<span class="region-loc">N. Virginia</span>
</button>
<button class="region-card" data-latency="35">
<span class="region-name">Europe</span>
<span class="region-loc">Frankfurt</span>
</button>
<button class="region-card" data-latency="80">
<span class="region-name">Asia Pacific</span>
<span class="region-loc">Mumbai</span>
</button>
</div>
<div class="latency-gauge">
<span class="gauge-label">Relative distance from Nairobi</span>
<span class="gauge-track"><span class="gauge-fill" id="gaugeFill"></span></span>
<span class="gauge-readout" id="gaugeReadout">Pick a region</span>
</div>
<p class="connector-note">The same latency logic from the top of this page applies here β <strong>picking a Region closer to your users is step one</strong>; edge caching is what handles the rest.</p>
<p class="section-label">Choosing a Region</p>
<p class="section-intro">Beyond raw distance, a few other factors decide where an app should live:</p>
<div class="tag-row">
<span class="tag-chip outline">User location</span>
<span class="tag-chip outline">Legal requirements</span>
<span class="tag-chip outline">Pricing</span>
<span class="tag-chip outline">Service availability</span>
<span class="tag-chip outline">Disaster recovery</span>
</div>
<h1>π’ Availability Zones</h1>
<p class="section-intro">Inside every Region sit multiple Availability Zones β 3 to 6 separate data centers, each with independent power, cooling, and networking, linked by high-speed connections. Try knocking one offline.</p>
<div class="az-demo" id="azDemo">
<div class="az-region-box">
<span class="az-region-label">Europe (Frankfurt) Region</span>
<div class="az-box" data-az="1"><span class="az-name">AZ-1</span><span class="az-status">Serving traffic</span></div>
<div class="az-box" data-az="2"><span class="az-name">AZ-2</span><span class="az-status">Standing by</span></div>
<div class="az-box" data-az="3"><span class="az-name">AZ-3</span><span class="az-status">Standing by</span></div>
</div>
<div class="az-readout status-ok" id="azReadout">All zones healthy β <strong class="status-word">app is online</strong>.</div>
<button class="az-btn" id="azToggle">Simulate an AZ outage</button>
</div>
<h1>π Edge Locations</h1>
<p class="section-intro">Edge Locations are AWS points of presence, well outside Region boundaries, that push content the last few hundred kilometers to the user β the same mechanism you tried at the top of this page.</p>
<div class="tag-row" style="margin-bottom: 1rem;">
<span class="tag-chip">Used by CloudFront</span>
<span class="tag-chip">Used by Route 53</span>
</div>
<div class="flow" id="edgeFlow">
<div class="flow-step" data-i="1">
<span class="num">01</span>
<div class="step-title">Request hits nearest edge</div>
<div class="step-detail">The user's request is routed to the closest edge location, not the origin server.</div>
</div>
<div class="flow-step" data-i="2">
<span class="num">02</span>
<div class="step-title">Cached content served</div>
<div class="step-detail">If the content is already cached there, it's delivered instantly β no trip to origin.</div>
</div>
<div class="flow-step" data-i="3">
<span class="num">03</span>
<div class="step-title">Latency drops</div>
<div class="step-detail">Shorter physical distance means a faster round trip, every time.</div>
</div>
</div>
<p class="flow-result">π Result: <strong>faster performance, globally.</strong></p>
</div>
<script>
(function () {
const wrapper = document.getElementById('awsInfraRoot');
// dark mode detection
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');
// ---- latency demo ----
const latencyDemo = wrapper.querySelector('#latencyDemo');
const cdnToggle = wrapper.querySelector('#cdnToggle');
const latencyTag = wrapper.querySelector('#latencyTag');
const latencyValue = wrapper.querySelector('#latencyValue');
cdnToggle.addEventListener('click', () => {
const cached = latencyDemo.classList.toggle('is-cached');
if (cached) {
latencyTag.textContent = 'Served from nearby edge';
latencyValue.textContent = 'Low latency';
cdnToggle.textContent = 'Remove the edge location';
} else {
latencyTag.textContent = 'Direct to origin';
latencyValue.textContent = 'High latency';
cdnToggle.textContent = 'Add a CloudFront edge location';
}
});
// ---- service comparison ----
wrapper.querySelectorAll('.compare-col').forEach(col => {
col.addEventListener('click', () => {
const already = col.classList.contains('is-highlighted');
wrapper.querySelectorAll('.compare-col').forEach(c => c.classList.remove('is-highlighted'));
if (!already) col.classList.add('is-highlighted');
});
});
// ---- region cards + latency gauge ----
const regionCards = wrapper.querySelectorAll('.region-card');
const gaugeFill = wrapper.querySelector('#gaugeFill');
const gaugeReadout = wrapper.querySelector('#gaugeReadout');
regionCards.forEach(card => {
card.addEventListener('click', () => {
const already = card.classList.contains('is-active');
regionCards.forEach(c => c.classList.remove('is-active'));
if (already) {
gaugeFill.style.width = '0%';
gaugeReadout.textContent = 'Pick a region';
return;
}
card.classList.add('is-active');
const pct = card.dataset.latency;
gaugeFill.style.width = pct + '%';
gaugeFill.style.background = pct < 50 ? 'var(--accent)' : 'var(--charge)';
const name = card.querySelector('.region-name').textContent;
gaugeReadout.textContent = (pct < 50 ? 'Closer β ' : 'Farther β ') + name;
});
});
// ---- AZ failover demo ----
const azDemo = wrapper.querySelector('#azDemo');
const azToggle = wrapper.querySelector('#azToggle');
const azReadout = wrapper.querySelector('#azReadout');
const az1 = wrapper.querySelector('.az-box[data-az="1"]');
const az2 = wrapper.querySelector('.az-box[data-az="2"]');
azToggle.addEventListener('click', () => {
const down = azDemo.classList.toggle('is-down');
if (down) {
az1.classList.add('is-down');
az1.querySelector('.az-status').textContent = 'Outage';
az2.classList.add('is-boosted');
az2.querySelector('.az-status').textContent = 'Now serving traffic';
azReadout.classList.remove('status-ok');
azReadout.classList.add('status-down');
azReadout.innerHTML = 'AZ-1 failed β traffic shifted to AZ-2 β <strong class="status-word">app stays online</strong>.';
azToggle.textContent = 'Restore AZ-1';
} else {
az1.classList.remove('is-down');
az1.querySelector('.az-status').textContent = 'Serving traffic';
az2.classList.remove('is-boosted');
az2.querySelector('.az-status').textContent = 'Standing by';
azReadout.classList.remove('status-down');
azReadout.classList.add('status-ok');
azReadout.innerHTML = 'All zones healthy β <strong class="status-word">app is online</strong>.';
azToggle.textContent = 'Simulate an AZ outage';
}
});
// ---- edge flow steps ----
wrapper.querySelectorAll('.flow-step').forEach(step => {
step.addEventListener('click', () => {
const wasOpen = step.classList.contains('is-open');
wrapper.querySelectorAll('.flow-step').forEach(s => s.classList.remove('is-open'));
if (!wasOpen) step.classList.add('is-open');
});
});
})();
</script>
</body>
</html>.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!');
});