Skip to content

Instantly share code, notes, and snippets.

@brianmcaudill
Created September 30, 2025 23:24
Show Gist options
  • Select an option

  • Save brianmcaudill/afff36aa25e8f386e9796f7886d324f5 to your computer and use it in GitHub Desktop.

Select an option

Save brianmcaudill/afff36aa25e8f386e9796f7886d324f5 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Video Quiz</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
max-width: 1500px;
width: 100%;
background: #fff;
border-radius: 16px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
overflow: hidden;
}
.video-wrapper {
position: relative;
padding-bottom: 56.25%;
height: 0;
background: #000;
}
iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.quiz-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.95);
display: none;
align-items: center;
justify-content: center;
z-index: 10;
animation: fadeIn 0.3s ease-in;
}
.quiz-overlay.active {
display: flex;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.quiz-card {
background: #fff;
border-radius: 12px;
padding: 32px;
max-width: 600px;
width: 90%;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
animation: slideUp 0.4s ease-out;
}
@keyframes slideUp {
from {
transform: translateY(20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.quiz-header {
margin-bottom: 24px;
}
.quiz-title {
font-size: 24px;
font-weight: 700;
color: #1a1a1a;
margin-bottom: 8px;
}
.quiz-question {
font-size: 18px;
color: #333;
line-height: 1.6;
}
.quiz-options {
display: flex;
flex-direction: column;
gap: 12px;
margin-bottom: 24px;
}
.option-btn {
background: #f7f7f7;
border: 2px solid #e0e0e0;
border-radius: 8px;
padding: 16px;
text-align: left;
font-size: 16px;
cursor: pointer;
transition: all 0.2s;
color: #333;
}
.option-btn:hover {
background: #ececec;
border-color: #667eea;
transform: translateX(4px);
}
.option-btn.selected {
background: #667eea;
border-color: #667eea;
color: #fff;
}
.option-btn.correct {
background: #10b981;
border-color: #10b981;
color: #fff;
}
.option-btn.incorrect {
background: #ef4444;
border-color: #ef4444;
color: #fff;
}
.option-btn:disabled {
cursor: not-allowed;
opacity: 0.7;
}
.feedback {
padding: 16px;
border-radius: 8px;
margin-bottom: 20px;
display: none;
animation: slideDown 0.3s ease-out;
}
@keyframes slideDown {
from {
transform: translateY(-10px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.feedback.show {
display: block;
}
.feedback.correct {
background: #d1fae5;
color: #065f46;
border-left: 4px solid #10b981;
}
.feedback.incorrect {
background: #fee2e2;
color: #991b1b;
border-left: 4px solid #ef4444;
}
.continue-btn {
background: #667eea;
color: #fff;
border: none;
border-radius: 8px;
padding: 14px 28px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
width: 100%;
transition: all 0.2s;
display: none;
}
.continue-btn.show {
display: block;
}
.continue-btn:hover {
background: #5568d3;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}
.progress-bar {
background: #f0f0f0;
padding: 16px;
border-bottom: 1px solid #e0e0e0;
}
.progress-text {
font-size: 14px;
color: #666;
margin-bottom: 8px;
}
.progress-track {
background: #e0e0e0;
height: 8px;
border-radius: 4px;
overflow: hidden;
}
.progress-fill {
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
height: 100%;
width: 0%;
transition: width 0.5s ease-out;
}
.debug {
position: absolute;
top: 10px;
left: 10px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
padding: 8px;
border-radius: 4px;
font-size: 12px;
z-index: 5;
font-family: monospace;
}
</style>
</head>
<body>
<div class="container">
<div class="progress-bar">
<div class="progress-text">Quiz Progress: <span id="progress-count">0</span> of 5 completed</div>
<div class="progress-track">
<div class="progress-fill" id="progress-fill"></div>
</div>
</div>
<div class="video-wrapper">
<div class="debug" id="debug">Loading...</div>
<iframe
id="youtube-player"
src="https://www.youtube.com/embed/2urhrcdYYrQ?enablejsapi=1&start=291"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
<div class="quiz-overlay" id="quiz-overlay">
<div class="quiz-card">
<div class="quiz-header">
<div class="quiz-title">Question <span id="question-number">1</span> of 5</div>
<div class="quiz-question" id="question-text"></div>
</div>
<div class="quiz-options" id="quiz-options"></div>
<div class="feedback" id="feedback"></div>
<button class="continue-btn" id="continue-btn">Continue Video</button>
</div>
</div>
</div>
</div>
<script src="https://www.youtube.com/iframe_api"></script>
<script>
// Timestamps in seconds from start of video: (MM*60)+SS
const questions = [
{
timestamp: 25, // 00:25 = (0*60)+25
question: "What is the first step in the AI-assisted coding workflow described in the video?",
options: [
"A) Immediately start writing code.",
"B) Create a detailed Project Requirements Document (PRD) or layout document.",
"C) Have the AI create tasks right away.",
"D) Design the sub-agents."
],
correct: 1,
feedback: "Correct! The process starts with creating a blueprint or PRD to outline the project, tech stack, and high-level overview before the AI creates any tasks."
},
{
timestamp: 53, // 00:53 = (0*60)+53
question: "In this gamified system, how does the AI earn \"XP\" (Experience Points)?",
options: [
"A) By completing the task as fast as possible.",
"B) By using the most complex code.",
"C) For writing good code and creating a good structure.",
"D) By asking the user for help."
],
correct: 2,
feedback: "That's right! The AI is rewarded with XP for high-quality, well-structured code, which incentivizes it to produce the best possible output."
},
{
timestamp: 126, // 02:06 = (2*60)+6
question: "According to the speaker, why is turning coding into a \"game\" an effective strategy for AI?",
options: [
"A) Because AI finds games more entertaining than work.",
"B) Because AI is programmed to always optimize its strategy to win any game it plays.",
"C) Because games have lower stakes than professional coding.",
"D) Because the AI can compete with other AIs for a high score."
],
correct: 1,
feedback: "Exactly! The core principle is that AIs are designed to find the most optimal strategy to win. By defining \"winning\" as writing the best code, the AI is driven to produce superior results."
},
{
timestamp: 181, // 03:01 = (3*60)+1
question: "What is the purpose of creating specialized \"sub-agents\"?",
options: [
"A) To slow down the AI's coding process for better review.",
"B) To create agents that are highly specialized in different phases (like research, testing, implementation) to maximize XP.",
"C) To have a backup AI in case the primary one fails.",
"D) To make the code harder for humans to understand."
],
correct: 1,
feedback: "Correct! The AI is instructed to create a team of specialized sub-agents. Each one is an expert in a specific area, and they collaborate to produce the highest quality work and earn the most XP."
},
{
timestamp: 256, // 04:16 = (4*60)+16
question: "The video mentions that the AI breaks the project down into several phases. Which of the following is NOT one of the phases mentioned?",
options: [
"A) Research",
"B) Implementation",
"C) Marketing and Sales",
"D) Testing and Optimization"
],
correct: 2,
feedback: "That's right! The AI plans for technical phases like research, implementation, testing, integration, and optimization, but not business-related phases like marketing."
}
];
let currentQuestionIndex = 0;
let completedQuestions = 0;
let player;
let checkInterval;
let questionsAnswered = new Set();
function onYouTubeIframeAPIReady() {
player = new YT.Player('youtube-player', {
videoId: '2urhrcdYYrQ',
playerVars: {
'enablejsapi': 1,
'start': 291
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
updateDebug('Player ready');
startTimeCheck();
}
function onPlayerStateChange(event) {
if (event.data === YT.PlayerState.PLAYING) {
updateDebug('Playing');
startTimeCheck();
} else if (event.data === YT.PlayerState.PAUSED) {
updateDebug('Paused');
stopTimeCheck();
}
}
function updateDebug(msg) {
const debug = document.getElementById('debug');
const time = player ? Math.floor(player.getCurrentTime()) : 0;
const nextQ = questions[currentQuestionIndex];
const nextTime = nextQ ? nextQ.timestamp : 'N/A';
debug.textContent = `${msg} | Time: ${time}s | Next Q: ${nextTime}s | Completed: ${completedQuestions}/5`;
}
function startTimeCheck() {
if (checkInterval) return;
checkInterval = setInterval(() => {
if (!player || !player.getCurrentTime) return;
const currentTime = Math.floor(player.getCurrentTime());
updateDebug('Checking');
// Find the next unanswered question
for (let i = 0; i < questions.length; i++) {
if (!questionsAnswered.has(i) && currentTime == questions[i].timestamp) {
currentQuestionIndex = i;
showQuiz(i);
stopTimeCheck();
break;
}
}
}, 200); // Check every 200ms for better precision
}
function stopTimeCheck() {
if (checkInterval) {
clearInterval(checkInterval);
checkInterval = null;
}
}
function showQuiz(index) {
if (player) {
player.pauseVideo();
}
const question = questions[index];
const overlay = document.getElementById('quiz-overlay');
const questionText = document.getElementById('question-text');
const questionNumber = document.getElementById('question-number');
const optionsContainer = document.getElementById('quiz-options');
const feedback = document.getElementById('feedback');
const continueBtn = document.getElementById('continue-btn');
questionText.textContent = question.question;
questionNumber.textContent = index + 1;
optionsContainer.innerHTML = '';
feedback.classList.remove('show', 'correct', 'incorrect');
continueBtn.classList.remove('show');
question.options.forEach((option, i) => {
const btn = document.createElement('button');
btn.className = 'option-btn';
btn.textContent = option;
btn.onclick = () => checkAnswer(i, question.correct, question.feedback, index);
optionsContainer.appendChild(btn);
});
overlay.classList.add('active');
updateDebug('Quiz shown');
}
function checkAnswer(selected, correct, feedbackText, questionIndex) {
const buttons = document.querySelectorAll('.option-btn');
const feedback = document.getElementById('feedback');
const continueBtn = document.getElementById('continue-btn');
buttons.forEach((btn, i) => {
btn.disabled = true;
if (i === correct) {
btn.classList.add('correct');
} else if (i === selected && selected !== correct) {
btn.classList.add('incorrect');
}
});
if (selected === correct) {
feedback.textContent = feedbackText;
feedback.classList.add('show', 'correct');
continueBtn.classList.add('show');
questionsAnswered.add(questionIndex);
completedQuestions++;
updateProgress();
updateDebug('Answer correct');
} else {
feedback.textContent = "Not quite. Try again!";
feedback.classList.add('show', 'incorrect');
setTimeout(() => {
buttons.forEach(btn => {
btn.disabled = false;
btn.classList.remove('incorrect', 'selected');
});
feedback.classList.remove('show');
}, 2000);
}
}
function updateProgress() {
const progressCount = document.getElementById('progress-count');
const progressFill = document.getElementById('progress-fill');
progressCount.textContent = completedQuestions;
progressFill.style.width = (completedQuestions / questions.length * 100) + '%';
}
document.getElementById('continue-btn').addEventListener('click', () => {
const overlay = document.getElementById('quiz-overlay');
overlay.classList.remove('active');
if (player) {
player.playVideo();
startTimeCheck();
}
updateDebug('Continuing');
});
// Initialize when API is ready
if (typeof YT !== 'undefined' && YT.Player) {
onYouTubeIframeAPIReady();
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment