console
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body { margin:0; padding:15px; font-family:sans-serif; background:#f4f6f9; }
.grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(120px,1fr)); gap:8px; }
.word-btn { padding:10px; background:#fff; border:1px solid #e3e7ed; border-radius:10px; font-size:16px; font-weight:bold; color:#333; text-align:left; cursor:pointer; }
.word-btn.speaking { background:#2563eb; color:#fff; }
</style>
</head>
<body>
<div class="grid" id="grid"></div>
<script>
const words = [
"compound","manufacture","simulation","aspiration","confidence","chronic","candidate","conform","response","perception","align","credential","signal","respond","precise","engagement","reinforce","exceptional","survive","pursue","contrast","encounter","persist","convention","genuine","withdraw","obligation","eccentric","trickle","privilege","curse","scan","amplify","elevate","suppress","mere","extinct","optimism","fascinate","emerge","preference","pattern","interaction","chronically","individual","lottery","lever","reveal","destiny","activate","rhythm","recognition","possess","desire","cautious","persistence","cognitive","routine","mutual","anecdote","modification","plight","compromise","opponent","arrogant","crumble","suffice","operative","apt","conference","positive","frequent","pilgrimage","trivial","intrinsically","equate","commission","grope","analogy","commence","productivity","crave","sustain","concise","instinct","financial","yawn","ivory","trench","galaxy","stalk","literal","fantastic","instruct","numerous","component","cannon","speculate","graze","finance","imprison","wreck","mature","module","identification","intake","mortality","bounce","melody","sentiment","satisfaction","priest","ranch","consecutive","luxury","reunion","bruise","beam","formula","preserve","subordinate","vein","autonomous","employment","fossil","augment","glitter","sensation","linger","bloodshed","obstacle","conservative","committee","element","specific","disgust","principle","pressure","underline","highlight","blackmail","infant","extensive","heap","precedent","complementary","stagnation","sophisticated","informed","construct","distinguish","susceptible","discipline","inertia","notify","settle","transport","embryo","exempt","customary","strait","streak","relevant","endure","cram","unfold","decisive","edible","mourning","mortal","exemption","bound","presume","steward","refreshment","virtual","shark","priority","simulate","comprehend","revelation","exaggerate","minimum","scramble","tranquil","sober","metaphor","expansion","phase","substitute","adherence","diversion","comprehensive","exhausted","intellectual","defect","denounce","intersection","champion","brood"
];
const grid = document.getElementById('grid');
const synth = window.speechSynthesis;
let lastBtn = null;
words.forEach((w, i) => {
const btn = document.createElement('button');
btn.className = 'word-btn';
btn.innerText = w;
btn.onclick = () => {
synth.cancel();
if (lastBtn) lastBtn.classList.remove('speaking');
lastBtn = btn;
btn.classList.add('speaking');
const u = new SpeechSynthesisUtterance(w);
u.lang = 'en-US';
u.rate = 0.9;
u.onend = () => btn.classList.remove('speaking');
synth.speak(u);
};
grid.appendChild(btn);
});
</script>
</body>
</html>