diff --git a/src/components/Header.astro b/src/components/Header.astro index 5d028d9..cbd5d0a 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -10,10 +10,11 @@ const prefix = curLocale === 'en' ? '/en' : ''; const isCurrent = (href: string) => path === href || path === href.replace(/\/$/, '') || path.startsWith(href); -// 顺序:开源 · 文章 · 图库 · 瞬间 · 关于(瞬间新进,开源前置) +// 顺序:开源 · 文章 · 书架 · 图库 · 瞬间 · 关于(书架=阅读轨延伸紧跟文章;瞬间新进,开源前置) const nav = [ { href: `${prefix}/opensource/`, label: t('nav_opensource', curLocale) }, { href: `${prefix}/archives/`, label: t('nav_posts', curLocale) }, + { href: `${prefix}/books/`, label: t('nav_books', curLocale) }, { href: `${prefix}/gallery/`, label: t('nav_gallery', curLocale) }, { href: `${prefix}/moments/`, label: t('nav_moments', curLocale) }, { href: `${prefix}/about/`, label: t('nav_about', curLocale) }, @@ -26,8 +27,9 @@ const switchLabel = curLocale === 'zh' ? 'EN' : '中'; @@ -110,6 +108,21 @@ const switchLabel = curLocale === 'zh' ? 'EN' : '中'; padding: 0; margin: 0; } + /* nav-side:导航+功能钮右聚;nav 可收缩(min-width:0)——内滚只发生在文本区 */ + .nav-side { + display: flex; + align-items: center; + gap: clamp(2px, 0.8vw, 8px); + min-width: 0; + margin-left: auto; + } + nav { min-width: 0; } + .nav-actions { + display: flex; + align-items: center; + gap: clamp(2px, 0.8vw, 8px); + flex: none; + } .nav-link { font-size: 15px; color: var(--ink-3); diff --git a/src/components/geek/Keyboard.astro b/src/components/geek/Keyboard.astro index bada4da..9b92194 100644 --- a/src/components/geek/Keyboard.astro +++ b/src/components/geek/Keyboard.astro @@ -10,6 +10,7 @@ const pre = locale === 'en' ? '/en' : ''; const routes: Record = { h: `${pre}/`, a: `${pre}/archives/`, + s: `${pre}/books/`, g: `${pre}/gallery/`, m: `${pre}/moments/`, b: `${pre}/about/`, @@ -25,6 +26,7 @@ const routes: Record = { ?{t('kbd_this_help', locale)} g h{t('kbd_gh_home', locale)} g a{t('kbd_ga_posts', locale)} + g s{t('kbd_gs_books', locale)} g g{t('kbd_gg_gallery', locale)} g m{t('kbd_gm_moments', locale)} /terminal{t('kbd_terminal', locale)} diff --git a/src/i18n/ui.ts b/src/i18n/ui.ts index cdb1d0b..909adb2 100644 --- a/src/i18n/ui.ts +++ b/src/i18n/ui.ts @@ -11,6 +11,8 @@ const dict = { nav_gallery: { zh: '图库', en: 'Gallery' }, nav_about: { zh: '关于', en: 'About' }, nav_opensource: { zh: '开源', en: 'Projects' }, // en 用短词:390-430px 尾部主题钮免内滚(用户拍板) + nav_books: { zh: '书架', en: 'Books' }, + kbd_gs_books: { zh: '书架', en: 'Books' }, search_label: { zh: '搜索', en: 'Search' }, search_placeholder: { zh: '搜索文章…(Esc 关闭)', en: 'Search posts… (Esc to close)' }, search_hint: { zh: '索引由 Pagefind 构建期生成 · 静态站零后端', en: 'Index built by Pagefind · zero-backend static site' }, diff --git a/tests/e2e.mjs b/tests/e2e.mjs index 05342ec..52101b3 100644 --- a/tests/e2e.mjs +++ b/tests/e2e.mjs @@ -83,7 +83,7 @@ ok('en 图库可达', page.url().includes('/en/gallery')); // E 车道回归:en 页导航必须整轨 /en/(用户实测"切语言后点导航回中文"的防线) const enNavHrefs = await page.$$eval('nav a[href^="/"]:not(.nav-lang)', (as) => as.map((a) => a.getAttribute('href'))); const enNavBad = await page.$$eval('nav a[href^="/"]:not(.nav-lang)', (as) => as.filter((a) => !(a.getAttribute('href') ?? '').startsWith('/en/')).map((a) => a.outerHTML.slice(0, 140))); -ok('en 导航全轨 /en/ 前缀', enNavBad.length === 0 && enNavHrefs.length >= 5, enNavBad.join(' ; ') || enNavHrefs.join(' ')); +ok('en 导航全轨 /en/ 前缀', enNavBad.length === 0 && enNavHrefs.length >= 6 && enNavHrefs.includes('/en/books/'), enNavBad.join(' ; ') || enNavHrefs.join(' ')); const enBrand = await page.getAttribute('a.brand', 'href'); ok('en 品牌链接指 /en/', enBrand === '/en/', String(enBrand));