diff --git a/.DS_Store b/.DS_Store
index 6d6d742..f867d09 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/assets/css/style.css b/assets/css/style.css
index 5aee516..8ee3c2f 100644
--- a/assets/css/style.css
+++ b/assets/css/style.css
@@ -403,6 +403,173 @@ a {
outline: none;
}
+/* Search trigger pill - glassmorphic floating button */
+.search-trigger-pill {
+ position: absolute;
+ right: 20px;
+ top: calc(100% + 12px);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 8px 14px;
+ background: rgba(255, 255, 255, 0.7);
+ backdrop-filter: blur(12px) saturate(1.5);
+ -webkit-backdrop-filter: blur(12px) saturate(1.5);
+ border: 1px solid rgba(255, 255, 255, 0.3);
+ border-radius: 20px;
+ box-shadow:
+ 0 4px 16px rgba(0, 0, 0, 0.1),
+ 0 0 0 1px rgba(255, 255, 255, 0.5),
+ inset 0 1px 0 rgba(255, 255, 255, 0.8);
+ cursor: pointer;
+ font-family: var(--font-body);
+ font-size: 13px;
+ font-weight: 500;
+ color: var(--text-color);
+ transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
+ z-index: 999;
+ opacity: 0.9;
+}
+
+.search-trigger-pill:hover {
+ opacity: 1;
+ transform: translateY(-2px);
+ box-shadow:
+ 0 8px 24px rgba(0, 0, 0, 0.15),
+ 0 0 0 1px rgba(255, 255, 255, 0.6),
+ inset 0 1px 0 rgba(255, 255, 255, 0.9);
+ background: rgba(255, 255, 255, 0.85);
+}
+
+.search-trigger-pill:active {
+ transform: translateY(0);
+ box-shadow:
+ 0 2px 8px rgba(0, 0, 0, 0.1),
+ 0 0 0 1px rgba(255, 255, 255, 0.5),
+ inset 0 1px 0 rgba(255, 255, 255, 0.8);
+}
+
+[data-theme="dark"] .search-trigger-pill {
+ background: rgba(30, 30, 30, 0.7);
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ box-shadow:
+ 0 4px 16px rgba(0, 0, 0, 0.3),
+ 0 0 0 1px rgba(255, 255, 255, 0.05),
+ inset 0 1px 0 rgba(255, 255, 255, 0.1);
+}
+
+[data-theme="dark"] .search-trigger-pill:hover {
+ background: rgba(40, 40, 40, 0.85);
+ border-color: rgba(255, 255, 255, 0.15);
+ box-shadow:
+ 0 8px 24px rgba(0, 0, 0, 0.4),
+ 0 0 0 1px rgba(255, 255, 255, 0.1),
+ inset 0 1px 0 rgba(255, 255, 255, 0.15);
+}
+
+.search-trigger-icon {
+ font-size: 16px;
+ line-height: 1;
+ opacity: 0.7;
+}
+
+.search-trigger-text {
+ font-weight: 500;
+ letter-spacing: 0.01em;
+}
+
+/* Search tooltip - glassmorphic hover tooltip */
+.search-tooltip {
+ position: absolute;
+ top: calc(100% + 8px);
+ left: 50%;
+ transform: translateX(-50%) translateY(5px);
+ padding: 6px 12px;
+ background: rgba(255, 255, 255, 0.85);
+ backdrop-filter: blur(12px) saturate(1.5);
+ -webkit-backdrop-filter: blur(12px) saturate(1.5);
+ border: 1px solid rgba(255, 255, 255, 0.4);
+ border-radius: 10px;
+ box-shadow:
+ 0 6px 20px rgba(0, 0, 0, 0.15),
+ 0 0 0 1px rgba(255, 255, 255, 0.6),
+ inset 0 1px 0 rgba(255, 255, 255, 0.9);
+ font-size: 11px;
+ font-weight: 500;
+ color: var(--text-color);
+ white-space: nowrap;
+ pointer-events: none;
+ opacity: 0;
+ visibility: hidden;
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+ z-index: 1000;
+}
+
+.search-tooltip::before {
+ content: "";
+ position: absolute;
+ top: -4px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 8px;
+ height: 8px;
+ background: rgba(255, 255, 255, 0.85);
+ border-left: 1px solid rgba(255, 255, 255, 0.4);
+ border-top: 1px solid rgba(255, 255, 255, 0.4);
+ transform: translateX(-50%) rotate(45deg);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+}
+
+[data-theme="dark"] .search-tooltip {
+ background: rgba(30, 30, 30, 0.9);
+ border: 1px solid rgba(255, 255, 255, 0.15);
+ box-shadow:
+ 0 6px 20px rgba(0, 0, 0, 0.4),
+ 0 0 0 1px rgba(255, 255, 255, 0.08),
+ inset 0 1px 0 rgba(255, 255, 255, 0.15);
+}
+
+[data-theme="dark"] .search-tooltip::before {
+ background: rgba(30, 30, 30, 0.9);
+ border-left-color: rgba(255, 255, 255, 0.15);
+ border-top-color: rgba(255, 255, 255, 0.15);
+}
+
+.search-trigger-pill:hover .search-tooltip {
+ opacity: 1;
+ visibility: visible;
+ transform: translateX(-50%) translateY(0);
+}
+
+.search-tooltip kbd {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 16px;
+ height: 16px;
+ padding: 0 4px;
+ margin: 0 2px;
+ font-family: var(--font-body);
+ font-size: 9px;
+ font-weight: 600;
+ line-height: 1;
+ background: rgba(0, 0, 0, 0.08);
+ border: 1px solid rgba(0, 0, 0, 0.12);
+ border-radius: 3px;
+ box-shadow:
+ 0 1px 2px rgba(0, 0, 0, 0.08),
+ inset 0 -1px 0 rgba(0, 0, 0, 0.12);
+}
+
+[data-theme="dark"] .search-tooltip kbd {
+ background: rgba(255, 255, 255, 0.12);
+ border: 1px solid rgba(255, 255, 255, 0.18);
+ box-shadow:
+ 0 1px 2px rgba(0, 0, 0, 0.3),
+ inset 0 -1px 0 rgba(255, 255, 255, 0.12);
+}
+
/* Center the logo */
.logo {
font-weight: 700;
@@ -881,6 +1048,38 @@ html, body {
padding: var(--space-xs) 10px;
}
+ .search-trigger-pill {
+ right: var(--space-md);
+ top: calc(100% + 8px);
+ padding: 6px 10px;
+ font-size: 11px;
+ gap: 6px;
+ }
+
+ .search-trigger-icon {
+ font-size: 14px;
+ }
+
+ .search-hint {
+ padding: var(--space-xs) var(--space-md);
+ }
+
+ .search-hint span {
+ font-size: 0.7rem;
+ }
+
+ .search-tooltip {
+ font-size: 10px;
+ padding: 5px 10px;
+ }
+
+ .search-tooltip kbd {
+ min-width: 14px;
+ height: 14px;
+ padding: 0 3px;
+ font-size: 8px;
+ }
+
.logo {
font-size: var(--text-xl);
position: relative;
@@ -1343,164 +1542,352 @@ html, body {
left: 0;
right: 0;
bottom: 0;
- background: rgba(0, 0, 0, 0.8);
+ background: rgba(0, 0, 0, 0.75);
z-index: 9999;
display: flex;
align-items: flex-start;
justify-content: center;
padding-top: 10vh;
- backdrop-filter: blur(8px);
- animation: fadeIn 0.2s ease;
+ backdrop-filter: blur(12px) saturate(1.5);
+ -webkit-backdrop-filter: blur(12px) saturate(1.5);
+ opacity: 0;
+ transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
-@keyframes fadeIn {
- from { opacity: 0; }
- to { opacity: 1; }
+.search-modal.visible {
+ opacity: 1;
}
.search-modal-content {
background: var(--surface-color);
- border-radius: 12px;
+ background: linear-gradient(135deg,
+ rgba(255, 255, 255, 0.05) 0%,
+ rgba(255, 255, 255, 0.02) 100%);
+ backdrop-filter: blur(20px);
+ -webkit-backdrop-filter: blur(20px);
+ border-radius: 20px;
width: 90%;
- max-width: 700px;
- max-height: 80vh;
+ max-width: 680px;
+ max-height: 75vh;
display: flex;
flex-direction: column;
- border: 1px solid var(--border-color);
- box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
- animation: slideDown 0.3s ease;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ box-shadow:
+ 0 20px 60px rgba(0, 0, 0, 0.4),
+ 0 0 0 1px rgba(255, 255, 255, 0.05),
+ inset 0 1px 0 rgba(255, 255, 255, 0.1);
+ transform: translateY(-20px) scale(0.95);
+ opacity: 0;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
-@keyframes slideDown {
- from {
- opacity: 0;
- transform: translateY(-20px);
- }
- to {
- opacity: 1;
- transform: translateY(0);
- }
+.search-modal.visible .search-modal-content {
+ transform: translateY(0) scale(1);
+ opacity: 1;
}
.search-header {
display: flex;
align-items: center;
- gap: var(--space-sm);
- padding: var(--space-lg);
- border-bottom: 1px solid var(--border-color);
+ gap: var(--space-md);
+ padding: var(--space-lg) var(--space-xl);
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
+ position: relative;
+}
+
+.search-header::before {
+ content: "🔍";
+ font-size: 1.25rem;
+ opacity: 0.4;
+ pointer-events: none;
+}
+
+.search-hint {
+ padding: var(--space-xs) var(--space-xl);
+ text-align: center;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.05);
+}
+
+.search-hint span {
+ font-size: 0.75rem;
+ color: var(--text-color);
+ opacity: 0.5;
+ font-weight: 400;
+ letter-spacing: 0.01em;
+}
+
+.search-hint kbd {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 18px;
+ height: 18px;
+ padding: 0 5px;
+ margin: 0 2px;
+ font-family: var(--font-body);
+ font-size: 10px;
+ font-weight: 600;
+ line-height: 1;
+ background: rgba(0, 0, 0, 0.05);
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-radius: 4px;
+ box-shadow:
+ 0 1px 2px rgba(0, 0, 0, 0.05),
+ inset 0 -1px 0 rgba(0, 0, 0, 0.1);
+}
+
+[data-theme="dark"] .search-hint kbd {
+ background: rgba(255, 255, 255, 0.08);
+ border: 1px solid rgba(255, 255, 255, 0.15);
+ box-shadow:
+ 0 1px 2px rgba(0, 0, 0, 0.2),
+ inset 0 -1px 0 rgba(255, 255, 255, 0.1);
}
.search-input {
flex: 1;
font-family: var(--font-body);
- font-size: var(--text-lg);
- padding: 0.75rem;
+ font-size: 1.125rem;
+ font-weight: 400;
+ padding: 0.5rem 0;
border: none;
background: transparent;
color: var(--text-color);
outline: none;
+ letter-spacing: 0.01em;
}
.search-input::placeholder {
color: var(--text-color);
- opacity: 0.5;
+ opacity: 0.4;
+ font-weight: 300;
}
.search-close {
- background: none;
- border: none;
+ background: rgba(255, 255, 255, 0.05);
+ border: 1px solid rgba(255, 255, 255, 0.1);
color: var(--text-color);
cursor: pointer;
padding: 0.5rem;
display: flex;
align-items: center;
justify-content: center;
- border-radius: 6px;
- transition: all var(--transition-normal);
+ border-radius: 10px;
+ opacity: 0.7;
+ transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.search-close:hover {
- background: var(--glass-bg);
+ background: rgba(255, 255, 255, 0.1);
+ border-color: var(--accent-color-blue);
color: var(--accent-color-blue);
+ opacity: 1;
+ transform: scale(1.05);
}
.search-results {
overflow-y: auto;
- padding: var(--space-sm);
- max-height: calc(80vh - 100px);
+ padding: var(--space-md) var(--space-lg);
+ max-height: calc(75vh - 120px);
+}
+
+.search-results::-webkit-scrollbar {
+ width: 8px;
+}
+
+.search-results::-webkit-scrollbar-track {
+ background: transparent;
+}
+
+.search-results::-webkit-scrollbar-thumb {
+ background: rgba(255, 255, 255, 0.1);
+ border-radius: 10px;
+}
+
+.search-results::-webkit-scrollbar-thumb:hover {
+ background: rgba(255, 255, 255, 0.2);
+}
+
+.search-result-count {
+ font-size: 0.75rem;
+ color: var(--text-color);
+ opacity: 0.4;
+ padding: 0 var(--space-xs);
+ margin-bottom: var(--space-md);
+ text-align: left;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 1px;
}
.search-result-item {
- padding: var(--space-md);
- border-radius: 8px;
+ padding: var(--space-md) var(--space-lg);
+ border-radius: 14px;
margin-bottom: var(--space-sm);
- transition: all var(--transition-normal);
+ transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
cursor: pointer;
text-decoration: none;
color: inherit;
display: block;
- border: 1px solid transparent;
+ border: 1px solid rgba(255, 255, 255, 0.05);
+ background: rgba(255, 255, 255, 0.02);
+ opacity: 0;
+ transform: translateY(10px);
+ animation: slideInResult 0.4s cubic-bezier(0.4, 0, 0.2, 1) forwards;
+ position: relative;
+ overflow: hidden;
+}
+
+.search-result-item::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 3px;
+ height: 100%;
+ background: linear-gradient(180deg,
+ var(--accent-color-blue) 0%,
+ transparent 100%);
+ opacity: 0;
+ transition: opacity 0.25s ease;
+}
+
+@keyframes slideInResult {
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
}
.search-result-item:hover {
- background: var(--glass-bg);
- border-color: var(--border-color);
- transform: translateX(4px);
+ background: rgba(255, 255, 255, 0.06);
+ border-color: rgba(255, 255, 255, 0.12);
+ transform: translateY(-3px);
+ box-shadow:
+ 0 8px 24px rgba(0, 0, 0, 0.15),
+ 0 0 0 1px rgba(255, 255, 255, 0.05);
+}
+
+.search-result-item:hover::before {
+ opacity: 1;
}
.search-result-title {
font-family: var(--font-heading);
- font-size: var(--text-lg);
- font-weight: 700;
- margin: 0 0 var(--space-xs) 0;
+ font-size: 1.0625rem;
+ font-weight: 600;
+ margin: 0 0 0.5rem 0;
color: var(--text-color);
+ transition: color 0.25s ease;
+ line-height: 1.4;
+ letter-spacing: -0.01em;
}
.search-result-item:hover .search-result-title {
color: var(--accent-color-blue);
+ background: linear-gradient(90deg,
+ var(--accent-color-blue) 0%,
+ #60a5fa 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
}
.search-result-meta {
- font-size: var(--text-sm);
+ font-size: 0.75rem;
color: var(--text-color);
- opacity: 0.6;
- margin-bottom: var(--space-xs);
+ opacity: 0.45;
+ margin-bottom: 0.625rem;
+ font-weight: 500;
+ letter-spacing: 0.02em;
}
.search-result-description {
- font-size: var(--text-base);
+ font-size: 0.9375rem;
color: var(--text-color);
- opacity: 0.8;
- line-height: 1.5;
+ opacity: 0.75;
+ line-height: 1.6;
margin: 0;
}
.search-result-tags {
display: flex;
- gap: var(--space-xs);
+ gap: 0.5rem;
flex-wrap: wrap;
- margin-top: var(--space-sm);
+ margin-top: 0.75rem;
}
.search-result-tag {
- font-size: var(--text-xs);
+ font-size: 0.6875rem;
color: var(--accent-color-blue);
- background: var(--glass-bg);
- padding: 0.2rem 0.6rem;
+ background: rgba(59, 130, 246, 0.1);
+ padding: 0.25rem 0.625rem;
border-radius: 12px;
- border: 1px solid var(--accent-color-blue);
+ border: 1px solid rgba(59, 130, 246, 0.2);
+ opacity: 0.9;
+ font-weight: 500;
+ letter-spacing: 0.02em;
+ transition: all 0.2s ease;
+}
+
+.search-result-item:hover .search-result-tag {
+ background: rgba(59, 130, 246, 0.15);
+ border-color: rgba(59, 130, 246, 0.4);
+ opacity: 1;
}
.search-no-results {
text-align: center;
- padding: var(--space-3xl);
+ padding: var(--space-2xl);
color: var(--text-color);
- opacity: 0.6;
+ opacity: 0.5;
}
.search-no-results-icon {
- font-size: 3rem;
- margin-bottom: var(--space-md);
+ font-size: 2.5rem;
+ margin-bottom: var(--space-sm);
+}
+
+/* Pagefind search term highlighting */
+.search-result-description mark {
+ background: linear-gradient(120deg,
+ rgba(59, 130, 246, 0.3) 0%,
+ rgba(59, 130, 246, 0.2) 100%);
+ color: var(--accent-color-blue);
+ padding: 0.15em 0.35em;
+ border-radius: 6px;
+ font-weight: 600;
+ border: 1px solid rgba(59, 130, 246, 0.3);
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.05);
+}
+
+/* Mobile responsive search */
+@media (max-width: 768px) {
+ .search-modal {
+ padding-top: 5vh;
+ }
+
+ .search-modal-content {
+ width: 95%;
+ max-height: 85vh;
+ border-radius: 12px;
+ }
+
+ .search-header {
+ padding: var(--space-sm) var(--space-md);
+ }
+
+ .search-input {
+ font-size: var(--text-sm);
+ }
+
+ .search-results {
+ max-height: calc(85vh - 70px);
+ }
+
+ .search-result-item {
+ padding: var(--space-sm);
+ }
}
/* --- Comments Section --- */
diff --git a/assets/js/search.js b/assets/js/search.js
index 0ff4013..565f118 100644
--- a/assets/js/search.js
+++ b/assets/js/search.js
@@ -1,113 +1,118 @@
-// Simple client-side search functionality
+// Pagefind search integration
(function() {
'use strict';
- let searchIndex = [];
+ let pagefind;
+ let pagefindLoaded = false;
let searchModal, searchInput, searchResults, searchClose;
- // Simple fuzzy search function
- function fuzzySearch(query, text) {
- if (!query || !text) return false;
+ // Lazy load Pagefind only when needed
+ async function ensurePagefind() {
+ if (pagefindLoaded) return;
- query = query.toLowerCase();
- text = text.toLowerCase();
-
- // Direct match gets highest priority
- if (text.includes(query)) return true;
-
- // Fuzzy match - all query chars appear in order
- let queryIndex = 0;
- for (let i = 0; i < text.length && queryIndex < query.length; i++) {
- if (text[i] === query[queryIndex]) {
- queryIndex++;
- }
+ try {
+ pagefind = await import('/pagefind/pagefind.js');
+ pagefindLoaded = true;
+ } catch (error) {
+ console.error('Error loading Pagefind:', error);
+ throw error;
}
- return queryIndex === query.length;
}
- // Search function
- function performSearch(query) {
+ // Perform search with Pagefind
+ async function performSearch(query) {
if (!query || query.length < 2) {
searchResults.innerHTML = '
🔍
Start typing to search posts...
';
return;
}
- const results = searchIndex.filter(post => {
- return fuzzySearch(query, post.title) ||
- fuzzySearch(query, post.description) ||
- fuzzySearch(query, post.content) ||
- (post.tags && post.tags.some(tag => fuzzySearch(query, tag))) ||
- (post.categories && post.categories.some(cat => fuzzySearch(query, cat)));
- });
+ // Show loading state immediately
+ searchResults.innerHTML = '';
- if (results.length === 0) {
- searchResults.innerHTML = '😕
No posts found matching your search.
';
- return;
+ try {
+ // Ensure Pagefind is loaded
+ await ensurePagefind();
+
+ const search = await pagefind.search(query);
+
+ if (search.results.length === 0) {
+ searchResults.innerHTML = '😕
No posts found matching your search.
';
+ return;
+ }
+
+ // Limit to first 10 results for speed
+ const limitedResults = search.results.slice(0, 10);
+
+ // Load data for limited results
+ const results = await Promise.all(
+ limitedResults.map(r => r.data())
+ );
+
+ displayResults(results, search.results.length);
+ } catch (error) {
+ console.error('Search error:', error);
+ searchResults.innerHTML = `⚠️
Unable to load search results. Please check your internet connection or refresh the page and try again.
${error && error.message ? `
Error: ${error.message}
` : ''}
`;
}
+ }
+
+ // Display search results with staggered animation
+ function displayResults(results, totalCount) {
+ const resultCount = totalCount > results.length
+ ? `Showing ${results.length} of ${totalCount} results
`
+ : `${results.length} result${results.length !== 1 ? 's' : ''}
`;
- // Clear previous results
- searchResults.innerHTML = '';
- results.forEach(post => {
- const item = document.createElement('a');
- item.className = 'search-result-item';
- item.href = post.permalink;
-
- const title = document.createElement('h3');
- title.className = 'search-result-title';
- title.textContent = post.title;
- item.appendChild(title);
-
- const meta = document.createElement('div');
- meta.className = 'search-result-meta';
- meta.textContent = post.date;
- item.appendChild(meta);
-
- const desc = document.createElement('p');
- desc.className = 'search-result-description';
- desc.textContent = post.description || post.content;
- item.appendChild(desc);
-
- if (post.tags && post.tags.length > 0) {
- const tagsDiv = document.createElement('div');
- tagsDiv.className = 'search-result-tags';
- post.tags.slice(0, 3).forEach(tag => {
- const tagSpan = document.createElement('span');
- tagSpan.className = 'search-result-tag';
- tagSpan.textContent = tag;
- tagsDiv.appendChild(tagSpan);
- });
- item.appendChild(tagsDiv);
- }
-
- searchResults.appendChild(item);
- });
+ const resultsHtml = results.map((result, index) => {
+ // Extract tags from meta if available
+ const tags = result.meta.tags ?
+ result.meta.tags.slice(0, 3).map(tag =>
+ `${tag}`
+ ).join('') : '';
+
+ return `
+
+ ${result.meta.title || 'Untitled'}
+ ${result.meta.date || ''}
+ ${result.excerpt}
+ ${tags ? `${tags}
` : ''}
+
+ `;
+ }).join('');
+
+ searchResults.innerHTML = resultCount + resultsHtml;
}
- // Open search modal
+ // Open search modal with animation
function openSearch() {
searchModal.style.display = 'flex';
document.body.style.overflow = 'hidden';
- setTimeout(() => searchInput.focus(), 100);
+
+ // Trigger animation
+ requestAnimationFrame(() => {
+ searchModal.classList.add('visible');
+ });
+
+ setTimeout(() => searchInput.focus(), 150);
+
+ // Preload Pagefind when modal opens (lazy load)
+ if (!pagefindLoaded) {
+ ensurePagefind().catch(err =>
+ console.error('Failed to preload Pagefind:', err)
+ );
+ }
}
- // Close search modal
+ // Close search modal with animation
function closeSearch() {
- searchModal.style.display = 'none';
+ searchModal.classList.remove('visible');
+
+ // Wait for animation to complete before hiding
+ setTimeout(() => {
+ searchModal.style.display = 'none';
+ searchInput.value = '';
+ searchResults.innerHTML = '🔍
Start typing to search posts...
';
+ }, 200);
+
document.body.style.overflow = '';
- searchInput.value = '';
- searchResults.innerHTML = '';
- }
-
- // Load search index
- function loadSearchIndex() {
- fetch('/index.json')
- .then(response => response.json())
- .then(data => {
- searchIndex = data;
- })
- .catch(error => {
- console.error('Error loading search index:', error);
- });
}
// Initialize search
@@ -116,11 +121,17 @@
searchInput = document.getElementById('search-input');
searchResults = document.getElementById('search-results');
searchClose = document.getElementById('search-close');
+ const searchTrigger = document.getElementById('search-trigger');
if (!searchModal || !searchInput || !searchResults) return;
- // Load search index
- loadSearchIndex();
+ // Keep the hint showing both shortcuts - works for everyone
+ // No need to change it, the HTML already has both ⌘ K and Ctrl K
+
+ // Wire up search trigger button
+ if (searchTrigger) {
+ searchTrigger.addEventListener('click', openSearch);
+ }
// Event listeners
searchClose.addEventListener('click', closeSearch);
@@ -144,13 +155,13 @@
}
});
- // Perform search as user types
+ // Perform search as user types (reduced debounce for faster response)
let searchTimeout;
searchInput.addEventListener('input', (e) => {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
performSearch(e.target.value);
- }, 200);
+ }, 150);
});
// Show initial message
@@ -165,4 +176,3 @@
}
})();
-
diff --git a/hugo.toml b/hugo.toml
index 5ca2396..443d8fe 100644
--- a/hugo.toml
+++ b/hugo.toml
@@ -5,9 +5,9 @@ enableRobotsTXT = true
enableGitInfo = true
canonifyURLs = true
-# Output formats for search
+# Output formats (JSON removed - Pagefind handles search indexing)
[outputs]
- home = ["HTML", "RSS", "JSON"]
+ home = ["HTML", "RSS"]
section = ["HTML", "RSS"]
# SEO and Performance
diff --git a/hugo_stats.json b/hugo_stats.json
index 13a3f50..6796437 100644
--- a/hugo_stats.json
+++ b/hugo_stats.json
@@ -24,6 +24,7 @@
"html",
"img",
"input",
+ "kbd",
"li",
"line",
"link",
@@ -140,10 +141,15 @@
"responsive-image",
"search-close",
"search-header",
+ "search-hint",
"search-input",
"search-modal",
"search-modal-content",
"search-results",
+ "search-tooltip",
+ "search-trigger-icon",
+ "search-trigger-pill",
+ "search-trigger-text",
"site-header",
"social-button",
"social-button-linkedin",
@@ -264,9 +270,11 @@
"saving-our-brains-before-theyre-toast",
"scaling-experience-not-compute",
"search-close",
+ "search-hint-text",
"search-input",
"search-modal",
"search-results",
+ "search-trigger",
"so-how-the-heck-do-you-protect-yourself",
"so-what",
"so-what-the-hell-do-we-do",
diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html
index 849964f..78cab9c 100644
--- a/layouts/_default/baseof.html
+++ b/layouts/_default/baseof.html
@@ -48,6 +48,15 @@
Main Site
+
+
+
@@ -62,6 +71,9 @@
+
+ Press ⌘ K or Ctrl K anywhere to search
+
diff --git a/layouts/_default/list.html b/layouts/_default/list.html
index e73e076..97c88ad 100644
--- a/layouts/_default/list.html
+++ b/layouts/_default/list.html
@@ -1,4 +1,5 @@
{{ define "main" }}
+
THE ONLY BLOGS YOU
@@ -107,4 +108,5 @@ {{ .Title }}
{{ end }}
+
{{ end }}
diff --git a/layouts/_default/single.html b/layouts/_default/single.html
index d2f596a..8ca7b07 100644
--- a/layouts/_default/single.html
+++ b/layouts/_default/single.html
@@ -1,5 +1,5 @@
{{ define "main" }}
-
+