fix(site): 全面适配移动端响应式布局与移动端导航抽屉

- 重构 Navbar 移动端菜单:采用内置可靠事件监听与毛玻璃抽屉式下拉(解决移动端汉堡菜单无法展开问题);
- 优化 Hero 区域移动端体验:主标题、按钮组 (w-full 弹性自适应)、Prompt 拷贝胶囊与 macOS 预览窗口全面适配 320px+ 手机窄屏;
- 重构 Bento 卖点卡片微缩 UI:针对 Card 1 (三栏布局) 增加 Mobile 适配(小屏下优雅精简为双栏高保真预览);
- 优化 Marquee 走马灯与 Guides 指南网格在移动端的间距与文字字号。
This commit is contained in:
tianma-if committed 2026-07-27 09:57:34 +08:00
1 parent 53bb498128
commit 85783c11eb
5 files changed
+258 -176

No files matched your search

+81 -82
View File
@@ -6,83 +6,82 @@ const locale = getSiteLocale(Astro.url.pathname);
const bento = siteCopy[locale].bento;
---
<section class="mt-16 md:mt-24 relative overflow-hidden" aria-labelledby="bento-features">
<section class="mt-12 md:mt-24 relative overflow-hidden" aria-labelledby="bento-features">
<!-- Subtle Glow background -->
<div class="absolute top-1/3 left-1/2 -translate-x-1/2 w-[700px] h-[400px] bg-emerald-500/5 rounded-full blur-3xl -z-10 pointer-events-none"></div>
<!-- Header -->
<div class="max-w-3xl mb-12 md:mb-16 text-center mx-auto px-4">
<div class="max-w-3xl mb-8 md:mb-16 text-center mx-auto px-4">
<span class="inline-block px-3.5 py-1 text-xs font-bold tracking-widest text-emerald-600 bg-emerald-50 rounded-full border border-emerald-200/60 uppercase">
{bento.eyebrow}
</span>
<h2 class="text-3xl md:text-4xl lg:text-5xl font-extrabold text-slate-900 tracking-tight mt-3" id="bento-features">
<h2 class="text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-extrabold text-slate-900 tracking-tight mt-3" id="bento-features">
{bento.heading}
</h2>
<p class="text-slate-600 mt-4 text-sm md:text-base leading-relaxed max-w-2xl mx-auto">
<p class="text-slate-600 mt-3 sm:mt-4 text-xs sm:text-sm md:text-base leading-relaxed max-w-2xl mx-auto">
{bento.subheading}
</p>
</div>
<!-- Bento Grid Container -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 max-w-6xl mx-auto px-4">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-6 max-w-6xl mx-auto px-4">
<!-- CARD 1: Classic Three-Pane Layout (Large Span 2 Cols on LG) -->
<div class="group relative overflow-hidden rounded-3xl border border-slate-200/90 bg-white p-6 md:p-8 shadow-sm transition-all duration-300 hover:shadow-xl hover:border-emerald-500/40 lg:col-span-2 flex flex-col justify-between">
<div class="mb-6 z-10">
<div class="flex items-center gap-2 mb-3">
<span class="px-2.5 py-0.5 text-[11px] font-bold text-emerald-700 bg-emerald-100/70 rounded-md">
<div class="group relative overflow-hidden rounded-2xl sm:rounded-3xl border border-slate-200/90 bg-white p-5 sm:p-6 md:p-8 shadow-sm transition-all duration-300 hover:shadow-xl hover:border-emerald-500/40 lg:col-span-2 flex flex-col justify-between">
<div class="mb-4 sm:mb-6 z-10">
<div class="flex flex-wrap items-center gap-2 mb-2.5">
<span class="px-2.5 py-0.5 text-[10px] sm:text-[11px] font-bold text-emerald-700 bg-emerald-100/70 rounded-md">
{bento.card1.badge}
</span>
<span class="text-slate-400 text-xs font-mono">{bento.card1.subBadge}</span>
<span class="text-slate-400 text-[11px] sm:text-xs font-mono">{bento.card1.subBadge}</span>
</div>
<h3 class="text-xl md:text-2xl font-bold text-slate-900 tracking-tight">
<h3 class="text-lg sm:text-xl md:text-2xl font-bold text-slate-900 tracking-tight">
{bento.card1.title}
</h3>
<p class="text-slate-600 text-sm mt-2 leading-relaxed max-w-xl">
<p class="text-slate-600 text-xs sm:text-sm mt-2 leading-relaxed max-w-xl">
{bento.card1.desc}
</p>
</div>
<!-- Micro UI Mockup: Three-Pane Preview -->
<div class="relative w-full rounded-xl border border-slate-200/80 bg-slate-50/80 p-2.5 shadow-inner mt-4 overflow-hidden group-hover:border-emerald-300 transition-colors">
<div class="grid grid-cols-12 gap-2 h-44 md:h-52 text-[11px] font-sans">
<!-- Left Notebook Tree -->
<div class="col-span-3 bg-white rounded-lg border border-slate-200/60 p-2.5 flex flex-col gap-1.5 shadow-2xs overflow-hidden">
<div class="flex items-center gap-1.5 text-slate-400 font-bold text-[10px] uppercase mb-1">
<!-- Micro UI Mockup: Three-Pane Preview (Responsive Layout for Mobile) -->
<div class="relative w-full rounded-xl border border-slate-200/80 bg-slate-50/80 p-2 sm:p-2.5 shadow-inner mt-2 sm:mt-4 overflow-hidden group-hover:border-emerald-300 transition-colors">
<div class="grid grid-cols-12 gap-1.5 sm:gap-2 h-44 md:h-52 text-[10px] sm:text-[11px] font-sans">
<!-- Left Notebook Tree (Hidden on extra small mobile screens < 400px to maintain clean readability) -->
<div class="hidden sm:flex col-span-3 bg-white rounded-lg border border-slate-200/60 p-2 sm:p-2.5 flex-col gap-1.5 shadow-2xs overflow-hidden">
<div class="flex items-center gap-1.5 text-slate-400 font-bold text-[9px] sm:text-[10px] uppercase mb-0.5">
<Icon name="bx:bx-folder" class="w-3.5 h-3.5 text-emerald-600" />
<span>{bento.card1.treeTitle}</span>
<span class="truncate">{bento.card1.treeTitle}</span>
</div>
<div class="bg-emerald-50 text-emerald-800 font-semibold px-2 py-1 rounded text-[10.5px] truncate flex items-center gap-1">
<div class="bg-emerald-50 text-emerald-800 font-semibold px-2 py-1 rounded text-[10px] sm:text-[10.5px] truncate flex items-center gap-1">
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 shrink-0"></span> {bento.card1.folder1}
</div>
<div class="text-slate-600 px-2 py-1 rounded hover:bg-slate-100 truncate">{bento.card1.folder2}</div>
<div class="text-slate-600 px-2 py-1 rounded hover:bg-slate-100 truncate">{bento.card1.folder3}</div>
<div class="text-slate-600 px-2 py-1 rounded hover:bg-slate-100 truncate pl-3 text-[10px] opacity-75">{bento.card1.folder4}</div>
</div>
<!-- Middle Note List -->
<div class="col-span-4 bg-white rounded-lg border border-slate-200/60 p-2 flex flex-col gap-1.5 shadow-2xs overflow-hidden">
<div class="text-slate-400 font-bold text-[10px] uppercase px-1 mb-0.5">{bento.card1.listTitle}</div>
<div class="border-l-2 border-emerald-500 bg-slate-50 p-2 rounded-r flex flex-col gap-0.5">
<div class="font-bold text-slate-800 text-[11px] truncate">{bento.card1.note1Title}</div>
<div class="text-[9.5px] text-slate-500 line-clamp-1">{bento.card1.note1Sub}</div>
<div class="col-span-5 sm:col-span-4 bg-white rounded-lg border border-slate-200/60 p-2 flex flex-col gap-1.5 shadow-2xs overflow-hidden">
<div class="text-slate-400 font-bold text-[9px] sm:text-[10px] uppercase px-1 mb-0.5">{bento.card1.listTitle}</div>
<div class="border-l-2 border-emerald-500 bg-slate-50 p-1.5 sm:p-2 rounded-r flex flex-col gap-0.5">
<div class="font-bold text-slate-800 text-[10px] sm:text-[11px] truncate">{bento.card1.note1Title}</div>
<div class="text-[9px] sm:text-[9.5px] text-slate-500 line-clamp-1">{bento.card1.note1Sub}</div>
</div>
<div class="p-2 rounded hover:bg-slate-50 flex flex-col gap-0.5 opacity-80">
<div class="font-medium text-slate-700 text-[10.5px] truncate">{bento.card1.note2Title}</div>
<div class="text-[9.5px] text-slate-400 line-clamp-1">{bento.card1.note2Sub}</div>
<div class="p-1.5 sm:p-2 rounded hover:bg-slate-50 flex flex-col gap-0.5 opacity-80">
<div class="font-medium text-slate-700 text-[10px] sm:text-[10.5px] truncate">{bento.card1.note2Title}</div>
<div class="text-[9px] sm:text-[9.5px] text-slate-400 line-clamp-1">{bento.card1.note2Sub}</div>
</div>
</div>
<!-- Right TipTap Editor Preview -->
<div class="col-span-5 bg-white rounded-lg border border-slate-200/60 p-3 flex flex-col gap-2 shadow-2xs overflow-hidden">
<div class="text-slate-900 font-bold text-xs border-b border-slate-100 pb-1.5 flex items-center justify-between">
<div class="col-span-7 sm:col-span-5 bg-white rounded-lg border border-slate-200/60 p-2 sm:p-3 flex flex-col gap-1.5 sm:gap-2 shadow-2xs overflow-hidden">
<div class="text-slate-900 font-bold text-[11px] sm:text-xs border-b border-slate-100 pb-1 flex items-center justify-between">
<span class="truncate">{bento.card1.editorTitle}</span>
<span class="text-[9px] bg-emerald-100 text-emerald-800 px-1.5 py-0.5 rounded font-mono shrink-0">TipTap</span>
<span class="text-[8.5px] sm:text-[9px] bg-emerald-100 text-emerald-800 px-1 py-0.5 rounded font-mono shrink-0">TipTap</span>
</div>
<p class="text-[10px] text-slate-600 leading-relaxed">
<p class="text-[9.5px] sm:text-[10px] text-slate-600 leading-relaxed line-clamp-3 sm:line-clamp-none">
{bento.card1.editorBody}
</p>
<div class="flex items-center gap-1 text-[9px] text-slate-400 mt-auto font-mono">
<div class="flex items-center gap-1 text-[8.5px] sm:text-[9px] text-slate-400 mt-auto font-mono">
<Icon name="bx:bx-check-shield" class="w-3 h-3 text-emerald-500 shrink-0" />
<span class="truncate">{bento.card1.editorSaveTag}</span>
</div>
@@ -92,126 +91,126 @@ const bento = siteCopy[locale].bento;
</div>
<!-- CARD 2: AI Agent & MCP Synergy (Col Span 1 on LG) -->
<div class="group relative overflow-hidden rounded-3xl border border-slate-200/90 bg-white p-6 md:p-8 shadow-sm transition-all duration-300 hover:shadow-xl hover:border-emerald-500/40 flex flex-col justify-between">
<div class="group relative overflow-hidden rounded-2xl sm:rounded-3xl border border-slate-200/90 bg-white p-5 sm:p-6 md:p-8 shadow-sm transition-all duration-300 hover:shadow-xl hover:border-emerald-500/40 flex flex-col justify-between">
<div class="z-10">
<div class="flex items-center gap-2 mb-3">
<span class="px-2.5 py-0.5 text-[11px] font-bold text-emerald-700 bg-emerald-100/70 rounded-md">
<div class="flex items-center gap-2 mb-2.5">
<span class="px-2.5 py-0.5 text-[10px] sm:text-[11px] font-bold text-emerald-700 bg-emerald-100/70 rounded-md">
{bento.card2.badge}
</span>
<span class="text-slate-400 text-xs font-mono">Remote MCP Endpoint</span>
<span class="text-slate-400 text-[11px] sm:text-xs font-mono">Remote MCP</span>
</div>
<h3 class="text-xl font-bold text-slate-900 tracking-tight">
<h3 class="text-lg sm:text-xl font-bold text-slate-900 tracking-tight">
{bento.card2.title}
</h3>
<p class="text-slate-600 text-sm mt-2 leading-relaxed">
<p class="text-slate-600 text-xs sm:text-sm mt-2 leading-relaxed">
{bento.card2.desc}
</p>
</div>
<!-- Micro UI Mockup: AI Prompt Bubble -->
<div class="relative w-full rounded-xl border border-slate-200/80 bg-slate-900 p-3.5 text-white font-mono text-[11px] mt-6 flex flex-col gap-2 shadow-md">
<div class="flex items-center justify-between text-[10px] text-slate-400 border-b border-slate-800 pb-1.5">
<span class="flex items-center gap-1.5 text-emerald-400 font-semibold">
<span class="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse"></span> {bento.card2.mockupStatus}
<div class="relative w-full rounded-xl border border-slate-200/80 bg-slate-900 p-3 sm:p-3.5 text-white font-mono text-[10px] sm:text-[11px] mt-4 sm:mt-6 flex flex-col gap-2 shadow-md">
<div class="flex items-center justify-between text-[9.5px] sm:text-[10px] text-slate-400 border-b border-slate-800 pb-1.5">
<span class="flex items-center gap-1.5 text-emerald-400 font-semibold truncate">
<span class="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse shrink-0"></span> {bento.card2.mockupStatus}
</span>
<span>Antigravity / Codex</span>
<span class="shrink-0 text-[9px] sm:text-[10px]">Antigravity / Codex</span>
</div>
<div class="bg-slate-800/80 p-2 rounded text-slate-300 text-[10.5px]">
<div class="bg-slate-800/80 p-2 rounded text-slate-300 text-[10px] sm:text-[10.5px] truncate">
<span class="text-emerald-400 font-bold">&gt;</span> {bento.card2.mockupCmd}
</div>
<div class="bg-emerald-950/60 border border-emerald-800/50 p-2 rounded text-emerald-300 text-[10px] leading-relaxed">
<div class="bg-emerald-950/60 border border-emerald-800/50 p-2 rounded text-emerald-300 text-[9.5px] sm:text-[10px] leading-relaxed">
{bento.card2.mockupResult}
</div>
</div>
</div>
<!-- CARD 3: Serverless Zero Cost (Col Span 1 on LG) -->
<div class="group relative overflow-hidden rounded-3xl border border-slate-200/90 bg-white p-6 md:p-8 shadow-sm transition-all duration-300 hover:shadow-xl hover:border-emerald-500/40 flex flex-col justify-between">
<div class="group relative overflow-hidden rounded-2xl sm:rounded-3xl border border-slate-200/90 bg-white p-5 sm:p-6 md:p-8 shadow-sm transition-all duration-300 hover:shadow-xl hover:border-emerald-500/40 flex flex-col justify-between">
<div class="z-10">
<div class="flex items-center gap-2 mb-3">
<span class="px-2.5 py-0.5 text-[11px] font-bold text-emerald-700 bg-emerald-100/70 rounded-md">
<div class="flex items-center gap-2 mb-2.5">
<span class="px-2.5 py-0.5 text-[10px] sm:text-[11px] font-bold text-emerald-700 bg-emerald-100/70 rounded-md">
{bento.card3.badge}
</span>
<span class="text-slate-400 text-xs font-mono">Cloudflare Native</span>
<span class="text-slate-400 text-[11px] sm:text-xs font-mono">Cloudflare Native</span>
</div>
<h3 class="text-xl font-bold text-slate-900 tracking-tight">
<h3 class="text-lg sm:text-xl font-bold text-slate-900 tracking-tight">
{bento.card3.title}
</h3>
<p class="text-slate-600 text-sm mt-2 leading-relaxed">
<p class="text-slate-600 text-xs sm:text-sm mt-2 leading-relaxed">
{bento.card3.desc}
</p>
</div>
<!-- Micro UI Mockup: 0 Cost Metrics Badge -->
<div class="relative w-full rounded-xl border border-emerald-100 bg-emerald-50/60 p-4 mt-6 flex items-center justify-between">
<div class="relative w-full rounded-xl border border-emerald-100 bg-emerald-50/60 p-3.5 sm:p-4 mt-4 sm:mt-6 flex items-center justify-between">
<div>
<div class="text-2xl md:text-3xl font-extrabold text-emerald-800">{bento.card3.price} <span class="text-xs font-medium text-emerald-600">{bento.card3.unit}</span></div>
<div class="text-[11px] font-medium text-emerald-700 mt-0.5">{bento.card3.sub}</div>
<div class="text-xl sm:text-2xl md:text-3xl font-extrabold text-emerald-800">{bento.card3.price} <span class="text-xs font-medium text-emerald-600">{bento.card3.unit}</span></div>
<div class="text-[10.5px] sm:text-[11px] font-medium text-emerald-700 mt-0.5">{bento.card3.sub}</div>
</div>
<div class="text-right">
<div class="text-lg font-bold text-slate-800">{bento.card3.metric}</div>
<div class="text-[10px] text-slate-500">{bento.card3.metricSub}</div>
<div class="text-base sm:text-lg font-bold text-slate-800">{bento.card3.metric}</div>
<div class="text-[9.5px] sm:text-[10px] text-slate-500">{bento.card3.metricSub}</div>
</div>
</div>
</div>
<!-- CARD 4: Rich Text Copy for Creators (Col Span 1 on LG) -->
<div class="group relative overflow-hidden rounded-3xl border border-slate-200/90 bg-white p-6 md:p-8 shadow-sm transition-all duration-300 hover:shadow-xl hover:border-emerald-500/40 flex flex-col justify-between">
<div class="group relative overflow-hidden rounded-2xl sm:rounded-3xl border border-slate-200/90 bg-white p-5 sm:p-6 md:p-8 shadow-sm transition-all duration-300 hover:shadow-xl hover:border-emerald-500/40 flex flex-col justify-between">
<div class="z-10">
<div class="flex items-center gap-2 mb-3">
<span class="px-2.5 py-0.5 text-[11px] font-bold text-emerald-700 bg-emerald-100/70 rounded-md">
<div class="flex items-center gap-2 mb-2.5">
<span class="px-2.5 py-0.5 text-[10px] sm:text-[11px] font-bold text-emerald-700 bg-emerald-100/70 rounded-md">
{bento.card4.badge}
</span>
<span class="text-slate-400 text-xs font-mono">Substack / Medium / 微信</span>
<span class="text-slate-400 text-[11px] sm:text-xs font-mono truncate">Substack / 微信</span>
</div>
<h3 class="text-xl font-bold text-slate-900 tracking-tight">
<h3 class="text-lg sm:text-xl font-bold text-slate-900 tracking-tight">
{bento.card4.title}
</h3>
<p class="text-slate-600 text-sm mt-2 leading-relaxed">
<p class="text-slate-600 text-xs sm:text-sm mt-2 leading-relaxed">
{bento.card4.desc}
</p>
</div>
<!-- Micro UI Mockup: Markdown to Inline CSS Rich Copy -->
<div class="relative w-full rounded-xl border border-slate-200 bg-slate-50 p-3 mt-6 flex flex-col gap-2">
<div class="flex items-center justify-between text-[10px] text-slate-500 font-mono border-b border-slate-200 pb-1">
<span>{bento.card4.srcTag}</span>
<span class="text-emerald-600 font-bold flex items-center gap-1">
<div class="relative w-full rounded-xl border border-slate-200 bg-slate-50 p-2.5 sm:p-3 mt-4 sm:mt-6 flex flex-col gap-2">
<div class="flex items-center justify-between text-[9.5px] sm:text-[10px] text-slate-500 font-mono border-b border-slate-200 pb-1">
<span class="truncate">{bento.card4.srcTag}</span>
<span class="text-emerald-600 font-bold flex items-center gap-1 shrink-0">
<Icon name="bx:bx-copy" class="w-3 h-3" /> {bento.card4.actionBtn}
</span>
</div>
<div class="bg-white p-2.5 rounded border border-slate-200 text-[11px] text-slate-800 leading-snug">
<span class="font-bold text-emerald-800">{bento.card4.previewTitle}</span>
<p class="text-slate-600 text-[10px] mt-1">{bento.card4.previewBody}</p>
<div class="bg-white p-2 sm:p-2.5 rounded border border-slate-200 text-[10.5px] sm:text-[11px] text-slate-800 leading-snug">
<span class="font-bold text-emerald-800 truncate block">{bento.card4.previewTitle}</span>
<p class="text-slate-600 text-[9.5px] sm:text-[10px] mt-1">{bento.card4.previewBody}</p>
</div>
</div>
</div>
<!-- CARD 5: Open Data & ZIP Backup (Col Span 1 on LG) -->
<div class="group relative overflow-hidden rounded-3xl border border-slate-200/90 bg-white p-6 md:p-8 shadow-sm transition-all duration-300 hover:shadow-xl hover:border-emerald-500/40 flex flex-col justify-between">
<div class="group relative overflow-hidden rounded-2xl sm:rounded-3xl border border-slate-200/90 bg-white p-5 sm:p-6 md:p-8 shadow-sm transition-all duration-300 hover:shadow-xl hover:border-emerald-500/40 flex flex-col justify-between">
<div class="z-10">
<div class="flex items-center gap-2 mb-3">
<span class="px-2.5 py-0.5 text-[11px] font-bold text-emerald-700 bg-emerald-100/70 rounded-md">
<div class="flex items-center gap-2 mb-2.5">
<span class="px-2.5 py-0.5 text-[10px] sm:text-[11px] font-bold text-emerald-700 bg-emerald-100/70 rounded-md">
{bento.card5.badge}
</span>
<span class="text-slate-400 text-xs font-mono">SQLite + ZIP Archive</span>
<span class="text-slate-400 text-[11px] sm:text-xs font-mono">SQLite + ZIP</span>
</div>
<h3 class="text-xl font-bold text-slate-900 tracking-tight">
<h3 class="text-lg sm:text-xl font-bold text-slate-900 tracking-tight">
{bento.card5.title}
</h3>
<p class="text-slate-600 text-sm mt-2 leading-relaxed">
<p class="text-slate-600 text-xs sm:text-sm mt-2 leading-relaxed">
{bento.card5.desc}
</p>
</div>
<!-- Micro UI Mockup: Lossless ZIP Archive -->
<div class="relative w-full rounded-xl border border-slate-200 bg-slate-50 p-3 mt-6 flex items-center gap-3">
<div class="h-10 w-10 shrink-0 grid place-items-center rounded-lg bg-emerald-600 text-white shadow-sm">
<Icon name="bx:bx-archive-in" class="w-5 h-5" />
<div class="relative w-full rounded-xl border border-slate-200 bg-slate-50 p-2.5 sm:p-3 mt-4 sm:mt-6 flex items-center gap-2.5 sm:gap-3">
<div class="h-9 w-9 sm:h-10 sm:w-10 shrink-0 grid place-items-center rounded-lg bg-emerald-600 text-white shadow-sm">
<Icon name="bx:bx-archive-in" class="w-4 h-4 sm:w-5 sm:h-5" />
</div>
<div class="overflow-hidden text-[11px]">
<div class="overflow-hidden text-[10.5px] sm:text-[11px]">
<div class="font-bold text-slate-800 truncate">{bento.card5.archiveTitle}</div>
<div class="text-[10px] text-slate-500 truncate">{bento.card5.archiveSub}</div>
<div class="text-[9.5px] sm:text-[10px] text-slate-500 truncate">{bento.card5.archiveSub}</div>
</div>
</div>
</div>
+16 -9
View File
@@ -5,29 +5,36 @@ const locale = getSiteLocale(Astro.url.pathname);
const copy = siteCopy[locale].guides;
---
<section class="mt-16 md:mt-24" aria-labelledby="guides">
<section class="mt-12 md:mt-24 px-4" aria-labelledby="guides">
<div class="max-w-3xl">
<p class="text-sm font-semibold text-brand-text">{copy.eyebrow}</p>
<h2 id="guides" class="mt-3 text-4xl font-bold tracking-tight text-slate-900 md:text-5xl">
<span class="inline-block px-3 py-1 text-xs font-bold tracking-widest text-emerald-600 bg-emerald-50 rounded-full border border-emerald-200/60 uppercase">
{copy.eyebrow}
</span>
<h2 id="guides" class="mt-3 text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-extrabold tracking-tight text-slate-900">
{copy.heading}
</h2>
<p class="mt-4 text-lg leading-8 text-slate-600">
<p class="mt-3 sm:mt-4 text-xs sm:text-sm md:text-base leading-relaxed text-slate-600">
{copy.description}
</p>
</div>
<div class="mt-8 grid gap-4 md:grid-cols-3">
<div class="mt-6 md:mt-8 grid gap-4 sm:grid-cols-2 md:grid-cols-3">
{
copy.items.map((item) => (
<a
href={getLocalizedPath(locale, item.href)}
class="group flex min-h-64 flex-col justify-between rounded-lg border border-slate-200 bg-white p-6 shadow-sm transition hover:-translate-y-0.5 hover:border-brand-border hover:shadow-lg"
class="group flex flex-col justify-between rounded-2xl border border-slate-200 bg-white p-5 sm:p-6 shadow-xs transition hover:-translate-y-0.5 hover:border-emerald-500/40 hover:shadow-lg"
>
<div>
<h3 class="text-xl font-bold text-slate-900 transition group-hover:text-brand-text">{item.title}</h3>
<p class="mt-3 text-sm leading-6 text-slate-600">{item.summary}</p>
<h3 class="text-base sm:text-lg font-bold text-slate-900 transition group-hover:text-emerald-700">{item.title}</h3>
<p class="mt-2.5 text-xs sm:text-sm leading-relaxed text-slate-600">{item.summary}</p>
</div>
<span class="mt-6 text-sm font-semibold text-brand-text">{item.cta}</span>
<span class="mt-5 text-xs sm:text-sm font-semibold text-emerald-700 flex items-center gap-1">
<span>{item.cta}</span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" class="w-3.5 h-3.5 transition-transform group-hover:translate-x-0.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
</svg>
</span>
</a>
))
}
+29 -29
View File
@@ -12,10 +12,10 @@ const copy = siteCopy[locale].hero;
const agentPromptText = copy.agentPromptText;
---
<main class="relative grid gap-10 lg:grid-cols-[minmax(0,1fr)_minmax(460px,1.1fr)] place-items-center pt-8 pb-12 md:pt-12 md:pb-16 overflow-hidden">
<main class="relative grid gap-8 lg:gap-10 lg:grid-cols-[minmax(0,1fr)_minmax(440px,1.1fr)] place-items-center pt-4 pb-10 md:pt-10 md:pb-16 overflow-hidden px-4 md:px-0">
<!-- Animated Background Orbs -->
<div class="absolute top-0 left-1/4 w-[450px] h-[450px] bg-brand/10 rounded-full blur-3xl animate-slow-spin pointer-events-none"></div>
<div class="absolute bottom-0 right-1/4 w-[380px] h-[380px] bg-emerald-400/10 rounded-full blur-3xl animate-float pointer-events-none"></div>
<div class="absolute top-0 left-1/4 w-[320px] md:w-[450px] h-[320px] md:h-[450px] bg-brand/10 rounded-full blur-3xl animate-slow-spin pointer-events-none"></div>
<div class="absolute bottom-0 right-1/4 w-[280px] md:w-[380px] h-[280px] md:h-[380px] bg-emerald-400/10 rounded-full blur-3xl animate-float pointer-events-none"></div>
<!-- Magic UI Meteors -->
<Meteors number={16} client:load />
@@ -24,36 +24,36 @@ const agentPromptText = copy.agentPromptText;
{copy.badgeText && (
<a
href={`${getLocalizedPath(locale, "/")}blog?tag=migration`}
class="animate-rise inline-flex items-center gap-2 px-3.5 py-1.5 mb-6 text-xs text-brand bg-brand/5 border border-brand-border/30 hover:border-brand/40 hover:bg-brand/10 rounded-full backdrop-blur-sm select-none hover:-translate-y-0.5 transition-all duration-300 group/badge cursor-pointer"
class="animate-rise inline-flex items-center gap-2 px-3 py-1.5 mb-5 md:mb-6 text-xs text-brand bg-brand/5 border border-brand-border/30 hover:border-brand/40 hover:bg-brand/10 rounded-full backdrop-blur-sm select-none hover:-translate-y-0.5 transition-all duration-300 group/badge cursor-pointer max-w-full"
style="animation-delay: 0ms;"
>
<span class="relative flex h-2 w-2">
<span class="relative flex h-2 w-2 shrink-0">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-brand opacity-75"></span>
<span class="relative inline-flex rounded-full h-2 w-2 bg-brand"></span>
</span>
<span class="text-slate-600 font-medium group-hover/badge:text-brand transition-colors">{copy.badgeText}</span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" class="w-3 h-3 text-slate-400 group-hover/badge:text-brand transition-all duration-300 transform group-hover/badge:translate-x-0.5">
<span class="text-slate-600 font-medium group-hover/badge:text-brand transition-colors text-[11px] sm:text-xs truncate">{copy.badgeText}</span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" class="w-3 h-3 text-slate-400 group-hover/badge:text-brand transition-all duration-300 transform group-hover/badge:translate-x-0.5 shrink-0">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
</svg>
</a>
)}
<h1 class="animate-rise text-4xl md:text-5xl xl:text-6xl font-extrabold text-slate-900 leading-[1.18] tracking-tight" style="animation-delay: 80ms;">
<h1 class="animate-rise text-3xl sm:text-4xl md:text-5xl xl:text-6xl font-extrabold text-slate-900 leading-[1.18] tracking-tight" style="animation-delay: 80ms;">
<span class="text-gradient">EdgeEver</span>
<div class="mt-3 flex flex-wrap items-center gap-2">
<span class="inline-block px-3 py-1 bg-emerald-600 text-white rounded-lg text-lg md:text-xl font-bold -rotate-1 shadow-md animate-pop">
<div class="mt-2.5 sm:mt-3 flex flex-wrap items-center gap-2">
<span class="inline-block px-2.5 py-1 bg-emerald-600 text-white rounded-lg text-base sm:text-lg md:text-xl font-bold -rotate-1 shadow-md animate-pop">
{copy.popHighlight}
</span>
</div>
<span class="hero-slogan block mt-4 max-w-xl text-lg md:text-xl font-normal leading-relaxed text-slate-600">{copy.slogan}</span>
<span class="hero-slogan block mt-3 sm:mt-4 max-w-xl text-base sm:text-lg md:text-xl font-normal leading-relaxed text-slate-600">{copy.slogan}</span>
</h1>
<!-- Primary Action Buttons -->
<div class="animate-rise mt-8 flex flex-wrap items-center gap-3.5 z-20" style="animation-delay: 160ms;">
<div class="animate-rise mt-6 sm:mt-8 flex flex-col sm:flex-row items-stretch sm:items-center gap-3 w-full sm:w-auto z-20" style="animation-delay: 160ms;">
<Link
href="https://demo.edgeever.org"
target="_blank"
class="group flex gap-2 items-center justify-center px-6 py-3 text-white bg-brand border-transparent shadow-[0_12px_30px_-14px_rgb(var(--edgeever-brand-rgb)/0.8)] hover:bg-brand-hover hover:shadow-brand/40 transition-all duration-300 hover:-translate-y-0.5 rounded-full font-semibold text-sm"
class="group flex gap-2 items-center justify-center px-6 py-3 text-white bg-brand border-transparent shadow-[0_12px_30px_-14px_rgb(var(--edgeever-brand-rgb)/0.8)] hover:bg-brand-hover hover:shadow-brand/40 transition-all duration-300 hover:-translate-y-0.5 rounded-full font-semibold text-sm w-full sm:w-auto"
rel="noopener">
<Icon class="w-4 h-4" name="bx:bx-show" />
{copy.demo}
@@ -63,7 +63,7 @@ const agentPromptText = copy.agentPromptText;
style="outline"
rel="noopener"
href="https://github.com/tianma-if/edgeever"
class="flex gap-2 items-center justify-center px-6 py-3 border border-slate-200 hover:border-slate-400 bg-white/80 backdrop-blur-sm text-slate-800 transition-all rounded-full font-semibold text-sm hover:-translate-y-0.5"
class="flex gap-2 items-center justify-center px-6 py-3 border border-slate-200 hover:border-slate-400 bg-white/80 backdrop-blur-sm text-slate-800 transition-all rounded-full font-semibold text-sm hover:-translate-y-0.5 w-full sm:w-auto"
target="_blank">
<Icon class="text-slate-800 w-4 h-4" name="bx:bxl-github" />
GitHub Star
@@ -71,7 +71,7 @@ const agentPromptText = copy.agentPromptText;
<a
rel="noopener"
href={getLocalizedPath(locale, "/blog/ai-agent-deploy-cloudflare")}
class="flex gap-2 items-center justify-center px-5 py-3 bg-brand/5 border border-brand/20 hover:border-brand/40 text-brand-text hover:bg-brand/10 transition-all rounded-full font-semibold text-sm hover:-translate-y-0.5"
class="flex gap-2 items-center justify-center px-5 py-3 bg-brand/5 border border-brand/20 hover:border-brand/40 text-brand-text hover:bg-brand/10 transition-all rounded-full font-semibold text-sm hover:-translate-y-0.5 w-full sm:w-auto"
>
<Icon class="w-4 h-4" name="simple-icons:cloudflare" />
{copy.agentInstall}
@@ -88,47 +88,47 @@ const agentPromptText = copy.agentPromptText;
type="button"
id="copy-agent-prompt"
title="点击复制 AI 部署 Prompt 指令"
class="group relative inline-flex items-center justify-between gap-3 w-full rounded-full border border-slate-200/90 bg-white/90 backdrop-blur hover:border-emerald-500/60 p-1.5 pl-4 transition-all hover:shadow-md cursor-pointer text-left select-none z-30"
class="group relative inline-flex items-center justify-between gap-2.5 w-full rounded-2xl sm:rounded-full border border-slate-200/90 bg-white/90 backdrop-blur hover:border-emerald-500/60 p-2 sm:p-1.5 sm:pl-4 transition-all hover:shadow-md cursor-pointer text-left select-none z-30"
>
<div class="flex items-center gap-2.5 overflow-hidden pointer-events-none">
<div class="flex items-center gap-2 overflow-hidden pointer-events-none min-w-0">
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-emerald-600 shrink-0"><path d="M12 19h8"></path><path d="m4 17 6-6-6-6"></path></svg>
<span class="font-mono text-xs text-slate-700 font-medium truncate">
<span class="font-mono text-[11px] sm:text-xs text-slate-700 font-medium truncate">
{copy.terminalCmd}
</span>
</div>
<span class="copy-icon-box grid h-7 w-7 shrink-0 place-items-center rounded-full bg-slate-100 text-slate-500 group-hover:bg-emerald-50 group-hover:text-emerald-700 transition-colors pointer-events-none">
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"></rect><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path></svg>
</span>
<span id="prompt-tooltip" class="absolute -top-10 right-4 hidden rounded-lg bg-emerald-700 px-3 py-1.5 text-xs font-semibold text-white shadow-lg transition-opacity pointer-events-none z-50 flex items-center gap-1.5">
<span id="prompt-tooltip" class="absolute -top-10 right-2 sm:right-4 hidden rounded-lg bg-emerald-700 px-3 py-1.5 text-xs font-semibold text-white shadow-lg transition-opacity pointer-events-none z-50 flex items-center gap-1.5">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>
<span>{copy.copySuccess}</span>
</span>
</button>
<span class="text-[11.5px] text-slate-600 pl-4 font-medium select-none">{copy.terminalSub}</span>
<span class="text-[11px] sm:text-[11.5px] text-slate-600 pl-2 sm:pl-4 font-medium select-none">{copy.terminalSub}</span>
</div>
</div>
</div>
<!-- macOS Browser Window Mockup (Pireel style) -->
<div class="animate-rise w-full relative z-10 flex justify-center lg:justify-end" style="animation-delay: 320ms;">
<div class="animate-rise w-full relative z-10 flex justify-center lg:justify-end mt-4 lg:mt-0" style="animation-delay: 320ms;">
<div class="relative w-full max-w-xl animate-float pointer-events-none select-none">
<!-- Glow Underlay -->
<div class="absolute -inset-1 bg-gradient-to-r from-emerald-500/20 via-brand/10 to-teal-500/20 rounded-2xl blur-xl opacity-70"></div>
<!-- macOS Window Container -->
<div class="relative rounded-2xl border border-slate-200/80 bg-white shadow-2xl overflow-hidden">
<div class="relative rounded-2xl border border-slate-200/80 bg-white shadow-xl sm:shadow-2xl overflow-hidden">
<!-- macOS Top Header Bar -->
<div class="flex items-center justify-between border-b border-slate-100 bg-slate-50/90 px-4 py-2.5 backdrop-blur-sm">
<div class="flex items-center justify-between border-b border-slate-100 bg-slate-50/90 px-3.5 py-2 backdrop-blur-sm">
<div class="flex items-center gap-1.5">
<span class="h-3 w-3 rounded-full bg-[#ff5f57] inline-block"></span>
<span class="h-3 w-3 rounded-full bg-[#febc2e] inline-block"></span>
<span class="h-3 w-3 rounded-full bg-[#28c840] inline-block"></span>
<span class="h-2.5 w-2.5 sm:h-3 sm:w-3 rounded-full bg-[#ff5f57] inline-block"></span>
<span class="h-2.5 w-2.5 sm:h-3 sm:w-3 rounded-full bg-[#febc2e] inline-block"></span>
<span class="h-2.5 w-2.5 sm:h-3 sm:w-3 rounded-full bg-[#28c840] inline-block"></span>
</div>
<div class="flex items-center gap-1 rounded-full bg-slate-200/60 px-3 py-0.5 text-center font-mono text-[11px] text-slate-500 font-medium">
<div class="flex items-center gap-1 rounded-full bg-slate-200/60 px-2.5 py-0.5 text-center font-mono text-[10px] sm:text-[11px] text-slate-500 font-medium">
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="text-slate-400 mr-1"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>
demo.edgeever.org
</div>
<div class="w-10"></div>
<div class="w-8 sm:w-10"></div>
</div>
<!-- Product Image Preview -->
@@ -197,7 +197,7 @@ const agentPromptText = copy.agentPromptText;
tooltip.classList.add("hidden");
}
if (iconContainer) {
iconContainer.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"></rect><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path></svg>';
iconContainer.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"></rect><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path></svg>';
}
}, 2500);
}
+15 -15
View File
@@ -9,36 +9,36 @@ const copy = siteCopy[locale].marquee;
const doubleItems = [...copy.items, ...copy.items];
---
<section class="mt-16 md:mt-24 w-full overflow-hidden py-10 bg-slate-50/60 border-y border-slate-200/60">
<div class="max-w-4xl mx-auto text-center px-4 mb-8">
<h3 class="text-2xl md:text-3xl font-extrabold text-slate-900 tracking-tight">
<section class="mt-12 md:mt-24 w-full overflow-hidden py-8 md:py-10 bg-slate-50/60 border-y border-slate-200/60">
<div class="max-w-4xl mx-auto text-center px-4 mb-6 md:mb-8">
<h3 class="text-xl sm:text-2xl md:text-3xl font-extrabold text-slate-900 tracking-tight">
{copy.title}
</h3>
<p class="text-slate-500 text-sm mt-2">
<p class="text-slate-500 text-xs sm:text-sm mt-1.5 md:mt-2 leading-relaxed">
{copy.subtitle}
</p>
</div>
<!-- Marquee Container with Side Gradient Fades -->
<div class="group relative mt-6 w-full">
<div class="flex w-max gap-4 animate-site-marquee group-hover:[animation-play-state:paused]">
<div class="group relative mt-4 md:mt-6 w-full">
<div class="flex w-max gap-3 sm:gap-4 animate-site-marquee group-hover:[animation-play-state:paused]">
{doubleItems.map((item) => (
<div class={`relative w-72 shrink-0 rounded-2xl border border-slate-200/80 bg-gradient-to-br ${item.color} p-5 shadow-xs transition-all duration-300 hover:shadow-md hover:border-emerald-400 bg-white`}>
<div class="flex items-center justify-between mb-3">
<span class="px-2 py-0.5 text-[10px] font-bold text-emerald-700 bg-emerald-100/80 rounded-md">
<div class={`relative w-64 sm:w-72 shrink-0 rounded-2xl border border-slate-200/80 bg-gradient-to-br ${item.color} p-4 sm:p-5 shadow-xs transition-all duration-300 hover:shadow-md hover:border-emerald-400 bg-white`}>
<div class="flex items-center justify-between mb-2.5 sm:mb-3">
<span class="px-2 py-0.5 text-[9.5px] sm:text-[10px] font-bold text-emerald-700 bg-emerald-100/80 rounded-md">
{item.tag}
</span>
<Icon name={item.icon} class="w-5 h-5 text-emerald-600" />
<Icon name={item.icon} class="w-4 h-4 sm:w-5 sm:h-5 text-emerald-600" />
</div>
<h4 class="font-bold text-slate-900 text-sm">{item.title}</h4>
<p class="text-slate-500 text-[11.5px] mt-1 leading-snug">{item.desc}</p>
<h4 class="font-bold text-slate-900 text-xs sm:text-sm">{item.title}</h4>
<p class="text-slate-500 text-[10.5px] sm:text-[11.5px] mt-1 leading-snug">{item.desc}</p>
</div>
))}
</div>
<!-- Side Gradient Fade Masks (Pireel Style) -->
<div class="pointer-events-none absolute inset-y-0 left-0 w-28 bg-gradient-to-r from-slate-50 via-slate-50/80 to-transparent z-10"></div>
<div class="pointer-events-none absolute inset-y-0 right-0 w-28 bg-gradient-to-l from-slate-50 via-slate-50/80 to-transparent z-10"></div>
<!-- Side Gradient Fade Masks -->
<div class="pointer-events-none absolute inset-y-0 left-0 w-12 sm:w-28 bg-gradient-to-r from-slate-50 via-slate-50/80 to-transparent z-10"></div>
<div class="pointer-events-none absolute inset-y-0 right-0 w-12 sm:w-28 bg-gradient-to-l from-slate-50 via-slate-50/80 to-transparent z-10"></div>
</div>
</section>
+117 -41
View File
@@ -3,7 +3,6 @@ import Container from "@/components/container.astro";
import Dropdown from "./dropdown.astro";
import LanguageSwitcher from "./language-switcher.astro";
import { Icon } from "astro-icon/components";
import { Astronav, MenuItems, MenuIcon } from "astro-navbar";
import { getLocalizedPath, getSiteLocale, siteCopy } from "@/i18n";
const locale = getSiteLocale(Astro.url.pathname);
@@ -46,28 +45,25 @@ const menuitems = [
---
<Container>
<header class="flex flex-col lg:flex-row justify-between items-center my-5">
<Astronav>
<div class="flex w-full lg:w-auto items-center justify-between">
<a href={getLocalizedPath(locale, "/")} class="flex items-center gap-2 text-lg" aria-label={copy.homeAria}>
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-[var(--edgeever-brand-logo-bg)]">
<svg class="h-6 w-6" viewBox="0 0 64 64" role="img" aria-hidden="true">
<rect x="14" y="10" width="36" height="44" rx="8" fill="var(--edgeever-brand-logo-mark)" />
<path d="M24 23h18v5H30v5h11v5H30v6h13v5H24V23Z" fill="var(--edgeever-brand-surface)" />
<path d="M19 16h26" stroke="var(--edgeever-brand-logo-accent)" stroke-width="3" stroke-linecap="round" />
</svg>
</span>
<span>
<span class="font-bold text-slate-800 tracking-tight">Edge</span><span class="text-slate-500">Ever</span>
</span>
</a>
<div class="block lg:hidden">
<MenuIcon class="w-4 h-4 text-gray-800" />
</div>
</div>
<header class="relative my-4 md:my-5 z-50">
<div class="flex items-center justify-between">
<!-- Logo Left -->
<a href={getLocalizedPath(locale, "/")} class="flex items-center gap-2 text-lg select-none" aria-label={copy.homeAria}>
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-[var(--edgeever-brand-logo-bg)] shadow-xs">
<svg class="h-6 w-6" viewBox="0 0 64 64" role="img" aria-hidden="true">
<rect x="14" y="10" width="36" height="44" rx="8" fill="var(--edgeever-brand-logo-mark)" />
<path d="M24 23h18v5H30v5h11v5H30v6h13v5H24V23Z" fill="var(--edgeever-brand-surface)" />
<path d="M19 16h26" stroke="var(--edgeever-brand-logo-accent)" stroke-width="3" stroke-linecap="round" />
</svg>
</span>
<span>
<span class="font-bold text-slate-800 tracking-tight text-base md:text-lg">Edge</span><span class="text-slate-500 text-base md:text-lg">Ever</span>
</span>
</a>
<MenuItems class="hidden w-full lg:w-auto mt-2 lg:flex lg:mt-0">
<ul class="flex flex-col lg:flex-row lg:gap-1">
<!-- Desktop Navigation Center -->
<nav class="hidden lg:flex items-center gap-1">
<ul class="flex items-center gap-1">
{
menuitems.map((item, index) => (
<>
@@ -83,7 +79,7 @@ const menuitems = [
<li>
<a
href={item.path}
class="flex lg:px-3 py-2 items-center text-[13px] font-semibold text-slate-600 hover:text-emerald-700 transition-colors">
class="px-3.5 py-2 text-[13.5px] font-semibold text-slate-600 hover:text-emerald-700 hover:bg-slate-100/70 rounded-full transition-colors">
<span>{item.title}</span>
</a>
</li>
@@ -92,30 +88,84 @@ const menuitems = [
))
}
</ul>
<div class="lg:hidden flex items-center mt-3 gap-4">
<a
href="https://github.com/tianma-if/edgeever"
target="_blank"
rel="noopener"
class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-semibold text-slate-700 bg-white border border-slate-200 rounded-full"
aria-label="GitHub"
>
<Icon class="h-4 w-4 text-slate-800" name="bx:bxl-github" />
<span>{copy.openSource}</span>
</a>
<LanguageSwitcher pathname={Astro.url.pathname} compact />
</div>
</MenuItems>
</Astronav>
</nav>
<div>
<div class="hidden lg:flex items-center gap-4">
<!-- Desktop Actions Right -->
<div class="hidden lg:flex items-center gap-3">
<LanguageSwitcher pathname={Astro.url.pathname} />
<a
href="https://github.com/tianma-if/edgeever"
target="_blank"
rel="noopener"
class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-semibold text-slate-700 hover:text-slate-900 bg-white hover:bg-slate-50 border border-slate-200 hover:border-slate-300 rounded-full transition-all duration-200 shadow-2xs"
class="inline-flex items-center gap-1.5 px-3.5 py-1.5 text-xs font-semibold text-slate-700 hover:text-slate-900 bg-white hover:bg-slate-50 border border-slate-200/90 hover:border-slate-300 rounded-full transition-all duration-200 shadow-2xs"
aria-label="GitHub"
>
<Icon class="h-4 w-4 text-slate-800" name="bx:bxl-github" />
<span>{copy.openSource}</span>
</a>
</div>
<!-- Mobile Hamburger Toggle Button -->
<button
type="button"
id="mobile-nav-toggle"
aria-label="Toggle mobile menu"
class="lg:hidden p-2 rounded-xl border border-slate-200/80 bg-white/90 text-slate-700 hover:bg-slate-100 focus:outline-none transition-colors"
>
<svg id="hamburger-icon" class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16" />
</svg>
<svg id="close-icon" class="w-5 h-5 hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<!-- Mobile Navigation Drawer -->
<div
id="mobile-nav-menu"
class="hidden lg:hidden mt-3 rounded-2xl border border-slate-200/90 bg-white/95 backdrop-blur-lg p-4 shadow-xl flex flex-col gap-3 transition-all"
>
<ul class="flex flex-col gap-1.5">
{
menuitems.map((item) => (
<>
{item.children ? (
<li class="py-1">
<div class="px-3 py-1 text-xs font-bold text-slate-400 uppercase tracking-wider">{item.title}</div>
<div class="mt-1 flex flex-col gap-1 pl-2">
{item.children.map((child) => (
<a
href={child.path}
class="px-3 py-2 text-xs font-semibold text-slate-700 hover:text-emerald-700 hover:bg-emerald-50/70 rounded-xl transition-colors"
>
{child.title}
</a>
))}
</div>
</li>
) : (
<li>
<a
href={item.path}
class="block px-3 py-2 text-sm font-semibold text-slate-700 hover:text-emerald-700 hover:bg-emerald-50/70 rounded-xl transition-colors"
>
{item.title}
</a>
</li>
)}
</>
))
}
</ul>
<div class="pt-3 border-t border-slate-100 flex items-center justify-between">
<LanguageSwitcher pathname={Astro.url.pathname} compact />
<a
href="https://github.com/tianma-if/edgeever"
target="_blank"
rel="noopener"
class="inline-flex items-center gap-1.5 px-3.5 py-1.5 text-xs font-semibold text-slate-700 bg-slate-50 border border-slate-200 rounded-full"
aria-label="GitHub"
>
<Icon class="h-4 w-4 text-slate-800" name="bx:bxl-github" />
@@ -125,3 +175,29 @@ const menuitems = [
</div>
</header>
</Container>
<script is:inline>
(function () {
document.addEventListener("click", function (e) {
var toggleBtn = e.target && e.target.closest ? e.target.closest("#mobile-nav-toggle") : null;
var menu = document.getElementById("mobile-nav-menu");
var hamburgerIcon = document.getElementById("hamburger-icon");
var closeIcon = document.getElementById("close-icon");
if (toggleBtn && menu) {
e.preventDefault();
e.stopPropagation();
var isHidden = menu.classList.contains("hidden");
if (isHidden) {
menu.classList.remove("hidden");
if (hamburgerIcon) hamburgerIcon.classList.add("hidden");
if (closeIcon) closeIcon.classList.remove("hidden");
} else {
menu.classList.add("hidden");
if (hamburgerIcon) hamburgerIcon.classList.remove("hidden");
if (closeIcon) closeIcon.classList.add("hidden");
}
}
});
})();
</script>