feat: add web development test files and public assets

- Added test HTML files for Panda CSS and memory quiz development
- Created public directory with game assets and test files
- Includes simple layout tests and memory quiz backup files

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock 2025-09-14 16:59:37 -05:00
parent 2c70e233ed
commit 0809858302
5 changed files with 951 additions and 0 deletions

View File

@ -0,0 +1,420 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Speed Memory Quiz - Soroban</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.game-container {
max-width: 800px;
margin: 0 auto;
background: white;
border-radius: 12px;
padding: 24px;
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
}
.header {
text-align: center;
margin-bottom: 24px;
}
.header h1 {
color: #333;
font-size: 2rem;
margin-bottom: 8px;
}
.header p {
color: #666;
font-size: 1.1rem;
}
.game-controls {
text-align: center;
margin-bottom: 24px;
}
.btn {
background: #4CAF50;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
margin: 8px;
transition: all 0.2s;
}
.btn:hover {
background: #45a049;
transform: translateY(-2px);
}
.btn:disabled {
background: #ccc;
cursor: not-allowed;
transform: none;
}
.quiz-display {
text-align: center;
padding: 40px;
min-height: 300px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.quiz-card {
background: #f8f9fa;
border: 2px solid #dee2e6;
border-radius: 8px;
padding: 20px;
margin: 16px;
min-width: 200px;
min-height: 200px;
display: flex;
align-items: center;
justify-content: center;
font-size: 3rem;
font-weight: bold;
color: #495057;
}
.input-section {
margin-top: 24px;
}
.input-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 16px;
margin: 16px 0;
}
.input-field {
padding: 12px;
border: 2px solid #dee2e6;
border-radius: 6px;
font-size: 18px;
text-align: center;
}
.input-field:focus {
outline: none;
border-color: #4CAF50;
}
.results {
background: #f8f9fa;
border-radius: 8px;
padding: 24px;
margin-top: 24px;
}
.score {
font-size: 2rem;
font-weight: bold;
color: #4CAF50;
margin-bottom: 16px;
}
.hidden { display: none; }
.settings {
background: #f8f9fa;
border-radius: 8px;
padding: 16px;
margin-bottom: 24px;
}
.setting-row {
display: flex;
justify-content: space-between;
align-items: center;
margin: 8px 0;
}
.setting-input {
padding: 6px 12px;
border: 1px solid #ccc;
border-radius: 4px;
width: 80px;
}
</style>
</head>
<body>
<div class="game-container">
<div class="header">
<h1>🧠 Speed Memory Quiz</h1>
<p>Cards will flash briefly - memorize the numbers and input them back</p>
</div>
<div id="settings-panel" class="settings">
<div class="setting-row">
<label>Number of Cards:</label>
<input type="number" id="card-count" class="setting-input" value="5" min="3" max="10">
</div>
<div class="setting-row">
<label>Display Time (seconds):</label>
<input type="number" id="display-time" class="setting-input" value="2" min="0.5" max="5" step="0.5">
</div>
<div class="setting-row">
<label>Number Range:</label>
<select id="number-range" class="setting-input" style="width: auto;">
<option value="1-9">1-9</option>
<option value="10-99" selected>10-99</option>
<option value="100-999">100-999</option>
</select>
</div>
</div>
<div class="game-controls">
<button id="start-btn" class="btn">Start Quiz</button>
<button id="reset-btn" class="btn" style="background: #f44336;">Reset</button>
</div>
<div id="quiz-display" class="quiz-display hidden">
<div id="progress-info"></div>
<div id="current-card" class="quiz-card"></div>
<div id="countdown"></div>
</div>
<div id="input-section" class="input-section hidden">
<h3>Enter the numbers you remember:</h3>
<div id="input-grid" class="input-grid"></div>
<div style="text-align: center; margin-top: 16px;">
<button id="submit-btn" class="btn">Submit Answers</button>
</div>
</div>
<div id="results-section" class="results hidden">
<div id="score-display" class="score"></div>
<div id="detailed-results"></div>
<div style="text-align: center; margin-top: 16px;">
<button id="play-again-btn" class="btn">Play Again</button>
</div>
</div>
</div>
<script>
class SorobanQuiz {
constructor() {
this.quizCards = [];
this.currentCardIndex = 0;
this.userAnswers = [];
this.isPlaying = false;
this.initializeElements();
this.attachEventListeners();
}
initializeElements() {
this.startBtn = document.getElementById('start-btn');
this.resetBtn = document.getElementById('reset-btn');
this.submitBtn = document.getElementById('submit-btn');
this.playAgainBtn = document.getElementById('play-again-btn');
this.settingsPanel = document.getElementById('settings-panel');
this.quizDisplay = document.getElementById('quiz-display');
this.inputSection = document.getElementById('input-section');
this.resultsSection = document.getElementById('results-section');
this.progressInfo = document.getElementById('progress-info');
this.currentCard = document.getElementById('current-card');
this.countdown = document.getElementById('countdown');
this.inputGrid = document.getElementById('input-grid');
this.scoreDisplay = document.getElementById('score-display');
this.detailedResults = document.getElementById('detailed-results');
this.cardCountInput = document.getElementById('card-count');
this.displayTimeInput = document.getElementById('display-time');
this.numberRangeSelect = document.getElementById('number-range');
}
attachEventListeners() {
this.startBtn.addEventListener('click', () => this.startQuiz());
this.resetBtn.addEventListener('click', () => this.resetQuiz());
this.submitBtn.addEventListener('click', () => this.submitAnswers());
this.playAgainBtn.addEventListener('click', () => this.resetQuiz());
}
generateRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
getNumberRange() {
const range = this.numberRangeSelect.value;
switch(range) {
case '1-9': return {min: 1, max: 9};
case '10-99': return {min: 10, max: 99};
case '100-999': return {min: 100, max: 999};
default: return {min: 10, max: 99};
}
}
startQuiz() {
if (this.isPlaying) return;
this.isPlaying = true;
this.currentCardIndex = 0;
this.userAnswers = [];
// Get settings
const cardCount = parseInt(this.cardCountInput.value);
const range = this.getNumberRange();
// Generate quiz cards
this.quizCards = [];
for (let i = 0; i < cardCount; i++) {
this.quizCards.push({
number: this.generateRandomNumber(range.min, range.max),
id: i
});
}
// Hide settings and show quiz
this.settingsPanel.classList.add('hidden');
this.quizDisplay.classList.remove('hidden');
this.startBtn.disabled = true;
// Start displaying cards
this.showNextCard();
}
showNextCard() {
if (this.currentCardIndex >= this.quizCards.length) {
this.showInputSection();
return;
}
const card = this.quizCards[this.currentCardIndex];
const displayTime = parseFloat(this.displayTimeInput.value) * 1000;
// Update progress
this.progressInfo.textContent = `Card ${this.currentCardIndex + 1} of ${this.quizCards.length}`;
// Show the number
this.currentCard.textContent = card.number;
this.countdown.textContent = '';
// Start countdown after display time
setTimeout(() => {
let timeLeft = Math.ceil(displayTime / 1000);
this.currentCard.textContent = '?';
const countdownInterval = setInterval(() => {
if (timeLeft <= 0) {
clearInterval(countdownInterval);
this.currentCardIndex++;
this.showNextCard();
} else {
this.countdown.textContent = `Next card in ${timeLeft}s`;
timeLeft--;
}
}, 1000);
}, displayTime);
}
showInputSection() {
this.quizDisplay.classList.add('hidden');
this.inputSection.classList.remove('hidden');
// Create input fields
this.inputGrid.innerHTML = '';
for (let i = 0; i < this.quizCards.length; i++) {
const input = document.createElement('input');
input.type = 'number';
input.className = 'input-field';
input.placeholder = `Card ${i + 1}`;
input.dataset.index = i;
// Auto-focus next input on Enter
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && i < this.quizCards.length - 1) {
this.inputGrid.children[i + 1].focus();
}
});
this.inputGrid.appendChild(input);
}
// Focus first input
if (this.inputGrid.children.length > 0) {
this.inputGrid.children[0].focus();
}
}
submitAnswers() {
// Collect answers
this.userAnswers = [];
const inputs = this.inputGrid.querySelectorAll('.input-field');
inputs.forEach((input, index) => {
this.userAnswers.push({
cardIndex: index,
answer: input.value ? parseInt(input.value) : null,
correct: this.quizCards[index].number
});
});
this.showResults();
}
showResults() {
this.inputSection.classList.add('hidden');
this.resultsSection.classList.remove('hidden');
// Calculate score
let correct = 0;
this.userAnswers.forEach(answer => {
if (answer.answer === answer.correct) correct++;
});
const percentage = Math.round((correct / this.quizCards.length) * 100);
// Show score
this.scoreDisplay.innerHTML = `
Score: ${correct}/${this.quizCards.length} (${percentage}%)
${percentage >= 80 ? '🎉' : percentage >= 60 ? '👍' : '💪'}
`;
// Show detailed results
let detailsHTML = '<div style="margin-top: 16px;"><h4>Review:</h4>';
this.userAnswers.forEach((answer, index) => {
const isCorrect = answer.answer === answer.correct;
const status = isCorrect ? '✅' : '❌';
const answerText = answer.answer !== null ? answer.answer : '(empty)';
detailsHTML += `
<div style="margin: 8px 0; padding: 8px; background: ${isCorrect ? '#e8f5e8' : '#ffe8e8'}; border-radius: 4px;">
${status} Card ${index + 1}: ${answer.correct} | Your answer: ${answerText}
</div>
`;
});
detailsHTML += '</div>';
this.detailedResults.innerHTML = detailsHTML;
}
resetQuiz() {
this.isPlaying = false;
this.currentCardIndex = 0;
this.userAnswers = [];
this.quizCards = [];
// Show settings, hide others
this.settingsPanel.classList.remove('hidden');
this.quizDisplay.classList.add('hidden');
this.inputSection.classList.add('hidden');
this.resultsSection.classList.add('hidden');
// Re-enable start button
this.startBtn.disabled = false;
// Clear displays
this.currentCard.textContent = '';
this.countdown.textContent = '';
this.inputGrid.innerHTML = '';
}
}
// Initialize the quiz when page loads
document.addEventListener('DOMContentLoaded', () => {
new SorobanQuiz();
});
</script>
</body>
</html>

