diff --git a/apps/web/src/components/Lander.astro b/apps/web/src/components/Lander.astro
index 25a62cbe8..bd368010b 100644
--- a/apps/web/src/components/Lander.astro
+++ b/apps/web/src/components/Lander.astro
@@ -14,14 +14,22 @@
@@ -340,7 +356,7 @@ tests:
.av-nav-links {
display: flex;
align-items: center;
- gap: 1.5rem;
+ gap: 1.25rem;
}
.av-nav-links > a {
@@ -355,6 +371,128 @@ tests:
color: var(--av-text);
}
+.av-nav-github {
+ display: flex;
+ align-items: center;
+ color: hsl(240, 5%, 65%) !important;
+ transition: color 0.15s !important;
+}
+
+.av-nav-github:hover {
+ color: var(--av-text) !important;
+}
+
+/* Search button */
+.av-nav-search {
+ all: unset;
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.35rem 0.75rem;
+ border: 1px solid var(--av-surface-border);
+ border-radius: 0.5rem;
+ background: var(--av-surface);
+ color: hsl(240, 5%, 65%);
+ font-size: 0.8rem;
+ font-family: inherit;
+ cursor: pointer;
+ transition: border-color 0.15s, color 0.15s, background 0.15s;
+ white-space: nowrap;
+ min-width: 12rem;
+}
+
+.av-nav-search:hover {
+ border-color: hsl(240, 5%, 40%);
+ color: var(--av-text-muted);
+ background: hsl(240, 10%, 14%);
+}
+
+.av-nav-search-label {
+ color: inherit;
+ flex: 1;
+ text-align: left;
+}
+
+.av-nav-search-kbd {
+ display: inline-flex;
+ gap: 0.2rem;
+ margin-left: auto;
+}
+
+.av-nav-search-kbd kbd {
+ display: inline-block;
+ padding: 0.1rem 0.35rem;
+ border: 1px solid hsl(240, 5%, 30%);
+ border-radius: 0.25rem;
+ background: hsl(240, 10%, 12%);
+ font-family: inherit;
+ font-size: 0.7rem;
+ line-height: 1.3;
+ color: hsl(240, 5%, 50%);
+}
+
+/* Search dialog */
+.av-search-dialog {
+ position: fixed;
+ inset: 0;
+ margin: 0;
+ padding: 0;
+ border: 0;
+ width: 100%;
+ max-width: 100%;
+ height: 100%;
+ max-height: 100%;
+ background: transparent;
+}
+
+.av-search-dialog::backdrop {
+ background: rgba(0, 0, 0, 0.6);
+ backdrop-filter: blur(4px);
+}
+
+.av-search-dialog[open] {
+ display: flex;
+ justify-content: center;
+ align-items: flex-start;
+}
+
+.av-search-dialog-frame {
+ position: relative;
+ margin-top: 4rem;
+ width: 90%;
+ max-width: 40rem;
+ max-height: calc(100vh - 8rem);
+ overflow: auto;
+ background: hsl(240, 10%, 10%);
+ border: 1px solid var(--av-surface-border);
+ border-radius: 0.5rem;
+ padding: 1.5rem;
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
+}
+
+.av-search-close {
+ position: absolute;
+ top: 0.75rem;
+ right: 0.75rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 2rem;
+ height: 2rem;
+ border: none;
+ border-radius: 0.375rem;
+ background: transparent;
+ color: hsl(240, 5%, 50%);
+ cursor: pointer;
+ transition: color 0.15s, background 0.15s;
+ z-index: 1;
+}
+
+.av-search-close:hover {
+ color: var(--av-text);
+ background: hsl(240, 10%, 16%);
+}
+
.av-nav-pill {
all: unset;
display: flex;
@@ -464,6 +602,38 @@ tests:
display: flex;
gap: 0.875rem;
flex-wrap: wrap;
+ align-items: center;
+}
+
+.av-hero-install {
+ all: unset;
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ cursor: pointer;
+ padding: 0.4rem 0.75rem;
+ background: var(--av-surface);
+ border: 1px solid var(--av-surface-border);
+ border-radius: 6px;
+ font-family: var(--av-font-mono);
+ font-size: 0.8rem;
+ color: hsl(240, 5%, 65%);
+ transition: border-color 0.15s, color 0.15s;
+ margin-top: 1.5rem;
+}
+
+.av-hero-install:hover {
+ border-color: var(--av-indigo);
+ color: hsl(240, 5%, 85%);
+}
+
+.av-hero-install-prompt {
+ color: var(--av-cyan);
+ font-weight: 600;
+}
+
+.av-hero-install code {
+ font-family: inherit;
}
.av-btn-primary {
@@ -1024,10 +1194,19 @@ td code {
grid-template-columns: 1fr;
}
- .av-nav-pill {
+ .av-nav-search {
+ min-width: auto;
+ }
+
+ .av-nav-search-label,
+ .av-nav-search-kbd {
display: none;
}
+ .av-hero-install {
+ font-size: 0.75rem;
+ }
+
.av-table-fade {
display: block;
position: absolute;
@@ -1126,6 +1305,87 @@ td code {
});
});
+ // Search modal
+ const searchBtn = document.getElementById('av-nav-search');
+ const dialog = document.getElementById('av-search-dialog') as HTMLDialogElement;
+ let pagefindLoaded = false;
+
+ function openSearch() {
+ dialog.showModal();
+ document.body.style.overflow = 'hidden';
+ if (!pagefindLoaded) {
+ pagefindLoaded = true;
+ const link = document.createElement('link');
+ link.rel = 'stylesheet';
+ link.href = '/pagefind/pagefind-ui.css';
+ document.head.appendChild(link);
+ const darkStyles = document.createElement('style');
+ darkStyles.textContent = `
+ #av-search-container {
+ --pagefind-ui-scale: 0.8;
+ --pagefind-ui-primary: #e2e8f0;
+ --pagefind-ui-text: #cbd5e1;
+ --pagefind-ui-font: system-ui, -apple-system, sans-serif;
+ --pagefind-ui-background: hsl(240,10%,6%);
+ --pagefind-ui-border: #475569;
+ --pagefind-ui-border-width: 1px;
+ --pagefind-ui-tag: #475569;
+ }
+ #av-search-container .pagefind-ui__form::before { --pagefind-ui-text: #e2e8f0; opacity: 1; }
+ #av-search-container .pagefind-ui__search-input { color: #f8fafc; font-weight: 400; }
+ #av-search-container input:focus { --pagefind-ui-border: #06b6d4; }
+ #av-search-container .pagefind-ui__search-clear { width: calc(60px * var(--pagefind-ui-scale)); padding: 0; background-color: transparent; overflow: hidden; }
+ `;
+ document.head.appendChild(darkStyles);
+ const script = document.createElement('script');
+ script.src = '/pagefind/pagefind-ui.js';
+ script.onload = () => {
+ // @ts-ignore
+ new PagefindUI({ element: '#av-search-container', showImages: false, showSubResults: true, baseUrl: '/' });
+ setTimeout(() => {
+ const input = dialog.querySelector('.pagefind-ui__search-input');
+ if (input) input.focus();
+ }, 50);
+ };
+ document.head.appendChild(script);
+ } else {
+ setTimeout(() => {
+ const input = dialog.querySelector('.pagefind-ui__search-input');
+ if (input) { input.focus(); input.select(); }
+ }, 50);
+ }
+ }
+
+ function closeSearch() {
+ dialog.close();
+ document.body.style.overflow = '';
+ }
+
+ if (searchBtn) searchBtn.addEventListener('click', openSearch);
+ const closeSearchBtn = document.getElementById('av-search-close');
+ if (closeSearchBtn) closeSearchBtn.addEventListener('click', closeSearch);
+ dialog?.addEventListener('click', (e) => { if (e.target === dialog) closeSearch(); });
+ dialog?.addEventListener('close', () => { document.body.style.overflow = ''; });
+ dialog?.addEventListener('click', (e) => {
+ const target = e.target as HTMLElement;
+ if (target.closest('a[href]')) closeSearch();
+ });
+
+ document.addEventListener('keydown', (e) => {
+ if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
+ e.preventDefault();
+ dialog?.open ? closeSearch() : openSearch();
+ }
+ if (e.key === 'Escape' && dialog?.open) closeSearch();
+ });
+
+ // Update kbd hint for Mac
+ if (navigator.platform.includes('Mac') || navigator.userAgent.includes('Mac')) {
+ document.querySelectorAll('.av-nav-search-kbd').forEach((el) => {
+ el.innerHTML = '\u2318K';
+ });
+ }
+
// Nav scroll detection
const nav = document.getElementById("av-nav");
if (nav) {