|
|
@@ -1,254 +1,220 @@ |
|
|
|
<template> |
|
|
|
<!-- Header --> |
|
|
|
<header class="fixed top-0 z-50 w-full bg-slate-900/70 backdrop-blur-[50px]"> |
|
|
|
<div class="max-w-screen-2xl mx-auto px-4 sm:px-6 lg:px-10"> |
|
|
|
<div class="h-[55px] flex justify-between items-center sm:h-[72px]"> |
|
|
|
<div class="flex justify-start items-center gap-12 lg:gap-24"> |
|
|
|
<nuxt-link :to="homePath" class="brand-link mt-[5px] flex-shrink-0"> |
|
|
|
<i |
|
|
|
class="icon-brand text-white text-1xl sm:text-2xl block transition-[transform,filter] duration-500 ease-in-out" |
|
|
|
></i> |
|
|
|
</nuxt-link> |
|
|
|
<!-- Desktop Menu --> |
|
|
|
<nav |
|
|
|
class="hidden md:flex justify-start items-start gap-1 lg:gap-7 xl:gap-14" |
|
|
|
> |
|
|
|
<template v-for="item in menuItems" :key="item.label"> |
|
|
|
<!-- Regular Link --> |
|
|
|
<nuxt-link |
|
|
|
v-if="!item.isDropdown" |
|
|
|
class="main-nav-link relative inline-block justify-start text-white text-sm opacity-80 hover:opacity-100 transition-opacity py-2 px-3 rounded-md" |
|
|
|
:to="item.path" |
|
|
|
:class="[ |
|
|
|
route.path === item.path |
|
|
|
? 'font-bold opacity-100 bg-white/15' |
|
|
|
: '', |
|
|
|
]" |
|
|
|
> |
|
|
|
{{ t(item.label) }} |
|
|
|
</nuxt-link> |
|
|
|
|
|
|
|
<!-- Dropdown Container --> |
|
|
|
<div |
|
|
|
v-else-if="item.isDropdown" |
|
|
|
class="relative" |
|
|
|
@mouseleave="handleMouseLeave" |
|
|
|
> |
|
|
|
<!-- Dropdown Trigger --> |
|
|
|
<div |
|
|
|
@mouseenter="handleMouseEnter(item.label)" |
|
|
|
class="justify-start text-white text-sm opacity-80 hover:opacity-100 transition-opacity cursor-pointer flex items-center gap-1 py-2 px-3 rounded-md" |
|
|
|
<!-- 导航容器 --> |
|
|
|
<div class="w-full"> |
|
|
|
<!-- 内容居中容器 --> |
|
|
|
<div class="max-w-screen-2xl mx-auto px-4 sm:px-6 lg:px-10"> |
|
|
|
<div class="h-[55px] flex justify-between items-center sm:h-[72px]"> |
|
|
|
<div class="flex justify-start items-center gap-12 lg:gap-24"> |
|
|
|
<nuxt-link :to="homePath" class="brand-link mt-[5px] flex-shrink-0"> |
|
|
|
<i |
|
|
|
class="icon-brand text-white text-1xl sm:text-2xl block transition-[transform,filter] duration-500 ease-in-out" |
|
|
|
></i> |
|
|
|
</nuxt-link> |
|
|
|
<!-- Desktop Menu --> |
|
|
|
<nav |
|
|
|
class="hidden md:flex justify-start items-start gap-1 lg:gap-7 xl:gap-14" |
|
|
|
> |
|
|
|
<template v-for="item in menuItems" :key="item.label"> |
|
|
|
<!-- Regular Link --> |
|
|
|
<nuxt-link |
|
|
|
v-if="!item.isDropdown" |
|
|
|
class="main-nav-link relative inline-block justify-start text-white text-sm opacity-80 hover:opacity-100 transition-opacity py-2 px-3 rounded-md" |
|
|
|
:to="item.path" |
|
|
|
:class="[ |
|
|
|
route.path.startsWith(item.pathPrefix) |
|
|
|
route.path === item.path |
|
|
|
? 'font-bold opacity-100 bg-white/15' |
|
|
|
: '', |
|
|
|
]" |
|
|
|
> |
|
|
|
<span>{{ t(item.label) }}</span> |
|
|
|
</div> |
|
|
|
{{ t(item.label) }} |
|
|
|
</nuxt-link> |
|
|
|
|
|
|
|
<!-- Dropdown Panel --> |
|
|
|
<transition name="fade-down"> |
|
|
|
<!-- Dropdown Container --> |
|
|
|
<div |
|
|
|
v-else-if="item.isDropdown" |
|
|
|
class="relative" |
|
|
|
@mouseleave="handleMouseLeave" |
|
|
|
> |
|
|
|
<!-- Dropdown Trigger --> |
|
|
|
<div |
|
|
|
v-if="item.isDropdown && openDropdown === item.label" |
|
|
|
@mouseenter="handleMouseEnter(item.label)" |
|
|
|
class="absolute left-[-15px] top-full mt-4 w-[550px] bg-slate-900/95 backdrop-blur-[50px] rounded-none border-none shadow-none p-0 z-10 gap-0 transition-all duration-300" |
|
|
|
class="justify-start text-white text-sm opacity-80 hover:opacity-100 transition-opacity cursor-pointer flex items-center gap-1 py-2 px-3 rounded-md" |
|
|
|
:class="[route.path.startsWith(item.pathPrefix) ? 'font-bold opacity-100 bg-white/15' : '']" |
|
|
|
> |
|
|
|
<span>{{ t(item.label) }}</span> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- Dropdown Panel --> |
|
|
|
<transition name="fade-down"> |
|
|
|
<div |
|
|
|
v-for="(section, index) in item.children" |
|
|
|
:key="index" |
|
|
|
class="rounded-none p-2 flex flex-col gap-1" |
|
|
|
v-if="item.isDropdown && openDropdown === item.label" |
|
|
|
@mouseenter="handleMouseEnter(item.label)" |
|
|
|
class="fixed left-0 top-[70px] w-screen bg-slate-900/95 backdrop-blur-[50px] border-t border-b border-slate-700/20 shadow-2xl z-10" |
|
|
|
> |
|
|
|
<div class="grid grid-cols-2 gap-8 p-2"> |
|
|
|
<!-- 企业用户产品组 --> |
|
|
|
<div class="relative group/card"> |
|
|
|
<div class="relative space-y-4"> |
|
|
|
<div |
|
|
|
class="px-6 py-4 text-sm font-semibold text-gray-200 bg-gradient-to-br from-slate-800/90 to-slate-900/90 rounded-xl border border-slate-700/30 shadow-2xl backdrop-blur-sm group-hover/card:shadow-blue-500/10 transition-all duration-500" |
|
|
|
> |
|
|
|
<nuxt-link |
|
|
|
:to="`${homePath}products?audiences=1`" |
|
|
|
class="flex items-center gap-4" |
|
|
|
@click="handleMouseLeave" |
|
|
|
> |
|
|
|
<div |
|
|
|
class="p-2 rounded-lg bg-gradient-to-br from-blue-500/20 to-indigo-500/20 group-hover/card:from-blue-500/30 group-hover/card:to-indigo-500/30 transition-all duration-500" |
|
|
|
> |
|
|
|
<i |
|
|
|
class="icon-building text-2xl text-blue-400" |
|
|
|
></i> |
|
|
|
</div> |
|
|
|
<div> |
|
|
|
<span |
|
|
|
class="block text-lg font-medium tracking-wide text-white" |
|
|
|
>{{ t("home.business.title") }}</span |
|
|
|
<!-- 内容居中容器 --> |
|
|
|
<div class="max-w-screen-2xl mx-auto px-4 sm:px-6 lg:px-10 py-12"> |
|
|
|
<!-- 主内容网格 --> |
|
|
|
<div> |
|
|
|
<!-- 产品分类列 (原有的分类逻辑和数据) --> |
|
|
|
<div> |
|
|
|
<h3 class="text-xs font-semibold text-gray-400 uppercase tracking-wide mb-4"> |
|
|
|
{{ t("common.productCategories") }} |
|
|
|
</h3> |
|
|
|
<div class="flex gap-x-32 gap-y-8"> |
|
|
|
<!-- 企业用户产品组 --> |
|
|
|
<div> |
|
|
|
<h4 class="text-base font-semibold text-white mb-3"> |
|
|
|
<nuxt-link |
|
|
|
:to="`${homePath}products?audiences=1`" |
|
|
|
class="flex items-center gap-2 hover:text-cyan-400 transition-colors" |
|
|
|
@click="handleMouseLeave" |
|
|
|
> |
|
|
|
</div> |
|
|
|
</nuxt-link> |
|
|
|
</div> |
|
|
|
<ul class="space-y-2"> |
|
|
|
<li |
|
|
|
v-for="link in getGroupedItems(section.items) |
|
|
|
.enterprise" |
|
|
|
:key="link.path" |
|
|
|
class="group/item" |
|
|
|
> |
|
|
|
<nuxt-link |
|
|
|
:to="link.path" |
|
|
|
@click="handleMouseLeave" |
|
|
|
class="block text-base text-gray-200 rounded-lg py-2.5 px-4 transition-all duration-200 hover:text-white hover:bg-white/5 relative" |
|
|
|
:class="{ |
|
|
|
'text-white font-medium bg-white/10': |
|
|
|
route.path === link.path, |
|
|
|
}" |
|
|
|
> |
|
|
|
<span |
|
|
|
class="relative flex items-center gap-3" |
|
|
|
<span>{{ t("home.business.title") }}</span> |
|
|
|
</nuxt-link> |
|
|
|
</h4> |
|
|
|
<ul class="space-y-2"> |
|
|
|
<li |
|
|
|
v-for="link in getGroupedItems(item.children[0].items).enterprise" |
|
|
|
:key="link.path" |
|
|
|
> |
|
|
|
<span |
|
|
|
class="w-1.5 h-1.5 rounded-full bg-white/30 group-hover/item:bg-white/60 transition-colors duration-200" |
|
|
|
></span> |
|
|
|
<span class="text-base">{{ |
|
|
|
t(link.label) |
|
|
|
}}</span> |
|
|
|
</span> |
|
|
|
</nuxt-link> |
|
|
|
</li> |
|
|
|
</ul> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 个人用户产品组 --> |
|
|
|
<div class="relative group/card"> |
|
|
|
<div class="relative space-y-4"> |
|
|
|
<div |
|
|
|
class="px-6 py-4 text-sm font-semibold text-gray-200 bg-gradient-to-br from-slate-800/90 to-slate-900/90 rounded-xl border border-slate-700/30 shadow-2xl backdrop-blur-sm group-hover/card:shadow-cyan-500/10 transition-all duration-500" |
|
|
|
> |
|
|
|
<nuxt-link |
|
|
|
:to="`${homePath}products?audiences=0`" |
|
|
|
class="flex items-center gap-4" |
|
|
|
@click="handleMouseLeave" |
|
|
|
> |
|
|
|
<div |
|
|
|
class="p-2 rounded-lg bg-gradient-to-br from-cyan-500/20 to-blue-500/20 group-hover/card:from-cyan-500/30 group-hover/card:to-blue-500/30 transition-all duration-500" |
|
|
|
> |
|
|
|
<i |
|
|
|
class="icon-user text-2xl text-cyan-400" |
|
|
|
></i> |
|
|
|
</div> |
|
|
|
<div> |
|
|
|
<span |
|
|
|
class="block text-lg font-medium tracking-wide text-white" |
|
|
|
>{{ t("home.personal.title") }}</span |
|
|
|
<nuxt-link |
|
|
|
:to="link.path" |
|
|
|
@click="handleMouseLeave" |
|
|
|
class="block text-[16px] text-gray-300 hover:text-white transition-colors" |
|
|
|
> |
|
|
|
{{ t(link.label) }} |
|
|
|
</nuxt-link> |
|
|
|
<ul v-if="link.tags && link.tags.length" class="mt-1"> |
|
|
|
<li v-for="tag in link.tags" :key="tag"> |
|
|
|
<nuxt-link |
|
|
|
:to="`${link.path}&tag=${tag}`" |
|
|
|
@click.stop="handleMouseLeave" |
|
|
|
class="text-sm text-gray-400 hover:text-white transition-colors duration-200" |
|
|
|
> |
|
|
|
{{ tag }} |
|
|
|
</nuxt-link> |
|
|
|
</li> |
|
|
|
</ul> |
|
|
|
</li> |
|
|
|
</ul> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 个人用户产品组 --> |
|
|
|
<div class="flex-1"> |
|
|
|
<h4 class="text-base font-semibold text-white mb-3"> |
|
|
|
<nuxt-link |
|
|
|
:to="`${homePath}products?audiences=0`" |
|
|
|
class="flex items-center gap-2 hover:text-cyan-400 transition-colors" |
|
|
|
@click="handleMouseLeave" |
|
|
|
> |
|
|
|
</div> |
|
|
|
</nuxt-link> |
|
|
|
</div> |
|
|
|
<ul class="space-y-2"> |
|
|
|
<li |
|
|
|
v-for="link in getGroupedItems(section.items) |
|
|
|
.personal" |
|
|
|
:key="link.path" |
|
|
|
class="group/item" |
|
|
|
> |
|
|
|
<nuxt-link |
|
|
|
:to="link.path" |
|
|
|
@click="handleMouseLeave" |
|
|
|
class="block text-base text-gray-200 rounded-lg py-2.5 px-4 transition-all duration-200 hover:text-white hover:bg-white/5 relative" |
|
|
|
:class="{ |
|
|
|
'text-white font-medium bg-white/10 is-active': |
|
|
|
route.path === link.path, |
|
|
|
}" |
|
|
|
> |
|
|
|
<span |
|
|
|
class="relative flex items-center gap-3" |
|
|
|
<span>{{ t("home.personal.title") }}</span> |
|
|
|
</nuxt-link> |
|
|
|
</h4> |
|
|
|
<ul class="flex gap-12"> |
|
|
|
<li |
|
|
|
v-for="link in getGroupedItems(item.children[0].items).personal" |
|
|
|
:key="link.path" |
|
|
|
> |
|
|
|
<span |
|
|
|
class="w-1.5 h-1.5 rounded-full bg-white/30 group-hover/item:bg-white/60 transition-colors duration-200" |
|
|
|
></span> |
|
|
|
<span class="text-base">{{ |
|
|
|
t(link.label) |
|
|
|
}}</span> |
|
|
|
</span> |
|
|
|
</nuxt-link> |
|
|
|
</li> |
|
|
|
</ul> |
|
|
|
<nuxt-link |
|
|
|
:to="link.path" |
|
|
|
@click="handleMouseLeave" |
|
|
|
class="block text-[16px] text-gray-300 hover:text-white transition-colors" |
|
|
|
> |
|
|
|
{{ t(link.label) }} |
|
|
|
</nuxt-link> |
|
|
|
<ul v-if="link.tags && link.tags.length" class="mt-1"> |
|
|
|
<li v-for="tag in link.tags" :key="tag"> |
|
|
|
<nuxt-link |
|
|
|
:to="`${link.path}&tag=${tag}`" |
|
|
|
@click.stop="handleMouseLeave" |
|
|
|
class="text-sm text-gray-400 hover:text-white transition-colors duration-200" |
|
|
|
> |
|
|
|
{{ tag }} |
|
|
|
</nuxt-link> |
|
|
|
</li> |
|
|
|
</ul> |
|
|
|
</li> |
|
|
|
</ul> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</transition> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
</nav> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="flex justify-start items-center gap-4 md:gap-6"> |
|
|
|
<!-- Search --> |
|
|
|
<div |
|
|
|
@click="openSearch" |
|
|
|
class="w-auto h-8 relative items-center opacity-40 rounded-2xl pr-4 hover:opacity-100 transition-opacity duration-300 hidden md:flex cursor-pointer" |
|
|
|
style="border: 0.5px solid rgba(255, 255, 255, 0.4)" |
|
|
|
> |
|
|
|
<span |
|
|
|
class="flex items-center justify-center w-8 h-8 opacity-80 hover:opacity-100 text-white" |
|
|
|
> |
|
|
|
<i class="icon-search text-sm"></i> |
|
|
|
</span> |
|
|
|
<span |
|
|
|
class="hidden lg:inline-block ml-1 text-white text-sm opacity-80" |
|
|
|
> |
|
|
|
{{ t("common.search") }} |
|
|
|
</span> |
|
|
|
<!-- Input overlay could go here if implementing search --> |
|
|
|
</transition> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
</nav> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- Language --> |
|
|
|
<LanguageSwitcher /> |
|
|
|
|
|
|
|
<!-- Mobile Menu Button --> |
|
|
|
<div class="md:hidden"> |
|
|
|
<button |
|
|
|
@click="toggleMobileMenu" |
|
|
|
class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 bg-white/10 hover:text-white hover:bg-white/20 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white" |
|
|
|
<div class="flex justify-start items-center gap-4 md:gap-6"> |
|
|
|
<!-- Search --> |
|
|
|
<div |
|
|
|
@click="openSearch" |
|
|
|
class="w-auto h-8 relative items-center opacity-40 rounded-2xl pr-4 hover:opacity-100 transition-opacity duration-300 hidden md:flex cursor-pointer" |
|
|
|
style="border: 0.5px solid rgba(255, 255, 255, 0.4)" |
|
|
|
> |
|
|
|
<span class="sr-only">Open main menu</span> |
|
|
|
<!-- Icon when menu is closed. --> |
|
|
|
<svg |
|
|
|
v-if="!mobileMenuOpen" |
|
|
|
class="block h-6 w-6" |
|
|
|
xmlns="http://www.w3.org/2000/svg" |
|
|
|
fill="none" |
|
|
|
viewBox="0 0 24 24" |
|
|
|
stroke="currentColor" |
|
|
|
aria-hidden="true" |
|
|
|
<span |
|
|
|
class="flex items-center justify-center w-8 h-8 opacity-80 hover:opacity-100 text-white" |
|
|
|
> |
|
|
|
<path |
|
|
|
stroke-linecap="round" |
|
|
|
stroke-linejoin="round" |
|
|
|
stroke-width="2" |
|
|
|
d="M4 6h16M4 12h16M4 18h16" |
|
|
|
/> |
|
|
|
</svg> |
|
|
|
<!-- Icon when menu is open. --> |
|
|
|
<svg |
|
|
|
v-else |
|
|
|
class="block h-6 w-6" |
|
|
|
xmlns="http://www.w3.org/2000/svg" |
|
|
|
fill="none" |
|
|
|
viewBox="0 0 24 24" |
|
|
|
stroke="currentColor" |
|
|
|
aria-hidden="true" |
|
|
|
<i class="icon-search text-sm"></i> |
|
|
|
</span> |
|
|
|
<span |
|
|
|
class="hidden lg:inline-block ml-1 text-white text-sm opacity-80" |
|
|
|
> |
|
|
|
<path |
|
|
|
stroke-linecap="round" |
|
|
|
stroke-linejoin="round" |
|
|
|
stroke-width="2" |
|
|
|
d="M6 18L18 6M6 6l12 12" |
|
|
|
/> |
|
|
|
</svg> |
|
|
|
</button> |
|
|
|
{{ t("common.search") }} |
|
|
|
</span> |
|
|
|
<!-- Input overlay could go here if implementing search --> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- Language --> |
|
|
|
<LanguageSwitcher /> |
|
|
|
|
|
|
|
<!-- Mobile Menu Button --> |
|
|
|
<div class="md:hidden"> |
|
|
|
<button |
|
|
|
@click="toggleMobileMenu" |
|
|
|
class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 bg-white/10 hover:text-white hover:bg-white/20 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white" |
|
|
|
> |
|
|
|
<span class="sr-only">Open main menu</span> |
|
|
|
<!-- Icon when menu is closed. --> |
|
|
|
<svg |
|
|
|
v-if="!mobileMenuOpen" |
|
|
|
class="block h-6 w-6" |
|
|
|
xmlns="http://www.w3.org/2000/svg" |
|
|
|
fill="none" |
|
|
|
viewBox="0 0 24 24" |
|
|
|
stroke="currentColor" |
|
|
|
aria-hidden="true" |
|
|
|
> |
|
|
|
<path |
|
|
|
stroke-linecap="round" |
|
|
|
stroke-linejoin="round" |
|
|
|
stroke-width="2" |
|
|
|
d="M4 6h16M4 12h16M4 18h16" |
|
|
|
/> |
|
|
|
</svg> |
|
|
|
<!-- Icon when menu is open. --> |
|
|
|
<svg |
|
|
|
v-else |
|
|
|
class="block h-6 w-6" |
|
|
|
xmlns="http://www.w3.org/2000/svg" |
|
|
|
fill="none" |
|
|
|
viewBox="0 0 24 24" |
|
|
|
stroke="currentColor" |
|
|
|
aria-hidden="true" |
|
|
|
> |
|
|
|
<path |
|
|
|
stroke-linecap="round" |
|
|
|
stroke-linejoin="round" |
|
|
|
stroke-width="2" |
|
|
|
d="M6 18L18 6M6 6l12 12" |
|
|
|
/> |
|
|
|
</svg> |
|
|
|
</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
@@ -453,6 +419,7 @@ |
|
|
|
import { ref, computed, watch, nextTick } from "#imports"; |
|
|
|
import { useI18n } from "vue-i18n"; |
|
|
|
import { useSearch } from "~/composables/useSearch"; |
|
|
|
import { defineComponent } from "vue"; |
|
|
|
|
|
|
|
/** |
|
|
|
* 页面头部组件 |
|
|
@@ -493,7 +460,6 @@ const { data: categoryResponse } = await useAsyncData( |
|
|
|
// 转换为需要的格式 |
|
|
|
return content |
|
|
|
.map((item: any) => { |
|
|
|
console.log(item); |
|
|
|
return { |
|
|
|
label: item.title, |
|
|
|
path: `/products?category=${encodeURIComponent( |
|
|
@@ -501,6 +467,7 @@ const { data: categoryResponse } = await useAsyncData( |
|
|
|
)}&audiences=${item.meta.audiences}`, |
|
|
|
id: item.meta.id, |
|
|
|
audiences: item.meta.audiences, |
|
|
|
tags: item.meta.tags, |
|
|
|
}; |
|
|
|
}) |
|
|
|
.sort((a, b) => (a.id || 0) - (b.id || 0)); |
|
|
@@ -731,13 +698,13 @@ header { |
|
|
|
/* Transition for dropdown */ |
|
|
|
.fade-down-enter-active, |
|
|
|
.fade-down-leave-active { |
|
|
|
transition: all 0.2s ease-out; |
|
|
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
|
|
|
} |
|
|
|
|
|
|
|
.fade-down-enter-from, |
|
|
|
.fade-down-leave-to { |
|
|
|
opacity: 0; |
|
|
|
transform: translateY(-10px); |
|
|
|
transform: translateY(-12px); |
|
|
|
} |
|
|
|
|
|
|
|
/* Transition for search overlay */ |
|
|
@@ -881,4 +848,67 @@ header { |
|
|
|
display: none; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* 优化下拉菜单动画 */ |
|
|
|
.fade-down-enter-active, |
|
|
|
.fade-down-leave-active { |
|
|
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
|
|
|
} |
|
|
|
|
|
|
|
.fade-down-enter-from, |
|
|
|
.fade-down-leave-to { |
|
|
|
opacity: 0; |
|
|
|
transform: translateY(-12px); |
|
|
|
} |
|
|
|
|
|
|
|
/* 添加下拉菜单背景渐变 */ |
|
|
|
.bg-slate-900\/95 { |
|
|
|
background: linear-gradient(to bottom, rgba(15, 23, 42, 0.95), rgba(15, 23, 42, 0.98)); |
|
|
|
} |
|
|
|
|
|
|
|
/* 响应式布局 */ |
|
|
|
@media (max-width: 1280px) { |
|
|
|
/* 调整主网格为 3 列,产品分类占 1 列,帮助/主题占 2 列 */ |
|
|
|
.md\\:grid-cols-4 { |
|
|
|
grid-template-columns: repeat(3, minmax(0, 1fr)); |
|
|
|
} |
|
|
|
.md\\:col-span-2 { |
|
|
|
grid-column: span 1 / span 1; /* 产品分类在 1280px 以下只占 1 列 */ |
|
|
|
} |
|
|
|
/* 帮助和实用主题的父容器 */ |
|
|
|
.md\\:col-span-2.grid.grid-cols-1.sm\\:grid-cols-2 { |
|
|
|
grid-column: span 2 / span 2; /* 帮助/主题在 1280px 以下占 2 列 */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@media (max-width: 1024px) { |
|
|
|
/* 主网格在 1024px 以下变为 2 列 */ |
|
|
|
.md\\:grid-cols-4 { |
|
|
|
grid-template-columns: repeat(2, minmax(0, 1fr)); |
|
|
|
} |
|
|
|
/* 产品分类在 1024px 以下仍然占 1 列 */ |
|
|
|
.md\\:col-span-2 { |
|
|
|
grid-column: span 1 / span 1; |
|
|
|
} |
|
|
|
/* 帮助和实用主题的父容器在 1024px 以下仍然占 1 列 */ |
|
|
|
.md\\:col-span-2.grid.grid-cols-1.sm\\:grid-cols-2 { |
|
|
|
grid-column: span 1 / span 1; |
|
|
|
} |
|
|
|
/* 产品分类和帮助主题内部的 sm:grid-cols-2 变为单列 */ |
|
|
|
.sm\\:grid-cols-2 { |
|
|
|
grid-template-columns: repeat(1, minmax(0, 1fr)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@media (max-width: 768px) { |
|
|
|
/* 在移动端,所有列都变为单列堆叠 */ |
|
|
|
.md\\:grid-cols-4, |
|
|
|
.md\\:col-span-2, |
|
|
|
.md\\:col-span-2.grid, |
|
|
|
.sm\\:grid-cols-2 { |
|
|
|
grid-template-columns: repeat(1, minmax(0, 1fr)); |
|
|
|
grid-column: span 1 / span 1; |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |
|
|
|
|