View File

@ -0,0 +1,420 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Speed Memory Quiz - Soroban</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.game-container {
max-width: 800px;
margin: 0 auto;
background: white;
border-radius: 12px;
padding: 24px;
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
}
.header {
text-align: center;
margin-bottom: 24px;
}
.header h1 {
color: #333;
font-size: 2rem;
margin-bottom: 8px;
}
.header p {
color: #666;
font-size: 1.1rem;
}
.game-controls {
text-align: center;
margin-bottom: 24px;
}
.btn {
background: #4CAF50;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
margin: 8px;
transition: all 0.2s;
}
.btn:hover {
background: #45a049;
transform: translateY(-2px);
}
.btn:disabled {
background: #ccc;
cursor: not-allowed;
transform: none;
}
.quiz-display {
text-align: center;
padding: 40px;
min-height: 300px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.quiz-card {
background: #f8f9fa;
border: 2px solid #dee2e6;
border-radius: 8px;
padding: 20px;
margin: 16px;
min-width: 200px;
min-height: 200px;
display: flex;
align-items: center;
justify-content: center;
font-size: 3rem;
font-weight: bold;
color: #495057;
}
.input-section {
margin-top: 24px;
}
.input-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 16px;
margin: 16px 0;
}
.input-field {
padding: 12px;
border: 2px solid #dee2e6;
border-radius: 6px;
font-size: 18px;
text-align: center;
}
.input-field:focus {
outline: none;
border-color: #4CAF50;
}
.results {
background: #f8f9fa;
border-radius: 8px;
padding: 24px;
margin-top: 24px;
}
.score {
font-size: 2rem;
font-weight: bold;
color: #4CAF50;
margin-bottom: 16px;
}
.hidden { display: none; }
.settings {
background: #f8f9fa;
border-radius: 8px;
padding: 16px;
margin-bottom: 24px;
}
.setting-row {
display: flex;
justify-content: space-between;
align-items: center;
margin: 8px 0;
}
.setting-input {
padding: 6px 12px;
border: 1px solid #ccc;
border-radius: 4px;
width: 80px;
}
</style>
</head>
<body>
<div class="game-container">
<div class="header">
<h1>🧠 Speed Memory Quiz</h1>
<p>Cards will flash briefly - memorize the numbers and input them back</p>
</div>
<div id="settings-panel" class="settings">
<div class="setting-row">
<label>Number of Cards:</label>
<input type="number" id="card-count" class="setting-input" value="5" min="3" max="10">
</div>
<div class="setting-row">
<label>Display Time (seconds):</label>
<input type="number" id="display-time" class="setting-input" value="2" min="0.5" max="5" step="0.5">
</div>
<div class="setting-row">
<label>Number Range:</label>
<select id="number-range" class="setting-input" style="width: auto;">
<option value="1-9">1-9</option>
<option value="10-99" selected>10-99</option>
<option value="100-999">100-999</option>
</select>
</div>
</div>
<div class="game-controls">
<button id="start-btn" class="btn">Start Quiz</button>
<button id="reset-btn" class="btn" style="background: #f44336;">Reset</button>
</div>
<div id="quiz-display" class="quiz-display hidden">
<div id="progress-info"></div>
<div id="current-card" class="quiz-card"></div>
<div id="countdown"></div>
</div>
<div id="input-section" class="input-section hidden">
<h3>Enter the numbers you remember:</h3>
<div id="input-grid" class="input-grid"></div>
<div style="text-align: center; margin-top: 16px;">
<button id="submit-btn" class="btn">Submit Answers</button>
</div>
</div>
<div id="results-section" class="results hidden">
<div id="score-display" class="score"></div>
<div id="detailed-results"></div>
<div style="text-align: center; margin-top: 16px;">
<button id="play-again-btn" class="btn">Play Again</button>
</div>
</div>
</div>
<script>
class SorobanQuiz {
constructor() {
this.quizCards = [];
this.currentCardIndex = 0;
this.userAnswers = [];
this.isPlaying = false;
this.initializeElements();
this.attachEventListeners();
}
initializeElements() {
this.startBtn = document.getElementById('start-btn');
this.resetBtn = document.getElementById('reset-btn');
this.submitBtn = document.getElementById('submit-btn');
this.playAgainBtn = document.getElementById('play-again-btn');
this.settingsPanel = document.getElementById('settings-panel');
this.quizDisplay = document.getElementById('quiz-display');
this.inputSection = document.getElementById('input-section');
this.resultsSection = document.getElementById('results-section');
this.progressInfo = document.getElementById('progress-info');
this.currentCard = document.getElementById('current-card');
this.countdown = document.getElementById('countdown');
this.inputGrid = document.getElementById('input-grid');
this.scoreDisplay = document.getElementById('score-display');
this.detailedResults = document.getElementById('detailed-results');
this.cardCountInput = document.getElementById('card-count');
this.displayTimeInput = document.getElementById('display-time');
this.numberRangeSelect = document.getElementById('number-range');
}
attachEventListeners() {
this.startBtn.addEventListener('click', () => this.startQuiz());
this.resetBtn.addEventListener('click', () => this.resetQuiz());
this.submitBtn.addEventListener('click', () => this.submitAnswers());
this.playAgainBtn.addEventListener('click', () => this.resetQuiz());
}
generateRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
getNumberRange() {
const range = this.numberRangeSelect.value;
switch(range) {
case '1-9': return {min: 1, max: 9};
case '10-99': return {min: 10, max: 99};
case '100-999': return {min: 100, max: 999};
default: return {min: 10, max: 99};
}
}
startQuiz() {
if (this.isPlaying) return;
this.isPlaying = true;
this.currentCardIndex = 0;
this.userAnswers = [];
// Get settings
const cardCount = parseInt(this.cardCountInput.value);
const range = this.getNumberRange();
// Generate quiz cards
this.quizCards = [];
for (let i = 0; i < cardCount; i++) {
this.quizCards.push({
number: this.generateRandomNumber(range.min, range.max),
id: i
});
}
// Hide settings and show quiz
this.settingsPanel.classList.add('hidden');
this.quizDisplay.classList.remove('hidden');
this.startBtn.disabled = true;
// Start displaying cards
this.showNextCard();
}
showNextCard() {
if (this.currentCardIndex >= this.quizCards.length) {
this.showInputSection();
return;
}
const card = this.quizCards[this.currentCardIndex];
const displayTime = parseFloat(this.displayTimeInput.value) * 1000;
// Update progress
this.progressInfo.textContent = `Card ${this.currentCardIndex + 1} of ${this.quizCards.length}`;
// Show the number
this.currentCard.textContent = card.number;
this.countdown.textContent = '';
// Start countdown after display time
setTimeout(() => {
let timeLeft = Math.ceil(displayTime / 1000);
this.currentCard.textContent = '?';
const countdownInterval = setInterval(() => {
if (timeLeft <= 0) {
clearInterval(countdownInterval);
this.currentCardIndex++;
this.showNextCard();
} else {
this.countdown.textContent = `Next card in ${timeLeft}s`;
timeLeft--;
}
}, 1000);
}, displayTime);
}
showInputSection() {
this.quizDisplay.classList.add('hidden');
this.inputSection.classList.remove('hidden');
// Create input fields
this.inputGrid.innerHTML = '';
for (let i = 0; i < this.quizCards.length; i++) {
const input = document.createElement('input');
input.type = 'number';
input.className = 'input-field';
input.placeholder = `Card ${i + 1}`;
input.dataset.index = i;
// Auto-focus next input on Enter
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && i < this.quizCards.length - 1) {
this.inputGrid.children[i + 1].focus();
}
});
this.inputGrid.appendChild(input);
}
// Focus first input
if (this.inputGrid.children.length > 0) {
this.inputGrid.children[0].focus();
}
}
submitAnswers() {
// Collect answers
this.userAnswers = [];
const inputs = this.inputGrid.querySelectorAll('.input-field');
inputs.forEach((input, index) => {
this.userAnswers.push({
cardIndex: index,
answer: input.value ? parseInt(input.value) : null,
correct: this.quizCards[index].number
});
});
this.showResults();
}
showResults() {
this.inputSection.classList.add('hidden');
this.resultsSection.classList.remove('hidden');
// Calculate score
let correct = 0;
this.userAnswers.forEach(answer => {
if (answer.answer === answer.correct) correct++;
});
const percentage = Math.round((correct / this.quizCards.length) * 100);
// Show score
this.scoreDisplay.innerHTML = `
Score: ${correct}/${this.quizCards.length} (${percentage}%)
${percentage >= 80 ? '🎉' : percentage >= 60 ? '👍' : '💪'}
`;
// Show detailed results
let detailsHTML = '<div style="margin-top: 16px;"><h4>Review:</h4>';
this.userAnswers.forEach((answer, index) => {
const isCorrect = answer.answer === answer.correct;
const status = isCorrect ? '✅' : '❌';
const answerText = answer.answer !== null ? answer.answer : '(empty)';
detailsHTML += `
<div style="margin: 8px 0; padding: 8px; background: ${isCorrect ? '#e8f5e8' : '#ffe8e8'}; border-radius: 4px;">
${status} Card ${index + 1}: ${answer.correct} | Your answer: ${answerText}
</div>
`;
});
detailsHTML += '</div>';
this.detailedResults.innerHTML = detailsHTML;
}
resetQuiz() {
this.isPlaying = false;
this.currentCardIndex = 0;
this.userAnswers = [];
this.quizCards = [];
// Show settings, hide others
this.settingsPanel.classList.remove('hidden');
this.quizDisplay.classList.add('hidden');
this.inputSection.classList.add('hidden');
this.resultsSection.classList.add('hidden');
// Re-enable start button
this.startBtn.disabled = false;
// Clear displays
this.currentCard.textContent = '';
this.countdown.textContent = '';
this.inputGrid.innerHTML = '';
}
}
// Initialize the quiz when page loads
document.addEventListener('DOMContentLoaded', () => {
new SorobanQuiz();
});
</script>
</body>
</html>

