fix(site): 全面适配移动端响应式布局与移动端导航抽屉
- 重构 Navbar 移动端菜单:采用内置可靠事件监听与毛玻璃抽屉式下拉(解决移动端汉堡菜单无法展开问题); - 优化 Hero 区域移动端体验:主标题、按钮组 (w-full 弹性自适应)、Prompt 拷贝胶囊与 macOS 预览窗口全面适配 320px+ 手机窄屏; - 重构 Bento 卖点卡片微缩 UI:针对 Card 1 (三栏布局) 增加 Mobile 适配(小屏下优雅精简为双栏高保真预览); - 优化 Marquee 走马灯与 Guides 指南网格在移动端的间距与文字字号。
This commit is contained in:
1 parent
53bb498128
commit
85783c11eb
5 files changed
+258
-176
No files matched your search
@@ -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">></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>
|
||||
|
||||
@@ -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>
|
||||
))
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
Reference in new issue
Block a user