feat: 交付官方 Docker 运行时,外观改背景图并下线自定义 CSS/JS

站点/后台分轨背景与用户列表排序一并落地;生产 CORS 改走 SITE_URL,健康检查带版本号。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-18 05:27:33 +08:00
parent 5f7193042f
commit d784b0ea7a
68 changed files with 2588 additions and 768 deletions

View File

@@ -6,8 +6,8 @@
============================================================ */
:root {
/* 浅色(默认)——中性暖灰底 + 纯白卡片浮起 */
--bg: #f7f7f5;
/* 浅色(默认)——画廊白底,卡片纯白浮起 */
--bg: #fafbfc;
--panel: #ffffff;
--panel-2: #f2f4f7;
--tint: #eceff3;
@@ -56,8 +56,11 @@
--stock-badge-low-bg: var(--tint);
--stock-badge-low-fg: var(--ink-3);
/* 工作台语义:选中用描边+文字色指示,底保持面板色,避免品牌色铺底 */
--nav-active-bg: var(--panel);
/* 工作台可点块悬停底:左栏、帖子行、右栏公告/热门/友链/关于本站、目录等共用。
改这一处即可全局换悬停色;选中态仍走 --nav-active-*。按钮/菜单等控件不要绑这个。 */
--item-hover-bg: var(--accent-soft);
/* 工作台语义:选中用主题色淡底 */
--nav-active-bg: var(--accent-soft);
--nav-active-ink: var(--accent);
--nav-active-line: rgba(59, 91, 219, 0.38);
--rank-1: #96620f;
@@ -68,9 +71,11 @@
--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);
/* 页面画布:极淡品牌绿光晕 + SVG 噪点(色值集中于此) */
--bg-halo: rgba(7, 192, 95, 0.04);
--bg-noise-opacity: 0.03;
/* 页面画布:主题色柔光 + 发丝网格(纯 CSS,随 --accent 换肤) */
--bg-halo: color-mix(in srgb, var(--accent) 8%, transparent);
--bg-mesh: color-mix(in srgb, var(--ink) 3.2%, transparent);
--bg-grid-line: rgba(15, 23, 42, 0.05);
--bg-grid-size: 28px;
/* next/font 构建期自托管,变量由 layout.tsx 注入;
本地系统字体仅作网络字体分片就绪前的回退(PingFang/雅黑与 Noto 观感接近) */
@@ -96,8 +101,8 @@
}
.dark {
/* 近黑暖灰:面板逐层浮起,靛蓝提亮为长春花蓝 */
--bg: #101211;
/* 近黑冷灰:面板逐层浮起,靛蓝提亮为长春花蓝 */
--bg: #0c0d10;
--panel: #181b21;
--panel-2: #20242c;
--tint: #282d37;
@@ -144,8 +149,9 @@
--stock-badge-low-bg: var(--tint);
--stock-badge-low-fg: var(--ink-3);
/* 工作台语义:选中不铺品牌色底 */
--nav-active-bg: var(--panel);
--item-hover-bg: var(--accent-soft);
/* 工作台语义:选中用主题色淡底 */
--nav-active-bg: var(--accent-soft);
--nav-active-ink: #a9b8ff;
--nav-active-line: rgba(141, 163, 255, 0.38);
--rank-1: #e3bf74;
@@ -156,8 +162,10 @@
--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);
--bg-halo: rgba(7, 192, 95, 0.03);
--bg-noise-opacity: 0.04;
--bg-halo: color-mix(in srgb, var(--accent) 14%, transparent);
--bg-mesh: color-mix(in srgb, var(--ink) 5%, transparent);
--bg-grid-line: rgba(238, 241, 246, 0.045);
--bg-grid-size: 28px;
color-scheme: dark;
}
@@ -165,6 +173,14 @@
html {
scrollbar-color: var(--line-2) transparent;
background-color: var(--bg); /* 橡皮筋 overscroll 与画布同色 */
--j13-bg-site-image: none;
--j13-bg-site-size: cover;
--j13-bg-site-repeat: no-repeat;
--j13-bg-site-position: center;
--j13-bg-admin-image: none;
--j13-bg-admin-size: cover;
--j13-bg-admin-repeat: no-repeat;
--j13-bg-admin-position: center;
}
body {
@@ -178,14 +194,17 @@ body {
isolation: isolate; /* 让 z-index:-1 的画布层停在内容之下、html 之上 */
}
/* 克制画布:fixed 伪元素(不用 background-attachment:fixed,避免移动端掉帧) */
/* 画布纹饰:固定层(不用 background-attachment:fixed,避免移动端掉帧)。
柔光 + 发丝网格均为静态 CSS,无 JS、无 SVG 滤镜、无持续动画。 */
body::before {
content: "";
position: fixed;
inset: 0;
z-index: -1;
pointer-events: none;
background: radial-gradient(ellipse 80% 50% at 50% -20%, var(--bg-halo), transparent 70%);
background:
radial-gradient(ellipse 78% 48% at 16% -14%, var(--bg-halo), transparent 62%),
radial-gradient(ellipse 52% 36% at 96% 0%, var(--bg-mesh), transparent 58%);
}
body::after {
@@ -194,9 +213,23 @@ body::after {
inset: 0;
z-index: -1;
pointer-events: none;
opacity: var(--bg-noise-opacity);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 160' width='160' height='160'%3E%3Cfilter id='n' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
background-size: 160px 160px;
background-image:
repeating-linear-gradient(
to right,
var(--bg-grid-line) 0,
var(--bg-grid-line) 1px,
transparent 1px,
transparent var(--bg-grid-size)
),
repeating-linear-gradient(
to bottom,
var(--bg-grid-line) 0,
var(--bg-grid-line) 1px,
transparent 1px,
transparent var(--bg-grid-size)
);
-webkit-mask-image: radial-gradient(ellipse 92% 78% at 50% 16%, #000 12%, transparent 74%);
mask-image: radial-gradient(ellipse 92% 78% at 50% 16%, #000 12%, transparent 74%);
}
@media print {
@@ -213,6 +246,27 @@ body::after {
}
}
/* 自定义背景图:改写 canvas 的 ::before 固定层,关闭发丝网格。
前台 / 后台用 data-j13-chrome 分轨,软导航只改该属性即可切换。 */
html.j13-has-site-bg[data-j13-chrome="site"] body::before {
background-color: var(--bg);
background-image: var(--j13-bg-site-image);
background-size: var(--j13-bg-site-size);
background-repeat: var(--j13-bg-site-repeat);
background-position: var(--j13-bg-site-position);
}
html.j13-has-admin-bg[data-j13-chrome="admin"] body::before {
background-color: var(--bg);
background-image: var(--j13-bg-admin-image);
background-size: var(--j13-bg-admin-size);
background-repeat: var(--j13-bg-admin-repeat);
background-position: var(--j13-bg-admin-position);
}
html.j13-has-site-bg[data-j13-chrome="site"] body::after,
html.j13-has-admin-bg[data-j13-chrome="admin"] body::after {
display: none;
}
/* 全站悬停即显提示气泡(配合 TipHost + data-tip,替代原生 title 延迟) */
.j13-tip-bubble {
position: fixed;
@@ -3077,6 +3131,10 @@ body:has([data-admin-viewport]) {
.admin-canvas:has(.j13-compose-page) {
padding: 0;
}
/* 用户管理吸顶:顶内边距挪到 .admin-users-page,sticky 才能贴紧顶栏而不提前定住 */
.admin-canvas:has(.admin-users-stick) {
padding-top: 0;
}
.admin-canvas .j13-compose-page,
.admin-canvas .j13-compose-stage {
min-height: 100%;
@@ -3335,6 +3393,13 @@ a.j13-mention-token:hover {
inset: 0;
z-index: 1;
}
/* 标题本身在 overflow 里会被裁半圈;焦点画在铺满整行的 ::after 内侧 */
.stretch-link:focus-visible {
outline: none;
}
.stretch-link:focus-visible::after {
box-shadow: inset 0 0 0 2.5px var(--accent);
}
.above-link {
position: relative;
z-index: 2;
@@ -3740,6 +3805,28 @@ a.j13-mention-token:hover {
}
}
/* 用户管理:搜索栏 + 列头贴齐 admin-topbar(滚动容器是 .admin-canvas) */
.admin-users-page {
padding-top: 1.25rem;
}
@media (min-width: 640px) {
.admin-users-page {
padding-top: 1.5rem;
}
}
@media (min-width: 1024px) {
.admin-users-page {
padding-top: 1.75rem;
}
}
.admin-users-stick {
position: sticky;
top: 0;
z-index: 20;
background: var(--panel);
box-shadow: var(--shadow-sm);
}
/* 内容管理页:窄屏可整页滚;桌面高度由上方未分层的 canvas:has 规则锁定 */
.admin-content-page {
display: flex;
@@ -4419,7 +4506,7 @@ a.j13-mention-token:hover {
}
.j13-anno-item:hover,
.j13-anno-item:focus-visible {
background: var(--accent-soft);
background: var(--item-hover-bg);
border-color: color-mix(in srgb, var(--accent) 28%, var(--line));
}
.j13-anno-item:hover::before,
@@ -4761,13 +4848,18 @@ a.j13-mention-token:hover {
color: var(--accent);
transform: translateY(-1px);
}
/* 当前页:与全站选中态一致的主题色淡化底(而非实心填充) */
/* 当前页:主题色实心底,字色走 --accent-on 保证对比 */
.pager-btn.is-current,
.pager-btn.is-current:hover {
background: var(--nav-active-bg);
border-color: var(--nav-active-line);
color: var(--nav-active-ink);
background: var(--accent);
border-color: var(--accent);
color: var(--accent-on);
font-weight: 600;
transform: none;
}
.pager-btn.is-current:hover {
background: var(--accent-hi);
border-color: var(--accent-hi);
}
/* ----- 辅助 ----- */
@@ -4822,7 +4914,7 @@ a.j13-mention-token:hover {
.j13-tab:hover {
color: var(--ink);
border-color: var(--line-2);
background: var(--panel-2);
background: var(--item-hover-bg);
}
.j13-tab[aria-selected="true"] {
background: var(--nav-active-bg);
@@ -4848,7 +4940,7 @@ a.j13-mention-token:hover {
}
}
/* 侧栏导航项:无选中态的悬停/聚焦与榜单、公告一致,用主题色淡底 */
/* 侧栏导航项:无选中态的悬停/聚焦与榜单、公告一致,走 --item-hover-bg */
.j13-raillink {
display: flex;
align-items: center;
@@ -4863,7 +4955,7 @@ a.j13-mention-token:hover {
}
.j13-raillink:hover,
.j13-raillink:focus-visible {
background: var(--panel-2);
background: var(--item-hover-bg);
color: var(--ink);
}
.j13-raillink[aria-current="page"],
@@ -4875,8 +4967,17 @@ a.j13-mention-token:hover {
font-weight: 600;
}
/* 首页左栏「全部讨论 / 板块目录」卡片:与面包屑的纯文字位置指引区分,
承载讨论量等发现型信息,点击在工作台内筛选帖子流 */
/* 正文内嵌面包屑:无独立底块,靠所在面板保证对比 */
.j13-page-crumb {
color: var(--ink-3);
}
.j13-page-crumb.is-ruled {
padding-bottom: 14px;
margin-bottom: 20px;
border-bottom: 1px solid var(--line);
}
/* 板块导航行:默认独立卡片;落入 j13-module 后收成内嵌列表 */
.j13-bcard {
display: flex;
align-items: center;
@@ -4888,24 +4989,25 @@ a.j13-mention-token:hover {
border-radius: var(--r-sm);
transition: border-color 0.16s ease, background 0.16s ease;
}
.j13-bcard:hover {
border-color: var(--line-2);
background: var(--panel-2);
/* 悬停/选中必须叠在不透明 --panel 上:半透明 accent-soft 会把网格透出来 */
.j13-bcard:hover,
.j13-bcard:focus-visible {
border-color: var(--nav-active-line);
background: color-mix(in srgb, var(--accent) 10%, var(--panel));
}
.j13-bcard:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
/* 选中态:全站统一使用主题色淡化底(--nav-active-bg,随站点主题色联动),
与 raillink / chip / tab / 顶部导航 pill 的选中表达保持一致 */
.j13-bcard[aria-current="page"],
.j13-bcard[aria-current="page"]:hover {
.j13-bcard[aria-current="page"]:hover,
.j13-bcard[aria-current="page"]:focus-visible {
border-color: var(--nav-active-line);
background: var(--nav-active-bg);
background: color-mix(in srgb, var(--accent) 12%, var(--panel));
}
.j13-bcard-name {
color: var(--ink);
font-size: 14px;
font-size: 13.5px;
font-weight: 500;
}
.j13-bcard[aria-current="page"] .j13-bcard-name {
@@ -4922,6 +5024,49 @@ a.j13-mention-token:hover {
font-weight: 800;
flex-shrink: 0;
}
.j13-module .j13-bcard {
background: transparent;
border-color: transparent;
padding: 7px 8px;
border-radius: 10px;
}
.j13-module .j13-bcard:hover,
.j13-module .j13-bcard:focus-visible {
border-color: transparent;
background: color-mix(in srgb, var(--accent) 10%, var(--panel));
}
/* 滚动容器会把外扩 outline 裁成半圈:描边改画在条目内侧 */
.j13-module .j13-bcard:focus-visible {
outline: 2.5px solid var(--accent);
outline-offset: -2px;
}
.j13-module .j13-bcard[aria-current="page"],
.j13-module .j13-bcard[aria-current="page"]:hover,
.j13-module .j13-bcard[aria-current="page"]:focus-visible {
border-color: var(--nav-active-line);
background: color-mix(in srgb, var(--accent) 12%, var(--panel));
}
.j13-module .j13-bcard[aria-current="page"]:focus-visible {
outline: 2.5px solid var(--accent);
outline-offset: -2px;
}
.j13-module .j13-bcard-ico {
width: 30px;
height: 30px;
border-radius: 8px;
font-size: 12px;
}
.j13-board-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.j13-board-split {
height: 1px;
background: var(--line);
margin: 2px 4px;
flex-shrink: 0;
}
@media (prefers-reduced-motion: reduce) {
.j13-bcard {
transition: none;
@@ -4972,8 +5117,11 @@ a.j13-mention-token:hover {
}
.j13-about-item:hover,
.j13-about-item:focus-visible {
background: var(--panel);
border-color: var(--line-2);
background: var(--item-hover-bg);
border-color: var(--nav-active-line);
}
.j13-about-item:focus-visible {
outline-offset: -2px;
}
.j13-about-ico {
width: 30px;
@@ -5175,6 +5323,9 @@ a.j13-mention-token:hover {
font-weight: 500;
white-space: nowrap;
}
.j13-checkin-flow:focus-visible {
outline-offset: 1px;
}
/* 热门榜单 */
.j13-rank {
@@ -5186,10 +5337,13 @@ a.j13-mention-token:hover {
border-radius: 10px;
transition: background 0.16s ease;
}
/* 榜单行:无选中态的导航项,悬停/聚焦统一使用主题色淡化底 */
/* 榜单行:无选中态的导航项,悬停/聚焦走 --item-hover-bg */
.j13-rank:hover,
.j13-rank:focus-visible {
background: var(--accent-soft);
background: var(--item-hover-bg);
}
.j13-rank:focus-visible {
outline-offset: -2px;
}
.j13-rank-title {
display: block;
@@ -5263,9 +5417,9 @@ a.j13-mention-token:hover {
}
.j13-chip:hover,
.j13-chip:focus-visible {
background: var(--panel-2);
border-color: var(--line-2);
color: var(--ink);
background: var(--item-hover-bg);
border-color: color-mix(in srgb, var(--accent) 38%, var(--line));
color: var(--accent);
}
.j13-chip[aria-current="page"],
.j13-chip[aria-current="page"]:hover,
@@ -5274,6 +5428,14 @@ a.j13-mention-token:hover {
border-color: var(--nav-active-line);
color: var(--nav-active-ink);
}
.j13-chip:focus-visible {
outline-offset: -2px;
}
/* overflow:hidden 的列表面板:整行链接外描边会被圆角裁切 */
.panel.overflow-hidden > a:focus-visible {
outline-offset: -2px;
}
/* 帖子详情侧栏内的滚动承载区(目录 / 作者帖子列表):
配合栏容器的 max-height 独立滚动,细滚动条、不产生滚动链 */
@@ -5294,8 +5456,11 @@ a.j13-mention-token:hover {
.j13-rail-scroll::-webkit-scrollbar-track {
background: transparent;
}
.j13-rail-scroll :focus-visible {
outline-offset: -2px;
}
/* 文章目录项:悬停/聚焦与侧栏其他可点块统一为主题色淡底 */
/* 文章目录项:悬停/聚焦与侧栏其他可点块统一走 --item-hover-bg */
.j13-toc-link {
display: block;
padding: 6px 4px 6px 12px;
@@ -5313,7 +5478,7 @@ a.j13-mention-token:hover {
.j13-toc-link:hover,
.j13-toc-link:focus-visible {
color: var(--accent);
background: var(--panel-2);
background: var(--item-hover-bg);
}
.j13-toc-link.is-active,
.j13-toc-link.is-active:hover,
@@ -5823,20 +5988,20 @@ html.dark .prose-content pre[data-theme] span {
width: 2.75rem;
height: 2.75rem;
border-radius: 999px;
border: 1px solid var(--line-2);
background: color-mix(in srgb, var(--panel) 92%, transparent);
color: var(--ink-2);
box-shadow: var(--shadow-lg);
backdrop-filter: blur(14px);
-webkit-backdrop-filter: blur(14px);
border: 1px solid var(--accent);
background: var(--accent);
color: var(--accent-on);
box-shadow: 0 1px 2px rgba(16, 24, 40, 0.12),
0 4px 14px color-mix(in srgb, var(--accent) 32%, transparent);
cursor: pointer;
transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease,
box-shadow 0.15s ease;
}
.j13-back-top:hover,
.j13-back-top:focus-visible {
color: var(--accent);
background: var(--accent-soft);
border-color: color-mix(in srgb, var(--accent) 28%, var(--line-2));
background: var(--accent-hi);
border-color: var(--accent-hi);
color: var(--accent-on);
outline: none;
}
/* 帖子移动端底栏上方抬高,避免遮挡 */