View File

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Speed Memory Quiz - Soroban</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.game-container {
max-width: 800px;
margin: 0 auto;
background: white;
border-radius: 12px;
padding: 24px;
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
}
.header {
text-align: center;
margin-bottom: 24px;
}
.header h1 {
color: #333;
font-size: 2rem;
margin-bottom: 8px;
}
.header p {
color: #666;
font-size: 1.1rem;
}
.btn {
background: #4CAF50;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
margin: 8px;
transition: all 0.2s;
}
.btn:hover {
background: #45a049;
transform: translateY(-2px);
}
</style>
</head>
<body>
<div class="game-container">
<div class="header">
<h1>🧠 Speed Memory Quiz</h1>
<p>This is a test with simplified CSS</p>
</div>
<button class="btn">Test Button</button>
</div>
</body>
</html>

View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Test CSS</title>
<style>
body { background: red; color: white; font-size: 24px; padding: 20px; }
.test { background: blue; padding: 20px; margin: 20px; }
</style>
</head>
<body>
<h1>Test CSS</h1>
<div class="test">This should have blue background</div>
<p>This should be white text on red background</p>
</body>
</html>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<title>Test Panda CSS</title>
<style>
/* Inline test to see if the page styling issue is basic layout */
.test-center {
text-align: center;
padding: 20px;
max-width: 800px;
margin: 0 auto;
background: #f5f5f5;
border: 2px solid #333;
}
.test-btn {
background: #007bff;
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
cursor: pointer;
margin: 10px;
}
</style>
</head>
<body>
<div class="test-center">
<h2>Basic Layout Test</h2>
<p>This should be centered with a grey background and border</p>
<button class="test-btn">Test Button 1</button>
<button class="test-btn">Test Button 2</button>
</div>
</body>
</html>