<!DOCTYPE html> <html lang="uk"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <link rel="icon" type="image/png" href="favicon.png"> <style> :root { --md-sys-color-surface: #FFFFFF; --md-sys-color-on-surface: #1C1B1F; --md-sys-color-surface-container: #F3F3F3; --md-sys-color-outline: #E0E0E0; --md-sys-color-primary: #000000; } body { font-family: 'Segoe UI', Roboto, sans-serif; background-color: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface); margin: 0; display: flex; justify-content: center; } *:focus { outline: none !important; } button, input, a { -webkit-tap-highlight-color: transparent; } .container { width: 100%; max-width: 800px; padding: 16px 16px 40px 16px; box-sizing: border-box; } .top-bar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; gap: 10px; } .lang-switch { display: flex; position: relative; background: var(--md-sys-color-surface-container); padding: 4px; border-radius: 12px; flex-shrink: 0; overflow: hidden; } .lang-slider { position: absolute; top: 4px; left: 4px; width: calc(50% - 4px); height: calc(100% - 8px); background: var(--md-sys-color-surface); border-radius: 8px; transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); z-index: 1; } .lang-btn { background: none; border: none; padding: 6px 12px; font-size: 11px; cursor: pointer; border-radius: 8px; color: #777; font-weight: 600; position: relative; z-index: 2; transition: color 0.3s ease; } .lang-btn.active { color: var(--md-sys-color-on-surface); } .attribution { font-size: 11px; color: #555; text-align: right; line-height: 1.4; } .attribution a { color: inherit; text-decoration: none; } .search-bar { display: flex; align-items: center; background: var(--md-sys-color-surface-container); border-radius: 28px; padding: 4px 4px 4px 16px; margin-bottom: 32px; } input { flex: 1; border: none; background: transparent; padding: 8px 0; font-size: 16px; outline: none; color: inherit; min-width: 0; transition: opacity 0.2s, filter 0.2s; } #search-btn { background: var(--md-sys-color-on-surface); color: white; border: none; padding: 10px 20px; border-radius: 24px; font-size: 14px; font-weight: 500; cursor: pointer; transition: transform 0.2s ease; white-space: nowrap; } #search-btn span { transition: opacity 0.2s, filter 0.2s; display: inline-block; } #search-btn:active { transform: scale(0.96); } .reveal { opacity: 0; transform: translateY(20px); filter: blur(8px); transition: all 0.6s cubic-bezier(0.1, 0.9, 0.2, 1); will-change: transform, opacity, filter; } .reveal.visible { opacity: 1; transform: translateY(0); filter: blur(0); } .ui-hidden { opacity: 0; filter: blur(4px); } h1 { font-size: 2rem; font-weight: 400; margin: 0 0 16px 0; word-wrap: break-word; } #output { line-height: 1.6; font-size: 16px; } #output img { max-width: 100%; height: auto; border-radius: 0 !important; margin: 12px 0; } table { width: 100% !important; border-collapse: collapse; margin: 16px 0; border: 1px solid var(--md-sys-color-outline); display: block; overflow-x: auto; } th, td { padding: 10px; border: 1px solid var(--md-sys-color-outline); text-align: left; min-width: 100px; } .infobox { float: none !important; width: 100% !important; margin: 0 0 24px 0 !important; background: var(--md-sys-color-surface-container) !important; border-radius: 20px; border: none !important; padding: 16px; box-sizing: border-box; } .mw-empty-elt, .mw-editsection, .navbox, .ambox, .sistersitebox, .mw-jump-link { display: none; } a { color: black; text-decoration: underline; text-underline-offset: 4px; } @media (max-width: 600px) { h1 { font-size: 1.75rem; } } </style> </head> <body> <div class="container"> <div class="top-bar"> <div class="lang-switch"> <div id="lang-slider" class="lang-slider"></div> <button id="btn-uk" class="lang-btn active" onclick="setLang('uk')">UK</button> <button id="btn-en" class="lang-btn" onclick="setLang('en')">EN</button> </div> <div class="attribution"> Powered by <a href="https://www.mediawiki.org" target="_blank"><b>Mediawiki</b></a> | <a href="https://orchis.w10.site/source.html" target="_blank"><b>Source Code</b></a> </div> </div> <div class="search-bar"> <input type="text" id="topic" placeholder="Введіть тему..." autocomplete="off"> <button id="search-btn" onclick="searchWiki()"><span id="search-btn-text">Пошук</span></button> </div> <div id="output"></div> </div> <script type="module"> window.setLang = setLang; window.searchWiki = searchWiki; let uiLang = 'uk', currentArticleLang = 'uk', originalHtml = ''; const i18n = { uk: { placeholder: "Введіть тему...", button: "Пошук", loading: "Завантаження...", notFound: "Статтю не знайдено.", error: "Помилка." }, en: { placeholder: "Enter topic...", button: "Search", loading: "Loading...", notFound: "Not found.", error: "Error." } }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) entry.target.classList.add('visible'); }); }, { threshold: 0.1 }); function applyReveal() { const children = document.getElementById('output') .querySelectorAll('h1, h2, h3, h4, p, table, .infobox, img, ul, ol'); children.forEach(el => { el.classList.add('reveal'); observer.observe(el); }); } function fixPaths(html, lang) { const div = document.createElement('div'); div.innerHTML = html; const base = `https://${lang}.wikipedia.org`; div.querySelectorAll('img').forEach(img => { let src = img.getAttribute('src'); if (src && src.startsWith('//')) img.src = 'https:' + src; else if (src && src.startsWith('/')) img.src = base + src; img.removeAttribute('srcset'); }); div.querySelectorAll('[href]').forEach(el => { let href = el.getAttribute('href'); if (href && href.startsWith('//')) el.setAttribute('href', 'https:' + href); }); return div.innerHTML; } function setContent(html) { const box = document.getElementById('output'); box.innerHTML = html; applyReveal(); attachLinks(); } async function setLang(lang) { if (uiLang === lang) return; uiLang = lang; const slider = document.getElementById('lang-slider'); const input = document.getElementById('topic'); const btnText = document.getElementById('search-btn-text'); slider.style.transform = lang === 'en' ? 'translateX(100%)' : 'translateX(0)'; input.classList.add('ui-hidden'); btnText.classList.add('ui-hidden'); await new Promise(r => setTimeout(r, 200)); document.querySelectorAll('.lang-btn').forEach(btn => btn.classList.remove('active')); document.getElementById(`btn-${lang}`).classList.add('active'); input.placeholder = i18n[lang].placeholder; btnText.innerText = i18n[lang].button; requestAnimationFrame(() => { requestAnimationFrame(() => { input.classList.remove('ui-hidden'); btnText.classList.remove('ui-hidden'); }); }); } function attachLinks() { const box = document.getElementById('output'); const input = document.getElementById('topic'); box.querySelectorAll('a').forEach(link => { const href = link.getAttribute('href'); if (href?.includes('/wiki/') && !href.includes(':')) { link.onclick = (e) => { e.preventDefault(); const parts = href.split('/wiki/'); const nextTitle = decodeURIComponent(parts[parts.length - 1]).replace(/_/g, ' '); input.value = nextTitle; searchWiki(nextTitle); }; } else if (href && !href.startsWith('#')) { link.target = '_blank'; } }); } async function searchWiki(targetTitle = null) { const input = document.getElementById('topic'); const query = targetTitle || input.value.trim(); if (!query) return; setContent(`<h4>${i18n[uiLang].loading}</h4>`); currentArticleLang = /[а-яёіїєґ]/i.test(query) ? 'uk' : 'en'; try { const baseUrl = `https://${currentArticleLang}.wikipedia.org/w/api.php`; const sRes = await fetch( `${baseUrl}?action=opensearch&search=${encodeURIComponent(query)}&limit=1&format=json&origin=*` ); const sData = await sRes.json(); const title = sData[1][0]; if (!title) { setContent(`<h2>${i18n[uiLang].notFound}</h2>`); return; } const cRes = await fetch( `${baseUrl}?action=parse&page=${encodeURIComponent(title)}&prop=text&format=json&origin=*&redirects=1` ); const cData = await cRes.json(); let rawHtml = `<h1>${cData.parse.title}</h1>` + cData.parse.text['*']; originalHtml = fixPaths(rawHtml, currentArticleLang); setContent(originalHtml); window.scrollTo({ top: 0, behavior: 'smooth' }); } catch (e) { setContent(`<h2>${i18n[uiLang].error}</h2>`); } } document.getElementById('topic') .addEventListener('keypress', (e) => { if (e.key === 'Enter') searchWiki(); }); </script> </body> </html>