Files
jiang13-bbs/frontend/app/globals.css
freefire 95921d24fa feat(home): add homepage hero banner and migrate community stats
- 新增首页欢迎横幅组件,包含时段问候、用户问候语、发帖引导按钮和社区统计数据
- 从CommunityPanels中移除stats相关逻辑,将社区统计迁移到新的HomeHero组件中
- 优化全局样式,添加横幅相关的CSS动画和样式类
2026-09-13 04:39:20 +08:00

850 lines
22 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@import "tailwindcss";
/* ============================================================
姜十三论坛 · GRAPHITE INDIGO 设计系统
冷调石墨灰阶 / 纯白卡片 / 靛蓝主色 / 近黑锌灰暗色
============================================================ */
:root {
/* 浅色(默认)——冷调石墨:底色微蓝灰,面板纯白浮起,层次干净锐利 */
--bg: #f6f7f9;
--panel: #ffffff;
--panel-2: #f2f4f7;
--tint: #eceff3;
--ink: #161a22;
--ink-2: #4b5260;
--ink-3: #5b6270;
--line: #e4e7ec; /* 装饰性分隔/卡片边(非交互,配合阴影与底色高差) */
--line-2: #7c8698; /* 功能性边界:输入框/按钮/分页等可交互控件,满足 1.4.11 ≥3:1 */
--accent: #3b5bdb;
--accent-hi: #3451c8;
--accent-soft: rgba(59, 91, 219, 0.1);
--accent-on: #ffffff;
--clay: #a5420a;
--clay-soft: rgba(165, 66, 10, 0.12);
--gold: #825700;
--gold-soft: rgba(130, 87, 0, 0.13);
--danger: #c8281e;
--danger-soft: rgba(200, 40, 30, 0.09);
--ok: #137333;
--ok-soft: rgba(19, 115, 51, 0.1);
/* 工作台语义:导航选中态 / 榜单奖牌色 */
--nav-active-bg: var(--accent-soft);
--nav-active-ink: var(--accent);
--nav-active-line: rgba(59, 91, 219, 0.22);
--rank-1: #96620f;
--rank-2: #5d6676;
--rank-3: #a05a2c;
--shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.05);
--shadow: 0 2px 8px rgba(16, 24, 40, 0.05), 0 10px 28px rgba(16, 24, 40, 0.06);
--shadow-lg: 0 6px 16px rgba(16, 24, 40, 0.08), 0 20px 48px rgba(16, 24, 40, 0.12);
/* next/font 构建期自托管,变量由 layout.tsx 注入;
本地系统字体仅作网络字体分片就绪前的回退(PingFang/雅黑与 Noto 观感接近) */
--font-display: var(--font-jakarta), var(--font-noto-sc), -apple-system,
"PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
--font-sans: var(--font-jakarta), var(--font-noto-sc), -apple-system,
"PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
--font-mono: var(--font-jetbrains), var(--font-noto-sc), ui-monospace,
"Cascadia Code", Consolas, monospace;
--r: 18px;
--r-sm: 12px;
color-scheme: light;
}
.dark {
/* 近黑锌灰:面板逐层浮起,靛蓝提亮为长春花蓝 */
--bg: #0f1115;
--panel: #181b21;
--panel-2: #20242c;
--tint: #282d37;
--ink: #eef1f6;
--ink-2: #b6bdc9;
--ink-3: #98a1b2;
--line: rgba(238, 241, 246, 0.08); /* 装饰性分隔/卡片边 */
--line-2: rgba(238, 241, 246, 0.38); /* 功能性控件边界,1.4.11 ≥3:1 */
--accent: #8ea2ff;
--accent-hi: #a9b8ff;
--accent-soft: rgba(141, 163, 255, 0.16);
--accent-on: #10162b;
--clay: #f0875a;
--clay-soft: rgba(240, 135, 90, 0.16);
--gold: #e0b259;
--gold-soft: rgba(224, 178, 89, 0.16);
--danger: #ff6b60;
--danger-soft: rgba(255, 107, 96, 0.15);
--ok: #58d18a;
--ok-soft: rgba(88, 209, 138, 0.15);
/* 工作台语义 */
--nav-active-bg: rgba(141, 163, 255, 0.14);
--nav-active-ink: #a9b8ff;
--nav-active-line: rgba(141, 163, 255, 0.3);
--rank-1: #e3bf74;
--rank-2: #b9c1cd;
--rank-3: #e0a06e;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow: 0 2px 8px rgba(0, 0, 0, 0.28), 0 12px 32px rgba(0, 0, 0, 0.22);
--shadow-lg: 0 6px 18px rgba(0, 0, 0, 0.35), 0 24px 56px rgba(0, 0, 0, 0.3);
color-scheme: dark;
}
html {
scrollbar-color: var(--line-2) transparent;
}
body {
background-color: var(--bg);
color: var(--ink);
font-family: var(--font-sans);
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
::selection {
background: var(--accent);
color: var(--accent-on);
}
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-thumb {
background: var(--line-2);
border-radius: 99px;
border: 3px solid var(--bg);
}
/* 链接重置放入 base 层:避免未分层规则击败 components 层的 .btn-primary 等类
(Tailwind v4 中未分层样式优先级高于任何 @layer) */
@layer base {
/* 必须在 base 层:未分层的 * 选择器会击败 @layer components 中所有
border-color(.field/.btn-line/.pager-btn 等曾因此实际渲染成 --line) */
*,
::before,
::after {
border-color: var(--line);
}
a {
color: inherit;
text-decoration: none;
}
}
h1, h2, h3, h4 {
font-family: var(--font-display);
letter-spacing: -0.015em;
}
:focus-visible {
outline: 2.5px solid var(--accent);
outline-offset: 2px;
border-radius: 6px;
}
@layer components {
/* ----- 小标签(旧名 .kicker 保留兼容) ----- */
.kicker {
font-family: var(--font-sans);
font-size: 12.5px;
font-weight: 600;
letter-spacing: 0.02em;
color: var(--ink-3);
}
/* ----- 卡片 ----- */
.panel {
background: var(--panel);
border: 1px solid var(--line);
border-radius: var(--r);
box-shadow: var(--shadow-sm);
}
.hover-lift {
transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.hover-lift:hover {
transform: translateY(-2px);
box-shadow: var(--shadow);
border-color: var(--line-2);
}
/* 整行可点:标题链接的 ::after 铺满最近的 relative 行容器,
行内其他交互元素加 .above-link 抬到点击层之上 */
.stretch-link::after {
content: "";
position: absolute;
inset: 0;
z-index: 1;
}
.above-link {
position: relative;
z-index: 2;
}
/* ----- 按钮(胶囊) ----- */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 7px;
padding: 10px 20px;
border-radius: 999px;
font-size: 14px;
font-weight: 600;
line-height: 1;
border: 1px solid transparent;
cursor: pointer;
transition: background 0.15s, border-color 0.15s, color 0.15s,
transform 0.12s ease, box-shadow 0.15s;
white-space: nowrap;
}
.btn:active { transform: scale(0.97); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-primary {
background: var(--accent);
color: var(--accent-on);
box-shadow: 0 1px 2px rgba(16, 24, 40, 0.12), 0 2px 8px rgba(59, 91, 219, 0.22);
}
.btn-primary:hover:not(:disabled) {
background: var(--accent-hi);
transform: translateY(-1px);
box-shadow: 0 2px 6px rgba(16, 24, 40, 0.1), 0 8px 20px rgba(59, 91, 219, 0.3);
}
.btn-primary:active:not(:disabled) {
transform: translateY(0);
}
.btn-line {
background: var(--panel);
border-color: var(--line-2);
color: var(--ink);
}
.btn-line:hover:not(:disabled) {
border-color: var(--accent);
color: var(--accent);
}
.btn-danger {
background: var(--danger-soft);
color: var(--danger);
}
.btn-danger:hover:not(:disabled) {
background: var(--danger);
color: #fff;
}
.dark .btn-danger:hover:not(:disabled) {
/* 暗色 danger 为亮红,白字仅 2.79:1,改用深色文字 */
color: #1a0c0b;
}
.btn-sm { padding: 7px 14px; font-size: 13px; }
/* ----- 点赞按钮:未赞描边态,hover 同色系填充;已赞为浅底实心态 ----- */
.j13-like {
border-color: var(--line-2);
color: var(--ink-2);
background: var(--panel);
transition:
border-color 0.15s ease,
color 0.15s ease,
background-color 0.15s ease,
box-shadow 0.15s ease;
}
.j13-like svg {
transition: transform 0.15s ease;
}
.j13-like:hover:not(:disabled),
.j13-like.is-liked {
border-color: var(--accent);
color: var(--accent);
background: var(--accent-soft);
}
/* 已赞态 hover 再加深一档,并给同色系投影;心形轻微放大(不改变布局) */
.j13-like:hover:not(:disabled) {
box-shadow: 0 2px 10px color-mix(in srgb, var(--accent) 22%, transparent);
}
.j13-like.is-liked:hover:not(:disabled) {
background: color-mix(in srgb, var(--accent) 17%, transparent);
}
.j13-like:hover:not(:disabled) svg {
transform: scale(1.15);
}
.j13-like:active:not(:disabled) svg {
transform: scale(0.95);
}
.j13-like:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
.j13-like,
.j13-like svg {
transition: none;
}
.j13-like:hover:not(:disabled) svg,
.j13-like:active:not(:disabled) svg {
transform: none;
}
}
/* ----- 表单 ----- */
.field-label {
display: block;
font-size: 13px;
font-weight: 600;
color: var(--ink-2);
margin-bottom: 8px;
}
.field {
width: 100%;
padding: 12px 15px;
background: var(--bg);
border: 1px solid var(--line-2);
border-radius: var(--r-sm);
color: var(--ink);
font-size: 15px;
font-family: var(--font-sans);
transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
/* 占位符不使用 opacity:透明度与底色合成后浅色仅 3.7:1,实色 ink-3 达 5.72:1 */
.field::placeholder { color: var(--ink-3); }
.field:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3.5px var(--accent-soft);
background: var(--panel);
}
textarea.field {
font-family: var(--font-sans);
font-size: 15px;
line-height: 1.75;
resize: vertical;
}
/* ----- 标签 / 徽标 ----- */
.chip {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12.5px;
font-weight: 500;
padding: 4px 12px;
background: var(--tint);
color: var(--ink-2);
border-radius: 999px;
white-space: nowrap;
transition: background 0.15s, color 0.15s;
}
a.chip:hover {
background: var(--accent-soft);
color: var(--accent);
}
.badge-pin {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12px;
font-weight: 700;
padding: 4px 11px;
background: var(--clay-soft);
color: var(--clay);
border-radius: 999px;
white-space: nowrap;
}
.badge-rec {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12px;
font-weight: 700;
padding: 4px 11px;
background: var(--gold-soft);
color: var(--gold);
border-radius: 999px;
white-space: nowrap;
}
/* ----- 分页 ----- */
.pager-btn {
background: var(--panel);
border-color: var(--line-2);
color: var(--ink-2);
}
.pager-btn:hover {
border-color: var(--accent);
color: var(--accent);
transform: translateY(-1px);
}
.pager-btn.is-current,
.pager-btn.is-current:hover {
background: var(--accent);
border-color: var(--accent);
color: var(--accent-on);
font-weight: 700;
}
/* ----- 辅助 ----- */
.meta {
font-family: var(--font-sans);
font-size: 12.5px;
color: var(--ink-3);
font-variant-numeric: tabular-nums;
}
.link-accent { color: var(--accent); }
.link-accent:hover { color: var(--accent-hi); }
.alert-error {
padding: 12px 15px;
border: 1px solid color-mix(in srgb, var(--danger) 30%, transparent);
background: var(--danger-soft);
color: var(--danger);
border-radius: var(--r-sm);
font-size: 14px;
font-weight: 500;
}
.alert-ok {
padding: 12px 15px;
border: 1px solid color-mix(in srgb, var(--ok) 30%, transparent);
background: var(--ok-soft);
color: var(--ok);
border-radius: var(--r-sm);
font-size: 14px;
font-weight: 500;
}
/* ============================================================
工作台组件(WORKSPACE EDITION)
============================================================ */
/* 分段控件:凹陷轨道 + 凸起的白色选中胶囊 */
.j13-seg {
display: inline-flex;
align-items: center;
gap: 2px;
padding: 4px;
background: var(--tint);
border: 1px solid var(--line);
border-radius: 999px;
}
.j13-seg [role="tab"] {
appearance: none;
border: 1px solid transparent;
background: transparent;
border-radius: 999px;
padding: 6.5px 15px;
font-family: var(--font-sans);
font-size: 13.5px;
font-weight: 600;
color: var(--ink-3);
cursor: pointer;
white-space: nowrap;
transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease,
transform 0.12s ease;
}
.j13-seg [role="tab"]:hover {
color: var(--ink);
}
.j13-seg [role="tab"][aria-selected="true"] {
background: var(--panel);
color: var(--accent);
box-shadow: var(--shadow-sm);
font-weight: 700;
}
.j13-seg [role="tab"]:active {
transform: scale(0.97);
}
/* 侧栏导航项 */
.j13-raillink {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 10px;
border: 1px solid transparent;
border-radius: var(--r-sm);
font-size: 14px;
font-weight: 500;
color: var(--ink-2);
transition: background 0.16s ease, color 0.16s ease, border-color 0.16s ease;
}
.j13-raillink:hover {
background: var(--panel-2);
color: var(--ink);
}
.j13-raillink[aria-current="page"] {
background: var(--nav-active-bg);
border-color: var(--nav-active-line);
color: var(--nav-active-ink);
font-weight: 700;
}
/* 工作台模块卡 */
.j13-module {
background: var(--panel);
border: 1px solid var(--line);
border-radius: var(--r);
box-shadow: var(--shadow-sm);
padding: 16px;
}
.j13-module-title {
display: flex;
align-items: center;
gap: 7px;
font-size: 13px;
font-weight: 700;
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);
border: 1px solid var(--line);
border-radius: var(--r-sm);
}
.j13-stat .j13-stat-num {
font-size: 22px;
font-weight: 800;
line-height: 1.15;
letter-spacing: -0.015em;
color: var(--ink);
font-variant-numeric: tabular-nums;
}
.j13-stat .j13-stat-lab {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12px;
color: var(--ink-3);
white-space: nowrap;
}
/* 热门榜单 */
.j13-rank {
position: relative;
display: flex;
align-items: flex-start;
gap: 10px;
padding: 8px 8px;
border-radius: 10px;
transition: background 0.16s ease;
}
.j13-rank:hover {
background: var(--panel-2);
}
.j13-rank .j13-rank-no {
width: 18px;
padding-top: 2px;
text-align: center;
font-size: 13px;
font-weight: 800;
font-variant-numeric: tabular-nums;
color: var(--ink-3);
flex-shrink: 0;
}
.j13-rank:nth-child(1) .j13-rank-no { color: var(--rank-1); }
.j13-rank:nth-child(2) .j13-rank-no { color: var(--rank-2); }
.j13-rank:nth-child(3) .j13-rank-no { color: var(--rank-3); }
/* 精选置顶卡 */
.j13-feature {
position: relative;
display: block;
padding: 15px 17px;
background: linear-gradient(135deg, var(--panel) 0%, var(--panel-2) 100%);
border: 1px solid var(--line);
border-radius: var(--r);
box-shadow: var(--shadow-sm);
transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.j13-feature:hover {
transform: translateY(-2px);
box-shadow: var(--shadow);
border-color: color-mix(in srgb, var(--accent) 32%, var(--line));
}
/* 首页欢迎横幅 */
.j13-hero {
position: relative;
overflow: hidden;
padding: 20px 22px;
border-radius: var(--r);
border: 1px solid var(--line);
box-shadow: var(--shadow-sm);
background:
linear-gradient(115deg, color-mix(in srgb, var(--accent-soft) 75%, var(--panel)) 0%, var(--panel) 60%);
}
.j13-hero-glow {
position: absolute;
top: -72px;
right: -52px;
width: 200px;
height: 200px;
border-radius: 9999px;
background: var(--accent-soft);
pointer-events: none;
}
.j13-hero-stats {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 12px 10px;
width: 100%;
}
.j13-hero-stat {
display: flex;
flex-direction: column;
gap: 3px;
min-width: 0;
}
.j13-hero-stat-num {
font-size: 21px;
font-weight: 800;
line-height: 1.15;
letter-spacing: -0.015em;
color: var(--ink);
font-variant-numeric: tabular-nums;
}
.j13-hero-stat-num.is-hot { color: var(--accent); }
.j13-hero-stat-lab {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12px;
color: var(--ink-3);
white-space: nowrap;
}
.j13-dot-pulse {
width: 6px;
height: 6px;
border-radius: 9999px;
background: var(--accent);
animation: j13-dot-pulse 2.4s ease-in-out infinite;
}
@media (min-width: 1024px) {
.j13-hero { padding: 22px 26px; }
.j13-hero-stats {
display: flex;
width: auto;
gap: 0;
}
.j13-hero-stat + .j13-hero-stat {
margin-left: 22px;
padding-left: 22px;
border-left: 1px solid var(--line);
}
}
/* 移动端横向板块条(滚动条隐藏,保留触控惯性) */
.j13-chips {
display: flex;
gap: 8px;
overflow-x: auto;
scrollbar-width: none;
-webkit-overflow-scrolling: touch;
padding-bottom: 2px;
}
.j13-chips::-webkit-scrollbar {
display: none;
}
.j13-chip {
display: inline-flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
padding: 7px 14px;
border: 1px solid var(--line-2);
background: var(--panel);
border-radius: 999px;
font-size: 13px;
font-weight: 600;
color: var(--ink-2);
white-space: nowrap;
transition: background 0.16s ease, color 0.16s ease, border-color 0.16s ease;
}
.j13-chip:hover {
border-color: var(--line-2);
color: var(--ink);
}
.j13-chip[aria-current="page"] {
background: var(--nav-active-bg);
border-color: var(--nav-active-line);
color: var(--nav-active-ink);
}
/* 帖子详情侧栏内的滚动承载区(目录 / 作者帖子列表):
配合栏容器的 max-height 独立滚动,细滚动条、不产生滚动链 */
.j13-rail-scroll {
min-height: 3.5rem;
overflow-y: auto;
overscroll-behavior: contain;
scrollbar-width: thin;
}
.j13-rail-scroll::-webkit-scrollbar {
width: 6px;
}
.j13-rail-scroll::-webkit-scrollbar-thumb {
background: var(--line-2);
border-radius: 99px;
border: none;
}
.j13-rail-scroll::-webkit-scrollbar-track {
background: transparent;
}
}
/* ============================================================
Markdown 正文
============================================================ */
.prose-content { font-size: 16.5px; line-height: 1.85; color: var(--ink); }
.prose-content h1 { font-size: 1.75rem; font-weight: 800; margin: 1.6rem 0 0.8rem; }
.prose-content h2 {
font-size: 1.4rem;
font-weight: 700;
margin: 1.9rem 0 0.7rem;
padding-bottom: 0.45rem;
border-bottom: 1px solid var(--line);
}
.prose-content h3 { font-size: 1.18rem; font-weight: 700; margin: 1.5rem 0 0.6rem; }
.prose-content p { margin: 0.9rem 0; }
.prose-content ul { list-style: disc; padding-left: 1.5rem; margin: 0.9rem 0; }
.prose-content ol { list-style: decimal; padding-left: 1.5rem; margin: 0.9rem 0; }
.prose-content li { margin: 0.35rem 0; }
.prose-content code {
font-family: var(--font-mono);
background: var(--tint);
padding: 0.12rem 0.45rem;
border-radius: 6px;
font-size: 0.86em;
}
.prose-content pre {
background: var(--panel-2) !important;
border: 1px solid var(--line);
padding: 1.05rem 1.15rem;
border-radius: var(--r-sm);
overflow-x: auto;
margin: 1.15rem 0;
}
.prose-content pre code { background: none; padding: 0; border-radius: 0; }
.prose-content blockquote {
border-left: 3px solid var(--accent);
background: var(--accent-soft);
border-radius: 0 var(--r-sm) var(--r-sm) 0;
padding: 0.7rem 1.1rem;
color: var(--ink-2);
margin: 1.2rem 0;
}
.prose-content a {
color: var(--accent);
text-decoration: underline;
text-underline-offset: 3px;
font-weight: 500;
}
.prose-content img {
max-width: 100%;
border-radius: var(--r-sm);
border: 1px solid var(--line);
}
.prose-content hr { border: none; border-top: 1px solid var(--line); margin: 2.2rem 0; }
.prose-content strong { font-weight: 700; }
@media (prefers-reduced-motion: reduce) {
* { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
/* 头像配色(浅/暗各自保证可读) */
.av-0 { background: rgba(52, 81, 200, 0.12); color: #3451c8; }
.av-1 { background: rgba(10, 99, 117, 0.12); color: #0a6375; }
.av-2 { background: rgba(109, 71, 192, 0.12); color: #6d47c0; }
.av-3 { background: rgba(27, 99, 158, 0.12); color: #1b639e; }
.av-4 { background: rgba(12, 102, 95, 0.13); color: #0c665f; }
.av-5 { background: rgba(171, 56, 93, 0.12); color: #ab385d; }
.av-6 { background: rgba(133, 88, 0, 0.14); color: #855800; }
.av-7 { background: rgba(82, 96, 122, 0.13); color: #52607a; }
.dark .av-0 { background: rgba(169, 184, 255, 0.18); color: #a9b8ff; }
.dark .av-1 { background: rgba(92, 201, 224, 0.18); color: #5cc9e0; }
.dark .av-2 { background: rgba(192, 168, 245, 0.18); color: #c0a8f5; }
.dark .av-3 { background: rgba(125, 184, 238, 0.18); color: #7db8ee; }
.dark .av-4 { background: rgba(94, 211, 189, 0.18); color: #5ed3bd; }
.dark .av-5 { background: rgba(240, 147, 181, 0.18); color: #f093b5; }
.dark .av-6 { background: rgba(224, 178, 89, 0.18); color: #e0b259; }
.dark .av-7 { background: rgba(170, 182, 207, 0.18); color: #aab6cf; }
/* ============================================================
微交互
============================================================ */
@keyframes j13-toast-in {
from { opacity: 0; transform: translateY(10px) scale(0.98); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
.j13-toast-in { animation: j13-toast-in 0.2s cubic-bezier(0.2, 0.9, 0.3, 1.2); }
@keyframes j13-heart-pop {
0% { transform: scale(1); }
45% { transform: scale(1.4); }
100% { transform: scale(1); }
}
.j13-heart-pop { animation: j13-heart-pop 0.18s ease-out; }
@keyframes j13-fade-up {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.j13-fade-up { animation: j13-fade-up 0.2s ease-out both; }
@keyframes j13-dot-pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.35; transform: scale(0.8); }
}
/* 跳到主内容 */
.skip-link {
position: fixed;
top: 10px;
left: 10px;
z-index: 10001;
padding: 10px 18px;
font-size: 13.5px;
font-weight: 600;
background: var(--accent);
color: var(--accent-on);
border-radius: 999px;
transform: translateY(-200%);
transition: transform 0.18s ease;
}
.skip-link:focus-visible {
transform: translateY(0);
outline: none;
}
/* 阅读进度条 */
.reading-progress {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 3px;
z-index: 60;
background: var(--accent);
transform-origin: 0 50%;
pointer-events: none;
}