|
1 | 1 | --- |
2 | 2 | import { ui, type Lang } from '../i18n'; |
3 | 3 |
|
4 | | -interface Props { |
5 | | - lang: string; |
6 | | -} |
7 | | -
|
| 4 | +interface Props { lang: string; } |
8 | 5 | const { lang } = Astro.props; |
9 | 6 | const l = lang as Lang; |
| 7 | +const isZh = lang === 'zh-hans'; |
10 | 8 |
|
11 | 9 | function t(key: keyof typeof ui['zh-hans']): string { |
12 | 10 | return ((ui[l] as typeof ui['zh-hans'])[key] ?? ui['zh-hans'][key]) as string; |
13 | 11 | } |
14 | 12 |
|
15 | | -const isZh = lang === 'zh-hans'; |
16 | | -
|
17 | 13 | const quickLinks = [ |
18 | | - { label: t('nav.about'), href: `/${lang}/about` }, |
| 14 | + { label: t('nav.about'), href: `/${lang}/about` }, |
19 | 15 | { label: t('nav.projects'), href: `/${lang}/projects` }, |
20 | | - { label: t('nav.tools'), href: `/${lang}/tools` }, |
| 16 | + { label: t('nav.tools'), href: `/${lang}/tools` }, |
21 | 17 | ]; |
22 | | -
|
23 | 18 | const learnLinks = [ |
24 | | - { label: isZh ? '博客' : 'Blog', href: `/${lang}/learn` }, |
25 | | - { label: isZh ? '教程' : 'Tutorials', href: `/${lang}/learn#tutorials` }, |
| 19 | + { label: isZh ? '博客' : 'Blog', href: `/${lang}/learn` }, |
| 20 | + { label: isZh ? '教程' : 'Tutorials', href: `/${lang}/learn#tutorials` }, |
26 | 21 | { label: isZh ? '技术规范' : 'Standards', href: `/${lang}/learn#standards` }, |
27 | 22 | ]; |
28 | | -
|
29 | 23 | const communityLinks = [ |
30 | | - { label: isZh ? '成员名录' : 'Members', href: `/${lang}/community` }, |
31 | | - { label: isZh ? '讨论区' : 'Discussions', href: 'https://github.com/MontageSubs/community/discussions', external: true }, |
32 | | - { label: isZh ? '行为准则' : 'Code of Conduct', href: `/${lang}/community#conduct` }, |
| 24 | + { label: isZh ? '成员名录' : 'Members', href: `/${lang}/community` }, |
| 25 | + { label: isZh ? '讨论区' : 'Discussions', href: 'https://github.com/MontageSubs/community/discussions', external: true }, |
| 26 | + { label: isZh ? '行为准则' : 'Code of Conduct', href: `/${lang}/community#conduct` }, |
33 | 27 | ]; |
34 | | -
|
35 | 28 | const contributeLinks = [ |
36 | 29 | { label: isZh ? '如何贡献' : 'How to Contribute', href: `/${lang}/contribute` }, |
37 | | - { label: isZh ? '翻译参与' : 'Translation', href: `/${lang}/contribute#translate` }, |
38 | | - { label: isZh ? '工具开发' : 'Development', href: `/${lang}/contribute#develop` }, |
39 | | - { label: isZh ? '支持我们' : 'Support Us', href: `/${lang}/contribute#support` }, |
| 30 | + { label: isZh ? '翻译参与' : 'Translation', href: `/${lang}/contribute#translate` }, |
| 31 | + { label: isZh ? '工具开发' : 'Development', href: `/${lang}/contribute#develop` }, |
| 32 | + { label: isZh ? '支持我们' : 'Support Us', href: `/${lang}/contribute#support` }, |
40 | 33 | ]; |
41 | | -
|
42 | 34 | const socials = [ |
43 | | - { name: 'Telegram', href: 'https://t.me/MontageSubs' }, |
44 | | - { name: 'Discord', href: 'https://discord.gg/montagesubs' }, |
45 | | - { name: 'YouTube', href: 'https://youtube.com/@MontageSubs' }, |
46 | | - { name: 'GitHub', href: 'https://github.com/MontageSubs' }, |
47 | | - { name: 'Twitter / X', href: 'https://twitter.com/MontageSubs' }, |
48 | | - { name: 'Bluesky', href: 'https://bsky.app/profile/montagesubs.bsky.social' }, |
49 | | - { name: 'Mastodon', href: 'https://mastodon.social/@MontageSubs' }, |
50 | | - { name: 'B站', href: 'https://space.bilibili.com/MontageSubs' }, |
51 | | - { name: '微博', href: 'https://weibo.com/MontageSubs' }, |
52 | | - { name: 'Instagram', href: 'https://instagram.com/MontageSubs' }, |
| 35 | + { name: 'Telegram', href: 'https://t.me/MontageSubs' }, |
| 36 | + { name: 'Discord', href: 'https://discord.gg/montagesubs' }, |
| 37 | + { name: 'YouTube', href: 'https://youtube.com/@MontageSubs' }, |
| 38 | + { name: 'GitHub', href: 'https://github.com/MontageSubs' }, |
| 39 | + { name: 'Twitter / X',href: 'https://twitter.com/MontageSubs' }, |
| 40 | + { name: 'Bluesky', href: 'https://bsky.app/profile/montagesubs.bsky.social' }, |
| 41 | + { name: 'Mastodon', href: 'https://mastodon.social/@MontageSubs' }, |
| 42 | + { name: 'B站', href: 'https://space.bilibili.com/MontageSubs' }, |
| 43 | + { name: '微博', href: 'https://weibo.com/MontageSubs' }, |
| 44 | + { name: 'Instagram', href: 'https://instagram.com/MontageSubs' }, |
53 | 45 | ]; |
54 | | -
|
55 | 46 | const legalLinks = [ |
56 | | - { label: t('footer.nonprofit'), href: `/${lang}/about#governance` }, |
57 | | - { label: t('footer.opensource'), href: 'https://github.com/MontageSubs', external: true }, |
58 | | - { label: t('footer.copyright_notice'), href: `/${lang}/about#copyright` }, |
59 | | - { label: t('footer.dmca'), href: `/${lang}/about#dmca` }, |
60 | | - { label: t('footer.privacy'), href: `/${lang}/about#privacy` }, |
| 47 | + { label: t('footer.nonprofit'), href: `/${lang}/about#governance` }, |
| 48 | + { label: t('footer.opensource'), href: 'https://github.com/MontageSubs', external: true }, |
| 49 | + { label: t('footer.copyright_notice'), href: `/${lang}/about#copyright` }, |
| 50 | + { label: t('footer.dmca'), href: `/${lang}/about#dmca` }, |
| 51 | + { label: t('footer.privacy'), href: `/${lang}/about#privacy` }, |
61 | 52 | ]; |
| 53 | +
|
| 54 | +const colYear = new Date().getFullYear(); |
62 | 55 | --- |
63 | 56 |
|
64 | | -<footer class="bg-[#0a0a0a] border-t border-white/[0.07] mt-auto" data-pagefind-ignore> |
65 | | - <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16"> |
| 57 | +<footer class="relative bg-ink border-t border-bone/[0.07] mt-auto" data-pagefind-ignore> |
| 58 | + |
| 59 | + <!-- Giant wordmark — editorial closer --> |
| 60 | + <div class="overflow-hidden border-b border-bone/[0.06]"> |
| 61 | + <div class="max-w-[1400px] mx-auto px-5 sm:px-8 lg:px-12 pt-20 pb-10"> |
| 62 | + <div class="flex items-end justify-between gap-6 flex-wrap"> |
| 63 | + <div> |
| 64 | + <p class="micro-label mb-6">{isZh ? '回到顶部 ↑' : 'Back to top ↑'} <a href="#top" class="text-bone-dim hover:text-signal-yellow ml-2">↑</a></p> |
| 65 | + <h2 class="font-display text-[clamp(4rem,16vw,16rem)] leading-[0.85] tracking-tightest text-bone"> |
| 66 | + Montage<span class="font-display-italic text-signal-yellow">Subs.</span> |
| 67 | + </h2> |
| 68 | + </div> |
| 69 | + </div> |
| 70 | + </div> |
| 71 | + </div> |
66 | 72 |
|
67 | | - <!-- Main columns --> |
68 | | - <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-8 mb-12"> |
| 73 | + <div class="max-w-[1400px] mx-auto px-5 sm:px-8 lg:px-12 py-16"> |
69 | 74 |
|
70 | | - <!-- Brand --> |
71 | | - <div class="col-span-2 md:col-span-3 lg:col-span-1"> |
72 | | - <a href={`/${lang}/`} class="inline-flex items-center gap-3 mb-5 group"> |
73 | | - <div class="w-10 h-10 bg-[#0a0a0a] border border-yellow-400/30 rounded-md flex items-center justify-center group-hover:border-yellow-400/60 transition-colors"> |
74 | | - <span class="text-yellow-400 font-black text-2xl leading-none select-none">M</span> |
75 | | - </div> |
76 | | - <span class="text-white font-semibold">{isZh ? '蒙太奇字幕社区' : 'MontageSubs'}</span> |
77 | | - </a> |
78 | | - <p class="text-gray-500 text-sm leading-relaxed max-w-[220px]"> |
| 75 | + <!-- Five-column grid --> |
| 76 | + <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-10 mb-14"> |
| 77 | + <div class="col-span-2 md:col-span-3 lg:col-span-2"> |
| 78 | + <p class="micro-label mb-5">— {isZh ? '关于本站' : 'About this site'}</p> |
| 79 | + <p class="text-bone-dim text-sm leading-relaxed max-w-sm"> |
79 | 80 | {t('footer.tagline')} |
80 | 81 | </p> |
| 82 | + <div class="mt-6 flex items-center gap-3"> |
| 83 | + <span class="inline-flex w-2 h-2 rounded-full bg-live"></span> |
| 84 | + <span class="font-mono text-[11px] text-bone-mute uppercase tracking-[0.18em]"> |
| 85 | + {isZh ? '社区开放中' : 'Community online'} · v0.1 |
| 86 | + </span> |
| 87 | + </div> |
81 | 88 | </div> |
82 | 89 |
|
83 | | - <!-- Quick Links --> |
84 | 90 | <div> |
85 | | - <h3 class="text-white text-xs font-semibold uppercase tracking-wider mb-4">{t('footer.quicklinks')}</h3> |
86 | | - <ul class="space-y-3"> |
| 91 | + <h3 class="micro-label mb-5">— {t('footer.quicklinks')}</h3> |
| 92 | + <ul class="space-y-2.5"> |
87 | 93 | {quickLinks.map(({ label, href }) => ( |
88 | | - <li> |
89 | | - <a href={href} class="text-gray-500 hover:text-gray-200 text-sm transition-colors">{label}</a> |
90 | | - </li> |
| 94 | + <li><a href={href} class="text-bone-dim hover:text-signal-yellow text-[14px] transition-colors">{label}</a></li> |
91 | 95 | ))} |
92 | 96 | </ul> |
93 | 97 | </div> |
94 | 98 |
|
95 | | - <!-- Learn --> |
96 | 99 | <div> |
97 | | - <h3 class="text-white text-xs font-semibold uppercase tracking-wider mb-4">{t('footer.learn_resources')}</h3> |
98 | | - <ul class="space-y-3"> |
| 100 | + <h3 class="micro-label mb-5">— {t('footer.learn_resources')}</h3> |
| 101 | + <ul class="space-y-2.5"> |
99 | 102 | {learnLinks.map(({ label, href }) => ( |
100 | | - <li> |
101 | | - <a href={href} class="text-gray-500 hover:text-gray-200 text-sm transition-colors">{label}</a> |
102 | | - </li> |
| 103 | + <li><a href={href} class="text-bone-dim hover:text-signal-yellow text-[14px] transition-colors">{label}</a></li> |
103 | 104 | ))} |
104 | 105 | </ul> |
105 | 106 | </div> |
106 | 107 |
|
107 | | - <!-- Community --> |
108 | 108 | <div> |
109 | | - <h3 class="text-white text-xs font-semibold uppercase tracking-wider mb-4">{t('footer.community')}</h3> |
110 | | - <ul class="space-y-3"> |
| 109 | + <h3 class="micro-label mb-5">— {t('footer.community')}</h3> |
| 110 | + <ul class="space-y-2.5"> |
111 | 111 | {communityLinks.map(({ label, href, external }) => ( |
112 | | - <li> |
113 | | - <a |
114 | | - href={href} |
115 | | - class="text-gray-500 hover:text-gray-200 text-sm transition-colors" |
116 | | - target={external ? '_blank' : undefined} |
117 | | - rel={external ? 'noopener noreferrer' : undefined} |
118 | | - > |
119 | | - {label} |
120 | | - </a> |
121 | | - </li> |
| 112 | + <li><a href={href} class="text-bone-dim hover:text-signal-yellow text-[14px] transition-colors" |
| 113 | + target={external ? '_blank' : undefined} rel={external ? 'noopener noreferrer' : undefined}>{label}</a></li> |
122 | 114 | ))} |
123 | 115 | </ul> |
124 | 116 | </div> |
125 | 117 |
|
126 | | - <!-- Contribute --> |
127 | 118 | <div> |
128 | | - <h3 class="text-white text-xs font-semibold uppercase tracking-wider mb-4">{t('footer.contribute')}</h3> |
129 | | - <ul class="space-y-3"> |
| 119 | + <h3 class="micro-label mb-5">— {t('footer.contribute')}</h3> |
| 120 | + <ul class="space-y-2.5"> |
130 | 121 | {contributeLinks.map(({ label, href }) => ( |
131 | | - <li> |
132 | | - <a href={href} class="text-gray-500 hover:text-gray-200 text-sm transition-colors">{label}</a> |
133 | | - </li> |
| 122 | + <li><a href={href} class="text-bone-dim hover:text-signal-yellow text-[14px] transition-colors">{label}</a></li> |
134 | 123 | ))} |
135 | 124 | </ul> |
136 | 125 | </div> |
137 | 126 | </div> |
138 | 127 |
|
139 | | - <!-- Social links + RSS --> |
140 | | - <div class="py-8 border-t border-white/[0.07]"> |
141 | | - <div class="flex flex-wrap gap-x-5 gap-y-3"> |
| 128 | + <!-- Socials marquee --> |
| 129 | + <div class="py-6 border-t border-bone/[0.06]"> |
| 130 | + <div class="flex flex-wrap gap-x-6 gap-y-2"> |
142 | 131 | {socials.map(({ name, href }) => ( |
143 | | - <a |
144 | | - href={href} |
145 | | - class="text-gray-500 hover:text-gray-300 text-sm transition-colors" |
146 | | - target="_blank" |
147 | | - rel="noopener noreferrer" |
148 | | - aria-label={name} |
149 | | - > |
| 132 | + <a href={href} target="_blank" rel="noopener noreferrer" |
| 133 | + class="text-bone-mute hover:text-bone text-[13px] transition-colors"> |
150 | 134 | {name} |
151 | 135 | </a> |
152 | 136 | ))} |
153 | | - <span class="text-gray-700 self-center">·</span> |
154 | | - <a href={`/${lang}/rss.xml`} class="text-gray-500 hover:text-yellow-400 text-sm transition-colors" aria-label="RSS"> |
155 | | - RSS |
156 | | - </a> |
157 | | - <a |
158 | | - href="https://substack.com/@montagesubs" |
159 | | - class="text-gray-500 hover:text-gray-300 text-sm transition-colors" |
160 | | - target="_blank" |
161 | | - rel="noopener noreferrer" |
162 | | - > |
163 | | - Substack |
164 | | - </a> |
| 137 | + <span class="text-bone-mute self-center">·</span> |
| 138 | + <a href={`/${lang}/rss.xml`} class="text-bone-mute hover:text-signal-yellow text-[13px] transition-colors">RSS</a> |
| 139 | + <a href="https://substack.com/@montagesubs" target="_blank" rel="noopener noreferrer" |
| 140 | + class="text-bone-mute hover:text-bone text-[13px] transition-colors">Substack</a> |
165 | 141 | </div> |
166 | 142 | </div> |
167 | 143 |
|
168 | | - <!-- Legal bar --> |
169 | | - <div class="pt-6 border-t border-white/[0.07] flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4"> |
170 | | - <p class="text-gray-600 text-xs">{t('footer.copyright')}</p> |
171 | | - <div class="flex flex-wrap gap-x-4 gap-y-1.5"> |
| 144 | + <!-- Legal --> |
| 145 | + <div class="pt-6 border-t border-bone/[0.06] flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4"> |
| 146 | + <p class="font-mono text-[11px] text-bone-mute tracking-wider"> |
| 147 | + {t('footer.copyright')} · {colYear} |
| 148 | + </p> |
| 149 | + <div class="flex flex-wrap gap-x-5 gap-y-1.5"> |
172 | 150 | {legalLinks.map(({ label, href, external }) => ( |
173 | | - <a |
174 | | - href={href} |
175 | | - class="text-gray-600 hover:text-gray-400 text-xs transition-colors" |
176 | | - target={external ? '_blank' : undefined} |
177 | | - rel={external ? 'noopener noreferrer' : undefined} |
178 | | - > |
179 | | - {label} |
180 | | - </a> |
| 151 | + <a href={href} class="text-bone-mute hover:text-bone text-[11px] font-mono uppercase tracking-[0.12em] transition-colors" |
| 152 | + target={external ? '_blank' : undefined} rel={external ? 'noopener noreferrer' : undefined}>{label}</a> |
181 | 153 | ))} |
182 | 154 | </div> |
183 | 155 | </div> |
| 156 | + |
184 | 157 | </div> |
185 | 158 | </footer> |
0 commit comments