@joaobarrosfranca · 5/22/2026, 6:11:31 PM
Initial version — all lines are new.
+<!DOCTYPE html>+<html lang="en">+<head>+ <meta charset="UTF-8">+ <meta name="viewport" content="width=device-width, initial-scale=1.0">+ <title>English Flashcards</title>+ <style>+ * {+ box-sizing: border-box;+ }+ html, body {+ height: 100%;+ margin: 0;+ padding: 0;+ overflow: hidden;+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);+ }+ .container {+ display: flex;+ flex-direction: column;+ height: 100%;+ padding: 20px;+ color: #fff;+ }+ .header {+ text-align: center;+ margin-bottom: 15px;+ }+ .header h1 {+ margin: 0 0 5px 0;+ font-size: 24px;+ font-weight: 700;+ }+ .progress-bar {+ width: 100%;+ height: 8px;+ background: rgba(255, 255, 255, 0.3);+ border-radius: 4px;+ overflow: hidden;+ margin-top: 10px;+ }+ .progress-fill {+ height: 100%;+ background: #4ade80;+ width: 0%;+ transition: width 0.3s ease;+ }+ .stats {+ display: flex;+ justify-content: space-around;+ font-size: 12px;+ margin-top: 8px;+ opacity: 0.9;+ }+ .card-container {+ flex: 1;+ display: flex;+ align-items: center;+ justify-content: center;+ perspective: 1000px;+ min-height: 0;+ }+ .card {+ width: 100%;+ max-width: 320px;+ aspect-ratio: 1;+ background: white;+ border-radius: 16px;+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);+ cursor: pointer;+ display: flex;+ flex-direction: column;+ align-items: center;+ justify-content: center;+ padding: 30px;+ text-align: center;+ transition: transform 0.6s;+ transform-style: preserve-3d;+ color: #333;+ position: relative;+ }+ .card.flipped {+ transform: rotateY(180deg);+ }+ .card-side {+ position: absolute;+ width: 100%;+ height: 100%;+ display: flex;+ flex-direction: column;+ align-items: center;+ justify-content: center;+ padding: 30px;+ backface-visibility: hidden;+ border-radius: 16px;+ }+ .card-front {+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);+ color: white;+ }+ .card-back {+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);+ color: white;+ transform: rotateY(180deg);+ }+ .card-label {+ font-size: 12px;+ opacity: 0.7;+ margin-bottom: 15px;+ text-transform: uppercase;+ letter-spacing: 1px;+ }+ .card-word {+ font-size: 32px;+ font-weight: 700;+ margin-bottom: 10px;+ }+ .card-hint {+ font-size: 13px;+ opacity: 0.8;+ margin-top: 10px;+ }+ .audio-btn {+ background: rgba(255, 255, 255, 0.3);+ border: 2px solid rgba(255, 255, 255, 0.5);+ color: white;+ width: 50px;+ height: 50px;+ border-radius: 50%;+ font-size: 24px;+ cursor: pointer;+ display: flex;+ align-items: center;+ justify-content: center;+ transition: all 0.2s;+ margin-top: 15px;+ }+ .audio-btn:active {+ background: rgba(255, 255, 255, 0.5);+ transform: scale(0.9);+ }+ .controls {+ display: flex;+ gap: 10px;+ margin-top: 20px;+ justify-content: center;+ flex-wrap: wrap;+ }+ .btn {+ padding: 10px 16px;+ border: none;+ border-radius: 8px;+ font-size: 14px;+ font-weight: 600;+ cursor: pointer;+ transition: all 0.2s;+ white-space: nowrap;+ }+ .btn-nav {+ background: rgba(255, 255, 255, 0.2);+ color: white;+ border: 2px solid rgba(255, 255, 255, 0.4);+ min-width: 80px;+ }+ .btn-nav:active {+ background: rgba(255, 255, 255, 0.4);+ transform: scale(0.95);+ }+ .btn-flip {+ background: rgba(255, 255, 255, 0.9);+ color: #667eea;+ flex: 1;+ min-width: 200px;+ font-size: 16px;+ }+ .btn-flip:active {+ background: white;+ transform: scale(0.95);+ }+ .btn-mark {+ background: rgba(255, 255, 255, 0.2);+ color: white;+ border: 2px solid rgba(255, 255, 255, 0.4);+ min-width: 60px;+ }+ .btn-mark.marked {+ background: #fbbf24;+ color: #333;+ border-color: #fbbf24;+ }+ .btn-mark:active {+ transform: scale(0.95);+ }+ .shuffle-btn {+ background: rgba(255, 255, 255, 0.2);+ color: white;+ border: 2px solid rgba(255, 255, 255, 0.4);+ padding: 8px 12px;+ }+ .shuffle-btn:active {+ background: rgba(255, 255, 255, 0.4);+ transform: scale(0.95);+ }+ </style>+</head>+<body>+ <div class="container">+ <div class="header">+ <h1>📚 English Vocab</h1>+ <div class="progress-bar">+ <div class="progress-fill"></div>+ </div>+ <div class="stats">+ <span id="current">Card 1 / 100</span>+ <span id="marked">⭐ 0 Marked</span>+ </div>+ </div>++ <div class="card-container">+ <div class="card" id="card">+ <div class="card-side card-front">+ <div class="card-label">Word</div>+ <div class="card-word" id="front-word">Abundant</div>+ <button class="audio-btn" id="audio-btn" title="Pronounce word">🔊</button>+ <div class="card-hint">(click to flip)</div>+ </div>+ <div class="card-side card-back">+ <div class="card-label">Definition</div>+ <div class="card-word" id="back-word" style="font-size: 24px; line-height: 1.4;">Existing or available in large quantities</div>+ </div>+ </div>+ </div>++ <div class="controls">+ <button class="btn btn-nav" id="prev-btn">← Prev</button>+ <button class="btn btn-flip" id="flip-btn">Flip Card</button>+ <button class="btn btn-mark" id="mark-btn" title="Mark for review">⭐</button>+ <button class="btn shuffle-btn" id="shuffle-btn" title="Shuffle cards">🔀</button>+ <button class="btn btn-nav" id="next-btn">Next →</button>+ </div>+ </div>++ <script>+ const words = [+ { word: "Abundant", def: "Existing or available in large quantities" },+ { word: "Benevolent", def: "Kind and generous" },+ { word: "Candid", def: "Truthful and honest" },+ { word: "Diligent", def: "Showing careful and persistent effort" },+ { word: "Eloquent", def: "Fluent and expressive in speaking" },+ { word: "Frugal", def: "Economical; spending little money" },+ { word: "Gregarious", def: "Fond of being in groups; social" },+ { word: "Humble", def: "Modest; not arrogant" },+ { word: "Idiosyncratic", def: "Unique to a person or group" },+ { word: "Jovial", def: "Cheerful and friendly" },+ { word: "Keen", def: "Eager; having a sharp interest" },+ { word: "Loquacious", def: "Talkative" },+ { word: "Meticulous", def: "Very careful and precise" },+ { word: "Nonchalant", def: "Calm and indifferent" },+ { word: "Oblivious", def: "Not aware; unaware" },+ { word: "Perspicacious", def: "Having keen insight; shrewd" },+ { word: "Querulous", def: "Complaining; whining" },+ { word: "Resilient", def: "Able to recover quickly" },+ { word: "Sagacious", def: "Wise; showing good judgment" },+ { word: "Tenacious", def: "Holding firmly; persistent" },+ { word: "Ubiquitous", def: "Present everywhere" },+ { word: "Verbose", def: "Using more words than necessary" },+ { word: "Wistful", def: "Feeling sad longing or regret" },+ { word: "Xenophobic", def: "Fearing or hating foreigners" },+ { word: "Yielding", def: "Giving way; flexible" },+ { word: "Zealous", def: "Enthusiastic; passionate" },+ { word: "Acrimonious", def: "Bitter or harsh in tone" },+ { word: "Belligerent", def: "Aggressive; ready to fight" },+ { word: "Cynical", def: "Distrusting human sincerity" },+ { word: "Deferential", def: "Showing respect" },+ { word: "Ephemeral", def: "Lasting a very short time" },+ { word: "Fastidious", def: "Very careful about details" },+ { word: "Gratuitous", def: "Uncalled for; unwarranted" },+ { word: "Heinous", def: "Shockingly wicked; evil" },+ { word: "Incongruous", def: "Not matching; out of place" },+ { word: "Jocular", def: "Joking; playful" },+ { word: "Kinetic", def: "Relating to motion" },+ { word: "Lethargic", def: "Sluggish; lacking energy" },+ { word: "Magnanimous", def: "Generous and noble" },+ { word: "Nefarious", def: "Wicked or criminal" },+ { word: "Obfuscate", def: "To confuse or make unclear" },+ { word: "Pellucid", def: "Clear; easy to understand" },+ { word: "Quintessential", def: "Most typical or perfect example" },+ { word: "Recalcitrant", def: "Stubbornly resistant" },+ { word: "Serendipity", def: "Finding something good by chance" },+ { word: "Temerity", def: "Reckless boldness" },+ { word: "Unctuous", def: "Excessively flattering or oily" },+ { word: "Vacuous", def: "Empty of content; stupid" },+ { word: "Wane", def: "To decrease; diminish" },+ { word: "Xenial", def: "Hospitable and friendly" },+ { word: "Yoke", def: "To join together; connect" },+ { word: "Zephyr", def: "A gentle breeze" },+ { word: "Abscond", def: "To leave secretly and not return" },+ { word: "Bombastic", def: "Pompous; using high-sounding language" },+ { word: "Circumlocution", def: "Speaking in a roundabout way" },+ { word: "Debunk", def: "To prove false" },+ { word: "Ebullient", def: "Enthusiastic and energetic" },+ { word: "Florid", def: "Excessively ornate; ruddy" },+ { word: "Gauche", def: "Lacking tact; left-handed" },+ { word: "Hedonistic", def: "Seeking pleasure as main goal" },+ { word: "Inane", def: "Silly; lacking sense" },+ { word: "Jargon", def: "Special vocabulary of a group" },+ { word: "Kismet", def: "Fate or destiny" },+ { word: "Laconic", def: "Using few words; brief" },+ { word: "Mellifluous", def: "Sweet-sounding" },+ { word: "Nascent", def: "Just beginning to exist" },+ { word: "Obsequious", def: "Excessively eager to please" },+ { word: "Pedantic", def: "Overly concerned with details" },+ { word: "Quixotic", def: "Idealistic but impractical" },+ { word: "Raucous", def: "Loud and harsh" },+ { word: "Salutary", def: "Beneficial; health-giving" },+ { word: "Taciturn", def: "Reserved; not talkative" },+ { word: "Undulate", def: "To move in waves" },+ { word: "Vestige", def: "A trace or remaining part" },+ { word: "Wanton", def: "Deliberate and unprovoked" },+ { word: "Xerophytic", def: "Adapted to dry climates" },+ { word: "Yearning", def: "Strong desire; longing" },+ { word: "Zealotry", def: "Excessive zeal; fanaticism" },+ { word: "Aesthetic", def: "Concerned with beauty" },+ { word: "Blithe", def: "Happy; carefree" },+ { word: "Congeal", def: "To solidify; freeze" },+ { word: "Doleful", def: "Sad; sorrowful" },+ { word: "Erudite", def: "Scholarly; learned" },+ { word: "Felicitous", def: "Well-suited; appropriate" },+ { word: "Genteel", def: "Well-mannered; refined" },+ { word: "Harbinger", def: "A sign of coming change" },+ { word: "Insipid", def: "Lacking flavor; dull" },+ { word: "Juxtapose", def: "To place side by side" },+ { word: "Kudos", def: "Praise; acclaim" },+ { word: "Luminous", def: "Bright; shining" },+ { word: "Malleable", def: "Able to be shaped; flexible" },+ { word: "Nebulous", def: "Cloudy; vague" },+ { word: "Oblique", def: "Slanting; indirect" },+ { word: "Pejorative", def: "Expressing disapproval" }+ ];++ let currentIndex = 0;+ let marked = new Set();+ let isFlipped = false;+ let audioContext = null;++ const card = document.getElementById('card');+ const frontWord = document.getElementById('front-word');+ const backWord = document.getElementById('back-word');+ const currentSpan = document.getElementById('current');+ const markedSpan = document.getElementById('marked');+ const progressFill = document.querySelector('.progress-fill');+ const flipBtn = document.getElementById('flip-btn');+ const nextBtn = document.getElementById('next-btn');+ const prevBtn = document.getElementById('prev-btn');+ const markBtn = document.getElementById('mark-btn');+ const shuffleBtn = document.getElementById('shuffle-btn');+ const audioBtn = document.getElementById('audio-btn');++ function playSound(freq = 400, duration = 0.1, type = 'sine') {+ try {+ if (!audioContext) {+ audioContext = new (window.AudioContext || window.webkitAudioContext)();+ }+ if (audioContext.state === 'suspended') {+ audioContext.resume();+ }+ const osc = audioContext.createOscillator();+ const gain = audioContext.createGain();+ osc.connect(gain);+ gain.connect(audioContext.destination);+ osc.frequency.value = freq;+ osc.type = type;+ gain.gain.setValueAtTime(0.15, audioContext.currentTime);+ gain.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + duration);+ osc.start(audioContext.currentTime);+ osc.stop(audioContext.currentTime + duration);+ } catch (e) {}+ }++ function speak(text) {+ try {+ if (!audioContext) {+ audioContext = new (window.AudioContext || window.webkitAudioContext)();+ }+ if (audioContext.state === 'suspended') {+ audioContext.resume();+ }++ if ('speechSynthesis' in window) {+ window.speechSynthesis.cancel();+ const utterance = new SpeechSynthesisUtterance(text);+ utterance.rate = 0.9;+ utterance.pitch = 1;+ utterance.volume = 1;+ window.speechSynthesis.speak(utterance);+ }+ } catch (e) {}+ }++ function updateCard() {+ const item = words[currentIndex];+ frontWord.textContent = item.word;+ backWord.textContent = item.def;+ card.classList.remove('flipped');+ isFlipped = false;++ currentSpan.textContent = `Card ${currentIndex + 1} / ${words.length}`;+ markedSpan.textContent = `⭐ ${marked.size} Marked`;+ progressFill.style.width = `${((currentIndex + 1) / words.length) * 100}%`;++ if (marked.has(currentIndex)) {+ markBtn.classList.add('marked');+ } else {+ markBtn.classList.remove('marked');+ }++ speak(item.word);+ }++ audioBtn.addEventListener('click', (e) => {+ e.stopPropagation();+ speak(words[currentIndex].word);+ playSound(600, 0.2);+ });++ flipBtn.addEventListener('click', () => {+ card.classList.toggle('flipped');+ isFlipped = !isFlipped;+ playSound(isFlipped ? 600 : 400, 0.15);+ });++ nextBtn.addEventListener('click', () => {+ if (currentIndex < words.length - 1) {+ currentIndex++;+ updateCard();+ playSound(500, 0.1);+ }+ });++ prevBtn.addEventListener('click', () => {+ if (currentIndex > 0) {+ currentIndex--;+ updateCard();+ playSound(500, 0.1);+ }+ });++ markBtn.addEventListener('click', () => {+ if (marked.has(currentIndex)) {+ marked.delete(currentIndex);+ playSound(300, 0.15);+ } else {+ marked.add(currentIndex);+ playSound(700, 0.15);+ }+ updateCard();+ });++ shuffleBtn.addEventListener('click', () => {+ for (let i = words.length - 1; i > 0; i--) {+ const j = Math.floor(Math.random() * (i + 1));+ [words[i], words[j]] = [words[j], words[i]];+ }+ currentIndex = 0;+ marked.clear();+ updateCard();+ playSound(800, 0.2);+ });++ card.addEventListener('click', () => {+ flipBtn.click();+ });++ updateCard();+ </script>+</body>+</html>