@ -1,5 +1,6 @@
|
||||
---
|
||||
import '@/styles/global.css'
|
||||
import LoadingScreen from '@/components/LoadingScreen.astro'
|
||||
import { href, ROUTES } from '@/lib/routes'
|
||||
import { getI18n } from '@/i18n/utils'
|
||||
import { LOCALE_NAMES } from '@/i18n/config'
|
||||
@ -62,7 +63,10 @@ const headers = {
|
||||
<title>{siteTitle}</title>
|
||||
</head>
|
||||
<body class="bg-white text-black min-h-screen flex flex-col p-[30px_50px] font-sans">
|
||||
|
||||
|
||||
<!-- 加载动画屏:独立组件,标记/样式/隐藏逻辑封装在 LoadingScreen.astro -->
|
||||
<LoadingScreen />
|
||||
|
||||
<!-- 顶部主导航栏 -->
|
||||
<nav class="flex justify-between items-center text-[13px] font-bold tracking-[0.5px] uppercase">
|
||||
<div class="flex flex-wrap items-center gap-6 md:gap-8">
|
||||
@ -80,7 +84,7 @@ const headers = {
|
||||
<svg class="w-2.5 h-2.5 transition-transform duration-200" :class="open ? 'rotate-180' : ''" viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div x-show="open" x-transition.opacity.duration.150ms class="absolute left-0 top-full mt-2 z-50 min-w-[240px] bg-white border border-black/10 shadow-sm py-1">
|
||||
<div x-show="open" x-cloak x-transition.opacity.duration.150ms class="absolute left-0 top-full mt-2 z-50 min-w-[240px] bg-white border border-black/10 shadow-sm py-1">
|
||||
{
|
||||
headers.runways.map((item) => (
|
||||
<a href={item.href} class="block px-4 py-2 text-[12px] uppercase tracking-[0.4px] hover:bg-black/5 transition-colors">
|
||||
@ -98,7 +102,7 @@ const headers = {
|
||||
<svg viewBox="0 0 12 12" width="10" height="10"><path d="M2.5 4.5l3.5 3 3.5-3" stroke="currentColor" fill="none" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div x-show="open" x-transition.opacity.duration.150ms class="absolute left-0 top-full mt-2 z-50 min-w-[240px] bg-white border border-black/10 shadow-sm py-1">
|
||||
<div x-show="open" x-cloak x-transition.opacity.duration.150ms class="absolute left-0 top-full mt-2 z-50 min-w-[240px] bg-white border border-black/10 shadow-sm py-1">
|
||||
{
|
||||
headers.streets.map((item) => (
|
||||
<a href={item.href} class="block px-4 py-2 text-[12px] uppercase tracking-[0.4px] hover:bg-black/5 transition-colors">
|
||||
@ -122,7 +126,7 @@ const headers = {
|
||||
<span>{LOCALE_NAMES[locale].nativeName}</span>
|
||||
</button>
|
||||
<ul
|
||||
x-show="open"
|
||||
x-show="open" x-cloak
|
||||
x-transition.opacity.duration.150ms
|
||||
class="absolute right-0 top-full min-w-[160px] bg-white border border-black/10 shadow-sm z-50 py-2"
|
||||
>
|
||||
@ -142,17 +146,17 @@ const headers = {
|
||||
</div>
|
||||
<div class="flex items-center gap-3" x-data="authMenu">
|
||||
<!-- 未登录:Login 链接(Alpine 登录后置为隐藏) -->
|
||||
<a x-show="!user" href={href(locale, ROUTES.login)} class="hover:opacity-60 transition-opacity duration-200 uppercase tracking-[0.5px] text-[13px]">{t('Login')}</a>
|
||||
<a x-show="!user" x-cloak href={href(locale, ROUTES.login)} class="hover:opacity-60 transition-opacity duration-200 uppercase tracking-[0.5px] text-[13px]">{t('Login')}</a>
|
||||
|
||||
<!-- 已登录:账号下拉(hover 展开,与语言切换器同款交互) -->
|
||||
<div x-show="user" class="relative" @mouseenter="open = true" @mouseleave="open = false">
|
||||
<div x-show="user" x-cloak class="relative" @mouseenter="open = true" @mouseleave="open = false">
|
||||
<button type="button" @click="open = !open" @click.outside="open = false" @keydown.escape.window="open = false" class="flex items-center gap-1.5 cursor-pointer hover:opacity-60 transition-opacity duration-200 p-1 -m-1 normal-case text-[13px] tracking-[0.5px]" aria-haspopup="menu" :aria-expanded="open">
|
||||
<span x-text="shortName"></span>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="acct-chevron w-[14px] h-[14px] transition-transform duration-200" :class="open ? 'rotate-180' : ''" aria-hidden="true">
|
||||
<polyline points="6 9 12 15 18 9"></polyline>
|
||||
</svg>
|
||||
</button>
|
||||
<ul x-show="open" x-transition.opacity.duration.150ms class="absolute right-0 top-full min-w-[160px] bg-white border border-black/10 shadow-sm z-50 py-2" role="menu">
|
||||
<ul x-show="open" x-cloak x-transition.opacity.duration.150ms class="absolute right-0 top-full min-w-[160px] bg-white border border-black/10 shadow-sm z-50 py-2" role="menu">
|
||||
<li role="none">
|
||||
<a href={href(locale, ROUTES.account)} @click="open = false" role="menuitem" class="block px-4 py-1.5 text-[13px] uppercase tracking-[0.5px] hover:bg-black/5 transition-colors opacity-60">{t('my account')}</a>
|
||||
</li>
|
||||
@ -236,7 +240,7 @@ const headers = {
|
||||
<div class="mt-6 text-[11px] font-mono text-zinc-400 uppercase tracking-widest">
|
||||
{t('© 2026 PORTFOLIO STUDIO. ALL RIGHTS RESERVED.')}
|
||||
</div>
|
||||
</footer>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user