{"id":1375,"date":"2026-03-14T19:40:28","date_gmt":"2026-03-14T19:40:28","guid":{"rendered":"https:\/\/www.dmt.agency\/?page_id=1375"},"modified":"2026-03-14T19:40:30","modified_gmt":"2026-03-14T19:40:30","slug":"learn-edtech-vocabulary-with-a-fun-scape-game","status":"publish","type":"page","link":"https:\/\/www.dmt.agency\/es\/learn-edtech-vocabulary-with-a-fun-scape-game\/","title":{"rendered":"Learn EdTech Vocabulary with a Fun Scape-Game"},"content":{"rendered":"\nimport React, { useState, useEffect, useMemo, useRef } from &#8216;react&#8217;;\nimport { \n  Heart, ShieldAlert, CheckCircle2, RefreshCw, Trophy, Skull, \n  Users, Network, Generic, Search, UserCog, Accessibility, \n  Play, CircleDollarSign, Recycle, Smartphone, Briefcase, \n  Leaf, Code, DatabaseZap, Lock, Eye, BookOpen, Clock, \n  Map as MapIcon, ChevronRight, MapPinned, Volume2, VolumeX,\n  Compass\n} from &#8216;lucide-react&#8217;;\n\n\/\/ STABLE ASSETS DEFINED OUTSIDE TO PREVENT INFINITE RE-RENDER LOOPS\nconst ASSETS = {\n  MAIN_MAP: &#8220;Main map.jpg&#8221;,\n  HERO: &#8220;The hero.jpg&#8221;,\n  LEVEL1: &#8220;Level 1.jpg&#8221;,\n  LEVEL2: &#8220;Level 2.jpg&#8221;,\n  LEVEL3: &#8220;Level 3.jpg&#8221;,\n  \/\/ NEW ILLUSTRATION ASSETS\n  BEGINNING: &#8220;Beggining.jpg&#8221;,\n  VICTORY: &#8220;Victory.jpg&#8221;,\n  GAMEOVER: &#8220;game over try again.jpg&#8221;,\n  BAD_ANSWER: &#8220;bad answer try again.jpg&#8221;,\n  CORRECT_ANSWER: &#8220;correct answer.jpg&#8221;,\n  LEVEL_ACHIEVED: &#8220;level achieved.jpg&#8221;,\n  \/\/ AUDIO ASSETS\n  MUSIC_URL: &#8220;https:\/\/cdn.pixabay.com\/audio\/2022\/03\/10\/audio_c8c8a730a2.mp3&#8221;, \/\/ Epic Cinematic\n  SUCCESS_SFX: &#8220;https:\/\/cdn.pixabay.com\/audio\/2021\/08\/04\/audio_bb6476e3d2.mp3&#8221;, \/\/ Success Ping\n  WRONG_SFX: &#8220;https:\/\/cdn.pixabay.com\/audio\/2022\/03\/15\/audio_2913e2f07b.mp3&#8221; \/\/ Error Buzzer\n};\n\nconst LEVEL_METADATA = [\n  {\n    levelId: 1,\n    name: &#8220;LEVEL 1: UX Mountain Range&#8221;,\n    intro: &#8220;Welcome to the soaring peaks of User Experience. Here, the layout is as steep as the slopes, and clarity is your only lifeline. Master the interface to find the path forward.&#8221;,\n    bg: ASSETS.LEVEL1,\n  },\n  {\n    levelId: 2,\n    name: &#8220;LEVEL 2: The Swamp of Techniques &#038; Ethics&#8221;,\n    intro: &#8220;You have descended into the murky wetlands where technology meets morality. Every step in this swamp requires a balance of technical skill and ethical integrity. Watch your footing.&#8221;,\n    bg: ASSETS.LEVEL2,\n  },\n  {\n    levelId: 3,\n    name: &#8220;LEVEL 3: The Desert of Constraints &#038; Risks&#8221;,\n    intro: &#8220;The final stretch. A vast expanse where resources are scarce and digital viruses howl like sandstorms. Guard your data and your sanity to reach the Valley of Wisdom.&#8221;,\n    bg: ASSETS.LEVEL3,\n  }\n];\n\nconst PUZZLES = [\n  \/\/ LEVEL 1: UX MOUNTAIN RANGE (0-5)\n  { answer: &#8216;Collaborative&#8217;, levelId: 1, icon: <Users className=\"w-8 h-8 text-blue-400\" \/>, challenge: &#8216;A word describing group-focused platforms.&#8217;, definition: &#8220;It&#8217;s a word used to describe platforms that encourage user-generated content (UGC). Comments, forums, chats, and chatbots interactions that foster group work are&#8230;&#8221; },\n  { answer: &#8216;Hypertext&#8217;, levelId: 1, icon: <Network className=\"w-8 h-8 text-blue-400\" \/>, challenge: &#8216;Name this linking system for ancient digital scrolls.&#8217;, definition: &#8216;A software system that allows extensive linking between sections of text and associated material.&#8217; },\n  { answer: &#8216;User-friendly&#8217;, levelId: 1, icon: <CheckCircle2 className=\"w-8 h-8 text-blue-400\" \/>, challenge: &#8216;A path that is simple and clear for everyone.&#8217;, definition: &#8216;Characterized by effective UI design leading to excellent UX. Simple, clear design ensuring intuitive usage for everyone.&#8217; },\n  { answer: &#8216;Navigability&#8217;, levelId: 1, icon: <Search className=\"w-8 h-8 text-blue-400\" \/>, challenge: &#8216;The ease of finding information in a vast library.&#8217;, definition: &#8216;Involves handling substantial volumes of data while ensuring it is easily found via search engines, glossaries, site maps, and indexes.&#8217; },\n  { answer: &#8216;Customized&#8217;, levelId: 1, icon: <UserCog className=\"w-8 h-8 text-blue-400\" \/>, challenge: &#8216;Shaping the journey to each individual.&#8217;, definition: &#8220;Made or changed according to the user&#8217;s needs:&#8221; },\n  { answer: &#8216;Accessibility&#8217;, levelId: 1, icon: <Accessibility className=\"w-8 h-8 text-blue-400\" \/>, challenge: &#8216;Design that empowers every user regardless of ability.&#8217;, definition: &#8216;Designing for all users regardless of their abilities\/disabilities, implementing tools like speech synthesis, subtitles, and simple language.&#8217; },\n\n  \/\/ LEVEL 2: THE SWAMP (6-12)\n  { answer: &#8216;multimedia&#8217;, levelId: 2, icon: <Play className=\"w-8 h-8 text-emerald-400\" \/>, challenge: &#8216;A mix of sights and sounds to navigate the depths.&#8217;, definition: &#8216;utilizing a variety of resource formats simultaneously, mixing text, image, sound, and video to enhance learning.&#8217; },\n  { answer: &#8216;affordable&#8217;, levelId: 2, icon: <CircleDollarSign className=\"w-8 h-8 text-emerald-400\" \/>, challenge: &#8216;Solutions that preserve the dwarf\\&#8217;s gold coins.&#8217;, definition: &#8216;A financial constraint: focusing on solutions that are free, cost-effective, or cheap to implement.&#8217; },\n  { answer: &#8216;Sustainable&#8217;, levelId: 2, icon: <Recycle className=\"w-8 h-8 text-emerald-400\" \/>, challenge: &#8216;Magic platforms built to last and upgrade easily.&#8217;, definition: &#8216;A long-term requirement: ensuring solutions are easy to maintain and upgrade over time.&#8217; },\n  { answer: &#8216;Responsive&#8217;, levelId: 2, icon: <Smartphone className=\"w-8 h-8 text-emerald-400\" \/>, challenge: &#8216;Platforms that adapt to smaller magic mirrors.&#8217;, definition: &#8216;A modern accessibility constraint: ensuring the learning platform is adaptive, and specifically optimized for mobile devices.&#8217; },\n  { answer: &#8216;Portable&#8217;, levelId: 2, icon: <Briefcase className=\"w-8 h-8 text-emerald-400\" \/>, challenge: &#8216;Carrying knowledge wherever the path leads.&#8217;, definition: &#8216;A connectivity requirement: creating a solution that is portable and useful for both online and offline learning situations.&#8217; },\n  { answer: &#8216;Eco-friendly&#8217;, levelId: 2, icon: <Leaf className=\"w-8 h-8 text-emerald-400\" \/>, challenge: &#8216;A commitment to the environment.&#8217;, definition: &#8220;Committing to &#8216;green&#8217; design principles.&#8221; },\n  { answer: &#8216;open-source&#8217;, levelId: 2, icon: <Code className=\"w-8 h-8 text-emerald-400\" \/>, challenge: &#8216;Secrets written in public scrolls.&#8217;, definition: &#8216;Public domain software platforms&#8217; },\n\n  \/\/ LEVEL 3: THE DESERT (13-18)\n  { answer: &#8216;infobesity&#8217;, levelId: 3, icon: <DatabaseZap className=\"w-8 h-8 text-orange-400\" \/>, challenge: &#8216;A storm of too many scrolls at once.&#8217;, definition: &#8216;The overwhelming feeling of being flooded by too much information at once.&#8217; },\n  { answer: &#8216;hacking&#8217;, levelId: 3, icon: <ShieldAlert className=\"w-8 h-8 text-orange-400\" \/>, challenge: &#8216;Shadowy figures breaking into the system.&#8217;, definition: &#8216;The gaining of unauthorized access to data in a system or computer.&#8217; },\n  { answer: &#8216;privacy&#8217;, levelId: 3, icon: <Lock className=\"w-8 h-8 text-orange-400\" \/>, challenge: &#8216;Hiding the true names of the travelers.&#8217;, definition: &#8216;A fundamental ethical constraint: the protection of individual user data and personal identity.&#8217; },\n  { answer: &#8216;moderation&#8217;, levelId: 3, icon: <Eye className=\"w-8 h-8 text-orange-400\" \/>, challenge: &#8216;Filtering winds to keep the air pure.&#8217;, definition: &#8216;Involve reviewing and filtering massive amounts of user interaction data to prevent issues.&#8217; },\n  { answer: &#8216;computer literacy&#8217;, levelId: 3, icon: <BookOpen className=\"w-8 h-8 text-orange-400\" \/>, challenge: &#8216;Skill needed to use desert tools.&#8217;, definition: &#8216;The knowledge and ability to use computers and related technology efficiently.&#8217; },\n  { answer: &#8216;FOMO&#8217;, levelId: 3, icon: <Clock className=\"w-8 h-8 text-orange-400\" \/>, challenge: &#8216;A mirage of missed opportunities.&#8217;, definition: &#8220;A psychological risk to users: the &#8216;Fear Of Missing Out&#8217; on content, interactions, or certifications.&#8221; }\n];\n\nconst App = () => {\n  \/\/ Game State\n  const [gameState, setGameState] = useState(&#8216;START&#8217;); \/\/ START, UNLOCK, PUZZLE, GAMEOVER, VICTORY\n  const [currentLevelIndex, setCurrentLevelIndex] = useState(0);\n  const [lives, setLives] = useState(3);\n  const [showFeedback, setShowFeedback] = useState(null); \n  const [isTransitioning, setIsTransitioning] = useState(false);\n  const [slotValues, setSlotValues] = useState([]);\n  const [isMuted, setIsMuted] = useState(false);\n\n  const inputRefs = useRef([]);\n  const audioRef = useRef(null);\n  const sfxRef = useRef(null);\n  \n  const currentPuzzle = PUZZLES[currentLevelIndex];\n  const currentLevelMetadata = useMemo(() => \n    LEVEL_METADATA.find(l => l.levelId === currentPuzzle.levelId), [currentPuzzle]);\n\n  \/\/ AUDIO INITIALIZATION\n  useEffect(() => {\n    audioRef.current = new Audio(ASSETS.MUSIC_URL);\n    audioRef.current.loop = true;\n    audioRef.current.volume = 0.4;\n    \n    sfxRef.current = new Audio();\n    \n    return () => {\n      audioRef.current?.pause();\n      audioRef.current = null;\n    };\n  }, []);\n\n  useEffect(() => {\n    if (audioRef.current) {\n      audioRef.current.muted = isMuted;\n    }\n  }, [isMuted]);\n\n  const playSFX = (url) => {\n    if (isMuted) return;\n    sfxRef.current.src = url;\n    sfxRef.current.play().catch(() => {});\n  };\n\n  \/\/ INITIALIZE INTERACTIVE SLOTS\n  useEffect(() => {\n    if (gameState !== &#8216;PUZZLE&#8217;) return;\n\n    const answerChars = currentPuzzle.answer.split(&#8221;);\n    const initialSlots = answerChars.map((char, index) => {\n      const isSeparator = [&#8216; &#8216;, &#8216;-&#8216;, &#8216;\/&#8217;, &#8216;.&#8217;, &#8216;(&#8216;, &#8216;)&#8217;].includes(char);\n      const isHint = !isSeparator &#038;&#038; index % 4 === 0;\n      return {\n        char: isSeparator || isHint ? char : &#8221;,\n        isEditable: !isSeparator &#038;&#038; !isHint,\n        target: char\n      };\n    });\n    \n    setSlotValues(initialSlots);\n    \n    const timer = setTimeout(() => {\n      const firstEditable = initialSlots.findIndex(s => s.isEditable);\n      if (inputRefs.current[firstEditable]) inputRefs.current[firstEditable].focus();\n    }, 150);\n    \n    return () => clearTimeout(timer);\n  }, [currentLevelIndex, gameState, currentPuzzle.answer]);\n\n  const handleSlotChange = (index, value) => {\n    const char = value.slice(-1); \n    const newSlots = [&#8230;slotValues];\n    newSlots[index].char = char;\n    setSlotValues(newSlots);\n\n    if (char !== &#8221; &#038;&#038; index < slotValues.length - 1) {\n      let next = index + 1;\n      while (next < slotValues.length &#038;&#038; !slotValues[next].isEditable) next++;\n      if (inputRefs.current[next]) inputRefs.current[next].focus();\n    }\n  };\n\n  const handleKeyDown = (index, e) => {\n    if (e.key === &#8216;Backspace&#8217; &#038;&#038; slotValues[index].char === &#8221; &#038;&#038; index > 0) {\n      let prev = index &#8211; 1;\n      while (prev >= 0 &#038;&#038; !slotValues[prev].isEditable) prev&#8211;;\n      if (inputRefs.current[prev]) inputRefs.current[prev].focus();\n    }\n    if (e.key === &#8216;Enter&#8217;) submitAttempt();\n  };\n\n  const submitAttempt = () => {\n    const userGuess = slotValues.map(s => s.char).join(&#8221;);\n    if (userGuess.toLowerCase() === currentPuzzle.answer.toLowerCase()) {\n      playSFX(ASSETS.SUCCESS_SFX);\n      setShowFeedback(&#8216;correct&#8217;);\n    } else {\n      playSFX(ASSETS.WRONG_SFX);\n      const newLives = lives &#8211; 1;\n      setLives(newLives);\n      if (newLives <= 0) {\n        setGameState('GAMEOVER');\n      } else {\n        setShowFeedback('wrong');\n      }\n    }\n  };\n\n  const handleContinue = () => {\n    const nextIdx = currentLevelIndex + 1;\n    const isLevelChange = nextIdx < PUZZLES.length &#038;&#038; PUZZLES[nextIdx].levelId !== currentPuzzle.levelId;\n    \n    setIsTransitioning(true);\n    setTimeout(() => {\n      setShowFeedback(null);\n      if (nextIdx < PUZZLES.length) {\n        setCurrentLevelIndex(nextIdx);\n        if (isLevelChange) {\n          setGameState('UNLOCK');\n        } else {\n          setGameState('PUZZLE');\n        }\n        setIsTransitioning(false);\n      } else {\n        setGameState('VICTORY');\n        setIsTransitioning(false);\n      }\n    }, 400);\n  };\n\n  const beginQuest = () => {\n    audioRef.current?.play().catch(() => {});\n    setGameState(&#8216;UNLOCK&#8217;);\n  };\n\n  const restartGame = () => {\n    setLives(3);\n    setCurrentLevelIndex(0);\n    setGameState(&#8216;START&#8217;);\n    setShowFeedback(null);\n  };\n\n  \/\/ UI Components\n  const HealthBar = () => (\n    <div className=\"fixed top-6 right-6 flex space-x-2 z-50\">\n      {[&#8230;Array(3)].map((_, i) => (\n        <Heart \n          key={i} \n          className={`w-10 h-10 transition-all duration-500 ${i < lives ? 'text-red-500 fill-red-500 drop-shadow-[0_0_10px_rgba(239,68,68,0.9)]' : 'text-slate-800'}`} \n        \/>\n      ))}\n      <button \n        onClick={() => setIsMuted(!isMuted)}\n        className=&#8221;ml-4 p-2 bg-black\/40 border border-white\/10 rounded-full hover:bg-black\/60 transition-colors&#8221;\n      >\n        {isMuted ? <VolumeX className=\"text-white\/40\" \/> : <Volume2 className=\"text-amber-500\" \/>}\n      <\/button>\n    <\/div>\n  );\n\n  const BackgroundOverlay = ({ src }) => (\n    <div \n      className=\"fixed inset-0 bg-cover bg-center bg-no-repeat transition-all duration-1000 -z-10\"\n      style={{ backgroundImage: `url(\"${src}\")` }}\n    >\n      <div className=\"absolute inset-0 bg-black\/75 backdrop-blur-[2px]\"><\/div>\n    <\/div>\n  );\n\n  if (gameState === &#8216;START&#8217;) {\n    return (\n      <div className=\"min-h-screen flex items-center justify-center text-white p-6 font-sans\">\n        <BackgroundOverlay src={ASSETS.MAIN_MAP} \/>\n        <div className=\"max-w-4xl w-full bg-slate-900\/95 backdrop-blur-xl border-4 border-slate-700\/50 rounded-[3rem] p-10 shadow-2xl text-center flex flex-col items-center\">\n          <div className=\"w-full h-80 rounded-3xl overflow-hidden mb-10 border-2 border-white\/20 shadow-2xl relative\">\n             <img src={ASSETS.BEGINNING} className=\"w-full h-full object-cover\" alt=\"The Beginning of the Journey\" \/>\n             <div className=\"absolute inset-0 bg-gradient-to-t from-black\/60 to-transparent\"><\/div>\n          <\/div>\n          <h1 className=\"text-5xl font-black mb-4 tracking-tighter uppercase text-amber-500 leading-tight drop-shadow-lg text-balance\">The Quest for EdTech Enlightenment<\/h1>\n          <p className=\"text-slate-400 mb-8 italic text-lg tracking-wide uppercase\">Escape the Luddite forest&#8230; find the Valley of Wisdom.<\/p>\n          \n          <button \n            onClick={beginQuest}\n            className=\"group flex items-center space-x-4 bg-amber-600 hover:bg-amber-500 text-white font-black py-6 px-16 rounded-2xl transition-all transform hover:scale-105 shadow-[0_15px_40px_rgba(217,119,6,0.4)]\"\n          >\n            <Play className=\"w-8 h-8 fill-white\" \/>\n            <span className=\"text-2xl uppercase tracking-widest\">Begin the Quest<\/span>\n            <ChevronRight className=\"w-8 h-8 group-hover:translate-x-2 transition-transform\" \/>\n          <\/button>\n        <\/div>\n      <\/div>\n    );\n  }\n\n  if (gameState === &#8216;UNLOCK&#8217;) {\n    return (\n      <div className=\"min-h-screen flex items-center justify-center text-white p-6 font-sans\">\n        <BackgroundOverlay src={currentLevelMetadata.bg} \/>\n        <div className=\"max-w-4xl w-full bg-black\/80 backdrop-blur-2xl border-2 border-amber-500\/30 rounded-[3rem] p-12 shadow-2xl text-center flex flex-col items-center animate-in fade-in zoom-in duration-500\">\n          <div className=\"w-full h-80 rounded-2xl overflow-hidden mb-8 border border-white\/10 shadow-lg\">\n             <img src={ASSETS.LEVEL_ACHIEVED} className=\"w-full h-full object-cover\" alt=\"Level Achieved\" \/>\n          <\/div>\n          <h2 className=\"text-amber-500 text-sm font-black tracking-[0.5em] uppercase mb-4\">Level Unlocked<\/h2>\n          <h1 className=\"text-5xl font-black mb-6 uppercase tracking-tight\">{currentLevelMetadata.name}<\/h1>\n          \n          <p className=\"text-2xl font-light leading-relaxed text-slate-300 max-w-2xl mb-12 italic\">\n            &#8220;{currentLevelMetadata.intro}&#8221;\n          <\/p>\n\n          <button \n            onClick={() => setGameState(&#8216;PUZZLE&#8217;)}\n            className=&#8221;bg-white text-black font-black py-6 px-16 rounded-2xl text-2xl hover:bg-amber-400 transition-all active:scale-95 shadow-xl uppercase tracking-widest flex items-center space-x-3&#8243;\n          >\n            <span>Enter the Gate<\/span>\n            <ChevronRight className=\"w-8 h-8\" \/>\n          <\/button>\n        <\/div>\n      <\/div>\n    );\n  }\n\n  if (gameState === &#8216;GAMEOVER&#8217;) {\n    return (\n      <div className=\"min-h-screen flex items-center justify-center p-6 relative\">\n        <BackgroundOverlay src={ASSETS.LEVEL3} \/>\n        <div className=\"max-w-4xl w-full text-center z-10 p-12 bg-black\/80 rounded-[3rem] border-2 border-red-500\/30 backdrop-blur-md shadow-2xl overflow-hidden\">\n          <div className=\"w-full h-80 rounded-2xl overflow-hidden mb-8 border border-red-900\/30\">\n            <img src={ASSETS.GAMEOVER} alt=\"Game Over\" className=\"w-full h-full object-cover\" \/>\n          <\/div>\n          <h1 className=\"text-7xl font-black mb-4 tracking-tighter text-red-600\">GAME OVER<\/h1>\n          <p className=\"text-2xl text-red-200\/70 mb-12 uppercase tracking-widest font-bold\">Ignorance has claimed the Brave Dwarf.<\/p>\n          <button onClick={restartGame} className=\"bg-red-600 hover:bg-red-500 py-6 px-14 rounded-2xl font-black text-2xl transition-all shadow-[0_0_40px_rgba(220,38,38,0.6)] active:scale-95 flex items-center justify-center mx-auto space-x-4\">\n            <RefreshCw className=\"w-8 h-8\" \/>\n            <span>RESTART QUEST<\/span>\n          <\/button>\n        <\/div>\n      <\/div>\n    );\n  }\n\n  if (gameState === &#8216;VICTORY&#8217;) {\n    return (\n      <div className=\"min-h-screen flex items-center justify-center p-6\">\n        <BackgroundOverlay src={ASSETS.MAIN_MAP} \/>\n        <div className=\"max-w-4xl w-full bg-white\/95 backdrop-blur-2xl border-4 border-amber-300 rounded-[3rem] p-12 shadow-[0_30px_100px_rgba(251,191,36,0.4)] text-center relative flex flex-col items-center\">\n          <div className=\"w-full h-80 rounded-2xl overflow-hidden mb-8 border border-amber-200 shadow-xl\">\n             <img src={ASSETS.VICTORY} className=\"w-full h-full object-cover\" alt=\"Victory\" \/>\n          <\/div>\n          <h1 className=\"text-6xl font-black mb-6 tracking-tight text-slate-900 leading-tight uppercase text-balance\">The Valley of Wisdom<\/h1>\n          <p className=\"text-2xl mb-12 text-slate-600 font-medium leading-relaxed\">\n            Congratulations! You have conquered the technical mists and ethical swamps. \n            <span className=\"block mt-4 text-amber-600 font-black uppercase tracking-widest text-3xl text-balance\">Victory is yours!<\/span>\n          <\/p>\n          <button onClick={restartGame} className=\"bg-slate-900 hover:bg-slate-800 text-white font-black py-6 px-16 rounded-3xl transition-all text-2xl shadow-2xl\">\n            PLAY AGAIN?\n          <\/button>\n        <\/div>\n      <\/div>\n    );\n  }\n\n  return (\n    <div className={`min-h-screen flex items-center justify-center text-white p-6 transition-opacity duration-500 ${isTransitioning ? 'opacity-0' : 'opacity-100'}`}>\n      <BackgroundOverlay src={currentPuzzle.bg} \/>\n      <HealthBar \/>\n\n      <main className=\"max-w-6xl w-full flex flex-col md:flex-row bg-slate-950\/85 backdrop-blur-3xl border border-white\/10 rounded-[2.5rem] shadow-2xl overflow-hidden min-h-[650px]\">\n        {\/* Left Panel: Location &#038; Dwarf *\/}\n        <div className=\"md:w-5\/12 bg-black\/50 p-8 flex flex-col items-center border-r border-white\/5\">\n          <div className=\"flex items-center space-x-2 mb-4 w-full justify-start\">\n              <MapPinned className=\"w-5 h-5 text-amber-500\" \/>\n              <span className=\"text-xs font-black uppercase tracking-widest text-white\/50\">Current Location<\/span>\n          <\/div>\n          <div className=\"w-full aspect-[4\/3] rounded-2xl border border-white\/10 mb-8 overflow-hidden relative shadow-2xl\">\n            <img src={currentPuzzle.bg} alt=\"Level Map\" className=\"w-full h-full object-cover\" \/>\n            <div className=\"absolute inset-0 bg-gradient-to-t from-black\/60 to-transparent\"><\/div>\n          <\/div>\n          <div className=\"w-28 h-28 rounded-full border-4 border-amber-500\/30 mb-6 overflow-hidden shadow-xl bg-slate-800 shrink-0\">\n            <img src={ASSETS.HERO} alt=\"EdTech the Dwarf\" className=\"w-full h-full object-cover scale-150\" \/>\n          <\/div>\n          <div className=\"text-center w-full\">\n            <h3 className=\"text-amber-500 font-black tracking-widest uppercase text-lg mb-2\">{currentPuzzle.level}<\/h3>\n            <p className=\"text-[10px] font-mono text-white\/30 uppercase tracking-[0.2em] mb-8\">Gate {currentLevelIndex + 1} of {PUZZLES.length}<\/p>\n            <div className=\"bg-white\/5 border border-white\/10 p-4 rounded-2xl flex items-center space-x-4\">\n               <div className=\"p-3 bg-white\/10 rounded-xl border border-white\/10 shadow-lg\">{currentPuzzle.icon}<\/div>\n               <div className=\"text-left\">\n                 <p className=\"text-[10px] uppercase font-bold text-white\/40 tracking-widest\">Terminal Key<\/p>\n                 <p className=\"text-xs text-white\/80 italic leading-snug\">Type your answer directly into the scroll slots.<\/p>\n               <\/div>\n            <\/div>\n          <\/div>\n        <\/div>\n\n        {\/* Right Panel: The Challenge *\/}\n        <div className=\"md:w-7\/12 p-12 flex flex-col relative overflow-hidden\">\n          <div className=\"flex-1\">\n            <div className=\"flex items-center space-x-3 mb-6\">\n               <div className=\"h-[2px] w-12 bg-amber-500\"><\/div>\n               <h2 className=\"text-xs font-black text-amber-500 uppercase tracking-[0.5em]\">The Encounter<\/h2>\n            <\/div>\n            <p className=\"text-white text-2xl font-light mb-12 leading-relaxed italic text-balance\">&#8220;{currentPuzzle.challenge}&#8221;<\/p>\n            <div className=\"bg-slate-900\/60 border-2 border-white\/5 rounded-[2rem] p-8 mb-12 shadow-inner relative group\">\n               <div className=\"absolute top-0 right-0 p-6 opacity-5 group-hover:opacity-10 transition-opacity\">{currentPuzzle.icon}<\/div>\n               <span className=\"text-white\/20 text-[10px] font-black uppercase tracking-[0.4em] mb-4 block\">Ancient Scroll Fragment<\/span>\n               <p className=\"text-3xl font-light text-slate-100 leading-snug tracking-tight\">{currentPuzzle.definition}<\/p>\n            <\/div>\n\n            {\/* INTERACTIVE CHARACTER SLOTS *\/}\n            <div className=\"mb-12 flex flex-col items-center\">\n              <span className=\"text-[10px] uppercase font-black text-white\/20 tracking-[0.6em] mb-6\">Terminology Decryption<\/span>\n              <div className=\"flex flex-wrap justify-center gap-2 max-w-full\">\n                {slotValues.map((slot, i) => (\n                  <div key={i} className=\"relative\">\n                    {slot.isEditable ? (\n                      <input\n                        ref={(el) => (inputRefs.current[i] = el)}\n                        type=&#8221;text&#8221;\n                        maxLength={1}\n                        value={slot.char}\n                        onChange={(e) => handleSlotChange(i, e.target.value)}\n                        onKeyDown={(e) => handleKeyDown(i, e)}\n                        className={`w-11 h-14 flex items-center justify-center rounded-xl border-2 text-2xl font-black text-center transition-all duration-300\n                          ${slot.char === &#8221; \n                            ? &#8216;bg-black\/50 border-white\/10 text-white\/10&#8217; \n                            : &#8216;bg-amber-600\/30 border-amber-500\/60 text-amber-400 shadow-[0_0_20px_rgba(245,158,11,0.2)] focus:border-amber-400 focus:outline-none focus:ring-2 focus:ring-amber-500\/20&#8217;}`}\n                      \/>\n                    ) : (\n                      <div \n                        className={`w-11 h-14 flex items-center justify-center rounded-xl text-2xl font-black\n                          ${[' ', '-', '\/', '.', '(', ')'].includes(slot.char) \n                            ? 'w-4 text-white\/20' \n                            : 'bg-white\/10 border-2 border-white\/5 text-white\/40'}`}\n                      >\n                        {slot.char}\n                      <\/div>\n                    )}\n                  <\/div>\n                ))}\n              <\/div>\n            <\/div>\n          <\/div>\n\n          <div className=\"flex justify-center z-10 pb-4\">\n            <button \n              onClick={submitAttempt}\n              className=\"bg-amber-600 hover:bg-amber-500 px-20 py-6 rounded-2xl font-black text-2xl shadow-2xl transition-all active:scale-95 border-b-4 border-amber-800 uppercase tracking-widest\"\n            >\n              Unlock Gate\n            <\/button>\n          <\/div>\n        <\/div>\n\n        {\/* Feedback Overlays *\/}\n        {showFeedback === &#8216;correct&#8217; &#038;&#038; (\n          <div className=\"absolute inset-0 bg-emerald-950\/98 backdrop-blur-3xl flex flex-col items-center justify-center text-center p-12 z-50 overflow-hidden\">\n            <div className=\"w-full h-80 rounded-3xl overflow-hidden mb-8 border-2 border-emerald-400 shadow-xl max-w-lg\">\n               <img src={ASSETS.CORRECT_ANSWER} className=\"w-full h-full object-cover\" alt=\"Correct Answer\" \/>\n            <\/div>\n            <h3 className=\"text-6xl font-black mb-6 uppercase tracking-tighter\">SUCCESS<\/h3>\n            <p className=\"text-2xl text-emerald-200\/80 mb-10 max-w-lg leading-relaxed\">The gate mechanism hums and slides open. You are one step closer to enlightenment.<\/p>\n            <button onClick={handleContinue} className=\"bg-emerald-500 hover:bg-emerald-400 text-slate-950 font-black py-7 px-20 rounded-2xl text-2xl transition-all flex items-center space-x-4 shadow-2xl active:scale-95 border-b-4 border-emerald-700\">\n              <span>CONTINUE QUEST<\/span>\n              <ChevronRight className=\"w-8 h-8\" \/>\n            <\/button>\n          <\/div>\n        )}\n\n        {showFeedback === &#8216;wrong&#8217; &#038;&#038; (\n          <div className=\"absolute inset-0 bg-red-950\/98 backdrop-blur-3xl flex flex-col items-center justify-center text-center p-12 z-50 overflow-hidden\">\n            <div className=\"w-full h-80 rounded-3xl overflow-hidden mb-8 border-2 border-red-400 shadow-xl max-w-lg\">\n               <img src={ASSETS.BAD_ANSWER} className=\"w-full h-full object-cover\" alt=\"Wrong Answer\" \/>\n            <\/div>\n            <h3 className=\"text-5xl font-black mb-6 uppercase text-red-100\">FAULT DETECTED<\/h3>\n            <p className=\"text-2xl text-red-200\/70 mb-10 max-w-xl leading-relaxed font-light italic text-balance\">&#8220;That vocabulary is not recognized. The Luddite mists close in&#8230;&#8221;<\/p>\n            <button onClick={() => { setShowFeedback(null); }} className=&#8221;bg-white text-red-950 hover:bg-slate-200 py-7 px-20 rounded-2xl font-black text-2xl transition-all shadow-2xl active:scale-95 flex items-center space-x-4 border-b-4 border-slate-300&#8243;>\n              <RefreshCw className=\"w-8 h-8\" \/>\n              <span>TRY AGAIN<\/span>\n            <\/button>\n          <\/div>\n        )}\n      <\/main>\n\n      <style dangerouslySetInnerHTML={{__html: `\n        @keyframes spin-slow {\n          from { transform: rotate(0deg); }\n          to { transform: rotate(360deg); }\n        }\n        .animate-spin-slow {\n          animation: spin-slow 8s linear infinite;\n        }\n      `}} \/>\n    <\/div>\n  );\n};\n\nexport default App;\n","protected":false},"excerpt":{"rendered":"<p>import React, { useState, useEffect, useMemo, useRef } from &#8216;react&#8217;; import { Heart, ShieldAlert, CheckCircle2, RefreshCw, Trophy, Skull, Users, Network, Generic, Search, UserCog, Accessibility, Play, CircleDollarSign, Recycle, Smartphone, Briefcase, Leaf, Code, DatabaseZap, Lock, Eye, BookOpen, Clock, Map as MapIcon, ChevronRight, MapPinned, Volume2, VolumeX, Compass } from &#8216;lucide-react&#8217;; \/\/ STABLE ASSETS DEFINED OUTSIDE TO PREVENT INFINITE [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}}},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Learn EdTech Vocabulary with a Fun Scape-Game - Digital Magnet Team<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dmt.agency\/es\/learn-edtech-vocabulary-with-a-fun-scape-game\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Learn EdTech Vocabulary with a Fun Scape-Game - Digital Magnet Team\" \/>\n<meta property=\"og:description\" content=\"import React, { useState, useEffect, useMemo, useRef } from &#8216;react&#8217;; import { Heart, ShieldAlert, CheckCircle2, RefreshCw, Trophy, Skull, Users, Network, Generic, Search, UserCog, Accessibility, Play, CircleDollarSign, Recycle, Smartphone, Briefcase, Leaf, Code, DatabaseZap, Lock, Eye, BookOpen, Clock, Map as MapIcon, ChevronRight, MapPinned, Volume2, VolumeX, Compass } from &#8216;lucide-react&#8217;; \/\/ STABLE ASSETS DEFINED OUTSIDE TO PREVENT INFINITE [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dmt.agency\/es\/learn-edtech-vocabulary-with-a-fun-scape-game\/\" \/>\n<meta property=\"og:site_name\" content=\"Digital Magnet Team\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-14T19:40:30+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dmt.agency\/learn-edtech-vocabulary-with-a-fun-scape-game\/\",\"url\":\"https:\/\/www.dmt.agency\/learn-edtech-vocabulary-with-a-fun-scape-game\/\",\"name\":\"Learn EdTech Vocabulary with a Fun Scape-Game - Digital Magnet Team\",\"isPartOf\":{\"@id\":\"https:\/\/www.dmt.agency\/#website\"},\"datePublished\":\"2026-03-14T19:40:28+00:00\",\"dateModified\":\"2026-03-14T19:40:30+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.dmt.agency\/learn-edtech-vocabulary-with-a-fun-scape-game\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dmt.agency\/learn-edtech-vocabulary-with-a-fun-scape-game\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dmt.agency\/learn-edtech-vocabulary-with-a-fun-scape-game\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.dmt.agency\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Learn EdTech Vocabulary with a Fun Scape-Game\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dmt.agency\/#website\",\"url\":\"https:\/\/www.dmt.agency\/\",\"name\":\"Digital Magnet Team\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.dmt.agency\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dmt.agency\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.dmt.agency\/#organization\",\"name\":\"Digital Magnet Team\",\"url\":\"https:\/\/www.dmt.agency\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.dmt.agency\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.dmt.agency\/wp-content\/uploads\/2020\/05\/cropped-DMT-2020-1.jpg\",\"contentUrl\":\"https:\/\/www.dmt.agency\/wp-content\/uploads\/2020\/05\/cropped-DMT-2020-1.jpg\",\"width\":500,\"height\":312,\"caption\":\"Digital Magnet Team\"},\"image\":{\"@id\":\"https:\/\/www.dmt.agency\/#\/schema\/logo\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Learn EdTech Vocabulary with a Fun Scape-Game - Digital Magnet Team","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dmt.agency\/es\/learn-edtech-vocabulary-with-a-fun-scape-game\/","og_locale":"es_ES","og_type":"article","og_title":"Learn EdTech Vocabulary with a Fun Scape-Game - Digital Magnet Team","og_description":"import React, { useState, useEffect, useMemo, useRef } from &#8216;react&#8217;; import { Heart, ShieldAlert, CheckCircle2, RefreshCw, Trophy, Skull, Users, Network, Generic, Search, UserCog, Accessibility, Play, CircleDollarSign, Recycle, Smartphone, Briefcase, Leaf, Code, DatabaseZap, Lock, Eye, BookOpen, Clock, Map as MapIcon, ChevronRight, MapPinned, Volume2, VolumeX, Compass } from &#8216;lucide-react&#8217;; \/\/ STABLE ASSETS DEFINED OUTSIDE TO PREVENT INFINITE [&hellip;]","og_url":"https:\/\/www.dmt.agency\/es\/learn-edtech-vocabulary-with-a-fun-scape-game\/","og_site_name":"Digital Magnet Team","article_modified_time":"2026-03-14T19:40:30+00:00","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.dmt.agency\/learn-edtech-vocabulary-with-a-fun-scape-game\/","url":"https:\/\/www.dmt.agency\/learn-edtech-vocabulary-with-a-fun-scape-game\/","name":"Learn EdTech Vocabulary with a Fun Scape-Game - Digital Magnet Team","isPartOf":{"@id":"https:\/\/www.dmt.agency\/#website"},"datePublished":"2026-03-14T19:40:28+00:00","dateModified":"2026-03-14T19:40:30+00:00","breadcrumb":{"@id":"https:\/\/www.dmt.agency\/learn-edtech-vocabulary-with-a-fun-scape-game\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dmt.agency\/learn-edtech-vocabulary-with-a-fun-scape-game\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dmt.agency\/learn-edtech-vocabulary-with-a-fun-scape-game\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.dmt.agency\/"},{"@type":"ListItem","position":2,"name":"Learn EdTech Vocabulary with a Fun Scape-Game"}]},{"@type":"WebSite","@id":"https:\/\/www.dmt.agency\/#website","url":"https:\/\/www.dmt.agency\/","name":"Digital Magnet Team","description":"","publisher":{"@id":"https:\/\/www.dmt.agency\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dmt.agency\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.dmt.agency\/#organization","name":"Digital Magnet Team","url":"https:\/\/www.dmt.agency\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.dmt.agency\/#\/schema\/logo\/image\/","url":"https:\/\/www.dmt.agency\/wp-content\/uploads\/2020\/05\/cropped-DMT-2020-1.jpg","contentUrl":"https:\/\/www.dmt.agency\/wp-content\/uploads\/2020\/05\/cropped-DMT-2020-1.jpg","width":500,"height":312,"caption":"Digital Magnet Team"},"image":{"@id":"https:\/\/www.dmt.agency\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.dmt.agency\/es\/wp-json\/wp\/v2\/pages\/1375"}],"collection":[{"href":"https:\/\/www.dmt.agency\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.dmt.agency\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.dmt.agency\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dmt.agency\/es\/wp-json\/wp\/v2\/comments?post=1375"}],"version-history":[{"count":2,"href":"https:\/\/www.dmt.agency\/es\/wp-json\/wp\/v2\/pages\/1375\/revisions"}],"predecessor-version":[{"id":1379,"href":"https:\/\/www.dmt.agency\/es\/wp-json\/wp\/v2\/pages\/1375\/revisions\/1379"}],"wp:attachment":[{"href":"https:\/\/www.dmt.agency\/es\/wp-json\/wp\/v2\/media?parent=1375"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}