polish(frontend): 修正中文字重发虚,并疏朗首页与数据区
补齐 Noto 600/800 并关闭伪粗;Header 加大加粗导航并加板块入口;去掉灰块底、加大列表行距,站点数据格居中缩小数字。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -159,7 +159,7 @@ export function AdminSidebar({ user }: { user: User }) {
|
||||
key={item.href}
|
||||
href={item.href}
|
||||
aria-current={active ? "page" : undefined}
|
||||
className="flex items-center gap-2.5 px-3 py-2.5 rounded-xl text-[13.5px] transition-colors"
|
||||
className="flex items-center gap-2.5 px-3 py-2.5 rounded-xl text-[13.5px] font-medium transition-colors"
|
||||
style={
|
||||
active
|
||||
? { background: "var(--nav-active-bg)", color: "var(--nav-active-ink)" }
|
||||
@@ -190,7 +190,7 @@ export function AdminSidebar({ user }: { user: User }) {
|
||||
<div className="flex items-center gap-2.5 mt-2 px-2.5 py-2.5 rounded-xl" style={{ background: "var(--panel-2)" }}>
|
||||
<Avatar name={user.nickname || user.username} src={user.avatar || undefined} size={32} />
|
||||
<div className="min-w-0 leading-tight">
|
||||
<p className="text-[13px] truncate" style={{ color: "var(--ink)" }}>
|
||||
<p className="text-[13px] font-medium truncate" style={{ color: "var(--ink)" }}>
|
||||
{user.nickname}
|
||||
</p>
|
||||
<p className="text-[11px] truncate" style={{ color: "var(--ink-3)" }}>
|
||||
|
||||
@@ -670,7 +670,7 @@ export default function UsersAdmin({
|
||||
<Avatar name={u.nickname || u.username} src={u.avatar || undefined} size={38} />
|
||||
<div className="min-w-0 flex-1 leading-tight">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<span className="text-[14px] truncate" style={{ color: "var(--ink)" }}>
|
||||
<span className="text-[14px] font-medium truncate" style={{ color: "var(--ink)" }}>
|
||||
{u.nickname}
|
||||
</span>
|
||||
{u.role !== ROLES.USER && (
|
||||
|
||||
@@ -109,8 +109,10 @@ body {
|
||||
background-color: var(--bg);
|
||||
color: var(--ink);
|
||||
font-family: var(--font-sans);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
/* 亚像素渲染在 Windows 高分屏更实;强制 grayscale 会让 400/500 中文偏虚 */
|
||||
-webkit-font-smoothing: auto;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-synthesis: none; /* 禁止伪粗,避免缺档字重糊成一团 */
|
||||
}
|
||||
|
||||
/* 全站悬停即显提示气泡(配合 TipHost + data-tip,替代原生 title 延迟) */
|
||||
@@ -282,7 +284,23 @@ body {
|
||||
padding: 14px 16px;
|
||||
border-radius: 14px;
|
||||
border: 1px solid var(--line);
|
||||
background: color-mix(in srgb, var(--tint) 65%, var(--panel));
|
||||
background: var(--panel);
|
||||
}
|
||||
.j13-interact-card.is-unsolved {
|
||||
background: color-mix(in srgb, var(--danger) 7%, var(--panel));
|
||||
border-color: color-mix(in srgb, var(--danger) 22%, var(--line));
|
||||
}
|
||||
.j13-interact-card.is-solved {
|
||||
background: color-mix(in srgb, var(--ok) 8%, var(--panel));
|
||||
border-color: color-mix(in srgb, var(--ok) 22%, var(--line));
|
||||
}
|
||||
.dark .j13-interact-card.is-unsolved {
|
||||
background: color-mix(in srgb, var(--danger) 14%, var(--panel));
|
||||
border-color: color-mix(in srgb, var(--danger) 32%, var(--line));
|
||||
}
|
||||
.dark .j13-interact-card.is-solved {
|
||||
background: color-mix(in srgb, var(--ok) 14%, var(--panel));
|
||||
border-color: color-mix(in srgb, var(--ok) 30%, var(--line));
|
||||
}
|
||||
|
||||
.j13-compose-field {
|
||||
@@ -924,7 +942,7 @@ a.j13-mention-token:hover {
|
||||
.field {
|
||||
width: 100%;
|
||||
padding: 12px 15px;
|
||||
background: var(--bg);
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--line-2);
|
||||
border-radius: var(--r-sm);
|
||||
color: var(--ink);
|
||||
@@ -1374,6 +1392,7 @@ a.j13-mention-token:hover {
|
||||
.j13-bcard-name {
|
||||
color: var(--ink);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.j13-bcard[aria-current="page"] .j13-bcard-name {
|
||||
color: var(--nav-active-ink);
|
||||
@@ -1407,26 +1426,26 @@ a.j13-mention-token:hover {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
font-size: 13.5px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.02em;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
/* 统计数字格 */
|
||||
/* 统计数字格:白底细线,避免灰块 */
|
||||
.j13-stat {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
min-width: 0;
|
||||
padding: 11px 13px;
|
||||
background: var(--panel-2);
|
||||
background: transparent;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--r-sm);
|
||||
}
|
||||
.j13-stat .j13-stat-num {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
font-weight: 500;
|
||||
line-height: 1.15;
|
||||
letter-spacing: -0.015em;
|
||||
color: var(--ink);
|
||||
@@ -1453,7 +1472,12 @@ a.j13-mention-token:hover {
|
||||
}
|
||||
.j13-pulse-cell {
|
||||
min-width: 0;
|
||||
padding: 12px 14px 11px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
padding: 14px 12px;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
@@ -1467,6 +1491,7 @@ a.j13-mention-token:hover {
|
||||
.j13-pulse-lab {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
font-size: 11.5px;
|
||||
font-weight: 400;
|
||||
@@ -1475,7 +1500,7 @@ a.j13-mention-token:hover {
|
||||
}
|
||||
.j13-pulse-num {
|
||||
margin-top: 6px;
|
||||
font-size: 22px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
line-height: 1.05;
|
||||
letter-spacing: -0.015em;
|
||||
@@ -1485,6 +1510,7 @@ a.j13-mention-token:hover {
|
||||
.j13-pulse-foot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 3px;
|
||||
margin-top: 6px;
|
||||
font-size: 10.5px;
|
||||
|
||||
@@ -24,7 +24,8 @@ const jakarta = Plus_Jakarta_Sans({
|
||||
});
|
||||
|
||||
const notoSC = Noto_Sans_SC({
|
||||
weight: ["400", "500", "700", "900"],
|
||||
// 须覆盖站内实际用到的字重:缺档时浏览器会伪粗(synthetic bold),中文在 2K 屏发虚发糊
|
||||
weight: ["400", "500", "600", "700", "800", "900"],
|
||||
variable: "--font-noto-sc",
|
||||
display: "swap",
|
||||
});
|
||||
|
||||
@@ -486,8 +486,8 @@ export default function CommentSection({
|
||||
</form>
|
||||
) : (
|
||||
<div
|
||||
className="mb-8 px-5 py-4 rounded-2xl flex items-center justify-between gap-4 flex-wrap"
|
||||
style={{ background: "var(--panel-2)" }}
|
||||
className="mb-8 px-5 py-4 rounded-2xl flex items-center justify-between gap-4 flex-wrap border"
|
||||
style={{ borderColor: "var(--line)", background: "transparent" }}
|
||||
>
|
||||
<span className="text-sm" style={{ color: "var(--ink-2)" }}>
|
||||
登录后参与讨论
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
ChevronDown,
|
||||
ShieldCheck,
|
||||
MessageSquare,
|
||||
LayoutGrid,
|
||||
} from "lucide-react";
|
||||
import { apiLogout, apiMe, apiChatUnreadSummary, type User } from "@/lib/api";
|
||||
import { hasAuthCookieHint } from "@/lib/cookies";
|
||||
@@ -233,14 +234,21 @@ export default function Header({
|
||||
</span>
|
||||
</span>
|
||||
</Link>
|
||||
<nav className="hidden lg:flex items-center gap-1 pl-3" style={{ borderLeft: "1px solid var(--line)" }}>
|
||||
<NavPill href="/" active={pathname === "/"} icon={<Home size={14} />}>
|
||||
<nav className="hidden lg:flex items-center gap-1.5 pl-3" style={{ borderLeft: "1px solid var(--line)" }}>
|
||||
<NavPill href="/" active={pathname === "/"} icon={<Home size={15} />}>
|
||||
首页
|
||||
</NavPill>
|
||||
<NavPill
|
||||
href="/boards"
|
||||
active={pathname === "/boards" || pathname?.startsWith("/board/") === true}
|
||||
icon={<LayoutGrid size={15} />}
|
||||
>
|
||||
板块
|
||||
</NavPill>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
{/* 中部留白:为后续主导航菜单项预留位置 */}
|
||||
{/* 中部弹性留白,把搜索与操作区推到右侧 */}
|
||||
<div className="hidden lg:block flex-1" aria-hidden />
|
||||
|
||||
{/* 右侧操作区:搜索靠右停靠 + 桌面/移动共用铃铛(仅挂载一次,避免重复轮询),
|
||||
@@ -370,6 +378,12 @@ export default function Header({
|
||||
</form>
|
||||
<div className="flex flex-col">
|
||||
<MobileLink href="/" active={pathname === "/"}>首页</MobileLink>
|
||||
<MobileLink
|
||||
href="/boards"
|
||||
active={pathname === "/boards" || pathname?.startsWith("/board/") === true}
|
||||
>
|
||||
板块
|
||||
</MobileLink>
|
||||
{user && <MobileLink href="/compose">发帖</MobileLink>}
|
||||
{user && (
|
||||
<MobileLink href="/chat" active={pathname?.startsWith("/chat") ?? false}>
|
||||
@@ -431,11 +445,11 @@ function NavPill({
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className="inline-flex items-center gap-1.5 px-3.5 py-2 rounded-full text-[13.5px] transition-colors"
|
||||
className="inline-flex items-center gap-1.5 px-3.5 py-2 rounded-full text-[15px] font-semibold transition-colors"
|
||||
style={
|
||||
active
|
||||
? { background: "var(--accent-soft)", color: "var(--accent)" }
|
||||
: { color: "var(--ink-2)" }
|
||||
: { color: "var(--ink)" }
|
||||
}
|
||||
>
|
||||
{icon}
|
||||
@@ -456,7 +470,7 @@ function MobileLink({
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className="px-3 py-3 rounded-2xl text-[15px] transition-colors"
|
||||
className="px-3 py-3 rounded-2xl text-[16px] font-semibold transition-colors"
|
||||
style={{
|
||||
color: active ? "var(--accent)" : "var(--ink)",
|
||||
background: active ? "var(--accent-soft)" : "transparent",
|
||||
|
||||
@@ -72,10 +72,10 @@ function QuestionPanel({ postId, state }: { postId: number; state: QuestionState
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="j13-interact-card">
|
||||
<section className={`j13-interact-card${state.solved ? " is-solved" : " is-unsolved"}`}>
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<div>
|
||||
<h2 className="font-semibold text-[15px]" style={{ color: "var(--ink)" }}>
|
||||
<h2 className="text-[15px] font-medium" style={{ color: "var(--ink)" }}>
|
||||
问答 · {state.solved ? "已解决" : "未解决"}
|
||||
</h2>
|
||||
<p className="meta text-[12.5px] mt-1">
|
||||
|
||||
@@ -40,8 +40,8 @@ export default function PostRow({
|
||||
}`}
|
||||
style={{
|
||||
borderColor: "var(--line)",
|
||||
paddingTop: compact ? 11 : 18,
|
||||
paddingBottom: compact ? 11 : 18,
|
||||
paddingTop: compact ? 15 : 22,
|
||||
paddingBottom: compact ? 15 : 22,
|
||||
animationDelay: `${Math.min(index, 9) * 35}ms`,
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -154,7 +154,7 @@ function HotRanking({ posts }: { posts: PostListItem[] }) {
|
||||
<span className="j13-rank-no">{i + 1}</span>
|
||||
<span className="min-w-0 flex-1">
|
||||
<span
|
||||
className="block truncate text-[13px] font-normal leading-snug transition-colors group-hover:text-[var(--accent)]"
|
||||
className="block truncate text-[13px] font-medium leading-snug transition-colors group-hover:text-[var(--accent)]"
|
||||
style={{ color: "var(--ink)" }}
|
||||
>
|
||||
{p.title}
|
||||
@@ -235,7 +235,7 @@ function ActiveUsers({ users }: { users: ActiveUser[] }) {
|
||||
<Avatar name={name} src={u.avatar} size={30} />
|
||||
<span className="flex-1 min-w-0">
|
||||
<span
|
||||
className="block truncate text-[13px] leading-tight"
|
||||
className="block truncate text-[13px] font-medium leading-tight"
|
||||
style={{ color: "var(--ink)" }}
|
||||
>
|
||||
{name}
|
||||
|
||||
Reference in New Issue
Block a user