agnes-love/_site/search/index.html

552 lines
20 KiB
HTML
Raw Permalink Normal View History

2026-06-25 00:57:39 +00:00
<!doctype html>
<html lang="en" class="scroll-smooth">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Search Results — Agnes the Alien</title>
<meta name="description" content="Personal website and blog of Agnes the Alien." />
<meta name="generator" content="Eleventy" />
<link rel="canonical" href="https://agnes.love/search/" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Agnes the Alien" />
<meta property="og:url" content="https://agnes.love/search/" />
<meta property="og:title" content="Search Results" />
<meta property="og:description" content="Personal website and blog of Agnes the Alien." />
<meta property="og:image" content="https://agnes.love//screenshot.png" />
<meta property="og:image:alt" content="Agnes the Alien preview" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Search Results" />
<meta name="twitter:description" content="Personal website and blog of Agnes the Alien." />
<meta name="twitter:image" content="https://agnes.love//screenshot.png" />
<meta name="twitter:image:alt" content="Agnes the Alien preview" />
<link rel="webmention" href="https://webmention.io/agnes.love/webmention" />
<link rel="pingback" href="https://webmention.io/agnes.love/xmlrpc" />
<link rel="stylesheet" href="/assets/css/build.css" />
<link rel="alternate" type="application/atom+xml" title="Agnes the Alien Feed" href="/feed.xml" />
<link rel="icon" href="/assets/favicon.svg" type="image/svg+xml">
<link rel="shortcut icon" href="/assets/favicon.svg" type="image/svg+xml">
<link rel="mask-icon" href="/assets/favicon.svg" color="#a78bfa">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png">
<link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png">
<meta name="theme-color" content="#a78bfa" />
<link rel="manifest" href="/manifest.webmanifest">
<link id="hljs-light" rel="stylesheet" href="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/styles/tokyo-night-light.min.css">
<link id="hljs-dark" rel="stylesheet" href="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/styles/tokyo-night-dark.min.css" disabled>
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/highlight.min.js" defer></script>
<script defer>
document.addEventListener('DOMContentLoaded', function () {
const html = document.documentElement;
const light = document.getElementById('hljs-light');
const dark = document.getElementById('hljs-dark');
function applyTheme() {
const isDark = html.classList.contains('dark');
if (light && dark) {
light.disabled = !!isDark;
dark.disabled = !isDark;
}
}
// Initial apply
applyTheme();
// Observe class changes on <html> to react to dark-mode toggle
const observer = new MutationObserver(applyTheme);
observer.observe(html, { attributes: true, attributeFilter: ['class'] });
// Highlight code blocks
document.querySelectorAll('pre code').forEach((el) => {
if (window.hljs && typeof window.hljs.highlightElement === 'function') {
window.hljs.highlightElement(el);
}
});
});
</script>
<style>
.contrast { filter: contrast(1.2) saturate(1.1); }
.reduce-motion * { transition: none !important; animation: none !important; }
</style>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "WebSite",
"url": "https://agnes.love",
"name": "Agnes the Alien",
"description": "Personal website and blog of Agnes the Alien."
},
{
"@type": "Organization",
"name": "Agnes the Alien",
"url": "https://agnes.love",
"sameAs": [
]
}
]
}
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://agnes.love"
},
{
"@type": "ListItem",
"position": 2,
"name": "Search Results",
"item": "https://agnes.love/search/"
}
]
}
</script>
</head>
<body class="bg-[var(--bg)] text-[var(--text)] min-h-screen flex flex-col">
<div id="progress-bar" aria-hidden="true"></div>
<header class="bg-[var(--surface)] border-b border-gray-200 dark:border-gray-700">
<div class="container mx-auto px-4 py-3 flex items-center gap-3">
<button id="hamburger" class="md:hidden p-2 rounded border border-gray-300 dark:border-gray-600" aria-label="Toggle menu" aria-controls="primary-nav" aria-expanded="false">
<span class="bar-1 block w-5 h-0.5 bg-gray-700 dark:bg-gray-200 mb-1 transition-transform"></span>
<span class="bar-2 block w-5 h-0.5 bg-gray-700 dark:bg-gray-200 mb-1 transition-opacity"></span>
<span class="bar-3 block w-5 h-0.5 bg-gray-700 dark:bg-gray-200 transition-transform"></span>
</button>
<a class="text-lg font-semibold" href="/">Agnes the Alien</a>
<form class="ml-auto hidden sm:block" role="search" aria-label="Site" action="/search/" method="get">
<label class="sr-only" for="q">Search</label>
<input id="q" name="q" type="search" placeholder="Search…" class="px-3 py-2 border rounded w-64" />
</form>
<div class="flex items-center gap-2 ml-2">
<button id="dark-toggle" class="px-2 py-1 text-sm border rounded" aria-pressed="false" aria-label="Toggle dark mode">🌙</button>
<div class="relative">
<button id="a11y-toggle" class="px-2 py-1 text-sm border rounded" aria-expanded="false" aria-controls="a11y-menu">A11y</button>
<div id="a11y-menu" class="absolute right-0 mt-1 bg-[var(--surface)] border rounded p-2 text-sm space-x-2 whitespace-nowrap hidden">
<button id="font-dec" class="px-2 py-1 border rounded">A-</button>
<button id="font-inc" class="px-2 py-1 border rounded">A+</button>
<button id="contrast-toggle" class="px-2 py-1 border rounded">Contrast</button>
<button id="motion-toggle" class="px-2 py-1 border rounded">Reduce motion</button>
<button id="font-toggle" type="button" aria-pressed="false" class="px-2 py-1 border rounded hidden md:inline-block">System Fonts</button>
</div>
</div>
</div>
</div>
</header>
<nav class="bg-[var(--surface)] border-b border-gray-200 dark:border-gray-700">
<div id="primary-nav" class="container mx-auto px-4 py-2 hidden md:block">
<ul class="flex flex-col md:flex-row text-base md:text-sm space-y-3 md:space-y-0 md:space-x-6">
<li>
<a href="/" class="nav-item block py-2 text-purple-600 dark:text-purple-400 "
>🏠 Home</a>
</li>
<li>
<a href="/blog/" class="nav-item block py-2 text-purple-600 dark:text-purple-400 "
>✍️ Blog</a>
</li>
<li>
<a href="/about/" class="nav-item block py-2 text-purple-600 dark:text-purple-400 "
>👋 About</a>
</li>
<li>
<a href="/uses/" class="nav-item block py-2 text-purple-600 dark:text-purple-400 "
>🛠️ Uses</a>
</li>
<li>
<a href="/now/" class="nav-item block py-2 text-purple-600 dark:text-purple-400 "
>📍 Now</a>
</li>
<li>
<a href="/contact/" class="nav-item block py-2 text-purple-600 dark:text-purple-400 "
>💬 Contact</a>
</li>
</ul>
</div>
</nav>
<div class="container mx-auto px-4 py-6 max-w-4xl flex-1">
<main>
<div class="max-w-4xl">
<h1 class="text-3xl font-bold mb-6 flex items-center gap-2">
🔍 Search Results
</h1>
<!-- Search form -->
<form class="mb-8" role="search" aria-label="Site search">
<div class="flex gap-2">
<input
id="search-query"
name="q"
type="search"
placeholder="Search posts, pages, and content..."
class="flex-1 px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-purple-500 focus:border-transparent"
autocomplete="off"
/>
<button
type="submit"
class="px-6 py-3 bg-purple-600 hover:bg-purple-700 text-white rounded-lg transition-colors font-medium"
>
Search
</button>
</div>
</form>
<!-- Search results container -->
<div id="search-results-container" class="hidden">
<div class="mb-4">
<p id="results-count" class="text-gray-600 dark:text-gray-400"></p>
</div>
<div id="search-results-list" class="space-y-6">
<!-- Results will be populated here -->
</div>
</div>
<!-- No results message -->
<div id="no-results" class="hidden text-center py-12">
<div class="text-6xl mb-4">🔍</div>
<h2 class="text-xl font-semibold mb-2">No results found</h2>
<p class="text-gray-600 dark:text-gray-400 mb-6">
Try different keywords or browse our content below.
</p>
<div class="flex flex-wrap justify-center gap-4">
<a href="/blog/" class="px-4 py-2 bg-purple-100 dark:bg-purple-900/30 text-purple-800 dark:text-purple-200 rounded-lg hover:bg-purple-200 dark:hover:bg-purple-900/50 transition-colors">
Browse All Posts
</a>
<a href="/archive/" class="px-4 py-2 bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-200 rounded-lg hover:bg-blue-200 dark:hover:bg-blue-900/50 transition-colors">
View Archive
</a>
<a href="/sitemap/" class="px-4 py-2 bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-200 rounded-lg hover:bg-green-200 dark:hover:bg-green-900/50 transition-colors">
Site Directory
</a>
</div>
</div>
<!-- Loading state -->
<div id="search-loading" class="hidden text-center py-12">
<div class="text-4xl mb-4"></div>
<p class="text-gray-600 dark:text-gray-400">Searching...</p>
</div>
<!-- Default content when no search -->
<div id="default-content">
<div class="text-center py-12">
<div class="text-6xl mb-4">🔍</div>
<h2 class="text-xl font-semibold mb-2">Search the site</h2>
<p class="text-gray-600 dark:text-gray-400 mb-6">
Find posts, pages, and content across the entire site.
</p>
</div>
<!-- Popular content -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
<div class="bg-[var(--surface)] rounded-lg p-6 border border-gray-200 dark:border-gray-700">
<h3 class="text-lg font-semibold mb-4 text-purple-700 dark:text-purple-300">📝 Recent Posts</h3>
<p class="text-gray-500 dark:text-gray-400 italic">No posts yet.</p>
</div>
<div class="bg-[var(--surface)] rounded-lg p-6 border border-gray-200 dark:border-gray-700">
<h3 class="text-lg font-semibold mb-4 text-blue-700 dark:text-blue-300">🏷️ Popular Tags</h3>
<p class="text-gray-500 dark:text-gray-400 italic">No tags yet.</p>
</div>
</div>
<!-- Search tips -->
<div class="bg-gradient-to-r from-purple-100 to-pink-100 dark:from-purple-900/20 dark:to-pink-900/20 rounded-lg p-6">
<h3 class="text-lg font-semibold mb-3">💡 Search Tips</h3>
<ul class="text-sm space-y-1 text-gray-700 dark:text-gray-300">
<li>• Use specific keywords for better results</li>
<li>• Search works across post titles, content, and tags</li>
<li>• Try different variations of your search terms</li>
<li>• Browse by tags or the archive for discovery</li>
</ul>
</div>
</div>
</div>
<script>
// Search results page functionality
(function() {
let searchIndex = null;
let flexSearch = null;
// Get query parameter from URL
function getQueryParam(param) {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get(param);
}
// Initialize search on page load
async function initSearchPage() {
try {
// Load search index
const response = await fetch('/search.json');
searchIndex = await response.json();
// Initialize FlexSearch
if (typeof FlexSearch !== 'undefined') {
flexSearch = new FlexSearch.Index({
tokenize: 'forward',
cache: true,
resolution: 9
});
// Add documents to search index
searchIndex.forEach((item, index) => {
if (item && item.title) {
const searchText = `${item.title} ${item.description || ''} ${item.content || ''} ${(item.tags || []).join(' ')}`;
flexSearch.add(index, searchText);
}
});
}
// Check for query parameter and perform search
const query = getQueryParam('q');
if (query) {
document.getElementById('search-query').value = query;
performSearch(query);
}
// Set up form submission
const form = document.querySelector('form[role="search"]');
form.addEventListener('submit', (e) => {
e.preventDefault();
const query = document.getElementById('search-query').value.trim();
if (query) {
// Update URL
const newUrl = new URL(window.location);
newUrl.searchParams.set('q', query);
window.history.pushState({}, '', newUrl);
performSearch(query);
}
});
} catch (error) {
console.error('Search initialization failed:', error);
}
}
function performSearch(query) {
if (!flexSearch || !searchIndex) return;
// Show loading
showElement('search-loading');
hideElement('default-content');
hideElement('search-results-container');
hideElement('no-results');
setTimeout(() => {
try {
const results = flexSearch.search(query, { limit: 20 });
const items = results.map(index => searchIndex[index]);
displayResults(items, query);
} catch (error) {
console.error('Search failed:', error);
showNoResults();
}
}, 300); // Small delay for better UX
}
function displayResults(items, query) {
hideElement('search-loading');
hideElement('default-content');
if (items.length === 0) {
showNoResults();
return;
}
// Show results container
showElement('search-results-container');
// Update results count
const count = document.getElementById('results-count');
count.textContent = `Found ${items.length} result${items.length === 1 ? '' : 's'} for "${query}"`;
// Display results
const container = document.getElementById('search-results-list');
container.innerHTML = items.map(item => `
<article class="border-b border-gray-200 dark:border-gray-700 pb-6 last:border-b-0">
<h2 class="text-xl font-semibold mb-2">
<a href="${item.id}" class="hover:text-purple-600 dark:hover:text-purple-400 transition-colors">
${highlightMatch(item.title, query)}
</a>
</h2>
<p class="text-gray-600 dark:text-gray-400 mb-3 leading-relaxed">
${highlightMatch(item.description || item.content, query)}
</p>
${item.tags && item.tags.length > 0 ? `
<div class="flex flex-wrap gap-2">
${item.tags.map(tag => `
<a href="/tags/${tag.toLowerCase().replace(/\s+/g, '-')}/" class="px-2 py-1 bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 rounded text-xs hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors">
#${tag}
</a>
`).join('')}
</div>
` : ''}
</article>
`).join('');
}
function showNoResults() {
hideElement('search-loading');
hideElement('default-content');
hideElement('search-results-container');
showElement('no-results');
}
function showElement(id) {
document.getElementById(id).classList.remove('hidden');
}
function hideElement(id) {
document.getElementById(id).classList.add('hidden');
}
function highlightMatch(text, query) {
if (!text || !query) return text || '';
const regex = new RegExp(`(${query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi');
return text.replace(regex, '<mark class="bg-yellow-200 dark:bg-yellow-800 px-1 rounded">$1</mark>');
}
// Initialize when DOM is ready
document.addEventListener('DOMContentLoaded', initSearchPage);
})();
</script>
</main>
</div>
<footer class="bg-[var(--surface)] border-t border-gray-200 dark:border-gray-700 mt-12">
<div class="container mx-auto px-4 py-8 max-w-4xl">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 text-sm">
<div>
<h3 class="font-semibold mb-2">Technical</h3>
<ul class="space-y-1 text-gray-600 dark:text-gray-400">
<li><a href="https://11ty.dev" target="_blank" rel="noopener">Built with Eleventy</a></li>
<li><a href="/style/" class="hover:text-blue-600">Style Guide</a></li>
<li><a href="https://treasurechest.alien.town/agnes/agnes-love/edit/main/search-results.njk" class="hover:text-blue-600" target="_blank" rel="noopener">Edit This Page</a></li>
<li><a href="https://treasurechest.alien.town/agnes/agnes-love/blob/main/GUIDE.md" class="hover:text-blue-600" target="_blank" rel="noopener">Project Guide</a></li>
</ul>
</div>
<div>
<h3 class="font-semibold mb-2">Navigation</h3>
<ul class="space-y-1 text-gray-600 dark:text-gray-400">
<li><a href="/sitemap/" class="hover:text-blue-600">Sitemap</a></li>
<li><a href="/archive/" class="hover:text-blue-600">Archive</a></li>
<li><a href="/categories/" class="hover:text-blue-600">Categories</a></li>
</ul>
</div>
<div>
<h3 class="font-semibold mb-2">Connect</h3>
<ul class="space-y-1 text-gray-600 dark:text-gray-400">
<li>
<a href="mailto:alienhospitals@gmail.com" rel="me" class="inline-flex items-center gap-2 hover:text-blue-600">
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" role="img"><path d="M4 4h16v16H4z"/><path d="m22 6-10 7L2 6"/></svg>
<span>Email</span>
</a>
</li>
<li>
<a href="https://alienhttps://lesbian.alien.dentist" target="_blank" rel="me noopener" class="inline-flex items-center gap-2 hover:text-blue-600">
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" role="img"><path d="M21.57 13.11c-.3 1.55-2.7 3.25-5.46 3.58-1.44.17-2.86.33-4.37.26-2.47-.11-4.43-.59-4.43-.59 0 .24.02.48.05.71.35 2.67 2.64 2.83 4.8 2.9 2.18.07 4.12-.54 4.12-.54l.09 1.99s-1.52.81-4.23.96c-1.5.08-3.36-.04-5.52-.65-4.69-1.26-5.5-6.33-5.63-11.46-.04-1.5-.02-2.92-.02-4.12 0-5.3 3.47-6.86 3.47-6.86 1.74-.8 4.72-1.14 7.83-1.16h.08c3.11.02 6.09.36 7.83 1.16 0 0 3.47 1.56 3.47 6.86 0 0 .04 3.01-.08 4.98-.05.82-.16 1.63-.34 2.41z"/></svg>
<span>Mastodon</span>
</a>
</li>
</ul>
</div>
</div>
<div class="border-t border-gray-200 dark:border-gray-700 mt-6 pt-6 text-center text-gray-500">
<p>
2025 Agnes the Alien •
<a href="/feed.xml" class="hover:text-blue-600">RSS</a>
Code: <a href="https://opensource.org/license/mit" target="_blank" rel="noopener" class="hover:text-blue-600">MIT</a>
Content: <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank" rel="noopener" class="hover:text-blue-600">CC BY-NC-SA 4.0</a>
</p>
</div>
</div>
</footer>
<script src="/assets/js/main.js"></script>
<script src="/assets/js/flexsearch.min.js"></script>
<script src="/assets/js/search.js"></script>
<script src="/assets/js/easter-eggs.js"></script>
</body>
</html>