Spaces:
Running
Running
| <html lang="vi"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Wiki Glass Dark Reader</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&family=Lora:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --glass-bg: rgba(25, 25, 25, 0.65); | |
| --glass-border: rgba(255, 255, 255, 0.08); | |
| --accent-blue: #3b82f6; | |
| } | |
| body { | |
| background: radial-gradient(circle at top right, #1e293b, #0f172a, #020617); | |
| color: #e2e8f0; | |
| font-family: 'Inter', sans-serif; | |
| min-height: 100vh; | |
| overflow-x: hidden; | |
| } | |
| .glass { | |
| background: var(--glass-bg); | |
| backdrop-filter: blur(20px); | |
| -webkit-backdrop-filter: blur(20px); | |
| border: 1px solid var(--glass-border); | |
| } | |
| .wiki-content-area { | |
| line-height: 1.8; | |
| font-size: 1.125rem; | |
| } | |
| .wiki-content-area h2 { | |
| font-size: 1.75rem; | |
| font-weight: 700; | |
| margin-top: 2.5rem; | |
| margin-bottom: 1.25rem; | |
| color: #f8fafc; | |
| border-bottom: 1px solid var(--glass-border); | |
| padding-bottom: 0.5rem; | |
| } | |
| .wiki-content-area p { | |
| margin-bottom: 1.5rem; | |
| color: #cbd5e1; | |
| } | |
| .wiki-content-area b, .wiki-content-area strong { | |
| color: #f1f5f9; | |
| font-weight: 600; | |
| } | |
| .wiki-content-area ul { | |
| list-style-type: none; | |
| padding-left: 1rem; | |
| margin-bottom: 1.5rem; | |
| } | |
| .wiki-content-area li { | |
| position: relative; | |
| padding-left: 1.5rem; | |
| margin-bottom: 0.75rem; | |
| } | |
| .wiki-content-area li::before { | |
| content: "•"; | |
| color: var(--accent-blue); | |
| position: absolute; | |
| left: 0; | |
| font-weight: bold; | |
| } | |
| .search-input { | |
| background: rgba(255, 255, 255, 0.05); | |
| border: 1px solid var(--glass-border); | |
| transition: all 0.3s ease; | |
| } | |
| .search-input:focus { | |
| background: rgba(255, 255, 255, 0.1); | |
| border-color: var(--accent-blue); | |
| box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.15); | |
| } | |
| .font-serif { font-family: 'Lora', serif; } | |
| .font-sans { font-family: 'Inter', sans-serif; } | |
| .image-shimmer { | |
| background: linear-gradient(90deg, #1e293b 25%, #334155 50%, #1e293b 75%); | |
| background-size: 200% 100%; | |
| animation: shimmer 2s infinite; | |
| } | |
| @keyframes shimmer { | |
| 0% { background-position: 200% 0; } | |
| 100% { background-position: -200% 0; } | |
| } | |
| .custom-scroll::-webkit-scrollbar { width: 8px; } | |
| .custom-scroll::-webkit-scrollbar-track { background: transparent; } | |
| .custom-scroll::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.1); border-radius: 4px; } | |
| .custom-scroll::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.2); } | |
| </style> | |
| </head> | |
| <body class="custom-scroll"> | |
| <!-- Sticky Header --> | |
| <header class="glass sticky top-0 z-50 px-6 py-4"> | |
| <div class="max-w-5xl mx-auto flex flex-col sm:flex-row items-center gap-6"> | |
| <div class="flex items-center gap-3"> | |
| <div class="w-10 h-10 bg-blue-600 rounded-xl flex items-center justify-center shadow-lg shadow-blue-900/20"> | |
| <svg class="text-white w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332-4.5-1.253"></path></svg> | |
| </div> | |
| <h1 class="text-xl font-extrabold tracking-tighter text-white">WIKI<span class="text-blue-500">GLASS</span></h1> | |
| </div> | |
| <div class="relative flex-1 w-full max-w-2xl"> | |
| <input | |
| type="text" | |
| id="searchQuery" | |
| placeholder="Tìm kiếm kiến thức..." | |
| class="search-input w-full py-3 px-5 rounded-2xl outline-none text-white placeholder-gray-500" | |
| onkeypress="if(event.key === 'Enter') performWikiFetch()" | |
| > | |
| <button | |
| onclick="performWikiFetch()" | |
| class="absolute right-2 top-1.5 bottom-1.5 px-5 bg-blue-600 hover:bg-blue-500 text-white text-sm font-bold rounded-xl transition-all active:scale-95" | |
| > | |
| TRA CỨU | |
| </button> | |
| </div> | |
| <div class="flex gap-2"> | |
| <button onclick="toggleFont()" id="fontBtn" class="p-2 rounded-lg bg-white/5 hover:bg-white/10 text-xs font-medium border border-white/10">SERIF</button> | |
| </div> | |
| </div> | |
| </header> | |
| <main class="max-w-4xl mx-auto px-6 py-12"> | |
| <!-- Loader --> | |
| <div id="loader" class="hidden flex flex-col items-center justify-center py-20"> | |
| <div class="w-12 h-12 border-4 border-blue-500/30 border-t-blue-500 rounded-full animate-spin"></div> | |
| <p class="mt-4 text-gray-400 font-medium">Đang xử lý dữ liệu Wiki...</p> | |
| </div> | |
| <!-- Article Container --> | |
| <article id="articleFrame" class="hidden"> | |
| <!-- Hero Image Section --> | |
| <div id="heroBox" class="relative w-full h-[300px] md:h-[450px] rounded-[2rem] overflow-hidden mb-12 glass shadow-2xl hidden"> | |
| <img id="articleImage" src="" class="w-full h-full object-cover"> | |
| <div class="absolute inset-0 bg-gradient-to-t from-slate-950/80 to-transparent"></div> | |
| </div> | |
| <div class="glass rounded-[2.5rem] p-8 md:p-16 relative overflow-hidden"> | |
| <div class="absolute top-0 left-0 w-32 h-32 bg-blue-600/10 blur-[80px] -z-10"></div> | |
| <header class="mb-10"> | |
| <div class="flex items-center gap-3 mb-4"> | |
| <span class="px-3 py-1 bg-blue-500/10 text-blue-400 text-[10px] font-bold uppercase tracking-[0.2em] rounded-full border border-blue-500/20">Wikipedia Source</span> | |
| <span id="langTag" class="text-gray-500 text-[10px] font-bold uppercase">VI_VN</span> | |
| </div> | |
| <h2 id="articleTitle" class="text-4xl md:text-6xl font-extrabold text-white leading-tight"></h2> | |
| </header> | |
| <div id="articleContent" class="wiki-content-area font-sans"> | |
| <!-- Wikipedia content injected here --> | |
| </div> | |
| <footer class="mt-16 pt-8 border-t border-white/5 flex flex-col sm:flex-row justify-between items-center gap-6"> | |
| <p class="text-gray-500 text-sm italic">Nội dung được cung cấp theo giấy phép Creative Commons.</p> | |
| <a id="sourceUrl" href="#" target="_blank" class="flex items-center gap-2 text-blue-400 font-bold hover:text-blue-300 transition-colors"> | |
| Mở liên kết gốc | |
| <svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path></svg> | |
| </a> | |
| </footer> | |
| </div> | |
| </article> | |
| <!-- Initial Placeholder --> | |
| <div id="emptyState" class="text-center py-20 opacity-40"> | |
| <div class="text-8xl mb-6">🔭</div> | |
| <h3 class="text-2xl font-bold text-white mb-2">Trung tâm Tri thức Glass</h3> | |
| <p class="max-w-xs mx-auto text-gray-400">Khám phá thế giới qua lăng kính trực quan và hiện đại.</p> | |
| </div> | |
| </main> | |
| <script> | |
| let isSerif = false; | |
| function toggleFont() { | |
| const content = document.getElementById('articleContent'); | |
| const btn = document.getElementById('fontBtn'); | |
| isSerif = !isSerif; | |
| if (isSerif) { | |
| content.classList.remove('font-sans'); | |
| content.classList.add('font-serif'); | |
| btn.innerText = 'SANS'; | |
| } else { | |
| content.classList.remove('font-serif'); | |
| content.classList.add('font-sans'); | |
| btn.innerText = 'SERIF'; | |
| } | |
| } | |
| async function performWikiFetch() { | |
| const query = document.getElementById('searchQuery').value.trim(); | |
| const loader = document.getElementById('loader'); | |
| const frame = document.getElementById('articleFrame'); | |
| const empty = document.getElementById('emptyState'); | |
| if (!query) return; | |
| // UI Transitions | |
| loader.classList.remove('hidden'); | |
| frame.classList.add('hidden'); | |
| empty.classList.add('hidden'); | |
| try { | |
| // Search for the most relevant page | |
| const sUrl = `https://vi.wikipedia.org/w/api.php?action=query&list=search&srsearch=${encodeURIComponent(query)}&format=json&origin=*`; | |
| const sResp = await fetch(sUrl); | |
| const sData = await sResp.json(); | |
| if (!sData.query.search.length) throw "Không tìm thấy dữ liệu phù hợp."; | |
| const bestMatch = sData.query.search[0].title; | |
| // Fetch content and high-res image | |
| const cUrl = `https://vi.wikipedia.org/w/api.php?action=query&prop=extracts|pageimages&titles=${encodeURIComponent(bestMatch)}&format=json&origin=*&pithumbsize=1200`; | |
| const cResp = await fetch(cUrl); | |
| const cData = await cResp.json(); | |
| const pages = cData.query.pages; | |
| const pid = Object.keys(pages)[0]; | |
| const page = pages[pid]; | |
| // Update UI | |
| document.getElementById('articleTitle').innerText = page.title; | |
| document.getElementById('articleContent').innerHTML = page.extract; | |
| document.getElementById('sourceUrl').href = `https://vi.wikipedia.org/wiki/${encodeURIComponent(page.title)}`; | |
| const hero = document.getElementById('heroBox'); | |
| if (page.thumbnail) { | |
| document.getElementById('articleImage').src = page.thumbnail.source; | |
| hero.classList.remove('hidden'); | |
| } else { | |
| hero.classList.add('hidden'); | |
| } | |
| loader.classList.add('hidden'); | |
| frame.classList.remove('hidden'); | |
| window.scrollTo({ top: 0, behavior: 'smooth' }); | |
| } catch (err) { | |
| loader.classList.add('hidden'); | |
| empty.classList.remove('hidden'); | |
| alert(err); | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> | |