Files
rohitg00--ai-engineering-fr…/site/index.html
T
2026-07-13 12:09:03 +08:00

829 lines
27 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Engineering from Scratch</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect width='32' height='32' fill='%23fafaf5'/><rect x='2' y='2' width='28' height='28' fill='none' stroke='%233553ff' stroke-width='1.2'/><text x='6' y='22' font-size='14' font-family='monospace' fill='%233553ff'>AI</text></svg>">
<meta name="description" content="AI Engineering from Scratch is a free, open-source curriculum that builds every core AI algorithm by hand — 503 lessons, 20 phases, four languages. The math, the model, the tokenizer, and the agent loop. Once, by hand.">
<link rel="canonical" href="https://aiengineeringfromscratch.com/">
<meta property="og:title" content="AI Engineering from Scratch">
<meta property="og:description" content="503 lessons. 20 phases. Write the backprop, the tokenizer, the attention mechanism, and the agent loop by hand before any framework gets imported. Python, TypeScript, Rust, Julia.">
<meta property="og:image" content="https://aiengineeringfromscratch.com/og-image.png?v=3">
<meta property="og:url" content="https://aiengineeringfromscratch.com">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="AI Engineering from Scratch">
<meta name="twitter:description" content="503 lessons. 20 phases. Write the backprop, the tokenizer, the attention mechanism, and the agent loop by hand.">
<meta name="twitter:image" content="https://aiengineeringfromscratch.com/og-image.png?v=3">
<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=VT323&family=Source+Serif+4:ital,opsz,wght@0,8..60,400..700;1,8..60,400..700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css?v=20260525a">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://aiengineeringfromscratch.com/#org",
"name": "AI Engineering from Scratch",
"url": "https://aiengineeringfromscratch.com",
"logo": "https://aiengineeringfromscratch.com/og-image.png",
"sameAs": ["https://github.com/rohitg00/ai-engineering-from-scratch", "https://github.com/rohitg00"],
"founder": { "@type": "Person", "name": "Rohit Ghumare", "url": "https://github.com/rohitg00" }
},
{
"@type": "WebSite",
"@id": "https://aiengineeringfromscratch.com/#website",
"url": "https://aiengineeringfromscratch.com",
"name": "AI Engineering from Scratch",
"description": "A free, open-source curriculum that builds every core AI algorithm by hand.",
"publisher": { "@id": "https://aiengineeringfromscratch.com/#org" },
"potentialAction": {
"@type": "SearchAction",
"target": { "@type": "EntryPoint", "urlTemplate": "https://aiengineeringfromscratch.com/catalog.html?q={search_term_string}" },
"query-input": "required name=search_term_string"
}
},
{
"@type": "Course",
"@id": "https://aiengineeringfromscratch.com/#course",
"name": "AI Engineering from Scratch",
"description": "503 lessons across 20 phases. Write the backprop, the tokenizer, the attention mechanism, and the agent loop by hand before any framework gets imported.",
"provider": { "@id": "https://aiengineeringfromscratch.com/#org" },
"url": "https://aiengineeringfromscratch.com",
"isAccessibleForFree": true,
"inLanguage": "en",
"teaches": ["Neural networks", "Backpropagation", "Tokenization", "Attention mechanisms", "LLM training", "Inference optimization", "Agent loops", "Model context protocol"],
"hasCourseInstance": {
"@type": "CourseInstance",
"courseMode": "online",
"instructor": { "@type": "Person", "name": "Rohit Ghumare" }
}
}
]
}
</script>
<style>
.manual-masthead {
padding: 96px 0 24px;
border-bottom: 1px solid var(--rule-soft);
}
.manual-meta-row {
display: flex;
justify-content: space-between;
align-items: baseline;
gap: 16px;
flex-wrap: wrap;
margin-bottom: 32px;
font-family: var(--font-mono);
font-size: 0.72rem;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--ink-mute);
}
.manual-meta-row .right {
color: var(--blueprint);
}
.manual-title {
display: block;
font-family: var(--font-display);
font-size: clamp(3.2rem, 11vw, 8rem);
line-height: 0.86;
letter-spacing: 0.02em;
text-transform: uppercase;
color: var(--blueprint);
}
.manual-tagline {
max-width: 720px;
margin: 28px 0 8px;
font-family: var(--font-body);
font-size: clamp(1.05rem, 1.7vw, 1.25rem);
line-height: 1.55;
color: var(--ink);
}
.manual-attribution {
font-family: var(--font-body);
font-size: 0.95rem;
color: var(--ink-soft);
font-style: italic;
}
.masthead-cta {
display: flex;
gap: 12px;
flex-wrap: wrap;
margin-top: 20px;
}
.masthead-btn {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 9px 14px;
border: 1px solid var(--ink);
background: var(--bg);
color: var(--ink);
text-decoration: none;
font-family: var(--font-mono);
font-size: 0.82rem;
letter-spacing: 0.02em;
transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.masthead-btn:hover,
.masthead-btn:focus-visible {
background: var(--ink);
color: var(--bg);
}
.masthead-btn--primary {
border-color: var(--blueprint);
color: var(--blueprint);
}
.masthead-btn--primary:hover,
.masthead-btn--primary:focus-visible {
background: var(--blueprint);
color: var(--bg);
}
.masthead-btn-count {
padding-left: 8px;
margin-left: 4px;
border-left: 1px solid currentColor;
opacity: 0.85;
font-variant-numeric: tabular-nums;
}
@media (max-width: 480px) {
.masthead-btn { font-size: 0.78rem; padding: 8px 12px; }
}
.preface {
padding: 48px 0 32px;
border-bottom: 1px solid var(--rule-soft);
}
.preface-grid {
display: grid;
grid-template-columns: 200px 1fr;
gap: 48px;
}
.preface-eyebrow {
font-family: var(--font-mono);
font-size: 0.74rem;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--blueprint);
}
.preface-body {
column-count: 2;
column-gap: 48px;
column-rule: 1px solid var(--rule-soft);
font-family: var(--font-body);
font-size: 1rem;
line-height: 1.7;
text-align: justify;
hyphens: auto;
}
.preface-body p {
margin-bottom: 1em;
break-inside: avoid-column;
}
.preface-body p:first-of-type::first-letter {
font-family: var(--font-display);
float: left;
font-size: 4.4rem;
line-height: 0.85;
padding: 0.06em 0.14em 0 0;
color: var(--blueprint);
}
.figure-demo {
padding: 24px 0 0;
border-bottom: 1px solid var(--rule-soft);
}
.figure-demo-eyebrow {
font-family: var(--font-mono);
font-size: 0.74rem;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--blueprint);
margin-bottom: 6px;
}
.figure-demo-caption {
max-width: 640px;
font-family: var(--font-body);
font-size: 0.96rem;
line-height: 1.5;
color: var(--ink-soft);
margin-bottom: 0;
}
.figure-demo-svg {
width: 100%;
max-width: 760px;
margin: 0 auto;
}
.figure-demo-svg svg {
width: 100%;
height: auto;
display: block;
}
@media (max-width: 768px) {
.figure-demo { padding: 16px 0 0; }
}
.stat-block {
padding: 32px 0 40px;
border-bottom: 1px solid var(--rule-soft);
}
.stat-block-title {
font-family: var(--font-mono);
font-size: 0.78rem;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--blueprint);
margin-bottom: 24px;
}
.stat-rows {
display: grid;
grid-template-columns: 1fr;
gap: 10px;
max-width: 760px;
font-family: var(--font-mono);
font-size: 0.92rem;
}
.stat-row {
display: grid;
grid-template-columns: 200px minmax(0, 360px) 110px;
align-items: center;
gap: 16px;
padding: 4px 0;
}
.stat-row-label {
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--ink-soft);
}
.stat-row-bar {
position: relative;
height: 14px;
background: var(--rule-soft);
overflow: hidden;
font-size: 0;
line-height: 0;
text-indent: -9999px;
}
.stat-row-bar::before {
content: "";
position: absolute;
inset: 0;
width: var(--bar-pct, 0%);
background: var(--blueprint);
transition: width 0.6s ease;
}
.stat-row-value {
text-align: right;
font-variant-numeric: tabular-nums;
color: var(--ink);
letter-spacing: 0.04em;
white-space: nowrap;
}
.toc {
padding: 56px 0 80px;
border-bottom: 1px solid var(--rule-soft);
}
.toc-title {
font-family: var(--font-mono);
font-size: 0.78rem;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--blueprint);
margin-bottom: 8px;
}
.toc-subtitle {
font-family: var(--font-body);
font-size: 0.95rem;
color: var(--ink-soft);
margin-bottom: 32px;
}
.toc-list {
display: flex;
flex-direction: column;
gap: 0;
border-top: 1px solid var(--rule-soft);
}
.toc-row {
display: grid;
grid-template-columns: 56px 1fr auto auto;
align-items: baseline;
padding: 14px 0;
gap: 16px;
border-bottom: 1px solid var(--rule-soft);
cursor: pointer;
transition: background 0.15s;
}
.toc-row:hover {
background: var(--blueprint-tint);
}
.toc-num {
font-family: var(--font-mono);
font-size: 0.78rem;
letter-spacing: 0.1em;
color: var(--blueprint);
}
.toc-name {
font-family: var(--font-display);
font-size: 1.4rem;
text-transform: uppercase;
letter-spacing: 0.02em;
color: var(--ink);
line-height: 1.05;
}
.toc-leader {
flex: 1;
border-bottom: 1px dotted var(--rule-soft);
margin: 0 12px;
transform: translateY(-4px);
}
.toc-meta {
font-family: var(--font-mono);
font-size: 0.74rem;
letter-spacing: 0.08em;
color: var(--ink-mute);
font-variant-numeric: tabular-nums;
min-width: 80px;
text-align: right;
}
.toc-status {
width: 12px;
height: 12px;
border: 1px solid var(--ink);
flex-shrink: 0;
margin-right: 6px;
display: inline-block;
vertical-align: middle;
}
.toc-status.complete {
background: var(--blueprint);
border-color: var(--blueprint);
}
.toc-status.in-progress {
background: linear-gradient(135deg, var(--blueprint) 0%, var(--blueprint) 50%, transparent 50%, transparent 100%);
border-color: var(--blueprint);
}
.toc-status.planned {
background: transparent;
border-style: dashed;
border-color: var(--ink-mute);
}
.legend {
padding: 32px 0 72px;
display: flex;
gap: 28px;
flex-wrap: wrap;
align-items: center;
font-family: var(--font-mono);
font-size: 0.74rem;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--ink-soft);
}
.legend-item {
display: flex;
align-items: center;
gap: 8px;
}
.colophon {
padding: 48px 0;
border-top: 1px solid var(--rule-soft);
}
.colophon-grid {
display: grid;
grid-template-columns: 200px minmax(0, 1fr);
gap: 48px;
font-family: var(--font-body);
font-size: 0.96rem;
color: var(--ink-soft);
}
.colophon-grid > div {
min-width: 0;
}
.colophon-eyebrow {
font-family: var(--font-mono);
font-size: 0.74rem;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--blueprint);
}
.colophon-cmd {
display: flex;
align-items: center;
gap: 12px;
margin-top: 16px;
padding: 10px 16px;
background: var(--code-bg);
border: 1px solid var(--rule-soft);
font-family: var(--font-mono);
font-size: 0.85rem;
color: var(--blueprint);
max-width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.colophon-cmd code {
white-space: nowrap;
}
.colophon-cmd .copy-btn {
flex-shrink: 0;
position: sticky;
right: 0;
background: var(--code-bg);
padding-left: 8px;
}
@media (max-width: 900px) {
.manual-masthead { padding: 80px 0 16px; }
.preface { padding: 32px 0; }
.stat-block { padding: 32px 0; }
.toc { padding: 32px 0 40px; }
.colophon { padding: 32px 0; }
.manual-meta-row { margin-bottom: 20px; }
.manual-tagline { margin: 20px 0 6px; font-size: 1rem; }
.manual-attribution { font-size: 0.9rem; }
.preface-grid,
.colophon-grid {
grid-template-columns: 1fr;
gap: 12px;
}
.preface-body {
column-count: 1;
font-size: 0.98rem;
line-height: 1.65;
}
.preface-body p:first-of-type::first-letter {
font-size: 3.2rem;
}
.stat-rows { gap: 8px; }
.stat-row {
grid-template-columns: 160px minmax(0, 1fr) 92px;
gap: 12px;
font-size: 0.82rem;
}
.stat-block-title,
.toc-title { margin-bottom: 16px; }
.toc-subtitle { margin-bottom: 20px; }
.toc-row {
grid-template-columns: 36px 1fr auto;
padding: 11px 0;
}
.toc-row .toc-meta + .toc-meta {
display: none;
}
.toc-leader {
display: none;
}
.toc-name {
font-size: 1.1rem;
}
.colophon-cmd {
max-width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
}
@media (max-width: 480px) {
.manual-masthead { padding: 72px 0 12px; }
.preface { padding: 24px 0; }
.stat-block { padding: 24px 0; }
.toc { padding: 24px 0 32px; }
.colophon { padding: 24px 0; }
.manual-title {
font-size: clamp(2.4rem, 14vw, 3.6rem);
line-height: 0.92;
}
.manual-meta-row {
font-size: 0.6rem;
letter-spacing: 0.12em;
margin-bottom: 16px;
gap: 8px;
}
.manual-tagline {
font-size: 0.96rem;
margin: 16px 0 4px;
}
.ascii-rule {
margin: 16px 0;
}
.preface-eyebrow,
.stat-block-title,
.toc-title,
.colophon-eyebrow { font-size: 0.7rem; }
.preface-body {
font-size: 0.94rem;
line-height: 1.6;
text-align: left;
}
.preface-body p:first-of-type::first-letter {
font-size: 2.8rem;
padding: 0.04em 0.1em 0 0;
}
.stat-row {
grid-template-columns: 1fr;
gap: 2px;
padding: 6px 0;
}
.stat-row-bar {
order: 3;
}
.stat-row-value {
order: 2;
text-align: left;
}
.toc-row {
grid-template-columns: 30px 1fr auto;
gap: 8px;
padding: 10px 0;
}
.toc-name {
font-size: 0.96rem;
white-space: normal;
}
.toc-num {
font-size: 0.7rem;
}
}
/* Figure card (makingsoftware aesthetic) */
.figure-card {
border: 1px solid var(--rule-soft);
background: var(--bg);
padding: 0;
margin: 24px 0 36px;
background-image: radial-gradient(circle at 4px 4px, rgba(0,0,0,0.05) 1px, transparent 1.5px);
background-size: 16px 16px;
}
.figure-head {
display: flex;
justify-content: space-between;
gap: 16px;
padding: 14px 24px;
border-bottom: 1px solid var(--rule-soft);
font-family: var(--font-mono);
font-size: 0.72rem;
letter-spacing: 0.14em;
text-transform: uppercase;
}
.figure-head .left { color: var(--blueprint); }
.figure-head .right { color: var(--ink-mute); }
.figure-body {
padding: 32px 24px;
overflow-x: auto;
}
.figure-body svg { display: block; width: 100%; height: auto; max-width: 1100px; margin: 0 auto; color: var(--blueprint); }
.figure-foot {
padding: 14px 24px;
border-top: 1px solid var(--rule-soft);
font-family: var(--font-body);
font-size: 0.96rem;
color: var(--ink-soft);
line-height: 1.5;
}
</style>
</head>
<body>
<a href="#main" class="skip-link">Skip to content</a>
<header class="site-header">
<div class="header-inner">
<a href="index.html" class="logo">
<span class="logo-icon" aria-hidden="true"></span> AI / FROM SCRATCH
</a>
<nav class="header-nav">
<a href="#contents">Contents</a>
<a href="catalog.html">Catalog</a>
<a href="prereqs.html">Roadmap</a>
<a href="glossary.html">Glossary</a>
<a href="about.html">About</a>
<a href="https://github.com/rohitg00/ai-engineering-from-scratch" target="_blank" rel="noopener" class="header-github">
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.4 3-.405 1.02.005 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
<span class="star-count" data-loading="true" aria-label="GitHub stars"></span>
</a>
</nav>
<button class="search-toggle" type="button" data-cmd-palette
aria-label="Search (⌘K)" title="Search (⌘K)">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2.5"
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="11" cy="11" r="8"/>
<line x1="21" y1="21" x2="16.65" y2="16.65"/>
</svg>
</button>
<button class="theme-toggle" id="themeToggle" aria-label="Toggle theme" type="button">
<span class="theme-icon" id="themeIcon">N</span>
</button>
</div>
</header>
<main id="main">
<section class="manual-masthead container">
<div class="manual-meta-row">
<span>FIG_000 &middot; curriculum v1.0 · 2026</span>
<span class="right">open source · MIT</span>
</div>
<h1 class="manual-title">AI Engineering<br>from Scratch</h1>
<p class="manual-tagline reveal">503 lessons. 20 phases. Every algorithm built from raw math before a single framework gets imported.</p>
<p class="manual-attribution reveal" style="--stagger-delay: 80ms;">Maintained by Rohit Ghumare and contributors. Run on your own machine.</p>
<div class="masthead-cta reveal" style="--stagger-delay: 140ms;">
<a class="masthead-btn masthead-btn--primary" href="https://github.com/rohitg00/ai-engineering-from-scratch" target="_blank" rel="noopener" aria-label="Star ai-engineering-from-scratch on GitHub">
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279L12 19.896l-7.416 3.517 1.48-8.279L0 9.306l8.332-1.151z"/></svg>
<span>Star on GitHub</span>
<span class="masthead-btn-count" data-gh-stars="rohitg00/ai-engineering-from-scratch" data-loading="true"></span>
</a>
<a class="masthead-btn" href="https://github.com/rohitg00" target="_blank" rel="noopener" aria-label="Follow Rohit Ghumare on GitHub">
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.4 3-.405 1.02.005 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
<span>Follow @rohitg00</span>
</a>
</div>
<div class="ascii-rule" style="margin-top:48px;"></div>
</section>
<section class="preface container">
<div class="preface-grid">
<div class="preface-eyebrow reveal reveal--left">How this works</div>
<div class="preface-body reveal" style="--stagger-delay: 120ms;">
<p>Most AI material teaches in scattered pieces. A paper here, a fine-tuning post there, a flashy agent demo somewhere else. The pieces rarely line up. You ship a chatbot but can't explain its loss curve. You hook a function to an agent but can't say what attention does inside the model that's calling it.</p>
<p>This curriculum is the spine. 20 phases, 503 lessons, four languages: Python, TypeScript, Rust, Julia. Linear algebra at one end, autonomous swarms at the other. Every algorithm gets built from raw math first. Backprop. Tokenizer. Attention. Agent loop. By the time PyTorch shows up, you already know what it's doing under the hood.</p>
<p>Each lesson runs the same loop: read the problem, derive the math, write the code, run the test, keep the artifact. No five-minute videos, no copy-paste deploys, no hand-holding. Free, open source, and built to run on your own laptop.</p>
</div>
</div>
</section>
<section class="stat-block container">
<div class="stat-block-title reveal reveal--left">Current Progress</div>
<div class="stat-rows reveal" style="--stagger-delay: 100ms;" id="statRows">
<div class="stat-row">
<span class="stat-row-label">Finished Lessons</span>
<span class="stat-row-bar" data-bar="complete" style="--bar-pct:0%;" aria-hidden="true">bar</span>
<span class="stat-row-value" data-stat="complete-frac">0 / 0</span>
</div>
<div class="stat-row">
<span class="stat-row-label">Phases</span>
<span class="stat-row-bar" data-bar="phases" style="--bar-pct:0%;" aria-hidden="true">bar</span>
<span class="stat-row-value" data-stat="phases-frac">0 / 0</span>
</div>
<div class="stat-row">
<span class="stat-row-label">Languages</span>
<span class="stat-row-bar" data-bar="languages" style="--bar-pct:100%;" aria-hidden="true">bar</span>
<span class="stat-row-value">4</span>
</div>
<div class="stat-row">
<span class="stat-row-label">Glossary Terms</span>
<span class="stat-row-bar" data-bar="glossary" style="--bar-pct:100%;" aria-hidden="true">bar</span>
<span class="stat-row-value" data-stat="glossary-count">···</span>
</div>
</div>
</section>
<section class="toc container" id="contents">
<div class="toc-title reveal reveal--left">Curriculum · 20 phases · 503 lessons</div>
<div class="toc-subtitle reveal" style="--stagger-delay: 80ms;">Tap a phase to expand its lessons. Each one ships when its math, code, and test are all written.</div>
<div class="toc-list" id="phasesGrid"></div>
<div class="legend">
<span class="legend-item"><span class="toc-status complete"></span> Complete</span>
<span class="legend-item"><span class="toc-status in-progress"></span> In progress</span>
<span class="legend-item"><span class="toc-status planned"></span> Planned</span>
</div>
</section>
<div class="modal-overlay" id="modalOverlay">
<div class="modal" id="modal">
<button class="modal-close" id="modalClose" type="button">×</button>
<div class="modal-header">
<span class="modal-phase-num" id="modalPhaseNum"></span>
<h2 class="modal-title" id="modalTitle"></h2>
<p class="modal-desc" id="modalDesc"></p>
<div class="modal-progress" id="modalProgress" style="display:none;"></div>
<div class="modal-progress-bar" id="modalProgressBar" style="display:none;"><div class="modal-progress-bar-fill" id="modalProgressBarFill"></div></div>
</div>
<div class="modal-lessons" id="modalLessons"></div>
<div class="modal-footer">
<span class="modal-footer-note">Progress saved in browser only</span>
<button class="modal-reset" id="modalReset" type="button">Reset progress</button>
</div>
</div>
</div>
<section class="colophon container">
<div class="colophon-grid">
<div class="colophon-eyebrow reveal reveal--left">Colophon</div>
<div class="reveal" style="--stagger-delay: 80ms;">
<p>The entire curriculum is on GitHub. Clone it, fork it, learn at your own pace. No paywall, no signup. Every lesson has runnable code in Python, TypeScript, Rust, or Julia, depending on what fits the concept best.</p>
<div class="colophon-cmd">
<code id="cloneCmd">git clone https://github.com/rohitg00/ai-engineering-from-scratch.git</code>
<button class="copy-btn" id="copyBtn" aria-label="Copy command" type="button">cp</button>
</div>
</div>
</div>
</section>
</main>
<footer class="site-footer">
<div class="container footer-inner">
<p>© 2026 · open source · free forever</p>
<div class="footer-links">
<a href="https://github.com/rohitg00/ai-engineering-from-scratch" target="_blank" rel="noopener">GitHub</a>
<a href="about.html">About</a>
<a href="catalog.html">Catalog</a>
<a href="glossary.html">Glossary</a>
<a href="https://github.com/rohitg00/ai-engineering-from-scratch/issues/new/choose" target="_blank" rel="noopener">Report</a>
</div>
</div>
</footer>
<script src="data.js?v=20260525a"></script>
<script src="progress.js?v=20260525a"></script>
<script src="header.js?v=20260525a" defer></script>
<script src="cmdpalette.js?v=20260525a" defer></script>
<script src="app.js?v=20260525a"></script>
<script defer src="https://va.vercel-scripts.com/v1/script.js"></script>
</body>
</html>