<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NEON | Local Search Engine</title>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;700&display=swap" rel="stylesheet">
<style>
:root {
--bg: #000000;
--text: #ffffff;
--accent: #ffffff;
--faded: rgba(255, 255, 255, 0.1);
--neon-blue: #4dabff;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Space Grotesk', sans-serif;
}
body {
background-color: var(--bg);
min-height: 100vh;
color: var(--text);
display: flex;
flex-direction: column;
overflow-x: hidden;
line-height: 1.5;
}
body::before {
content: "";
position: fixed;
top: 0; left: 0; width: 100%; height: 100%;
background: url('https://grainy-gradients.vercel.app/noise.svg');
opacity: 0.05;
pointer-events: none;
z-index: 99;
}
#container {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1);
padding: 20px;
}
.logo-container { margin-bottom: 50px; text-align: left; }
.logo-line {
font-size: 16px;
font-weight: 700;
letter-spacing: 0.5rem;
text-transform: uppercase;
line-height: 1.4;
display: flex;
align-items: baseline;
}
.logo-line span { font-weight: 300; letter-spacing: 0.2rem; opacity: 0.4; margin-left: 15px; font-size: 13px; }
.search-wrapper { width: 100%; max-width: 550px; position: relative; z-index: 10; margin-bottom: 20px; }
input {
width: 100%;
background: transparent;
border: none;
border-left: 1px solid var(--faded);
padding: 15px 60px 15px 25px;
color: white;
font-size: 20px;
font-weight: 300;
outline: none;
transition: 0.4s;
}
input:focus { border-left: 1px solid var(--accent); }
.search-trigger {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
background: transparent;
border: none;
color: white;
cursor: pointer;
padding: 12px;
opacity: 0.2;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
input:not(:placeholder-shown) ~ .search-trigger,
.search-trigger:hover {
opacity: 1;
background: rgba(255,255,255,0.05);
filter: drop-shadow(0 0 12px white);
}
#results-view {
display: none;
width: 100%;
max-width: 800px;
margin: 0 auto;
padding: 0 20px 120px 20px;
}
/* --- HAMBURGER MENU --- */
#menu-toggle {
position: fixed;
top: 30px;
right: 30px;
z-index: 1000;
background: transparent;
border: none;
cursor: pointer;
display: flex;
flex-direction: column;
gap: 6px;
padding: 10px;
}
.bar { width: 22px; height: 1px; background-color: white; transition: 0.3s; }
.active-toggle .bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.active-toggle .bar:nth-child(2) { opacity: 0; }
.active-toggle .bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
#sidebar {
position: fixed;
top: 0;
right: -320px;
width: 320px;
height: 100%;
background: rgba(0, 0, 0, 0.98);
backdrop-filter: blur(20px);
border-left: 1px solid var(--faded);
z-index: 999;
transition: 0.5s cubic-bezier(0.16, 1, 0.3, 1);
padding: 100px 50px;
}
#sidebar.active { right: 0; }
.nav-header { font-size: 10px; letter-spacing: 5px; color: var(--faded); margin-bottom: 50px; text-transform: uppercase; }
.nav-links { display: flex; flex-direction: column; gap: 30px; }
.nav-links a {
color: white;
text-decoration: none;
font-size: 18px;
font-weight: 300;
letter-spacing: 2px;
transition: 0.3s;
}
.nav-links a:hover { color: var(--neon-blue); padding-left: 10px; }
/* --- LOCAL RESULT STYLES --- */
.result-item { margin-bottom: 35px; opacity: 0; transform: translateY(15px); animation: slideUp 0.6s ease forwards; }
.result-title { color: var(--neon-blue); text-decoration: none; font-size: 20px; display: block; margin-bottom: 6px; font-weight: 400; }
.result-title:hover { text-decoration: underline; }
.result-link { color: #666; font-size: 11px; margin-top: 5px; word-break: break-all; text-transform: uppercase; letter-spacing: 1px; }
.no-results { color: #444; font-size: 14px; letter-spacing: 1px; text-align: center; margin-top: 40px; }
body.searching #container { justify-content: flex-start; padding-top: 40px; min-height: auto; flex-grow: 0; }
body.searching .logo-container { margin-bottom: 30px; transform: scale(0.8); }
body.searching #results-view { display: block; }
@keyframes slideUp { from { opacity: 0; transform: translateY(15px); } to { opacity: 1; transform: translateY(0); } }
.footer { position: fixed; bottom: 30px; width: 100%; text-align: center; font-size: 10px; letter-spacing: 5px; color: var(--faded); pointer-events: none; }
</style>
</head>
<body>
<button id="menu-toggle" onclick="toggleMenu()">
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
</button>
<nav id="sidebar">
<div class="nav-header">Local Engine</div>
<div class="nav-links">
<a href="#" onclick="toggleMenu()">Search Home</a>
</div>
</nav>
<div id="container">
<div class="logo-container">
<div class="logo-line">N<span>ext</span></div>
<div class="logo-line">E<span>volution</span></div>
<div class="logo-line">O<span>f</span></div>
<div class="logo-line">N<span>avigation</span></div>
</div>
<div class="search-wrapper">
<input type="text" id="queryInput" placeholder="explore" autocomplete="off" spellcheck="false" autofocus>
<button class="search-trigger" id="searchBtn">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<circle cx="11" cy="11" r="8"></circle>
<line x1="21" x2="16.65" y1="21" y2="16.65"></line>
</svg>
</button>
</div>
</div>
<div id="results-view">
<div id="main-web-results"></div>
</div>
<div class="footer">SIMPLE. FAST. YOURS.</div>
<script src="sites.js"></script>
<script>
const input = document.getElementById('queryInput');
const searchBtn = document.getElementById('searchBtn');
const body = document.body;
const webDiv = document.getElementById('main-web-results');
// Parse data from sites.js file
const sites = rawSitesData.split('\n')
.map(line => line.trim())
.filter(line => line.length > 0);
// Sidebar View Toggle Function
function toggleMenu() {
document.getElementById('sidebar').classList.toggle('active');
document.getElementById('menu-toggle').classList.toggle('active-toggle');
}
// High-performance clean search functionality
function performSearch() {
const rawQuery = input.value.toLowerCase().trim();
if (!rawQuery) {
body.classList.remove('searching');
webDiv.innerHTML = '';
return;
}
body.classList.add('searching');
webDiv.innerHTML = "";
const queryTerms = rawQuery.split(/\s+/);
const cleanQuery = rawQuery.replace(/[^a-z0-9]/g, '');
let htmlOutput = '';
let matchCount = 0;
for (let i = 0; i < sites.length; i++) {
const site = sites[i];
const lowerSite = site.toLowerCase();
const cleanSite = lowerSite.replace(/[^a-z0-9]/g, '');
let isMatch = false;
if (lowerSite.includes(rawQuery)) {
isMatch = true;
} else if (cleanSite.includes(cleanQuery)) {
isMatch = true;
} else {
let matchAllTerms = true;
for (let j = 0; j < queryTerms.length; j++) {
if (!lowerSite.includes(queryTerms[j])) {
matchAllTerms = false;
break;
}
}
if (matchAllTerms) {
isMatch = true;
}
}
if (isMatch) {
let displayHost = site;
try { displayHost = new URL(`https://${site}`).hostname; } catch(e){}
htmlOutput += `
<div class="result-item" style="animation-delay: ${matchCount * 0.04}s">
<a href="https://${site}" target="_blank" rel="noopener noreferrer" class="result-title">${site}</a>
<div class="result-link">${displayHost}</div>
</div>
`;
matchCount++;
}
}
webDiv.innerHTML = htmlOutput || '<div class="no-results">ZERO NODES FOUND.</div>';
}
searchBtn.addEventListener('click', performSearch);
input.addEventListener('keydown', (e) => { if (e.key === 'Enter') performSearch(); });
</script>
</body>
</html>