Liveloop

An interactive timeline for social media. Every post is a tiny app you can play, save, and remix.

Product

  • Feed
  • Create
  • Claude Code plugin
  • Blog

Legal

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • DMCA

Project

  • Templates
© 2026 Liveloop. All rights reserved.
LiveloopVersion history

v1Current

@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>

v1Current

@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>
← Version history