Initial commit
This commit is contained in:
12
.claude-plugin/plugin.json
Normal file
12
.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "reading-teacher",
|
||||||
|
"description": "Interactive reading teacher that instantly generates playful, engaging learning experiences for children ages 1-10. Creates visual playgrounds, phonics games, and interactive stories to build reading skills from letter recognition to comprehension.",
|
||||||
|
"version": "0.0.0-2025.11.28",
|
||||||
|
"author": {
|
||||||
|
"name": "James Rochabrun",
|
||||||
|
"email": "jamesrochabrun@gmail.com"
|
||||||
|
},
|
||||||
|
"skills": [
|
||||||
|
"./skills/reading-teacher"
|
||||||
|
]
|
||||||
|
}
|
||||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# reading-teacher
|
||||||
|
|
||||||
|
Interactive reading teacher that instantly generates playful, engaging learning experiences for children ages 1-10. Creates visual playgrounds, phonics games, and interactive stories to build reading skills from letter recognition to comprehension.
|
||||||
64
plugin.lock.json
Normal file
64
plugin.lock.json
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
{
|
||||||
|
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||||
|
"pluginId": "gh:jamesrochabrun/skills:reading-teacher",
|
||||||
|
"normalized": {
|
||||||
|
"repo": null,
|
||||||
|
"ref": "refs/tags/v20251128.0",
|
||||||
|
"commit": "21c73ab18b8ce1694397ddb4c39fbec37f960250",
|
||||||
|
"treeHash": "b0f51d7872bab15c98e5a018d190bcce9a6e8efff7d899bce1c88f1c35ed222e",
|
||||||
|
"generatedAt": "2025-11-28T10:17:55.263112Z",
|
||||||
|
"toolVersion": "publish_plugins.py@0.2.0"
|
||||||
|
},
|
||||||
|
"origin": {
|
||||||
|
"remote": "git@github.com:zhongweili/42plugin-data.git",
|
||||||
|
"branch": "master",
|
||||||
|
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
|
||||||
|
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
|
||||||
|
},
|
||||||
|
"manifest": {
|
||||||
|
"name": "reading-teacher",
|
||||||
|
"description": "Interactive reading teacher that instantly generates playful, engaging learning experiences for children ages 1-10. Creates visual playgrounds, phonics games, and interactive stories to build reading skills from letter recognition to comprehension."
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"path": "README.md",
|
||||||
|
"sha256": "697becc79f12812415b0859f786ccdfa8da06bd00681c97aee2d573611982d38"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".claude-plugin/plugin.json",
|
||||||
|
"sha256": "7d3d690995f735037a6b6defabd0f04ff001151f383eda5924de85925f3376c2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/reading-teacher/SKILL.md",
|
||||||
|
"sha256": "68ec269659172c6e2ee4b994c741ff5dfc63202355aa7ee76a061b438615514b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/reading-teacher/references/phonics.md",
|
||||||
|
"sha256": "0a35c8ec6d27ba47eb53583ecfed43627f4016e166b9c57818e5343215783ad1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/reading-teacher/references/sight_words.md",
|
||||||
|
"sha256": "dead70fd53581f64855a2a818743365bb0e9463bede9fb209bc8ae2dc95a4181"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/reading-teacher/references/comprehension.md",
|
||||||
|
"sha256": "1dfef05e28702fed914656616452f027fc6a5826a6bcd9040198075b89b60830"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/reading-teacher/scripts/generate_playground.sh",
|
||||||
|
"sha256": "a05b696e33eaa7886605c91edada2cece9e65ae95ea3e65c0641130abebd158f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/reading-teacher/scripts/generate_game.sh",
|
||||||
|
"sha256": "cf8d653da58603ecce22ecb8c46f77f204ee24a00e10002901a211e67edd9ac9"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dirSha256": "b0f51d7872bab15c98e5a018d190bcce9a6e8efff7d899bce1c88f1c35ed222e"
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"scannedAt": null,
|
||||||
|
"scannerVersion": null,
|
||||||
|
"flags": []
|
||||||
|
}
|
||||||
|
}
|
||||||
848
skills/reading-teacher/SKILL.md
Normal file
848
skills/reading-teacher/SKILL.md
Normal file
@@ -0,0 +1,848 @@
|
|||||||
|
---
|
||||||
|
name: reading-teacher
|
||||||
|
description: Interactive reading teacher that instantly generates playful, engaging learning experiences for children ages 1-10. Creates visual playgrounds, phonics games, and interactive stories to build reading skills from letter recognition to comprehension.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Reading Teacher
|
||||||
|
|
||||||
|
An interactive, playful reading teacher that instantly generates engaging learning experiences through interactive artifacts, visual playgrounds, and gamified challenges for young learners.
|
||||||
|
|
||||||
|
## What This Skill Does
|
||||||
|
|
||||||
|
Transforms reading education into interactive, visual experiences:
|
||||||
|
- **Instant Playground Generation** - Creates interactive HTML/JS artifacts on demand
|
||||||
|
- **Age-Appropriate Content** - Tailored for ages 1-10 with developmental stages
|
||||||
|
- **Multi-Sensory Learning** - Visual, auditory, and interactive elements
|
||||||
|
- **Phonics & Sight Words** - Systematic phonics instruction and high-frequency words
|
||||||
|
- **Story Building** - Interactive story creation and comprehension
|
||||||
|
- **Gamification** - Stars, badges, rewards, and progress tracking
|
||||||
|
- **Parent/Teacher Tools** - Progress reports and customization options
|
||||||
|
|
||||||
|
## Why This Skill Matters
|
||||||
|
|
||||||
|
**Traditional reading instruction:**
|
||||||
|
- Limited engagement and interactivity
|
||||||
|
- One-size-fits-all approach
|
||||||
|
- Difficult to maintain young attention spans
|
||||||
|
- Limited practice opportunities
|
||||||
|
- Hard to track individual progress
|
||||||
|
|
||||||
|
**With this skill:**
|
||||||
|
- Instant engagement through games
|
||||||
|
- Personalized to child's level
|
||||||
|
- Fun, rewarding experiences
|
||||||
|
- Unlimited practice variations
|
||||||
|
- Clear progress tracking
|
||||||
|
- Multi-sensory approach
|
||||||
|
|
||||||
|
## Core Principles
|
||||||
|
|
||||||
|
### 1. Developmentally Appropriate
|
||||||
|
- Age-specific content and challenges
|
||||||
|
- Scaffolded learning progression
|
||||||
|
- Appropriate complexity levels
|
||||||
|
- Sensitive to attention spans
|
||||||
|
- Celebrates every milestone
|
||||||
|
|
||||||
|
### 2. Multi-Sensory Engagement
|
||||||
|
- Visual letter displays
|
||||||
|
- Audio pronunciation
|
||||||
|
- Interactive touch/click
|
||||||
|
- Animated feedback
|
||||||
|
- Colorful, engaging design
|
||||||
|
|
||||||
|
### 3. Play-Based Learning
|
||||||
|
- Games over drills
|
||||||
|
- Story-driven activities
|
||||||
|
- Character companions
|
||||||
|
- Reward systems
|
||||||
|
- Celebration animations
|
||||||
|
|
||||||
|
### 4. Systematic Instruction
|
||||||
|
- Sequential skill building
|
||||||
|
- Phonics-based approach
|
||||||
|
- High-frequency sight words
|
||||||
|
- Comprehension strategies
|
||||||
|
- Fluency development
|
||||||
|
|
||||||
|
### 5. Positive Reinforcement
|
||||||
|
- Immediate encouragement
|
||||||
|
- Visual progress markers
|
||||||
|
- Achievement celebrations
|
||||||
|
- No negative feedback
|
||||||
|
- Growth mindset focus
|
||||||
|
|
||||||
|
## Reading Stages Covered
|
||||||
|
|
||||||
|
### Pre-Reading (Ages 1-3)
|
||||||
|
**Skills:**
|
||||||
|
- Letter recognition (uppercase & lowercase)
|
||||||
|
- Letter sounds (phonemic awareness)
|
||||||
|
- Environmental print awareness
|
||||||
|
- Book handling skills
|
||||||
|
- Listening comprehension
|
||||||
|
|
||||||
|
**Activities:**
|
||||||
|
- 🔤 Alphabet song with animations
|
||||||
|
- 🎨 Letter tracing games
|
||||||
|
- 🔊 Sound matching activities
|
||||||
|
- 📚 Interactive picture books
|
||||||
|
- 🎵 Rhyming word games
|
||||||
|
|
||||||
|
### Early Reading (Ages 3-5)
|
||||||
|
**Skills:**
|
||||||
|
- Letter-sound correspondence
|
||||||
|
- Beginning phonics (CVC words)
|
||||||
|
- Print awareness
|
||||||
|
- Simple sight words
|
||||||
|
- Picture-text connection
|
||||||
|
|
||||||
|
**Activities:**
|
||||||
|
- 🐱 CVC word building (cat, dog, sun)
|
||||||
|
- 🎯 Sight word matching games
|
||||||
|
- 📖 Simple sentence reading
|
||||||
|
- 🧩 Word family exploration
|
||||||
|
- ✨ Rhyme time challenges
|
||||||
|
|
||||||
|
### Beginning Readers (Ages 5-7)
|
||||||
|
**Skills:**
|
||||||
|
- Phonics patterns (blends, digraphs)
|
||||||
|
- Expanding sight word vocabulary
|
||||||
|
- Simple sentence reading
|
||||||
|
- Basic comprehension
|
||||||
|
- Fluency building
|
||||||
|
|
||||||
|
**Activities:**
|
||||||
|
- 🌟 Digraph detective games (ch, sh, th)
|
||||||
|
- 📝 Sentence building workshops
|
||||||
|
- 📚 Decodable story readers
|
||||||
|
- 🎭 Character comprehension
|
||||||
|
- ⏱️ Fluency practice tracks
|
||||||
|
|
||||||
|
### Developing Readers (Ages 7-10)
|
||||||
|
**Skills:**
|
||||||
|
- Advanced phonics patterns
|
||||||
|
- Multi-syllable words
|
||||||
|
- Reading comprehension strategies
|
||||||
|
- Vocabulary development
|
||||||
|
- Fluent reading
|
||||||
|
|
||||||
|
**Activities:**
|
||||||
|
- 📖 Story comprehension challenges
|
||||||
|
- 🔍 Context clue detectives
|
||||||
|
- 📚 Chapter book companions
|
||||||
|
- ✍️ Story writing studios
|
||||||
|
- 🎯 Vocabulary builders
|
||||||
|
|
||||||
|
## Interactive Playground Examples
|
||||||
|
|
||||||
|
### Example 1: Letter Land Adventure (Ages 1-3)
|
||||||
|
|
||||||
|
**User asks:** "Help my toddler learn letters"
|
||||||
|
|
||||||
|
**Teacher generates:**
|
||||||
|
```html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>🌈 Letter Land Adventure!</title>
|
||||||
|
<style>
|
||||||
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
|
body {
|
||||||
|
font-family: 'Comic Sans MS', 'Chalkboard SE', cursive, sans-serif;
|
||||||
|
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 3em;
|
||||||
|
color: #FF6B9D;
|
||||||
|
text-shadow: 3px 3px 6px rgba(0,0,0,0.1);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.stars {
|
||||||
|
font-size: 2em;
|
||||||
|
background: rgba(255,255,255,0.8);
|
||||||
|
padding: 10px 30px;
|
||||||
|
border-radius: 30px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.letter-display {
|
||||||
|
background: white;
|
||||||
|
width: 400px;
|
||||||
|
height: 400px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 15em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #FF6B9D;
|
||||||
|
box-shadow: 0 20px 60px rgba(0,0,0,0.2);
|
||||||
|
margin: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.letter-display:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 30px 80px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
.letter-display:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
.controls {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
margin: 20px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.btn {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 20px 40px;
|
||||||
|
font-size: 1.5em;
|
||||||
|
border-radius: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
font-weight: bold;
|
||||||
|
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
.btn:hover { transform: translateY(-5px); }
|
||||||
|
.btn:active { transform: translateY(0); }
|
||||||
|
.letter-name {
|
||||||
|
font-size: 2em;
|
||||||
|
margin: 20px;
|
||||||
|
color: #667eea;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.celebration {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) scale(0);
|
||||||
|
font-size: 10em;
|
||||||
|
animation: celebrate 1s ease forwards;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
@keyframes celebrate {
|
||||||
|
0% { transform: translate(-50%, -50%) scale(0) rotate(0deg); }
|
||||||
|
50% { transform: translate(-50%, -50%) scale(1.5) rotate(180deg); }
|
||||||
|
100% { transform: translate(-50%, -50%) scale(1) rotate(360deg); opacity: 0; }
|
||||||
|
}
|
||||||
|
.alphabet-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
|
||||||
|
gap: 10px;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
.alphabet-letter {
|
||||||
|
background: white;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 15px;
|
||||||
|
font-size: 2em;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
|
||||||
|
font-weight: bold;
|
||||||
|
color: #667eea;
|
||||||
|
}
|
||||||
|
.alphabet-letter:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
background: #FFD700;
|
||||||
|
}
|
||||||
|
.alphabet-letter.learned {
|
||||||
|
background: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.letter-display { width: 300px; height: 300px; font-size: 10em; }
|
||||||
|
h1 { font-size: 2em; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="header">
|
||||||
|
<h1>🌈 Letter Land Adventure!</h1>
|
||||||
|
<div class="stars">
|
||||||
|
Stars: <span id="stars">0</span> ⭐
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="letter-display" id="letterDisplay" onclick="speakLetter()">
|
||||||
|
A
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="letter-name" id="letterName">
|
||||||
|
Click the letter to hear its name and sound!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<button class="btn" onclick="nextLetter()">Next Letter ➡️</button>
|
||||||
|
<button class="btn" onclick="randomLetter()">Random Letter 🎲</button>
|
||||||
|
<button class="btn" onclick="showAlphabet()">Show All 🔤</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alphabet-grid" id="alphabetGrid" style="display: none;"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
|
||||||
|
const letterNames = {
|
||||||
|
'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephant',
|
||||||
|
'F': 'Fish', 'G': 'Goat', 'H': 'Hat', 'I': 'Ice Cream', 'J': 'Juice',
|
||||||
|
'K': 'Kite', 'L': 'Lion', 'M': 'Moon', 'N': 'Nest', 'O': 'Orange',
|
||||||
|
'P': 'Pig', 'Q': 'Queen', 'R': 'Rabbit', 'S': 'Sun', 'T': 'Tiger',
|
||||||
|
'U': 'Umbrella', 'V': 'Violin', 'W': 'Whale', 'X': 'X-ray', 'Y': 'Yellow', 'Z': 'Zebra'
|
||||||
|
};
|
||||||
|
const letterSounds = {
|
||||||
|
'A': 'ah', 'B': 'buh', 'C': 'kuh', 'D': 'duh', 'E': 'eh',
|
||||||
|
'F': 'fuh', 'G': 'guh', 'H': 'huh', 'I': 'ih', 'J': 'juh',
|
||||||
|
'K': 'kuh', 'L': 'luh', 'M': 'muh', 'N': 'nuh', 'O': 'ah',
|
||||||
|
'P': 'puh', 'Q': 'kwuh', 'R': 'ruh', 'S': 'sss', 'T': 'tuh',
|
||||||
|
'U': 'uh', 'V': 'vuh', 'W': 'wuh', 'X': 'ks', 'Y': 'yuh', 'Z': 'zzz'
|
||||||
|
};
|
||||||
|
|
||||||
|
let currentIndex = 0;
|
||||||
|
let stars = 0;
|
||||||
|
let learnedLetters = new Set();
|
||||||
|
const colors = ['#FF6B9D', '#4ECDC4', '#FFE66D', '#A8E6CF', '#FF8B94', '#C7CEEA'];
|
||||||
|
|
||||||
|
function updateDisplay(letter) {
|
||||||
|
const display = document.getElementById('letterDisplay');
|
||||||
|
display.textContent = letter;
|
||||||
|
display.style.color = colors[Math.floor(Math.random() * colors.length)];
|
||||||
|
|
||||||
|
const name = document.getElementById('letterName');
|
||||||
|
name.textContent = `${letter} is for ${letterNames[letter]}!`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function speakLetter() {
|
||||||
|
const letter = document.getElementById('letterDisplay').textContent;
|
||||||
|
|
||||||
|
// Award star
|
||||||
|
stars++;
|
||||||
|
document.getElementById('stars').textContent = stars;
|
||||||
|
|
||||||
|
// Mark as learned
|
||||||
|
if (!learnedLetters.has(letter)) {
|
||||||
|
learnedLetters.add(letter);
|
||||||
|
updateAlphabetGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show celebration
|
||||||
|
celebrate('🎉');
|
||||||
|
|
||||||
|
// Simulate speech (in real implementation, use Web Speech API)
|
||||||
|
const name = document.getElementById('letterName');
|
||||||
|
name.textContent = `${letter}! ${letter} says "${letterSounds[letter]}"`;
|
||||||
|
|
||||||
|
// Change color
|
||||||
|
const display = document.getElementById('letterDisplay');
|
||||||
|
display.style.color = colors[Math.floor(Math.random() * colors.length)];
|
||||||
|
|
||||||
|
// Could use Web Speech API here:
|
||||||
|
// const utterance = new SpeechSynthesisUtterance(`${letter}. ${letter} is for ${letterNames[letter]}`);
|
||||||
|
// speechSynthesis.speak(utterance);
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextLetter() {
|
||||||
|
currentIndex = (currentIndex + 1) % alphabet.length;
|
||||||
|
updateDisplay(alphabet[currentIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function randomLetter() {
|
||||||
|
currentIndex = Math.floor(Math.random() * alphabet.length);
|
||||||
|
updateDisplay(alphabet[currentIndex]);
|
||||||
|
celebrate('✨');
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAlphabet() {
|
||||||
|
const grid = document.getElementById('alphabetGrid');
|
||||||
|
if (grid.style.display === 'none') {
|
||||||
|
grid.style.display = 'grid';
|
||||||
|
if (grid.children.length === 0) {
|
||||||
|
alphabet.forEach(letter => {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.className = 'alphabet-letter';
|
||||||
|
div.textContent = letter;
|
||||||
|
div.onclick = () => {
|
||||||
|
currentIndex = alphabet.indexOf(letter);
|
||||||
|
updateDisplay(letter);
|
||||||
|
speakLetter();
|
||||||
|
};
|
||||||
|
grid.appendChild(div);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
grid.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateAlphabetGrid() {
|
||||||
|
const grid = document.getElementById('alphabetGrid');
|
||||||
|
if (grid.children.length > 0) {
|
||||||
|
Array.from(grid.children).forEach((div, i) => {
|
||||||
|
if (learnedLetters.has(alphabet[i])) {
|
||||||
|
div.classList.add('learned');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function celebrate(emoji) {
|
||||||
|
const celebration = document.createElement('div');
|
||||||
|
celebration.className = 'celebration';
|
||||||
|
celebration.textContent = emoji;
|
||||||
|
document.body.appendChild(celebration);
|
||||||
|
setTimeout(() => celebration.remove(), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
updateDisplay(alphabet[0]);
|
||||||
|
|
||||||
|
// Encourage interaction
|
||||||
|
setTimeout(() => {
|
||||||
|
const name = document.getElementById('letterName');
|
||||||
|
name.textContent = '👆 Click the letter to hear it!';
|
||||||
|
}, 3000);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Large, colorful letter display
|
||||||
|
- Click to hear letter name and sound
|
||||||
|
- Progress tracking with stars
|
||||||
|
- Alphabet grid showing learned letters
|
||||||
|
- Randomization for variety
|
||||||
|
- Encouraging animations
|
||||||
|
- Mobile-friendly touch interface
|
||||||
|
|
||||||
|
### Example 2: Sight Word Safari (Ages 5-7)
|
||||||
|
|
||||||
|
**User asks:** "Practice sight words for first grade"
|
||||||
|
|
||||||
|
**Teacher generates:** Interactive safari game with:
|
||||||
|
- High-frequency Dolch/Fry words
|
||||||
|
- Word recognition challenges
|
||||||
|
- Sentence building activities
|
||||||
|
- Timed reading practice
|
||||||
|
- Progress badges and rewards
|
||||||
|
|
||||||
|
### Example 3: Story Builder Studio (Ages 7-10)
|
||||||
|
|
||||||
|
**User asks:** "Help with reading comprehension"
|
||||||
|
|
||||||
|
**Teacher generates:** Interactive story workshop with:
|
||||||
|
- Choose-your-own-adventure format
|
||||||
|
- Comprehension questions embedded
|
||||||
|
- Vocabulary highlighting
|
||||||
|
- Character analysis tools
|
||||||
|
- Story sequencing activities
|
||||||
|
|
||||||
|
## Gamification System
|
||||||
|
|
||||||
|
### Rewards & Stars
|
||||||
|
- **Letter Stars** (1 star): Learn a new letter
|
||||||
|
- **Word Stars** (5 stars): Read a new word
|
||||||
|
- **Story Stars** (10 stars): Complete a story
|
||||||
|
- **Speed Stars** (3 stars): Quick recognition
|
||||||
|
- **Perfect Stars** (20 stars): 100% accuracy
|
||||||
|
|
||||||
|
### Achievement Badges
|
||||||
|
- 🌟 **ABC Master**: Learn all 26 letters
|
||||||
|
- 📖 **First Reader**: Read first complete sentence
|
||||||
|
- 🏆 **Word Wizard**: Master 50 sight words
|
||||||
|
- 🎯 **Perfect Week**: Practice 7 days in a row
|
||||||
|
- 🚀 **Speed Reader**: Read 20 words in 1 minute
|
||||||
|
- 📚 **Story Time**: Complete 10 stories
|
||||||
|
- 🎨 **Creative Writer**: Build own story
|
||||||
|
- ⭐ **Super Star**: Earn 1000 total stars
|
||||||
|
|
||||||
|
### Progress Tracking
|
||||||
|
- Letters learned (26 total)
|
||||||
|
- Sight words mastered
|
||||||
|
- Stories completed
|
||||||
|
- Reading streak (days)
|
||||||
|
- Time spent reading
|
||||||
|
- Accuracy percentage
|
||||||
|
- Reading level advancement
|
||||||
|
|
||||||
|
### Celebration Animations
|
||||||
|
- Confetti for achievements
|
||||||
|
- Star explosions for correct answers
|
||||||
|
- Character animations
|
||||||
|
- Sound effects (optional)
|
||||||
|
- Progress bar fills
|
||||||
|
- Level-up animations
|
||||||
|
|
||||||
|
## Learning Activities by Type
|
||||||
|
|
||||||
|
### Letter Recognition
|
||||||
|
**Activities:**
|
||||||
|
- Alphabet song with animations
|
||||||
|
- Letter matching games
|
||||||
|
- Upper/lowercase pairing
|
||||||
|
- Letter tracing (touch/mouse)
|
||||||
|
- Find the letter challenges
|
||||||
|
- Letter sorting activities
|
||||||
|
|
||||||
|
**Example Code:**
|
||||||
|
```javascript
|
||||||
|
function createLetterMatch() {
|
||||||
|
const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
|
||||||
|
const lowercase = 'abcdefghijklmnopqrstuvwxyz'.split('');
|
||||||
|
|
||||||
|
// Shuffle and match pairs
|
||||||
|
const pairs = uppercase.map((u, i) => ({
|
||||||
|
upper: u,
|
||||||
|
lower: lowercase[i],
|
||||||
|
matched: false
|
||||||
|
}));
|
||||||
|
|
||||||
|
return pairs;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phonics Practice
|
||||||
|
**Activities:**
|
||||||
|
- Sound matching (letter to sound)
|
||||||
|
- CVC word building (cat, dog, run)
|
||||||
|
- Word families (-at, -an, -ig)
|
||||||
|
- Rhyming word games
|
||||||
|
- Blend practice (bl, cr, st)
|
||||||
|
- Digraph detection (ch, sh, th)
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
const wordFamilies = {
|
||||||
|
'at': ['cat', 'bat', 'rat', 'hat', 'mat', 'sat'],
|
||||||
|
'an': ['can', 'man', 'pan', 'ran', 'van', 'fan'],
|
||||||
|
'ig': ['big', 'dig', 'fig', 'pig', 'wig', 'jig']
|
||||||
|
};
|
||||||
|
|
||||||
|
function generateWordFamily(family) {
|
||||||
|
return wordFamilies[family].map(word => ({
|
||||||
|
word: word,
|
||||||
|
letters: word.split(''),
|
||||||
|
sound: `/${family}/`
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sight Word Training
|
||||||
|
**High-Frequency Words (Dolch/Fry Lists):**
|
||||||
|
|
||||||
|
**Pre-K:**
|
||||||
|
```javascript
|
||||||
|
const preK = ['a', 'and', 'away', 'big', 'blue', 'can', 'come',
|
||||||
|
'down', 'find', 'for', 'funny', 'go', 'help', 'here',
|
||||||
|
'I', 'in', 'is', 'it', 'jump', 'little', 'look', 'make',
|
||||||
|
'me', 'my', 'not', 'one', 'play', 'red', 'run', 'said',
|
||||||
|
'see', 'the', 'three', 'to', 'two', 'up', 'we', 'where',
|
||||||
|
'yellow', 'you'];
|
||||||
|
```
|
||||||
|
|
||||||
|
**First Grade:**
|
||||||
|
```javascript
|
||||||
|
const firstGrade = ['after', 'again', 'an', 'any', 'as', 'ask', 'by',
|
||||||
|
'could', 'every', 'fly', 'from', 'give', 'going',
|
||||||
|
'had', 'has', 'her', 'him', 'his', 'how', 'just',
|
||||||
|
'know', 'let', 'live', 'may', 'of', 'old', 'once',
|
||||||
|
'open', 'over', 'put', 'round', 'some', 'stop',
|
||||||
|
'take', 'thank', 'them', 'then', 'think', 'walk',
|
||||||
|
'were', 'when'];
|
||||||
|
```
|
||||||
|
|
||||||
|
**Interactive Sight Word Game:**
|
||||||
|
```javascript
|
||||||
|
function createSightWordChallenge(wordList, timeLimit = 60) {
|
||||||
|
let score = 0;
|
||||||
|
let currentWord = '';
|
||||||
|
let timeRemaining = timeLimit;
|
||||||
|
|
||||||
|
function nextWord() {
|
||||||
|
currentWord = wordList[Math.floor(Math.random() * wordList.length)];
|
||||||
|
displayWord(currentWord);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkAnswer(userInput) {
|
||||||
|
if (userInput.toLowerCase() === currentWord.toLowerCase()) {
|
||||||
|
score++;
|
||||||
|
celebrate();
|
||||||
|
nextWord();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { nextWord, checkAnswer, score };
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reading Comprehension
|
||||||
|
**Strategies:**
|
||||||
|
- Predicting what happens next
|
||||||
|
- Identifying main characters
|
||||||
|
- Recalling story details
|
||||||
|
- Understanding cause/effect
|
||||||
|
- Making inferences
|
||||||
|
- Visualizing scenes
|
||||||
|
|
||||||
|
**Interactive Questions:**
|
||||||
|
```javascript
|
||||||
|
const comprehensionQuestions = {
|
||||||
|
'The Cat and the Hat': [
|
||||||
|
{
|
||||||
|
question: 'Who are the main characters?',
|
||||||
|
type: 'multiple-choice',
|
||||||
|
options: ['Cat, Kids', 'Dog, Bird', 'Fish, Mom'],
|
||||||
|
answer: 'Cat, Kids'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Where does the story take place?',
|
||||||
|
type: 'multiple-choice',
|
||||||
|
options: ['Outside', 'At home', 'At school'],
|
||||||
|
answer: 'At home'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'What did you like about the story?',
|
||||||
|
type: 'open-ended',
|
||||||
|
encouragement: 'Great thinking!'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Story Building
|
||||||
|
**Components:**
|
||||||
|
- Character selection
|
||||||
|
- Setting choices
|
||||||
|
- Problem/solution structure
|
||||||
|
- Sequence of events
|
||||||
|
- Ending options
|
||||||
|
- Illustration tools
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const storyElements = {
|
||||||
|
characters: ['🐱 Cat', '🐶 Dog', '🦊 Fox', '🐻 Bear', '🦁 Lion'],
|
||||||
|
settings: ['🏠 House', '🌳 Forest', '🏖️ Beach', '🏰 Castle', '🚀 Space'],
|
||||||
|
problems: ['Lost something', 'Made a friend', 'Went on adventure', 'Solved mystery'],
|
||||||
|
solutions: ['Found it!', 'Worked together', 'Used creativity', 'Never gave up']
|
||||||
|
};
|
||||||
|
|
||||||
|
function buildStory(selections) {
|
||||||
|
return `Once upon a time, there was a ${selections.character}.
|
||||||
|
The ${selections.character} lived in a ${selections.setting}.
|
||||||
|
One day, the ${selections.character} ${selections.problem}.
|
||||||
|
In the end, ${selections.solution}!`;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parent/Teacher Tools
|
||||||
|
|
||||||
|
### Progress Reports
|
||||||
|
```javascript
|
||||||
|
const progressReport = {
|
||||||
|
childName: 'Emma',
|
||||||
|
age: 6,
|
||||||
|
level: 'Beginning Reader',
|
||||||
|
stats: {
|
||||||
|
lettersLearned: 26,
|
||||||
|
sightWordsMastered: 45,
|
||||||
|
storiesCompleted: 12,
|
||||||
|
currentStreak: 7,
|
||||||
|
totalTimeMinutes: 240
|
||||||
|
},
|
||||||
|
strengths: ['Letter recognition', 'Phonics', 'Enthusiasm'],
|
||||||
|
workingOn: ['Sight words', 'Reading fluency'],
|
||||||
|
nextSteps: ['Practice high-frequency words', 'Read aloud daily']
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customization Options
|
||||||
|
- Adjust difficulty level
|
||||||
|
- Select word lists
|
||||||
|
- Choose themes/characters
|
||||||
|
- Set time limits
|
||||||
|
- Enable/disable sound
|
||||||
|
- Track multiple children
|
||||||
|
- Export progress data
|
||||||
|
|
||||||
|
## Technical Implementation
|
||||||
|
|
||||||
|
### Text-to-Speech (Web Speech API)
|
||||||
|
```javascript
|
||||||
|
function speakText(text, rate = 1.0) {
|
||||||
|
if ('speechSynthesis' in window) {
|
||||||
|
const utterance = new SpeechSynthesisUtterance(text);
|
||||||
|
utterance.rate = rate;
|
||||||
|
utterance.pitch = 1.2; // Higher pitch for kids
|
||||||
|
utterance.volume = 1.0;
|
||||||
|
speechSynthesis.speak(utterance);
|
||||||
|
} else {
|
||||||
|
// Fallback: show text with pronunciation guide
|
||||||
|
showPronunciation(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Interactive Word Building
|
||||||
|
```javascript
|
||||||
|
function createWordBuilder(targetWord) {
|
||||||
|
const letters = targetWord.split('');
|
||||||
|
const scrambled = shuffle([...letters]);
|
||||||
|
|
||||||
|
let builtWord = [];
|
||||||
|
|
||||||
|
function addLetter(letter) {
|
||||||
|
builtWord.push(letter);
|
||||||
|
updateDisplay();
|
||||||
|
|
||||||
|
if (builtWord.join('') === targetWord) {
|
||||||
|
celebrate('Correct!');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeLetter() {
|
||||||
|
builtWord.pop();
|
||||||
|
updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
return { addLetter, removeLetter, scrambled };
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reading Fluency Timer
|
||||||
|
```javascript
|
||||||
|
class FluencyTracker {
|
||||||
|
constructor(text) {
|
||||||
|
this.text = text;
|
||||||
|
this.wordCount = text.split(' ').length;
|
||||||
|
this.startTime = null;
|
||||||
|
this.endTime = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
this.startTime = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
this.endTime = Date.now();
|
||||||
|
return this.calculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
calculate() {
|
||||||
|
const seconds = (this.endTime - this.startTime) / 1000;
|
||||||
|
const minutes = seconds / 60;
|
||||||
|
const wpm = Math.round(this.wordCount / minutes);
|
||||||
|
|
||||||
|
return {
|
||||||
|
wordsPerMinute: wpm,
|
||||||
|
timeSeconds: seconds,
|
||||||
|
wordCount: this.wordCount,
|
||||||
|
rating: this.getRating(wpm)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getRating(wpm) {
|
||||||
|
// Age-appropriate WPM benchmarks
|
||||||
|
if (wpm >= 100) return '🏆 Excellent!';
|
||||||
|
if (wpm >= 70) return '⭐ Great job!';
|
||||||
|
if (wpm >= 50) return '👍 Good work!';
|
||||||
|
return '💪 Keep practicing!';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Reference Materials
|
||||||
|
|
||||||
|
All included in `/references`:
|
||||||
|
- **phonics.md** - Phonics patterns, rules, and activities
|
||||||
|
- **sight_words.md** - Dolch and Fry word lists by level
|
||||||
|
- **comprehension.md** - Reading strategies and question types
|
||||||
|
- **stories.md** - Decodable texts and story templates
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
All in `/scripts`:
|
||||||
|
- **generate_playground.sh** - Create interactive reading playground
|
||||||
|
- **generate_game.sh** - Build phonics or sight word game
|
||||||
|
- **generate_story.sh** - Create interactive story
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
### DO:
|
||||||
|
✅ Use large, clear fonts (minimum 24pt for beginners)
|
||||||
|
✅ Include audio pronunciation
|
||||||
|
✅ Provide immediate positive feedback
|
||||||
|
✅ Use colorful, engaging visuals
|
||||||
|
✅ Celebrate every success
|
||||||
|
✅ Keep sessions short (5-15 minutes)
|
||||||
|
✅ Make it playful and fun
|
||||||
|
✅ Track progress visibly
|
||||||
|
|
||||||
|
### DON'T:
|
||||||
|
❌ Use complex vocabulary
|
||||||
|
❌ Show negative feedback
|
||||||
|
❌ Make activities too long
|
||||||
|
❌ Use small or hard-to-read text
|
||||||
|
❌ Skip audio support
|
||||||
|
❌ Make it feel like work
|
||||||
|
❌ Overwhelm with too many choices
|
||||||
|
❌ Forget to celebrate progress
|
||||||
|
|
||||||
|
## Example Interactions
|
||||||
|
|
||||||
|
**Toddler (Age 2):**
|
||||||
|
> "Teach my toddler the alphabet"
|
||||||
|
|
||||||
|
*Generates: Interactive Letter Land with clickable letters, sounds, animations, and tracking*
|
||||||
|
|
||||||
|
**Kindergarten (Age 5):**
|
||||||
|
> "Help with CVC words"
|
||||||
|
|
||||||
|
*Generates: Word family game with cat, bat, rat - drag-and-drop letter building with sounds*
|
||||||
|
|
||||||
|
**First Grade (Age 6):**
|
||||||
|
> "Practice sight words"
|
||||||
|
|
||||||
|
*Generates: Sight Word Safari with timed challenges, sentences, and progress badges*
|
||||||
|
|
||||||
|
**Second Grade (Age 7):**
|
||||||
|
> "Reading comprehension practice"
|
||||||
|
|
||||||
|
*Generates: Interactive story with embedded questions, vocabulary help, and rewards*
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
This skill transforms reading education by:
|
||||||
|
- **Instant Engagement** - Generates playgrounds immediately
|
||||||
|
- **Multi-Sensory** - Visual, audio, interactive elements
|
||||||
|
- **Developmentally Appropriate** - Age 1-10 coverage
|
||||||
|
- **Systematic** - Phonics-based progression
|
||||||
|
- **Gamified** - Stars, badges, celebrations
|
||||||
|
- **Effective** - Research-based methods
|
||||||
|
- **Fun** - Play-based learning
|
||||||
|
|
||||||
|
**"Every child can learn to read with the right support and encouragement."** 📚
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Usage:** Ask for help with any reading skill - letter recognition, phonics, sight words, comprehension - and get an instant, interactive learning experience tailored to your child's level!
|
||||||
636
skills/reading-teacher/references/comprehension.md
Normal file
636
skills/reading-teacher/references/comprehension.md
Normal file
@@ -0,0 +1,636 @@
|
|||||||
|
# Reading Comprehension Reference
|
||||||
|
|
||||||
|
Strategies, question types, and interactive activities for developing reading comprehension.
|
||||||
|
|
||||||
|
## Comprehension Strategies
|
||||||
|
|
||||||
|
### Before Reading
|
||||||
|
```javascript
|
||||||
|
const beforeReadingStrategies = {
|
||||||
|
preview: {
|
||||||
|
name: 'Preview the Text',
|
||||||
|
steps: [
|
||||||
|
'Look at title and pictures',
|
||||||
|
'Read headings and subheadings',
|
||||||
|
'Predict what story is about',
|
||||||
|
'Ask: What do I already know about this topic?'
|
||||||
|
],
|
||||||
|
prompt: 'What do you think this story will be about?'
|
||||||
|
},
|
||||||
|
|
||||||
|
purpose: {
|
||||||
|
name: 'Set a Purpose',
|
||||||
|
steps: [
|
||||||
|
'Why am I reading this?',
|
||||||
|
'What do I want to learn?',
|
||||||
|
'How will I use this information?'
|
||||||
|
],
|
||||||
|
prompt: 'What do you want to find out from this story?'
|
||||||
|
},
|
||||||
|
|
||||||
|
vocabulary: {
|
||||||
|
name: 'Preview Key Words',
|
||||||
|
steps: [
|
||||||
|
'Identify unfamiliar words',
|
||||||
|
'Look at context',
|
||||||
|
'Check pictures for clues',
|
||||||
|
'Make predictions about meanings'
|
||||||
|
],
|
||||||
|
prompt: 'Are there any new words? What might they mean?'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### During Reading
|
||||||
|
```javascript
|
||||||
|
const duringReadingStrategies = {
|
||||||
|
visualize: {
|
||||||
|
name: 'Make Mental Pictures',
|
||||||
|
prompt: 'What do you see in your mind?',
|
||||||
|
activity: 'Draw what you\'re imagining'
|
||||||
|
},
|
||||||
|
|
||||||
|
question: {
|
||||||
|
name: 'Ask Questions',
|
||||||
|
prompts: [
|
||||||
|
'What is happening?',
|
||||||
|
'Why did that happen?',
|
||||||
|
'What will happen next?',
|
||||||
|
'How does the character feel?'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
connect: {
|
||||||
|
name: 'Make Connections',
|
||||||
|
types: {
|
||||||
|
textToSelf: 'Has this happened to you?',
|
||||||
|
textToText: 'Does this remind you of another story?',
|
||||||
|
textToWorld: 'Where have you seen this in real life?'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
clarify: {
|
||||||
|
name: 'Fix Confusions',
|
||||||
|
strategies: [
|
||||||
|
'Reread the sentence',
|
||||||
|
'Read ahead for clues',
|
||||||
|
'Look at pictures',
|
||||||
|
'Sound out unfamiliar words',
|
||||||
|
'Ask for help'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
predict: {
|
||||||
|
name: 'Make Predictions',
|
||||||
|
prompt: 'What do you think will happen next?',
|
||||||
|
check: 'Was your prediction correct?'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### After Reading
|
||||||
|
```javascript
|
||||||
|
const afterReadingStrategies = {
|
||||||
|
summarize: {
|
||||||
|
name: 'Retell the Story',
|
||||||
|
framework: {
|
||||||
|
beginning: 'How did the story start?',
|
||||||
|
middle: 'What happened?',
|
||||||
|
end: 'How did it end?'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mainIdea: {
|
||||||
|
name: 'Find the Main Idea',
|
||||||
|
questions: [
|
||||||
|
'What is the story mostly about?',
|
||||||
|
'What is the most important part?',
|
||||||
|
'What did you learn?'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
evaluate: {
|
||||||
|
name: 'Think About the Story',
|
||||||
|
questions: [
|
||||||
|
'Did you like it? Why?',
|
||||||
|
'What was your favorite part?',
|
||||||
|
'Would you recommend this to a friend?',
|
||||||
|
'What would you change?'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Question Types
|
||||||
|
|
||||||
|
### Literal Questions (Right There)
|
||||||
|
```javascript
|
||||||
|
const literalQuestions = {
|
||||||
|
who: 'Who is the main character?',
|
||||||
|
what: 'What happened in the story?',
|
||||||
|
when: 'When did this take place?',
|
||||||
|
where: 'Where does the story happen?',
|
||||||
|
how: 'How did the character solve the problem?',
|
||||||
|
|
||||||
|
examples: [
|
||||||
|
'What color was the cat?',
|
||||||
|
'Where did Tom go?',
|
||||||
|
'Who helped Sally?',
|
||||||
|
'When did they leave?'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Inferential Questions (Think & Search)
|
||||||
|
```javascript
|
||||||
|
const inferentialQuestions = {
|
||||||
|
why: 'Why did the character do that?',
|
||||||
|
cause: 'What caused this to happen?',
|
||||||
|
effect: 'What happened because of...?',
|
||||||
|
feeling: 'How do you think the character felt?',
|
||||||
|
motive: 'Why did the character want...?',
|
||||||
|
|
||||||
|
examples: [
|
||||||
|
'Why was the girl sad?',
|
||||||
|
'How did the boy feel when...?',
|
||||||
|
'What made the dog run away?',
|
||||||
|
'Why didn\'t they tell anyone?'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Evaluative Questions (Author & Me)
|
||||||
|
```javascript
|
||||||
|
const evaluativeQuestions = {
|
||||||
|
opinion: 'What do you think about...?',
|
||||||
|
judgment: 'Did the character make a good choice?',
|
||||||
|
alternative: 'What would you have done?',
|
||||||
|
theme: 'What lesson does this teach?',
|
||||||
|
|
||||||
|
examples: [
|
||||||
|
'Was it right for her to...?',
|
||||||
|
'What would you do in this situation?',
|
||||||
|
'Do you agree with the character?',
|
||||||
|
'What is the author trying to tell us?'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Creative Questions (On My Own)
|
||||||
|
```javascript
|
||||||
|
const creativeQuestions = {
|
||||||
|
extend: 'What might happen next?',
|
||||||
|
change: 'How would the story be different if...?',
|
||||||
|
relate: 'How is this like your life?',
|
||||||
|
imagine: 'What if the character had...?',
|
||||||
|
|
||||||
|
examples: [
|
||||||
|
'What would happen if the ending was different?',
|
||||||
|
'How would you feel if you were the character?',
|
||||||
|
'What other adventures might they have?',
|
||||||
|
'If you could change one thing, what would it be?'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Story Elements
|
||||||
|
|
||||||
|
### Character Analysis
|
||||||
|
```javascript
|
||||||
|
const characterAnalysis = {
|
||||||
|
traits: {
|
||||||
|
prompt: 'What is the character like?',
|
||||||
|
evidence: 'How do you know?',
|
||||||
|
categories: ['brave', 'kind', 'funny', 'smart', 'curious', 'helpful']
|
||||||
|
},
|
||||||
|
|
||||||
|
feelings: {
|
||||||
|
prompt: 'How does the character feel?',
|
||||||
|
changes: 'How do their feelings change?',
|
||||||
|
emotions: ['happy', 'sad', 'angry', 'scared', 'excited', 'surprised']
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
prompt: 'What does the character do?',
|
||||||
|
motives: 'Why do they do it?'
|
||||||
|
},
|
||||||
|
|
||||||
|
relationships: {
|
||||||
|
prompt: 'Who are the other characters?',
|
||||||
|
connections: 'How do they interact?'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setting
|
||||||
|
```javascript
|
||||||
|
const settingAnalysis = {
|
||||||
|
where: {
|
||||||
|
prompt: 'Where does the story take place?',
|
||||||
|
details: 'Describe the place'
|
||||||
|
},
|
||||||
|
|
||||||
|
when: {
|
||||||
|
prompt: 'When does the story happen?',
|
||||||
|
clues: ['time of day', 'season', 'past/present/future']
|
||||||
|
},
|
||||||
|
|
||||||
|
importance: {
|
||||||
|
prompt: 'Does the setting matter to the story?',
|
||||||
|
question: 'Would the story be different in a different place/time?'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Plot Structure
|
||||||
|
```javascript
|
||||||
|
const plotStructure = {
|
||||||
|
beginning: {
|
||||||
|
name: 'Introduction',
|
||||||
|
elements: ['characters', 'setting', 'situation'],
|
||||||
|
question: 'How does the story start?'
|
||||||
|
},
|
||||||
|
|
||||||
|
middle: {
|
||||||
|
name: 'Problem/Conflict',
|
||||||
|
elements: ['challenge', 'obstacle', 'quest'],
|
||||||
|
question: 'What problem do the characters face?'
|
||||||
|
},
|
||||||
|
|
||||||
|
climax: {
|
||||||
|
name: 'Turning Point',
|
||||||
|
elements: ['most exciting part', 'biggest challenge'],
|
||||||
|
question: 'What is the most important moment?'
|
||||||
|
},
|
||||||
|
|
||||||
|
end: {
|
||||||
|
name: 'Resolution',
|
||||||
|
elements: ['solution', 'outcome', 'lesson'],
|
||||||
|
question: 'How is the problem solved?'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Interactive Comprehension Activities
|
||||||
|
|
||||||
|
### Story Map
|
||||||
|
```javascript
|
||||||
|
function createStoryMap() {
|
||||||
|
return {
|
||||||
|
title: '',
|
||||||
|
characters: {
|
||||||
|
main: [],
|
||||||
|
supporting: []
|
||||||
|
},
|
||||||
|
setting: {
|
||||||
|
where: '',
|
||||||
|
when: ''
|
||||||
|
},
|
||||||
|
plot: {
|
||||||
|
beginning: '',
|
||||||
|
problem: '',
|
||||||
|
events: [],
|
||||||
|
solution: '',
|
||||||
|
ending: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
display: function() {
|
||||||
|
return `
|
||||||
|
📖 ${this.title}
|
||||||
|
👥 Characters: ${this.characters.main.join(', ')}
|
||||||
|
📍 Setting: ${this.setting.where} (${this.setting.when})
|
||||||
|
|
||||||
|
Story:
|
||||||
|
Beginning: ${this.plot.beginning}
|
||||||
|
Problem: ${this.plot.problem}
|
||||||
|
Events: ${this.plot.events.join(' → ')}
|
||||||
|
Solution: ${this.plot.solution}
|
||||||
|
Ending: ${this.plot.ending}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Question Generator
|
||||||
|
```javascript
|
||||||
|
function generateComprehensionQuestions(story, level) {
|
||||||
|
const questions = [];
|
||||||
|
|
||||||
|
// Literal questions (ages 5-7)
|
||||||
|
if (level <= 2) {
|
||||||
|
questions.push({
|
||||||
|
type: 'literal',
|
||||||
|
question: `Who is the main character in "${story.title}"?`,
|
||||||
|
answer: story.characters.main[0],
|
||||||
|
difficulty: 'easy'
|
||||||
|
});
|
||||||
|
|
||||||
|
questions.push({
|
||||||
|
type: 'literal',
|
||||||
|
question: `Where does the story take place?`,
|
||||||
|
answer: story.setting.where,
|
||||||
|
difficulty: 'easy'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inferential questions (ages 7-9)
|
||||||
|
if (level >= 2) {
|
||||||
|
questions.push({
|
||||||
|
type: 'inferential',
|
||||||
|
question: `Why do you think the character...?`,
|
||||||
|
answer: null, // Open-ended
|
||||||
|
difficulty: 'medium'
|
||||||
|
});
|
||||||
|
|
||||||
|
questions.push({
|
||||||
|
type: 'inferential',
|
||||||
|
question: `How did the character feel when...?`,
|
||||||
|
answer: null,
|
||||||
|
difficulty: 'medium'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluative questions (ages 9+)
|
||||||
|
if (level >= 3) {
|
||||||
|
questions.push({
|
||||||
|
type: 'evaluative',
|
||||||
|
question: `What would you have done differently?`,
|
||||||
|
answer: null,
|
||||||
|
difficulty: 'hard'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return questions;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cloze Reading (Fill in the Blank)
|
||||||
|
```javascript
|
||||||
|
function createClozeActivity(text, difficulty = 'medium') {
|
||||||
|
const words = text.split(' ');
|
||||||
|
const blanks = [];
|
||||||
|
|
||||||
|
// Remove every Nth word based on difficulty
|
||||||
|
const interval = difficulty === 'easy' ? 10 : difficulty === 'medium' ? 7 : 5;
|
||||||
|
|
||||||
|
const modified = words.map((word, index) => {
|
||||||
|
if (index % interval === 0 && word.length > 3) {
|
||||||
|
blanks.push({
|
||||||
|
position: index,
|
||||||
|
word: word,
|
||||||
|
hint: word[0] + '_'.repeat(word.length - 1)
|
||||||
|
});
|
||||||
|
return '______';
|
||||||
|
}
|
||||||
|
return word;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
original: text,
|
||||||
|
modified: modified.join(' '),
|
||||||
|
blanks: blanks,
|
||||||
|
|
||||||
|
check: function(userAnswers) {
|
||||||
|
let correct = 0;
|
||||||
|
userAnswers.forEach((answer, i) => {
|
||||||
|
if (answer.toLowerCase() === blanks[i].word.toLowerCase()) {
|
||||||
|
correct++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
correct: correct,
|
||||||
|
total: blanks.length,
|
||||||
|
percentage: Math.round((correct / blanks.length) * 100)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getHint: function(blankIndex) {
|
||||||
|
return blanks[blankIndex].hint;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sequence Activity
|
||||||
|
```javascript
|
||||||
|
function createSequenceActivity(events) {
|
||||||
|
const shuffled = shuffle([...events]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
events: events,
|
||||||
|
scrambled: shuffled,
|
||||||
|
userOrder: [],
|
||||||
|
|
||||||
|
check: function() {
|
||||||
|
return {
|
||||||
|
correct: JSON.stringify(this.userOrder) === JSON.stringify(events),
|
||||||
|
correctOrder: events,
|
||||||
|
userOrder: this.userOrder
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
hint: function() {
|
||||||
|
return `The story starts with: "${events[0]}"`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vocabulary in Context
|
||||||
|
```javascript
|
||||||
|
function createVocabularyActivity(text, targetWords) {
|
||||||
|
return targetWords.map(word => {
|
||||||
|
const sentence = findSentenceWith(text, word);
|
||||||
|
const context = getContext(text, word);
|
||||||
|
|
||||||
|
return {
|
||||||
|
word: word,
|
||||||
|
sentence: sentence,
|
||||||
|
beforeContext: context.before,
|
||||||
|
afterContext: context.after,
|
||||||
|
|
||||||
|
questions: [
|
||||||
|
{
|
||||||
|
type: 'multiple-choice',
|
||||||
|
question: `What does "${word}" mean in this sentence?`,
|
||||||
|
options: generateDefinitionOptions(word),
|
||||||
|
answer: getCorrectDefinition(word)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'context-clue',
|
||||||
|
question: 'Which words help you understand the meaning?',
|
||||||
|
answer: getContextClues(sentence, word)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
practice: {
|
||||||
|
blank: sentence.replace(word, '______'),
|
||||||
|
wordBank: [word, ...generateSimilarWords(word)],
|
||||||
|
correctWord: word
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Comprehension Games
|
||||||
|
|
||||||
|
### Story Detective
|
||||||
|
```javascript
|
||||||
|
class StoryDetective {
|
||||||
|
constructor(story) {
|
||||||
|
this.story = story;
|
||||||
|
this.clues = [];
|
||||||
|
this.questions = [];
|
||||||
|
this.score = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
addClue(question, answer, location) {
|
||||||
|
this.clues.push({
|
||||||
|
question: question,
|
||||||
|
answer: answer,
|
||||||
|
found: false,
|
||||||
|
location: location
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
checkClue(clueIndex, userAnswer) {
|
||||||
|
const clue = this.clues[clueIndex];
|
||||||
|
|
||||||
|
if (userAnswer.toLowerCase().includes(clue.answer.toLowerCase())) {
|
||||||
|
clue.found = true;
|
||||||
|
this.score += 10;
|
||||||
|
return {
|
||||||
|
correct: true,
|
||||||
|
message: '🔍 Clue found! +10 points',
|
||||||
|
location: clue.location
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
correct: false,
|
||||||
|
hint: `Look ${clue.location}`,
|
||||||
|
message: 'Keep searching!'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getProgress() {
|
||||||
|
const found = this.clues.filter(c => c.found).length;
|
||||||
|
return {
|
||||||
|
found: found,
|
||||||
|
total: this.clues.length,
|
||||||
|
percentage: Math.round((found / this.clues.length) * 100),
|
||||||
|
score: this.score
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reading Race
|
||||||
|
```javascript
|
||||||
|
class ReadingRace {
|
||||||
|
constructor(passage, questionsPerCheckpoint = 3) {
|
||||||
|
this.passage = passage;
|
||||||
|
this.checkpoints = this.createCheckpoints(questionsPerCheckpoint);
|
||||||
|
this.currentCheckpoint = 0;
|
||||||
|
this.startTime = null;
|
||||||
|
this.endTime = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
this.startTime = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
answerQuestion(answer) {
|
||||||
|
const checkpoint = this.checkpoints[this.currentCheckpoint];
|
||||||
|
const question = checkpoint.questions[checkpoint.currentQuestion];
|
||||||
|
|
||||||
|
const correct = this.checkAnswer(answer, question.answer);
|
||||||
|
|
||||||
|
if (correct) {
|
||||||
|
checkpoint.correct++;
|
||||||
|
checkpoint.currentQuestion++;
|
||||||
|
|
||||||
|
if (checkpoint.currentQuestion >= checkpoint.questions.length) {
|
||||||
|
this.currentCheckpoint++;
|
||||||
|
return {
|
||||||
|
checkpointComplete: true,
|
||||||
|
message: `🏁 Checkpoint ${this.currentCheckpoint} complete!`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { correct: correct };
|
||||||
|
}
|
||||||
|
|
||||||
|
finish() {
|
||||||
|
this.endTime = Date.now();
|
||||||
|
const time = (this.endTime - this.startTime) / 1000; // seconds
|
||||||
|
|
||||||
|
return {
|
||||||
|
time: time,
|
||||||
|
checkpoints: this.checkpoints.length,
|
||||||
|
accuracy: this.calculateAccuracy(),
|
||||||
|
rating: this.getRating(time, this.calculateAccuracy())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Progress Tracking
|
||||||
|
|
||||||
|
### Comprehension Skills Tracker
|
||||||
|
```javascript
|
||||||
|
class ComprehensionTracker {
|
||||||
|
constructor() {
|
||||||
|
this.skills = {
|
||||||
|
literal: { attempts: 0, correct: 0 },
|
||||||
|
inferential: { attempts: 0, correct: 0 },
|
||||||
|
evaluative: { attempts: 0, correct: 0 },
|
||||||
|
vocabulary: { attempts: 0, correct: 0 },
|
||||||
|
sequencing: { attempts: 0, correct: 0 },
|
||||||
|
mainIdea: { attempts: 0, correct: 0 },
|
||||||
|
causeEffect: { attempts: 0, correct: 0 }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
record(skillType, correct) {
|
||||||
|
this.skills[skillType].attempts++;
|
||||||
|
if (correct) this.skills[skillType].correct++;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSkillLevel(skillType) {
|
||||||
|
const skill = this.skills[skillType];
|
||||||
|
if (skill.attempts === 0) return 'Not Started';
|
||||||
|
|
||||||
|
const accuracy = skill.correct / skill.attempts;
|
||||||
|
|
||||||
|
if (accuracy >= 0.9) return 'Mastered';
|
||||||
|
if (accuracy >= 0.7) return 'Proficient';
|
||||||
|
if (accuracy >= 0.5) return 'Developing';
|
||||||
|
return 'Needs Practice';
|
||||||
|
}
|
||||||
|
|
||||||
|
getReport() {
|
||||||
|
return Object.entries(this.skills).map(([name, data]) => ({
|
||||||
|
skill: name,
|
||||||
|
level: this.getSkillLevel(name),
|
||||||
|
accuracy: data.attempts > 0 ? Math.round((data.correct / data.attempts) * 100) : 0,
|
||||||
|
attempts: data.attempts
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Reading comprehension tools provide:
|
||||||
|
- Before, during, and after reading strategies
|
||||||
|
- Multiple question types (literal, inferential, evaluative, creative)
|
||||||
|
- Story element analysis (character, setting, plot)
|
||||||
|
- Interactive activities (story maps, cloze, sequencing)
|
||||||
|
- Comprehension games
|
||||||
|
- Progress tracking
|
||||||
|
|
||||||
|
Use these patterns to create effective comprehension practice!
|
||||||
523
skills/reading-teacher/references/phonics.md
Normal file
523
skills/reading-teacher/references/phonics.md
Normal file
@@ -0,0 +1,523 @@
|
|||||||
|
# Phonics Reference
|
||||||
|
|
||||||
|
Systematic phonics instruction patterns and interactive activities.
|
||||||
|
|
||||||
|
## Phonemic Awareness (Pre-Reading)
|
||||||
|
|
||||||
|
### Sound Recognition
|
||||||
|
```javascript
|
||||||
|
const letterSounds = {
|
||||||
|
// Consonants
|
||||||
|
'B': 'buh', 'C': 'kuh', 'D': 'duh', 'F': 'fuh', 'G': 'guh',
|
||||||
|
'H': 'huh', 'J': 'juh', 'K': 'kuh', 'L': 'luh', 'M': 'muh',
|
||||||
|
'N': 'nuh', 'P': 'puh', 'Q': 'kwuh', 'R': 'ruh', 'S': 'sss',
|
||||||
|
'T': 'tuh', 'V': 'vuh', 'W': 'wuh', 'X': 'ks', 'Y': 'yuh', 'Z': 'zzz',
|
||||||
|
|
||||||
|
// Vowels (short sounds)
|
||||||
|
'A': 'ah (like apple)', 'E': 'eh (like egg)',
|
||||||
|
'I': 'ih (like igloo)', 'O': 'ah (like octopus)',
|
||||||
|
'U': 'uh (like umbrella)'
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rhyming Words
|
||||||
|
```javascript
|
||||||
|
const rhymePatterns = {
|
||||||
|
'at': {
|
||||||
|
words: ['cat', 'bat', 'rat', 'hat', 'mat', 'sat', 'fat', 'pat'],
|
||||||
|
emoji: '🐱',
|
||||||
|
color: '#FF6B9D'
|
||||||
|
},
|
||||||
|
'an': {
|
||||||
|
words: ['can', 'man', 'pan', 'ran', 'van', 'fan', 'tan', 'ban'],
|
||||||
|
emoji: '👨',
|
||||||
|
color: '#4ECDC4'
|
||||||
|
},
|
||||||
|
'ig': {
|
||||||
|
words: ['big', 'dig', 'fig', 'pig', 'wig', 'jig'],
|
||||||
|
emoji: '🐷',
|
||||||
|
color: '#FFE66D'
|
||||||
|
},
|
||||||
|
'op': {
|
||||||
|
words: ['hop', 'mop', 'pop', 'top', 'stop', 'shop', 'drop'],
|
||||||
|
emoji: '🛑',
|
||||||
|
color: '#A8E6CF'
|
||||||
|
},
|
||||||
|
'ug': {
|
||||||
|
words: ['bug', 'hug', 'mug', 'rug', 'tug', 'jug', 'dug'],
|
||||||
|
emoji: '🐛',
|
||||||
|
color: '#FF8B94'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function createRhymeGame(pattern) {
|
||||||
|
const { words, emoji, color } = rhymePatterns[pattern];
|
||||||
|
|
||||||
|
return {
|
||||||
|
pattern: pattern,
|
||||||
|
words: words,
|
||||||
|
display: words.map(w => `${emoji} ${w}`),
|
||||||
|
checkRhyme: (word) => word.endsWith(pattern)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## CVC Words (Consonant-Vowel-Consonant)
|
||||||
|
|
||||||
|
### Short Vowel Sounds
|
||||||
|
```javascript
|
||||||
|
const cvcWords = {
|
||||||
|
'a': [
|
||||||
|
'cat', 'bat', 'rat', 'hat', 'mat', 'sat', 'pat', 'fat',
|
||||||
|
'can', 'man', 'pan', 'ran', 'van', 'fan', 'tan', 'ban',
|
||||||
|
'bag', 'rag', 'tag', 'wag', 'sag', 'lag',
|
||||||
|
'cap', 'map', 'tap', 'nap', 'gap', 'lap', 'rap',
|
||||||
|
'dad', 'mad', 'sad', 'bad', 'had', 'pad'
|
||||||
|
],
|
||||||
|
|
||||||
|
'e': [
|
||||||
|
'bed', 'red', 'led', 'fed', 'wed',
|
||||||
|
'hen', 'pen', 'ten', 'den', 'men',
|
||||||
|
'pet', 'net', 'set', 'wet', 'get', 'let', 'met', 'vet',
|
||||||
|
'leg', 'peg', 'beg'
|
||||||
|
],
|
||||||
|
|
||||||
|
'i': [
|
||||||
|
'big', 'dig', 'fig', 'pig', 'wig', 'jig',
|
||||||
|
'bin', 'fin', 'pin', 'tin', 'win', 'din',
|
||||||
|
'bit', 'fit', 'hit', 'kit', 'pit', 'sit', 'lit',
|
||||||
|
'dip', 'hip', 'lip', 'rip', 'sip', 'tip', 'zip'
|
||||||
|
],
|
||||||
|
|
||||||
|
'o': [
|
||||||
|
'dog', 'fog', 'log', 'hog', 'jog',
|
||||||
|
'dot', 'hot', 'lot', 'not', 'pot', 'cot', 'got',
|
||||||
|
'hop', 'mop', 'pop', 'top', 'stop',
|
||||||
|
'box', 'fox', 'ox'
|
||||||
|
],
|
||||||
|
|
||||||
|
'u': [
|
||||||
|
'bug', 'hug', 'mug', 'rug', 'tug', 'jug', 'dug',
|
||||||
|
'bun', 'fun', 'run', 'sun', 'gun',
|
||||||
|
'bus', 'pus', 'us',
|
||||||
|
'but', 'cut', 'hut', 'nut', 'put'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
function generateCVCPractice(vowel, count = 5) {
|
||||||
|
const words = cvcWords[vowel];
|
||||||
|
const selected = shuffle(words).slice(0, count);
|
||||||
|
|
||||||
|
return selected.map(word => ({
|
||||||
|
word: word,
|
||||||
|
letters: word.split(''),
|
||||||
|
vowel: vowel,
|
||||||
|
consonants: word.split('').filter(l => l !== vowel),
|
||||||
|
image: getWordImage(word)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Word Building Activity
|
||||||
|
```javascript
|
||||||
|
function createWordBuilder(targetWord) {
|
||||||
|
const letters = targetWord.split('');
|
||||||
|
const allLetters = 'abcdefghijklmnopqrstuvwxyz'.split('');
|
||||||
|
|
||||||
|
// Create letter bank with correct letters plus distractors
|
||||||
|
const distractors = shuffle(allLetters.filter(l => !letters.includes(l))).slice(0, 3);
|
||||||
|
const letterBank = shuffle([...letters, ...distractors]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
target: targetWord,
|
||||||
|
letters: letterBank,
|
||||||
|
positions: Array(letters.length).fill(''),
|
||||||
|
|
||||||
|
checkWord: function(builtWord) {
|
||||||
|
return builtWord === targetWord;
|
||||||
|
},
|
||||||
|
|
||||||
|
givHint: function() {
|
||||||
|
const firstLetter = letters[0];
|
||||||
|
return `The word starts with "${firstLetter}"`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Consonant Blends
|
||||||
|
|
||||||
|
### Beginning Blends (2-letter)
|
||||||
|
```javascript
|
||||||
|
const beginningBlends = {
|
||||||
|
'bl': ['blue', 'black', 'block', 'blend', 'bless', 'bleed'],
|
||||||
|
'cl': ['clap', 'clam', 'class', 'climb', 'clock', 'close'],
|
||||||
|
'fl': ['flag', 'flap', 'flat', 'flip', 'flock', 'flow'],
|
||||||
|
'gl': ['glad', 'glass', 'glow', 'glue', 'globe'],
|
||||||
|
'pl': ['plan', 'plant', 'play', 'please', 'plug', 'plum'],
|
||||||
|
'sl': ['slam', 'slap', 'slip', 'slow', 'slug'],
|
||||||
|
|
||||||
|
'br': ['brain', 'branch', 'brave', 'bread', 'brick', 'bring'],
|
||||||
|
'cr': ['crab', 'crack', 'crash', 'crib', 'crop', 'cross'],
|
||||||
|
'dr': ['drag', 'drain', 'draw', 'dream', 'dress', 'drill'],
|
||||||
|
'fr': ['frame', 'fresh', 'friend', 'frog', 'front', 'fruit'],
|
||||||
|
'gr': ['grab', 'grade', 'grain', 'grass', 'green', 'grow'],
|
||||||
|
'pr': ['pray', 'press', 'pretty', 'price', 'print', 'prize'],
|
||||||
|
'tr': ['track', 'train', 'trash', 'tree', 'trick', 'truck'],
|
||||||
|
|
||||||
|
'sc': ['scale', 'scare', 'school', 'score', 'scout'],
|
||||||
|
'sk': ['skate', 'sketch', 'ski', 'skill', 'skip', 'sky'],
|
||||||
|
'sm': ['small', 'smart', 'smell', 'smile', 'smoke'],
|
||||||
|
'sn': ['snack', 'snail', 'snake', 'snap', 'snow'],
|
||||||
|
'sp': ['space', 'spark', 'speak', 'spell', 'spend', 'spin'],
|
||||||
|
'st': ['stack', 'stamp', 'stand', 'star', 'start', 'stop'],
|
||||||
|
'sw': ['swam', 'swap', 'sweep', 'sweet', 'swim', 'swing']
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ending Blends
|
||||||
|
```javascript
|
||||||
|
const endingBlends = {
|
||||||
|
'nd': ['and', 'band', 'hand', 'land', 'sand', 'stand', 'wind'],
|
||||||
|
'ng': ['bang', 'king', 'long', 'ring', 'sing', 'song', 'wing'],
|
||||||
|
'nk': ['bank', 'drink', 'pink', 'sink', 'tank', 'think', 'wink'],
|
||||||
|
'nt': ['ant', 'bent', 'went', 'hunt', 'plant', 'sent', 'want'],
|
||||||
|
'mp': ['camp', 'jump', 'lamp', 'pump', 'stamp'],
|
||||||
|
'sk': ['ask', 'desk', 'mask', 'risk', 'task'],
|
||||||
|
'st': ['best', 'fast', 'just', 'last', 'must', 'rest', 'test']
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Blend Practice Game
|
||||||
|
```javascript
|
||||||
|
function createBlendGame(blendType, blend) {
|
||||||
|
const words = beginningBlends[blend] || endingBlends[blend];
|
||||||
|
|
||||||
|
return {
|
||||||
|
blend: blend,
|
||||||
|
words: words,
|
||||||
|
sound: `"${blend}"`,
|
||||||
|
|
||||||
|
displayWord: function(word) {
|
||||||
|
const parts = word.split(blend);
|
||||||
|
return {
|
||||||
|
before: parts[0],
|
||||||
|
blend: blend,
|
||||||
|
after: parts[1] || parts[0],
|
||||||
|
highlight: blend
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
createChallenge: function() {
|
||||||
|
const correctWord = words[Math.floor(Math.random() * words.length)];
|
||||||
|
const otherBlends = Object.keys(beginningBlends).filter(b => b !== blend);
|
||||||
|
const wrongBlend = otherBlends[Math.floor(Math.random() * otherBlends.length)];
|
||||||
|
const wrongWord = beginningBlends[wrongBlend][0];
|
||||||
|
|
||||||
|
return {
|
||||||
|
question: `Which word has the "${blend}" sound?`,
|
||||||
|
options: shuffle([correctWord, wrongWord]),
|
||||||
|
answer: correctWord
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Digraphs
|
||||||
|
|
||||||
|
### Consonant Digraphs
|
||||||
|
```javascript
|
||||||
|
const digraphs = {
|
||||||
|
'ch': {
|
||||||
|
sound: 'ch (as in cheese)',
|
||||||
|
words: ['chain', 'chair', 'chalk', 'chap', 'chat', 'check', 'cheese',
|
||||||
|
'chess', 'chest', 'chick', 'child', 'chill', 'chip', 'chop'],
|
||||||
|
emoji: '🧀'
|
||||||
|
},
|
||||||
|
|
||||||
|
'sh': {
|
||||||
|
sound: 'sh (as in ship)',
|
||||||
|
words: ['shade', 'shake', 'shame', 'shape', 'share', 'shark', 'sharp',
|
||||||
|
'sheep', 'shelf', 'shell', 'shine', 'ship', 'shirt', 'shop'],
|
||||||
|
emoji: '🚢'
|
||||||
|
},
|
||||||
|
|
||||||
|
'th': {
|
||||||
|
sound: 'th (as in think)',
|
||||||
|
words: ['thank', 'that', 'them', 'then', 'there', 'these', 'thick',
|
||||||
|
'thin', 'thing', 'think', 'third', 'this', 'thorn', 'three'],
|
||||||
|
emoji: '🤔'
|
||||||
|
},
|
||||||
|
|
||||||
|
'wh': {
|
||||||
|
sound: 'wh (as in whale)',
|
||||||
|
words: ['whale', 'what', 'wheat', 'wheel', 'when', 'where',
|
||||||
|
'which', 'while', 'whip', 'white', 'why'],
|
||||||
|
emoji: '🐋'
|
||||||
|
},
|
||||||
|
|
||||||
|
'ph': {
|
||||||
|
sound: 'f (as in phone)',
|
||||||
|
words: ['phone', 'photo', 'phrase', 'physical'],
|
||||||
|
emoji: '📞'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vowel Digraphs
|
||||||
|
```javascript
|
||||||
|
const vowelDigraphs = {
|
||||||
|
'ai': {
|
||||||
|
sound: 'long a (as in rain)',
|
||||||
|
words: ['brain', 'chain', 'gain', 'mail', 'main', 'nail', 'pain',
|
||||||
|
'rail', 'rain', 'sail', 'tail', 'train', 'wait'],
|
||||||
|
emoji: '🌧️'
|
||||||
|
},
|
||||||
|
|
||||||
|
'ay': {
|
||||||
|
sound: 'long a (as in play)',
|
||||||
|
words: ['day', 'hay', 'jay', 'lay', 'may', 'pay', 'play',
|
||||||
|
'ray', 'say', 'stay', 'tray', 'way'],
|
||||||
|
emoji: '🎮'
|
||||||
|
},
|
||||||
|
|
||||||
|
'ea': {
|
||||||
|
sound: 'long e (as in eat)',
|
||||||
|
words: ['beach', 'bean', 'clean', 'dream', 'eat', 'leaf', 'mean',
|
||||||
|
'meat', 'peas', 'read', 'seal', 'steam', 'teach', 'team'],
|
||||||
|
emoji: '🍃'
|
||||||
|
},
|
||||||
|
|
||||||
|
'ee': {
|
||||||
|
sound: 'long e (as in tree)',
|
||||||
|
words: ['bee', 'feed', 'feel', 'free', 'green', 'knee', 'need',
|
||||||
|
'seed', 'see', 'sleep', 'street', 'tree', 'three', 'wheel'],
|
||||||
|
emoji: '🌳'
|
||||||
|
},
|
||||||
|
|
||||||
|
'oa': {
|
||||||
|
sound: 'long o (as in boat)',
|
||||||
|
words: ['boat', 'coat', 'float', 'goat', 'load', 'road',
|
||||||
|
'soap', 'soak', 'toad', 'toast'],
|
||||||
|
emoji: '🚤'
|
||||||
|
},
|
||||||
|
|
||||||
|
'ow': {
|
||||||
|
sound: 'long o (as in snow)',
|
||||||
|
words: ['blow', 'bow', 'flow', 'glow', 'grow', 'know',
|
||||||
|
'low', 'mow', 'row', 'show', 'slow', 'snow'],
|
||||||
|
emoji: '❄️'
|
||||||
|
},
|
||||||
|
|
||||||
|
'oo': {
|
||||||
|
sound: 'oo (as in moon)',
|
||||||
|
words: ['boom', 'boo', 'cool', 'food', 'moon', 'noon',
|
||||||
|
'pool', 'room', 'soon', 'spoon', 'zoo'],
|
||||||
|
emoji: '🌙'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Silent Letters
|
||||||
|
|
||||||
|
### Silent E (Magic E)
|
||||||
|
```javascript
|
||||||
|
const magicE = {
|
||||||
|
'a_e': {
|
||||||
|
pattern: 'a + consonant + e',
|
||||||
|
sound: 'long a',
|
||||||
|
pairs: [
|
||||||
|
{ short: 'cap', long: 'cape' },
|
||||||
|
{ short: 'hat', long: 'hate' },
|
||||||
|
{ short: 'mad', long: 'made' },
|
||||||
|
{ short: 'tap', long: 'tape' },
|
||||||
|
{ short: 'can', long: 'cane' },
|
||||||
|
{ short: 'pan', long: 'pane' },
|
||||||
|
{ short: 'plan', long: 'plane' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
'i_e': {
|
||||||
|
pattern: 'i + consonant + e',
|
||||||
|
sound: 'long i',
|
||||||
|
pairs: [
|
||||||
|
{ short: 'bit', long: 'bite' },
|
||||||
|
{ short: 'kit', long: 'kite' },
|
||||||
|
{ short: 'pin', long: 'pine' },
|
||||||
|
{ short: 'rip', long: 'ripe' },
|
||||||
|
{ short: 'dim', long: 'dime' },
|
||||||
|
{ short: 'slid', long: 'slide' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
'o_e': {
|
||||||
|
pattern: 'o + consonant + e',
|
||||||
|
sound: 'long o',
|
||||||
|
pairs: [
|
||||||
|
{ short: 'hop', long: 'hope' },
|
||||||
|
{ short: 'not', long: 'note' },
|
||||||
|
{ short: 'rob', long: 'robe' },
|
||||||
|
{ short: 'rod', long: 'rode' },
|
||||||
|
{ short: 'con', long: 'cone' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
'u_e': {
|
||||||
|
pattern: 'u + consonant + e',
|
||||||
|
sound: 'long u',
|
||||||
|
pairs: [
|
||||||
|
{ short: 'cub', long: 'cube' },
|
||||||
|
{ short: 'cut', long: 'cute' },
|
||||||
|
{ short: 'tub', long: 'tube' },
|
||||||
|
{ short: 'us', long: 'use' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function createMagicEGame(vowel) {
|
||||||
|
const pattern = `${vowel}_e`;
|
||||||
|
const pairs = magicE[pattern].pairs;
|
||||||
|
|
||||||
|
return {
|
||||||
|
pattern: pattern,
|
||||||
|
explanation: `Adding 'e' makes the ${vowel} say its name!`,
|
||||||
|
|
||||||
|
showTransformation: function(pair) {
|
||||||
|
return {
|
||||||
|
before: `${pair.short} (short ${vowel})`,
|
||||||
|
after: `${pair.long} (long ${vowel})`,
|
||||||
|
animation: `${pair.short} → ${pair.long}`
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
quiz: function() {
|
||||||
|
const pair = pairs[Math.floor(Math.random() * pairs.length)];
|
||||||
|
return {
|
||||||
|
question: `Add magic 'e' to "${pair.short}"`,
|
||||||
|
answer: pair.long
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Other Silent Letters
|
||||||
|
```javascript
|
||||||
|
const silentLetters = {
|
||||||
|
'silent k': {
|
||||||
|
words: ['knee', 'knife', 'knight', 'knit', 'knock', 'know'],
|
||||||
|
rule: 'K is silent before N'
|
||||||
|
},
|
||||||
|
'silent w': {
|
||||||
|
words: ['wrap', 'wrist', 'write', 'wrong', 'wreck'],
|
||||||
|
rule: 'W is silent before R'
|
||||||
|
},
|
||||||
|
'silent b': {
|
||||||
|
words: ['bomb', 'climb', 'comb', 'crumb', 'lamb', 'thumb'],
|
||||||
|
rule: 'B is silent after M'
|
||||||
|
},
|
||||||
|
'silent h': {
|
||||||
|
words: ['honest', 'honor', 'hour'],
|
||||||
|
rule: 'H is silent in some words'
|
||||||
|
},
|
||||||
|
'silent gh': {
|
||||||
|
words: ['high', 'light', 'night', 'right', 'fight', 'sight'],
|
||||||
|
rule: 'GH is silent in -ight words'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Interactive Phonics Activities
|
||||||
|
|
||||||
|
### Sound Sorting Game
|
||||||
|
```javascript
|
||||||
|
function createSoundSortingGame(targetSound) {
|
||||||
|
const withSound = getWordsWithSound(targetSound);
|
||||||
|
const withoutSound = getRandomWords(5);
|
||||||
|
|
||||||
|
return {
|
||||||
|
targetSound: targetSound,
|
||||||
|
allWords: shuffle([...withSound, ...withoutSound]),
|
||||||
|
|
||||||
|
checkWord: function(word) {
|
||||||
|
return word.includes(targetSound);
|
||||||
|
},
|
||||||
|
|
||||||
|
feedback: function(word, userChoice) {
|
||||||
|
const correct = this.checkWord(word);
|
||||||
|
if (userChoice === correct) {
|
||||||
|
return { correct: true, message: `✓ Yes! "${word}" has "${targetSound}"` };
|
||||||
|
} else {
|
||||||
|
return { correct: false, message: `Try again! Listen for "${targetSound}"` };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Word Family Builder
|
||||||
|
```javascript
|
||||||
|
function buildWordFamily(ending) {
|
||||||
|
const consonants = 'bcdfghjklmnpqrstvwxyz'.split('');
|
||||||
|
|
||||||
|
const words = consonants
|
||||||
|
.map(c => c + ending)
|
||||||
|
.filter(word => isRealWord(word));
|
||||||
|
|
||||||
|
return {
|
||||||
|
family: `-${ending}`,
|
||||||
|
words: words,
|
||||||
|
pattern: `_${ending}`,
|
||||||
|
|
||||||
|
display: function() {
|
||||||
|
return words.map(word => ({
|
||||||
|
word: word,
|
||||||
|
highlight: ending,
|
||||||
|
display: `${word[0]} + ${ending} = ${word}`
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
createPractice: function() {
|
||||||
|
const target = words[Math.floor(Math.random() * words.length)];
|
||||||
|
const missing = target[0];
|
||||||
|
|
||||||
|
return {
|
||||||
|
question: `_${ending} = ${target}`,
|
||||||
|
answer: missing,
|
||||||
|
word: target
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pronunciation Guides
|
||||||
|
|
||||||
|
### Visual Phonics Symbols
|
||||||
|
```javascript
|
||||||
|
const phonicsSymbols = {
|
||||||
|
shortA: { symbol: 'ă', example: 'apple', mouth: '😮' },
|
||||||
|
longA: { symbol: 'ā', example: 'ape', mouth: '😁' },
|
||||||
|
shortE: { symbol: 'ĕ', example: 'egg', mouth: '😐' },
|
||||||
|
longE: { symbol: 'ē', example: 'eat', mouth: '😊' },
|
||||||
|
shortI: { symbol: 'ĭ', example: 'igloo', mouth: '🙂' },
|
||||||
|
longI: { symbol: 'ī', example: 'ice', mouth: '😲' },
|
||||||
|
shortO: { symbol: 'ŏ', example: 'octopus', mouth: '😯' },
|
||||||
|
longO: { symbol: 'ō', example: 'open', mouth: '😮' },
|
||||||
|
shortU: { symbol: 'ŭ', example: 'umbrella', mouth: '😐' },
|
||||||
|
longU: { symbol: 'ū', example: 'use', mouth: '😗' }
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Phonics patterns provide:
|
||||||
|
- Systematic sound-letter correspondence
|
||||||
|
- Progressive skill building
|
||||||
|
- Interactive practice activities
|
||||||
|
- Visual and auditory learning
|
||||||
|
- Game-based engagement
|
||||||
|
- Clear pronunciation guides
|
||||||
|
|
||||||
|
Use these patterns to create effective phonics playgrounds!
|
||||||
506
skills/reading-teacher/references/sight_words.md
Normal file
506
skills/reading-teacher/references/sight_words.md
Normal file
@@ -0,0 +1,506 @@
|
|||||||
|
# Sight Words Reference
|
||||||
|
|
||||||
|
Comprehensive sight word lists organized by level (Dolch and Fry lists).
|
||||||
|
|
||||||
|
## What Are Sight Words?
|
||||||
|
|
||||||
|
Sight words are high-frequency words that appear often in text. Many don't follow regular phonics patterns, so children learn to recognize them instantly "by sight."
|
||||||
|
|
||||||
|
**Why They Matter:**
|
||||||
|
- 50-75% of all text consists of these words
|
||||||
|
- Essential for reading fluency
|
||||||
|
- Enable focus on content, not decoding
|
||||||
|
- Build reading confidence
|
||||||
|
|
||||||
|
## Dolch Sight Words
|
||||||
|
|
||||||
|
### Pre-Kindergarten (40 words)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const dolchPreK = [
|
||||||
|
'a', 'and', 'away', 'big', 'blue', 'can', 'come', 'down',
|
||||||
|
'find', 'for', 'funny', 'go', 'help', 'here', 'I', 'in',
|
||||||
|
'is', 'it', 'jump', 'little', 'look', 'make', 'me', 'my',
|
||||||
|
'not', 'one', 'play', 'red', 'run', 'said', 'see', 'the',
|
||||||
|
'three', 'to', 'two', 'up', 'we', 'where', 'yellow', 'you'
|
||||||
|
];
|
||||||
|
|
||||||
|
const preKByCategory = {
|
||||||
|
colors: ['blue', 'red', 'yellow'],
|
||||||
|
numbers: ['one', 'two', 'three'],
|
||||||
|
actions: ['come', 'down', 'find', 'go', 'help', 'jump', 'look', 'make', 'play', 'run', 'see'],
|
||||||
|
descriptive: ['big', 'funny', 'little'],
|
||||||
|
pronouns: ['I', 'it', 'me', 'my', 'we', 'you'],
|
||||||
|
prepositions: ['in', 'to', 'up'],
|
||||||
|
other: ['a', 'and', 'away', 'can', 'for', 'here', 'is', 'not', 'said', 'the', 'where']
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kindergarten (52 words)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const dolchKindergarten = [
|
||||||
|
'all', 'am', 'are', 'at', 'ate', 'be', 'black', 'brown',
|
||||||
|
'but', 'came', 'did', 'do', 'eat', 'four', 'get', 'good',
|
||||||
|
'have', 'he', 'into', 'like', 'must', 'new', 'no', 'now',
|
||||||
|
'on', 'our', 'out', 'please', 'pretty', 'ran', 'ride', 'saw',
|
||||||
|
'say', 'she', 'so', 'soon', 'that', 'there', 'they', 'this',
|
||||||
|
'too', 'under', 'want', 'was', 'well', 'went', 'what', 'white',
|
||||||
|
'who', 'will', 'with', 'yes'
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
### First Grade (41 words)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const dolchFirstGrade = [
|
||||||
|
'after', 'again', 'an', 'any', 'as', 'ask', 'by', 'could',
|
||||||
|
'every', 'fly', 'from', 'give', 'giving', 'had', 'has', 'her',
|
||||||
|
'him', 'his', 'how', 'just', 'know', 'let', 'live', 'may',
|
||||||
|
'of', 'old', 'once', 'open', 'over', 'put', 'round', 'some',
|
||||||
|
'stop', 'take', 'thank', 'them', 'then', 'think', 'walk', 'were',
|
||||||
|
'when'
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
### Second Grade (46 words)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const dolchSecondGrade = [
|
||||||
|
'always', 'around', 'because', 'been', 'before', 'best', 'both',
|
||||||
|
'buy', 'call', 'cold', 'does', 'don\'t', 'fast', 'first', 'five',
|
||||||
|
'found', 'gave', 'goes', 'green', 'its', 'made', 'many', 'off',
|
||||||
|
'or', 'pull', 'read', 'right', 'sing', 'sit', 'sleep', 'tell',
|
||||||
|
'their', 'these', 'those', 'upon', 'us', 'use', 'very', 'wash',
|
||||||
|
'which', 'why', 'wish', 'work', 'would', 'write', 'your'
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
### Third Grade (41 words)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const dolchThirdGrade = [
|
||||||
|
'about', 'better', 'bring', 'carry', 'clean', 'cut', 'done',
|
||||||
|
'draw', 'drink', 'eight', 'fall', 'far', 'full', 'got', 'grow',
|
||||||
|
'hold', 'hot', 'hurt', 'if', 'keep', 'kind', 'laugh', 'light',
|
||||||
|
'long', 'much', 'myself', 'never', 'only', 'own', 'pick', 'seven',
|
||||||
|
'shall', 'show', 'six', 'small', 'start', 'ten', 'today', 'together',
|
||||||
|
'try', 'warm'
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dolch Nouns (95 words)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const dolchNouns = [
|
||||||
|
'apple', 'baby', 'back', 'ball', 'bear', 'bed', 'bell', 'bird',
|
||||||
|
'birthday', 'boat', 'box', 'boy', 'bread', 'brother', 'cake', 'car',
|
||||||
|
'cat', 'chair', 'chicken', 'children', 'Christmas', 'coat', 'corn',
|
||||||
|
'cow', 'day', 'dog', 'doll', 'door', 'duck', 'egg', 'eye', 'farm',
|
||||||
|
'farmer', 'father', 'feet', 'fire', 'fish', 'floor', 'flower', 'game',
|
||||||
|
'garden', 'girl', 'goodbye', 'grass', 'ground', 'hand', 'head', 'hill',
|
||||||
|
'home', 'horse', 'house', 'kitty', 'leg', 'letter', 'man', 'men',
|
||||||
|
'milk', 'money', 'morning', 'mother', 'name', 'nest', 'night', 'paper',
|
||||||
|
'party', 'picture', 'pig', 'rabbit', 'rain', 'ring', 'robin', 'santa',
|
||||||
|
'school', 'seed', 'sheep', 'shoe', 'sister', 'snow', 'song', 'squirrel',
|
||||||
|
'stick', 'street', 'sun', 'table', 'thing', 'time', 'top', 'toy',
|
||||||
|
'tree', 'watch', 'water', 'way', 'wind', 'window', 'wood'
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
## Fry Sight Words
|
||||||
|
|
||||||
|
### First 100 (Most Common)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const fryFirst100 = {
|
||||||
|
'1-25': [
|
||||||
|
'the', 'of', 'and', 'a', 'to', 'in', 'is', 'you', 'that', 'it',
|
||||||
|
'he', 'was', 'for', 'on', 'are', 'as', 'with', 'his', 'they', 'I',
|
||||||
|
'at', 'be', 'this', 'have', 'from'
|
||||||
|
],
|
||||||
|
|
||||||
|
'26-50': [
|
||||||
|
'or', 'one', 'had', 'by', 'words', 'but', 'not', 'what', 'all', 'were',
|
||||||
|
'we', 'when', 'your', 'can', 'said', 'there', 'use', 'an', 'each', 'which',
|
||||||
|
'she', 'do', 'how', 'their', 'if'
|
||||||
|
],
|
||||||
|
|
||||||
|
'51-75': [
|
||||||
|
'will', 'up', 'other', 'about', 'out', 'many', 'then', 'them', 'these', 'so',
|
||||||
|
'some', 'her', 'would', 'make', 'like', 'him', 'into', 'time', 'has', 'look',
|
||||||
|
'two', 'more', 'write', 'go', 'see'
|
||||||
|
],
|
||||||
|
|
||||||
|
'76-100': [
|
||||||
|
'number', 'no', 'way', 'could', 'people', 'my', 'than', 'first', 'water', 'been',
|
||||||
|
'called', 'who', 'am', 'its', 'now', 'find', 'long', 'down', 'day', 'did',
|
||||||
|
'get', 'come', 'made', 'may', 'part'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Second 100
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const frySecond100 = {
|
||||||
|
'101-125': [
|
||||||
|
'over', 'new', 'sound', 'take', 'only', 'little', 'work', 'know', 'place', 'years',
|
||||||
|
'live', 'me', 'back', 'give', 'most', 'very', 'after', 'things', 'our', 'just',
|
||||||
|
'name', 'good', 'sentence', 'man', 'think'
|
||||||
|
],
|
||||||
|
|
||||||
|
'126-150': [
|
||||||
|
'say', 'great', 'where', 'help', 'through', 'much', 'before', 'line', 'right', 'too',
|
||||||
|
'means', 'old', 'any', 'same', 'tell', 'boy', 'follow', 'came', 'want', 'show',
|
||||||
|
'also', 'around', 'form', 'three', 'small'
|
||||||
|
],
|
||||||
|
|
||||||
|
'151-175': [
|
||||||
|
'set', 'put', 'end', 'does', 'another', 'well', 'large', 'must', 'big', 'even',
|
||||||
|
'such', 'because', 'turn', 'here', 'why', 'asked', 'went', 'men', 'read', 'need',
|
||||||
|
'land', 'different', 'home', 'us', 'move'
|
||||||
|
],
|
||||||
|
|
||||||
|
'176-200': [
|
||||||
|
'try', 'kind', 'hand', 'picture', 'again', 'change', 'off', 'play', 'spell', 'air',
|
||||||
|
'away', 'animal', 'house', 'point', 'page', 'letter', 'mother', 'answer', 'found', 'study',
|
||||||
|
'still', 'learn', 'should', 'America', 'world'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Interactive Practice Activities
|
||||||
|
|
||||||
|
### Sight Word Flash Cards
|
||||||
|
```javascript
|
||||||
|
function createFlashCards(wordList, timePerCard = 3000) {
|
||||||
|
let currentIndex = 0;
|
||||||
|
let correct = 0;
|
||||||
|
let total = 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
words: shuffle(wordList),
|
||||||
|
currentWord: wordList[0],
|
||||||
|
|
||||||
|
next: function() {
|
||||||
|
currentIndex = (currentIndex + 1) % this.words.length;
|
||||||
|
this.currentWord = this.words[currentIndex];
|
||||||
|
return this.currentWord;
|
||||||
|
},
|
||||||
|
|
||||||
|
checkAnswer: function(userAnswer) {
|
||||||
|
total++;
|
||||||
|
const isCorrect = userAnswer.toLowerCase() === this.currentWord.toLowerCase();
|
||||||
|
if (isCorrect) correct++;
|
||||||
|
|
||||||
|
return {
|
||||||
|
correct: isCorrect,
|
||||||
|
word: this.currentWord,
|
||||||
|
score: `${correct}/${total}`,
|
||||||
|
percentage: Math.round((correct / total) * 100)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getStats: function() {
|
||||||
|
return {
|
||||||
|
totalSeen: total,
|
||||||
|
totalCorrect: correct,
|
||||||
|
accuracy: total > 0 ? Math.round((correct / total) * 100) : 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Word Search Game
|
||||||
|
```javascript
|
||||||
|
function createWordSearch(words, size = 10) {
|
||||||
|
const grid = Array(size).fill().map(() => Array(size).fill(''));
|
||||||
|
const placed = [];
|
||||||
|
|
||||||
|
// Place words in grid
|
||||||
|
words.forEach(word => {
|
||||||
|
const direction = Math.random() < 0.5 ? 'horizontal' : 'vertical';
|
||||||
|
const position = placeWord(grid, word, direction);
|
||||||
|
if (position) {
|
||||||
|
placed.push({ word, ...position });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fill empty spaces with random letters
|
||||||
|
for (let i = 0; i < size; i++) {
|
||||||
|
for (let j = 0; j < size; j++) {
|
||||||
|
if (!grid[i][j]) {
|
||||||
|
grid[i][j] = String.fromCharCode(97 + Math.floor(Math.random() * 26));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
grid: grid,
|
||||||
|
words: words,
|
||||||
|
found: [],
|
||||||
|
|
||||||
|
checkWord: function(selectedCells) {
|
||||||
|
const word = selectedCells.map(cell => grid[cell.row][cell.col]).join('');
|
||||||
|
if (words.includes(word) && !this.found.includes(word)) {
|
||||||
|
this.found.push(word);
|
||||||
|
return { found: true, word: word };
|
||||||
|
}
|
||||||
|
return { found: false };
|
||||||
|
},
|
||||||
|
|
||||||
|
isComplete: function() {
|
||||||
|
return this.found.length === words.length;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sentence Building
|
||||||
|
```javascript
|
||||||
|
function createSentenceBuilder(sightWords) {
|
||||||
|
const sentenceTemplates = [
|
||||||
|
['I', 'can', 'see', 'the', '{noun}'],
|
||||||
|
['The', '{noun}', 'is', '{color}'],
|
||||||
|
['We', 'like', 'to', '{action}'],
|
||||||
|
['{name}', 'said', '{quote}'],
|
||||||
|
['Look', 'at', 'the', '{adjective}', '{noun}']
|
||||||
|
];
|
||||||
|
|
||||||
|
const fillWords = {
|
||||||
|
noun: ['cat', 'dog', 'ball', 'sun', 'tree'],
|
||||||
|
color: ['red', 'blue', 'green', 'yellow'],
|
||||||
|
action: ['play', 'run', 'jump', 'read'],
|
||||||
|
name: ['Tom', 'Sue', 'Mom', 'Dad'],
|
||||||
|
quote: ['"hello"', '"stop"', '"help"'],
|
||||||
|
adjective: ['big', 'little', 'funny', 'pretty']
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
generate: function() {
|
||||||
|
const template = sentenceTemplates[Math.floor(Math.random() * sentenceTemplates.length)];
|
||||||
|
const sentence = template.map(word => {
|
||||||
|
if (word.startsWith('{')) {
|
||||||
|
const type = word.slice(1, -1);
|
||||||
|
return fillWords[type][Math.floor(Math.random() * fillWords[type].length)];
|
||||||
|
}
|
||||||
|
return word;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
sentence: sentence.join(' '),
|
||||||
|
words: sentence,
|
||||||
|
sightWords: sentence.filter(w => sightWords.includes(w.toLowerCase()))
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
scramble: function() {
|
||||||
|
const { sentence, words } = this.generate();
|
||||||
|
return {
|
||||||
|
correctOrder: words,
|
||||||
|
scrambled: shuffle([...words]),
|
||||||
|
answer: sentence
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Memory Match Game
|
||||||
|
```javascript
|
||||||
|
function createMemoryMatch(words) {
|
||||||
|
// Create pairs: word and image/definition
|
||||||
|
const pairs = words.map(word => [
|
||||||
|
{ type: 'word', content: word, id: `${word}-word` },
|
||||||
|
{ type: 'image', content: getWordImage(word), id: `${word}-image` }
|
||||||
|
]).flat();
|
||||||
|
|
||||||
|
return {
|
||||||
|
cards: shuffle(pairs),
|
||||||
|
flipped: [],
|
||||||
|
matched: [],
|
||||||
|
|
||||||
|
flip: function(cardId) {
|
||||||
|
if (this.flipped.length < 2 && !this.flipped.includes(cardId)) {
|
||||||
|
this.flipped.push(cardId);
|
||||||
|
|
||||||
|
if (this.flipped.length === 2) {
|
||||||
|
return this.checkMatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { matched: false };
|
||||||
|
},
|
||||||
|
|
||||||
|
checkMatch: function() {
|
||||||
|
const [id1, id2] = this.flipped;
|
||||||
|
const card1 = this.cards.find(c => c.id === id1);
|
||||||
|
const card2 = this.cards.find(c => c.id === id2);
|
||||||
|
|
||||||
|
const word1 = id1.split('-')[0];
|
||||||
|
const word2 = id2.split('-')[0];
|
||||||
|
|
||||||
|
if (word1 === word2) {
|
||||||
|
this.matched.push(id1, id2);
|
||||||
|
this.flipped = [];
|
||||||
|
return { matched: true, word: word1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset after delay
|
||||||
|
setTimeout(() => { this.flipped = []; }, 1000);
|
||||||
|
return { matched: false };
|
||||||
|
},
|
||||||
|
|
||||||
|
isComplete: function() {
|
||||||
|
return this.matched.length === this.cards.length;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Typing Practice
|
||||||
|
```javascript
|
||||||
|
function createTypingPractice(words) {
|
||||||
|
let currentWordIndex = 0;
|
||||||
|
let startTime = null;
|
||||||
|
let stats = {
|
||||||
|
correct: 0,
|
||||||
|
total: 0,
|
||||||
|
wpm: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
currentWord: words[0],
|
||||||
|
|
||||||
|
start: function() {
|
||||||
|
startTime = Date.now();
|
||||||
|
},
|
||||||
|
|
||||||
|
check: function(typed) {
|
||||||
|
stats.total++;
|
||||||
|
const correct = typed === this.currentWord;
|
||||||
|
|
||||||
|
if (correct) {
|
||||||
|
stats.correct++;
|
||||||
|
currentWordIndex = (currentWordIndex + 1) % words.length;
|
||||||
|
this.currentWord = words[currentWordIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate WPM
|
||||||
|
const elapsed = (Date.now() - startTime) / 1000 / 60; // minutes
|
||||||
|
stats.wpm = Math.round(stats.correct / elapsed);
|
||||||
|
|
||||||
|
return {
|
||||||
|
correct: correct,
|
||||||
|
accuracy: Math.round((stats.correct / stats.total) * 100),
|
||||||
|
wpm: stats.wpm
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getStats: function() {
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Word List Management
|
||||||
|
|
||||||
|
### Adaptive Practice
|
||||||
|
```javascript
|
||||||
|
class AdaptiveSightWords {
|
||||||
|
constructor(allWords) {
|
||||||
|
this.allWords = allWords;
|
||||||
|
this.mastered = new Set();
|
||||||
|
this.practicing = new Set();
|
||||||
|
this.new = new Set(allWords);
|
||||||
|
}
|
||||||
|
|
||||||
|
getNextWord() {
|
||||||
|
// 70% practicing, 20% new, 10% review mastered
|
||||||
|
const rand = Math.random();
|
||||||
|
|
||||||
|
if (rand < 0.7 && this.practicing.size > 0) {
|
||||||
|
return this.selectFrom(this.practicing);
|
||||||
|
} else if (rand < 0.9 && this.new.size > 0) {
|
||||||
|
const word = this.selectFrom(this.new);
|
||||||
|
this.new.delete(word);
|
||||||
|
this.practicing.add(word);
|
||||||
|
return word;
|
||||||
|
} else if (this.mastered.size > 0) {
|
||||||
|
return this.selectFrom(this.mastered);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.selectFrom(this.allWords);
|
||||||
|
}
|
||||||
|
|
||||||
|
recordResult(word, correct) {
|
||||||
|
if (correct) {
|
||||||
|
// Move to mastered after 3 correct in a row
|
||||||
|
if (!this.mastered.has(word)) {
|
||||||
|
this.practicing.delete(word);
|
||||||
|
this.mastered.add(word);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Move back to practicing
|
||||||
|
this.mastered.delete(word);
|
||||||
|
this.practicing.add(word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectFrom(set) {
|
||||||
|
const arr = Array.from(set);
|
||||||
|
return arr[Math.floor(Math.random() * arr.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
getProgress() {
|
||||||
|
return {
|
||||||
|
total: this.allWords.length,
|
||||||
|
mastered: this.mastered.size,
|
||||||
|
practicing: this.practicing.size,
|
||||||
|
new: this.new.size,
|
||||||
|
percentage: Math.round((this.mastered.size / this.allWords.length) * 100)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Visual Design Guidelines
|
||||||
|
|
||||||
|
### Display Requirements
|
||||||
|
```javascript
|
||||||
|
const displaySettings = {
|
||||||
|
fontSize: {
|
||||||
|
preK: '48px',
|
||||||
|
kindergarten: '36px',
|
||||||
|
grade1: '32px',
|
||||||
|
grade2: '28px',
|
||||||
|
grade3: '24px'
|
||||||
|
},
|
||||||
|
|
||||||
|
colors: {
|
||||||
|
new: '#FF6B9D', // Pink - new words
|
||||||
|
practicing: '#FFE66D', // Yellow - practicing
|
||||||
|
mastered: '#4ECDC4' // Teal - mastered
|
||||||
|
},
|
||||||
|
|
||||||
|
timing: {
|
||||||
|
flashDuration: 3000, // 3 seconds per word
|
||||||
|
typingTimeout: 5000, // 5 seconds to type
|
||||||
|
memoryFlipDelay: 1000 // 1 second before flip back
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Sight word lists provide:
|
||||||
|
- Comprehensive Dolch and Fry word lists
|
||||||
|
- Grade-level organization
|
||||||
|
- Multiple practice modalities
|
||||||
|
- Adaptive learning systems
|
||||||
|
- Progress tracking
|
||||||
|
- Game-based activities
|
||||||
|
|
||||||
|
Use these lists to create effective sight word practice!
|
||||||
304
skills/reading-teacher/scripts/generate_game.sh
Executable file
304
skills/reading-teacher/scripts/generate_game.sh
Executable file
@@ -0,0 +1,304 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Reading Teacher - Game Generator
|
||||||
|
# Creates gamified reading challenges
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
print_success() { echo -e "${GREEN}✓ $1${NC}"; }
|
||||||
|
print_info() { echo -e "${BLUE}ℹ $1${NC}"; }
|
||||||
|
|
||||||
|
prompt_select() {
|
||||||
|
local prompt="$1"
|
||||||
|
local var_name="$2"
|
||||||
|
shift 2
|
||||||
|
local options=("$@")
|
||||||
|
echo -e "${BLUE}${prompt}${NC}"
|
||||||
|
PS3="Select (1-${#options[@]}): "
|
||||||
|
select opt in "${options[@]}"; do
|
||||||
|
if [ -n "$opt" ]; then
|
||||||
|
eval "$var_name='$opt'"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "╔════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Reading Teacher - Game Generator 🎮 ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_info "Step 1/3: Game Type"
|
||||||
|
prompt_select "What type of game?" GAME_TYPE \
|
||||||
|
"Sight Word Speed Challenge" \
|
||||||
|
"Phonics Matching Game" \
|
||||||
|
"Word Building Adventure" \
|
||||||
|
"Reading Comprehension Quiz"
|
||||||
|
|
||||||
|
print_info "Step 2/3: Difficulty"
|
||||||
|
prompt_select "Difficulty level?" DIFFICULTY \
|
||||||
|
"Easy (Kindergarten)" \
|
||||||
|
"Medium (1st-2nd Grade)" \
|
||||||
|
"Hard (3rd+ Grade)"
|
||||||
|
|
||||||
|
print_info "Step 3/3: Output"
|
||||||
|
read -p "Game name (e.g., sight-word-game.html): " OUTPUT_FILE
|
||||||
|
OUTPUT_DIR="./reading-games"
|
||||||
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
OUTPUT_PATH="$OUTPUT_DIR/$OUTPUT_FILE"
|
||||||
|
|
||||||
|
print_info "🎮 Generating your reading game..."
|
||||||
|
|
||||||
|
cat > "$OUTPUT_PATH" << 'EOF'
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>📚 Reading Game Challenge</title>
|
||||||
|
<style>
|
||||||
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
|
body {
|
||||||
|
font-family: 'Arial Black', sans-serif;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.game-container {
|
||||||
|
background: rgba(255,255,255,0.1);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
padding: 40px;
|
||||||
|
border-radius: 30px;
|
||||||
|
box-shadow: 0 20px 60px rgba(0,0,0,0.5);
|
||||||
|
max-width: 700px;
|
||||||
|
width: 90%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
h1 { font-size: 3em; margin-bottom: 20px; }
|
||||||
|
.stats {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
margin: 30px 0;
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
.stat-box {
|
||||||
|
background: rgba(255,255,255,0.2);
|
||||||
|
padding: 15px 25px;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
.word-display {
|
||||||
|
font-size: 5em;
|
||||||
|
margin: 40px 0;
|
||||||
|
font-weight: bold;
|
||||||
|
min-height: 120px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.answer-buttons {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 20px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.btn {
|
||||||
|
background: rgba(255,255,255,0.3);
|
||||||
|
border: 3px solid white;
|
||||||
|
padding: 30px;
|
||||||
|
font-size: 2em;
|
||||||
|
border-radius: 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
font-weight: bold;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.btn:hover {
|
||||||
|
background: rgba(255,255,255,0.5);
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
.timer {
|
||||||
|
font-size: 3em;
|
||||||
|
color: #FFD700;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.feedback {
|
||||||
|
font-size: 2em;
|
||||||
|
min-height: 60px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.correct { color: #4CAF50; }
|
||||||
|
.incorrect { color: #FF6347; }
|
||||||
|
.game-over {
|
||||||
|
display: none;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
.final-score { font-size: 5em; color: #FFD700; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="game-container">
|
||||||
|
<h1>🎯 Sight Word Challenge</h1>
|
||||||
|
|
||||||
|
<div class="stats">
|
||||||
|
<div class="stat-box">
|
||||||
|
<div>Score</div>
|
||||||
|
<div id="score">0</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-box">
|
||||||
|
<div>Streak</div>
|
||||||
|
<div id="streak">0</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="game-area">
|
||||||
|
<div class="timer" id="timer">60</div>
|
||||||
|
<div class="word-display" id="word">the</div>
|
||||||
|
<div class="answer-buttons">
|
||||||
|
<button class="btn" onclick="checkAnswer(true)">I Know It! ✓</button>
|
||||||
|
<button class="btn" onclick="checkAnswer(false)">Skip ➡️</button>
|
||||||
|
</div>
|
||||||
|
<div class="feedback" id="feedback"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="game-over" id="gameOver">
|
||||||
|
<h2>🎉 Time's Up!</h2>
|
||||||
|
<div class="final-score" id="finalScore">0</div>
|
||||||
|
<p id="rating"></p>
|
||||||
|
<button class="btn" onclick="restartGame()" style="grid-column: span 2;">Play Again 🔄</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const sightWords = [
|
||||||
|
'the', 'of', 'and', 'a', 'to', 'in', 'is', 'you', 'that', 'it',
|
||||||
|
'he', 'was', 'for', 'on', 'are', 'as', 'with', 'his', 'they', 'I',
|
||||||
|
'at', 'be', 'this', 'have', 'from', 'or', 'one', 'had', 'by', 'words',
|
||||||
|
'but', 'not', 'what', 'all', 'were', 'we', 'when', 'your', 'can', 'said',
|
||||||
|
'there', 'use', 'an', 'each', 'which', 'she', 'do', 'how', 'their', 'if'
|
||||||
|
];
|
||||||
|
|
||||||
|
let score = 0;
|
||||||
|
let streak = 0;
|
||||||
|
let timeRemaining = 60;
|
||||||
|
let currentWord = '';
|
||||||
|
let gameActive = true;
|
||||||
|
let timerInterval;
|
||||||
|
|
||||||
|
function newWord() {
|
||||||
|
currentWord = sightWords[Math.floor(Math.random() * sightWords.length)];
|
||||||
|
document.getElementById('word').textContent = currentWord;
|
||||||
|
document.getElementById('feedback').textContent = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkAnswer(knows) {
|
||||||
|
if (!gameActive) return;
|
||||||
|
|
||||||
|
const feedback = document.getElementById('feedback');
|
||||||
|
|
||||||
|
if (knows) {
|
||||||
|
streak++;
|
||||||
|
const points = 10 * (1 + streak * 0.1);
|
||||||
|
score += Math.floor(points);
|
||||||
|
|
||||||
|
feedback.innerHTML = `<span class="correct">✓ Great! +${Math.floor(points)}</span>`;
|
||||||
|
|
||||||
|
if (streak % 5 === 0) {
|
||||||
|
feedback.innerHTML += ` <span style="color: #FFD700;">🔥 ${streak} Streak!</span>`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
streak = 0;
|
||||||
|
feedback.innerHTML = `<span class="incorrect">Keep practicing "${currentWord}"!</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateStats();
|
||||||
|
setTimeout(newWord, 800);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStats() {
|
||||||
|
document.getElementById('score').textContent = score;
|
||||||
|
document.getElementById('streak').textContent = streak;
|
||||||
|
}
|
||||||
|
|
||||||
|
function startTimer() {
|
||||||
|
timerInterval = setInterval(() => {
|
||||||
|
timeRemaining--;
|
||||||
|
document.getElementById('timer').textContent = timeRemaining;
|
||||||
|
|
||||||
|
if (timeRemaining <= 10) {
|
||||||
|
document.getElementById('timer').style.color = '#FF6347';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeRemaining <= 0) {
|
||||||
|
endGame();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function endGame() {
|
||||||
|
gameActive = false;
|
||||||
|
clearInterval(timerInterval);
|
||||||
|
|
||||||
|
document.getElementById('game-area').style.display = 'none';
|
||||||
|
document.getElementById('gameOver').style.display = 'flex';
|
||||||
|
document.getElementById('finalScore').textContent = score;
|
||||||
|
|
||||||
|
let rating;
|
||||||
|
if (score >= 300) rating = '🏆 Reading Superstar!';
|
||||||
|
else if (score >= 200) rating = '⭐ Excellent Reader!';
|
||||||
|
else if (score >= 100) rating = '👍 Great Job!';
|
||||||
|
else rating = '💪 Keep Practicing!';
|
||||||
|
|
||||||
|
document.getElementById('rating').textContent = rating;
|
||||||
|
}
|
||||||
|
|
||||||
|
function restartGame() {
|
||||||
|
score = 0;
|
||||||
|
streak = 0;
|
||||||
|
timeRemaining = 60;
|
||||||
|
gameActive = true;
|
||||||
|
|
||||||
|
document.getElementById('game-area').style.display = 'block';
|
||||||
|
document.getElementById('gameOver').style.display = 'none';
|
||||||
|
document.getElementById('timer').style.color = '#FFD700';
|
||||||
|
|
||||||
|
updateStats();
|
||||||
|
newWord();
|
||||||
|
startTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard controls
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === ' ' || e.key === 'Enter') checkAnswer(true);
|
||||||
|
if (e.key === 'ArrowRight') checkAnswer(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
newWord();
|
||||||
|
startTimer();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_success "Game created: $OUTPUT_PATH"
|
||||||
|
echo ""
|
||||||
|
print_info "🎮 To play:"
|
||||||
|
echo " open $OUTPUT_PATH"
|
||||||
|
echo ""
|
||||||
|
print_info "Game features:"
|
||||||
|
echo " ✓ 60-second challenge"
|
||||||
|
echo " ✓ Sight word practice"
|
||||||
|
echo " ✓ Streak bonuses"
|
||||||
|
echo " ✓ Keyboard controls (Space/Enter = Know, Arrow = Skip)"
|
||||||
|
echo " ✓ Progress tracking"
|
||||||
|
echo ""
|
||||||
302
skills/reading-teacher/scripts/generate_playground.sh
Executable file
302
skills/reading-teacher/scripts/generate_playground.sh
Executable file
@@ -0,0 +1,302 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Reading Teacher - Interactive Playground Generator
|
||||||
|
# Creates instant, interactive reading learning experiences
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
PURPLE='\033[0;35m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
print_success() { echo -e "${GREEN}✓ $1${NC}"; }
|
||||||
|
print_info() { echo -e "${BLUE}ℹ $1${NC}"; }
|
||||||
|
|
||||||
|
prompt_select() {
|
||||||
|
local prompt="$1"
|
||||||
|
local var_name="$2"
|
||||||
|
shift 2
|
||||||
|
local options=("$@")
|
||||||
|
echo -e "${BLUE}${prompt}${NC}"
|
||||||
|
PS3="Select (1-${#options[@]}): "
|
||||||
|
select opt in "${options[@]}"; do
|
||||||
|
if [ -n "$opt" ]; then
|
||||||
|
eval "$var_name='$opt'"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "╔════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Reading Teacher - Playground Generator 📚 ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_info "Step 1/4: Age Group"
|
||||||
|
prompt_select "Choose age group:" AGE_GROUP \
|
||||||
|
"Toddler (Ages 1-3)" \
|
||||||
|
"Preschool (Ages 3-5)" \
|
||||||
|
"Early Elementary (Ages 5-7)" \
|
||||||
|
"Elementary (Ages 7-10)"
|
||||||
|
|
||||||
|
print_info "Step 2/4: Reading Skill"
|
||||||
|
case $AGE_GROUP in
|
||||||
|
"Toddler (Ages 1-3)")
|
||||||
|
prompt_select "Which skill?" SKILL \
|
||||||
|
"Letter Recognition" \
|
||||||
|
"Letter Sounds" \
|
||||||
|
"Alphabet Song"
|
||||||
|
;;
|
||||||
|
"Preschool (Ages 3-5)")
|
||||||
|
prompt_select "Which skill?" SKILL \
|
||||||
|
"Phonics - CVC Words" \
|
||||||
|
"Letter Matching" \
|
||||||
|
"Rhyming Words"
|
||||||
|
;;
|
||||||
|
"Early Elementary (Ages 5-7)")
|
||||||
|
prompt_select "Which skill?" SKILL \
|
||||||
|
"Sight Words" \
|
||||||
|
"Word Families" \
|
||||||
|
"Simple Sentences"
|
||||||
|
;;
|
||||||
|
"Elementary (Ages 7-10)")
|
||||||
|
prompt_select "Which skill?" SKILL \
|
||||||
|
"Reading Comprehension" \
|
||||||
|
"Vocabulary Building" \
|
||||||
|
"Story Sequencing"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
print_info "Step 3/4: Activity Type"
|
||||||
|
prompt_select "Type of activity?" ACTIVITY_TYPE \
|
||||||
|
"Interactive Explorer" \
|
||||||
|
"Practice Game" \
|
||||||
|
"Timed Challenge"
|
||||||
|
|
||||||
|
print_info "Step 4/4: Output"
|
||||||
|
read -p "Playground name (e.g., letter-land.html): " OUTPUT_FILE
|
||||||
|
OUTPUT_DIR="./reading-playgrounds"
|
||||||
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
OUTPUT_PATH="$OUTPUT_DIR/$OUTPUT_FILE"
|
||||||
|
|
||||||
|
print_info "📚 Generating your reading playground..."
|
||||||
|
|
||||||
|
# Generate based on skill (showing letter recognition as example)
|
||||||
|
cat > "$OUTPUT_PATH" << 'EOF'
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>📚 Reading Playground</title>
|
||||||
|
<style>
|
||||||
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
|
body {
|
||||||
|
font-family: 'Comic Sans MS', 'Chalkboard SE', cursive, sans-serif;
|
||||||
|
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 3em;
|
||||||
|
color: #FF6B9D;
|
||||||
|
text-shadow: 3px 3px 6px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.stars {
|
||||||
|
font-size: 2em;
|
||||||
|
background: rgba(255,255,255,0.8);
|
||||||
|
padding: 10px 30px;
|
||||||
|
border-radius: 30px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.letter-display {
|
||||||
|
background: white;
|
||||||
|
width: 350px;
|
||||||
|
height: 350px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 12em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #667eea;
|
||||||
|
box-shadow: 0 20px 60px rgba(0,0,0,0.2);
|
||||||
|
margin: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.letter-display:hover { transform: scale(1.05); }
|
||||||
|
.letter-display:active { transform: scale(0.95); }
|
||||||
|
.controls {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
margin: 20px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.btn {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 20px 40px;
|
||||||
|
font-size: 1.5em;
|
||||||
|
border-radius: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
font-weight: bold;
|
||||||
|
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
.btn:hover { transform: translateY(-5px); }
|
||||||
|
.instruction {
|
||||||
|
font-size: 1.8em;
|
||||||
|
color: #333;
|
||||||
|
margin: 20px;
|
||||||
|
text-align: center;
|
||||||
|
background: rgba(255,255,255,0.9);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 15px;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
.celebration {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) scale(0);
|
||||||
|
font-size: 8em;
|
||||||
|
animation: celebrate 1s ease forwards;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
@keyframes celebrate {
|
||||||
|
0% { transform: translate(-50%, -50%) scale(0) rotate(0); }
|
||||||
|
50% { transform: translate(-50%, -50%) scale(1.3) rotate(180deg); }
|
||||||
|
100% { transform: translate(-50%, -50%) scale(1) rotate(360deg); opacity: 0; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="header">
|
||||||
|
<h1>🌈 Letter Land Adventure!</h1>
|
||||||
|
<div class="stars">Stars: <span id="stars">0</span> ⭐</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="letter-display" id="letterDisplay" onclick="clickLetter()">A</div>
|
||||||
|
|
||||||
|
<div class="instruction" id="instruction">
|
||||||
|
Click the letter to hear its name and sound!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<button class="btn" onclick="nextLetter()">Next Letter ➡️</button>
|
||||||
|
<button class="btn" onclick="randomLetter()">Random 🎲</button>
|
||||||
|
<button class="btn" onclick="playGame()">Practice Game 🎮</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
|
||||||
|
const letterWords = {
|
||||||
|
'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephant',
|
||||||
|
'F': 'Fish', 'G': 'Goat', 'H': 'Hat', 'I': 'Ice Cream', 'J': 'Juice',
|
||||||
|
'K': 'Kite', 'L': 'Lion', 'M': 'Moon', 'N': 'Nest', 'O': 'Orange',
|
||||||
|
'P': 'Pig', 'Q': 'Queen', 'R': 'Rabbit', 'S': 'Sun', 'T': 'Tiger',
|
||||||
|
'U': 'Umbrella', 'V': 'Violin', 'W': 'Whale', 'X': 'X-ray', 'Y': 'Yellow', 'Z': 'Zebra'
|
||||||
|
};
|
||||||
|
const colors = ['#FF6B9D', '#4ECDC4', '#FFE66D', '#A8E6CF', '#FF8B94'];
|
||||||
|
|
||||||
|
let currentIndex = 0;
|
||||||
|
let stars = 0;
|
||||||
|
|
||||||
|
function updateDisplay(letter) {
|
||||||
|
const display = document.getElementById('letterDisplay');
|
||||||
|
display.textContent = letter;
|
||||||
|
display.style.color = colors[Math.floor(Math.random() * colors.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickLetter() {
|
||||||
|
const letter = document.getElementById('letterDisplay').textContent;
|
||||||
|
|
||||||
|
stars++;
|
||||||
|
document.getElementById('stars').textContent = stars;
|
||||||
|
|
||||||
|
celebrate('🎉');
|
||||||
|
|
||||||
|
// Update instruction
|
||||||
|
document.getElementById('instruction').textContent =
|
||||||
|
`${letter}! ${letter} is for ${letterWords[letter]}!`;
|
||||||
|
|
||||||
|
// Speak letter (if browser supports)
|
||||||
|
if ('speechSynthesis' in window) {
|
||||||
|
const utterance = new SpeechSynthesisUtterance(
|
||||||
|
`${letter}. ${letter} is for ${letterWords[letter]}`
|
||||||
|
);
|
||||||
|
utterance.rate = 0.8;
|
||||||
|
utterance.pitch = 1.3;
|
||||||
|
speechSynthesis.speak(utterance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextLetter() {
|
||||||
|
currentIndex = (currentIndex + 1) % alphabet.length;
|
||||||
|
updateDisplay(alphabet[currentIndex]);
|
||||||
|
document.getElementById('instruction').textContent = 'Click the letter!';
|
||||||
|
}
|
||||||
|
|
||||||
|
function randomLetter() {
|
||||||
|
currentIndex = Math.floor(Math.random() * alphabet.length);
|
||||||
|
updateDisplay(alphabet[currentIndex]);
|
||||||
|
celebrate('✨');
|
||||||
|
}
|
||||||
|
|
||||||
|
function playGame() {
|
||||||
|
// Simple recognition game
|
||||||
|
const target = alphabet[Math.floor(Math.random() * alphabet.length)];
|
||||||
|
document.getElementById('instruction').textContent =
|
||||||
|
`Find the letter ${target}! Click when you see it.`;
|
||||||
|
|
||||||
|
// Cycle through letters
|
||||||
|
let count = 0;
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
updateDisplay(alphabet[Math.floor(Math.random() * alphabet.length)]);
|
||||||
|
count++;
|
||||||
|
if (count > 20) clearInterval(interval);
|
||||||
|
}, 800);
|
||||||
|
}
|
||||||
|
|
||||||
|
function celebrate(emoji) {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.className = 'celebration';
|
||||||
|
div.textContent = emoji;
|
||||||
|
document.body.appendChild(div);
|
||||||
|
setTimeout(() => div.remove(), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
updateDisplay(alphabet[0]);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_success "Playground created: $OUTPUT_PATH"
|
||||||
|
echo ""
|
||||||
|
print_info "🚀 To use:"
|
||||||
|
echo " open $OUTPUT_PATH"
|
||||||
|
echo ""
|
||||||
|
print_info "Features:"
|
||||||
|
echo " ✓ Interactive letter display"
|
||||||
|
echo " ✓ Audio pronunciation (if supported)"
|
||||||
|
echo " ✓ Star rewards"
|
||||||
|
echo " ✓ Practice game mode"
|
||||||
|
echo " ✓ Colorful, engaging design"
|
||||||
|
echo ""
|
||||||
Reference in New Issue
Block a user