Lesson Planning
Implementation Patterns (Lessons Learned)
These patterns apply to building effective lessons for any subject. Follow these when creating new lesson components.
Split Chaotic Content Into Focused Lessons
The Problem: A lesson that tries to cover too much becomes overwhelming and hard to learn from.
The Solution: Split large topics into multiple focused lessons, each with ONE core objective.
Example: A lesson on "Transformers" trying to cover:
- •Attention mechanisms
- •Self-attention vs cross-attention
- •Positional encoding
- •Layer normalization
- •Training dynamics
Should be split into focused lessons:
- •
attention-mechanism— Just the core attention concept with visualization - •
self-attention— Multi-head self-attention with code - •
transformer-architecture— How the pieces fit together
Rule of thumb: If a lesson has more than 3-4 major sections, consider splitting it.
Interactive Widgets
Consider what concepts could be enhanced with interactive visualization or exploration. See the interactive-widgets skill for:
- •Ideation prompts to identify interactivity opportunities
- •Available components
- •Implementation patterns (expandable explorers, selector + visualization)
Quick check: For each lesson section, ask:
- •Would this benefit from visualization?
- •Could the user explore or manipulate something?
- •Is there an "aha moment" that interactivity could trigger?
Lesson Row Layout
CRITICAL: Always use the Row component from @/components/layout/Row.
Never create manual flex layouts in lessons. The Row component automatically injects an empty aside placeholder when no aside is provided, which prevents content from expanding full-width.
import { Row } from '@/components/layout/Row'
// ✅ CORRECT - Always use Row
<Row>
<Row.Content>
<Card ... />
</Row.Content>
<Row.Aside>
<TipBlock>...</TipBlock>
</Row.Aside>
</Row>
// ✅ CORRECT - Conditional aside (Row auto-injects empty placeholder)
<Row>
<Row.Content>
<Card ... />
</Row.Content>
{isExpanded && (
<Row.Aside>
<TipBlock>...</TipBlock>
</Row.Aside>
)}
</Row>
// ❌ WRONG - Manual flex layout (causes width issues!)
<div className="flex flex-col lg:flex-row gap-8 lg:gap-32 items-start">
<div className="w-full lg:w-[900px] flex-shrink-0">
<Card ... />
</div>
</div>
Why this matters: When the aside is conditionally rendered and you use manual flex, the content expands full-width when the aside is hidden. Row prevents this by always maintaining the 2-column structure.
Block Components for Content Types
Use lesson blocks from @/components/lessons for visual consistency.
For Asides (sidebar blocks):
| Block | Purpose | Color |
|---|---|---|
TipBlock | Helpful hints, "Use for" | Sky blue |
InsightBlock | Key concepts, "Why it works" | Violet |
TryThisBlock | Interactive prompts, variations | Emerald |
WarningBlock | Common mistakes | Rose |
ConceptBlock | Theory explanations | Neutral |
For Main Content (gradient cards):
| Block | Purpose | When to Use |
|---|---|---|
GradientCard | Single categorized card | Feature highlights, categorized info |
ComparisonRow | Two side-by-side cards | A vs B comparisons |
PhaseCard | Numbered sequential card | Multi-step processes, timeline phases |
See interactive-widgets skill → references/component-catalog.md for full component reference.
CodeBlock for Code Examples
Use CodeBlock from @/components/common/CodeBlock for syntax-highlighted code in lessons.
import { CodeBlock } from '@/components/common/CodeBlock'
<CodeBlock
code={`def forward(self, x):
return self.linear(x)`}
language="python"
filename="model.py" // Optional - shows in header
/>
Features:
- •Syntax highlighting via Prism (react-syntax-highlighter)
- •Faint line numbers with proper spacing
- •Theme-aware (dark/light mode via next-themes)
- •Copy to clipboard button (appears on hover)
- •Optional filename header
Styling notes (from ventures):
- •Line number color:
rgb(156 163 175 / 0.5)for dark,rgb(107 114 128 / 0.5)for light - •Container:
text-xsfor appropriate code size - •Background:
transparent(inherits from container) - •Uses
oneDark/oneLightthemes from react-syntax-highlighter
Hydration safety: The component handles SSR by defaulting to dark theme until mounted, avoiding hydration mismatches.
ClipboardCopy Component
Reusable clipboard copy button from @/components/common/ClipboardCopy.
import { ClipboardCopy } from '@/components/common/ClipboardCopy'
<ClipboardCopy text="content to copy" />
<ClipboardCopy text={code} className="h-7 w-7" />
<ClipboardCopy text={url} label="Copy URL" />
Props:
- •
text— Content to copy (required) - •
variant— Button variant:'ghost'(default),'default','outline' - •
size— Button size:'icon'(default),'sm','default','lg' - •
label— Optional text label (shows "Copied!" on success) - •
className— Additional classes
Uses useTimeout hook for the 2-second "copied" state reset.
Google Colab Notebooks
For hands-on exercises, link to Colab notebooks stored in the /notebooks/ directory.
Notebook naming: {module}-{lesson}-{topic}.ipynb (e.g., 1-1-6-linear-regression.ipynb)
Colab link format:
<a href="https://colab.research.google.com/github/brennancheung/CourseAI/blob/main/notebooks/1-1-6-linear-regression.ipynb" target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-2 px-4 py-2 rounded-md bg-primary text-primary-foreground font-medium text-sm hover:bg-primary/90 transition-colors" > <ExternalLink className="w-4 h-4" /> Open in Google Colab </a>
Best practice: Use the in-app interactive widgets (like TrainingLoopExplorer) for visualization, and link to Colab for the "implement it yourself" exercises. The widget shows what happens; the notebook lets them write the code.
Expandable Card Pattern
For lessons with multiple items to explore (concepts, techniques, models), use expandable cards wrapped in Row:
import { Row } from '@/components/layout/Row'
function ConceptRow({ concept, isExpanded, onToggle }) {
return (
<Row>
<Row.Content>
<ConceptCard
concept={concept}
isExpanded={isExpanded}
onToggle={onToggle}
/>
</Row.Content>
{isExpanded && (
<Row.Aside>
<TipBlock title="Key Insight">...</TipBlock>
<WarningBlock title="Common Misconceptions">...</WarningBlock>
</Row.Aside>
)}
</Row>
)
}
Key points:
- •Always use Row — even for expandable cards with conditional asides
- •Row auto-injects empty aside when not expanded, preventing full-width expansion
- •Card header is always visible with title + tagline
- •Expanded content shows detailed breakdown
- •Aside appears alongside expanded card with contextual tips
- •Only one card expanded at a time (controlled by parent)
Core Framework
1. Know the Learner
Before creating a lesson, understand current state:
Learner baseline:
- •Software engineer with strong programming background
- •Comfortable with Python, can read academic papers
- •Has used AI tools but wants deeper understanding
- •ADHD: needs low activation energy, clear scope, no decision paralysis
Identify the learning edge:
- •What can they almost do but not quite?
- •What's the next logical step from recent lessons?
- •What mental model would unlock new capability?
2. Define the Learning Objective
Every lesson needs ONE clear outcome:
Good objectives:
- •"Implement attention from scratch in PyTorch"
- •"Understand why layer normalization matters for transformer training"
- •"Build intuition for how diffusion models denoise"
Bad objectives:
- •"Get better at deep learning" (too vague)
- •"Understand transformers" (too big)
- •"Learn attention and normalization and training" (too many things)
The test: Can you say "After this lesson, I can ___" with a specific, observable skill?
3. Set Scope Boundaries (What You're NOT Doing)
This is critical for ADHD. Explicitly close doors:
NOT optimizing for speed NOT worrying about deployment NOT covering all variations Just focusing on: [the one thing]
Constraints liberate. Every "not" removes a decision.
Lesson Structure & Flow
The order of content in a lesson matters. Motivation drives learning.
The Pedagogical Flow
- •Context — What is this lesson about? Set constraints.
- •Hook — Motivate the learner immediately (see below)
- •Explain — Teach the concept now that they're interested
- •Explore — Let them interact and try things
- •Elaborate — Deeper concepts after basics are understood
- •Practice — Concrete steps to apply what they learned
- •Challenge — Final exercise to synthesize learning
- •Reflect — Capture what worked and what was hard
The Hook
The hook is critical. It comes right after context and before explanation. Its job is to increase motivation before teaching begins.
Types of hooks:
| Hook Type | Example |
|---|---|
| Demo | Interactive visualization showing the concept in action |
| Before/After | "Here's what GPT-2 outputs vs GPT-4 — what changed?" |
| Question | "Why can transformers understand context that RNNs can't?" |
| Challenge preview | "By the end, you'll implement this from scratch" |
| Real-world impact | "This technique enabled ChatGPT to exist" |
Hook principles:
- •Short — 30 seconds to 2 minutes max
- •Emotionally engaging — should create "I want to understand that" feeling
- •Directly relevant — must connect to what you're about to teach
- •No prerequisites — should work even if they don't understand the concept yet
ADHD-Friendly Checklist
Before finalizing any lesson, verify:
- • Single focus — One skill, one outcome
- • Low activation energy — Can start immediately
- • No decisions required — Clear path forward
- • Concrete deliverable — "Build X" not "Study Y"
- • Scope boundaries explicit — What you're NOT doing is stated
- • No guilt hooks — No streaks, no "you should have..."
- • Working memory friendly — All info in the lesson, nothing to remember
Deliberate Practice Checklist
- • Specific goal — Not vague improvement
- • At the edge — Requires focus, not too easy, not frustrating
- • Feedback available — Can test/verify if it's working
- • Repeatable — Can do it again with variation
- • Builds mental model — Develops internal representation