全局美化 v1

This commit is contained in:
tamakyi
2026-10-19 11:08:30 +08:00
parent b9a8afb2ec
commit d47329d505
27 changed files with 10220 additions and 219 deletions
+181 -11
View File
@@ -7,6 +7,52 @@
<meta name="msvalidate.01" content="2F185E8E63C93635F50B3574F3B31E42" />
<meta name="description" content="{{ if .MetaDescription }}{{ .MetaDescription }}{{ else }}{{ t .LangCode "site.description" }}{{ end }}">
<meta name="keywords" content="{{ t .LangCode "site.keywords" }}">
<!-- 主题初始化:必须在任何样式生效前执行,否则深色模式用户会先渲染出一帧亮色(顶栏白闪)。
只读 cookie 并打属性,切换逻辑仍在页面底部(#theme-toggle / #theme-toggle-mobile)。 -->
<script>
(function () {
var m = document.cookie.match(/(?:^|;\s*)theme=([^;]*)/);
if (m && m[1] === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
})();
</script>
<!-- 设计令牌:亮色为默认(:root),深色在 html[data-theme="dark"] 覆盖。
页面与组件样式一律引用 var(--tb-*),不再写死色值/圆角/阴影;
var() 的第二个参数仅作兜底(旧缓存页、邮件模板等不引入本文件的场景)。
改配色只动这一块,亮暗两套自动保持一致。 -->
<style>
:root {
--tb-bg: #f7f8fa;
--tb-surface: #ffffff;
--tb-surface-2: #f4f6f8;
--tb-surface-hover: #f3f7ff;
--tb-border: #e8eaee;
--tb-text: #1f2329;
--tb-text-secondary: #5c6370;
--tb-text-muted: #8a919c;
--tb-primary: #1e87f0;
--tb-primary-weak: rgba(30, 135, 240, 0.10);
--tb-radius: 12px;
--tb-radius-sm: 8px;
--tb-radius-xs: 6px;
--tb-shadow: 0 1px 2px rgba(16, 24, 40, 0.04), 0 12px 28px -18px rgba(16, 24, 40, 0.20);
--tb-shadow-hover: 0 1px 2px rgba(16, 24, 40, 0.05), 0 18px 40px -20px rgba(16, 24, 40, 0.28);
--tb-font: system-ui, -apple-system, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Microsoft YaHei", sans-serif;
}
html[data-theme="dark"] {
--tb-bg: #1a1d23;
--tb-surface: #242830;
--tb-surface-2: #2d323c;
--tb-surface-hover: rgba(92, 141, 255, 0.12);
--tb-border: #3a404c;
--tb-text: #d8dce4;
--tb-text-secondary: #a8b0bd;
--tb-text-muted: #8b93a1;
--tb-primary: #5c8dff;
--tb-primary-weak: rgba(92, 141, 255, 0.14);
--tb-shadow: 0 1px 2px rgba(0, 0, 0, 0.30), 0 12px 28px -18px rgba(0, 0, 0, 0.55);
--tb-shadow-hover: 0 1px 2px rgba(0, 0, 0, 0.35), 0 18px 40px -20px rgba(0, 0, 0, 0.65);
}
</style>
<!-- 预连接:UIkit 走公共 CDN(cdnjs.snrat.com),其余自托管库仍在本站 R2,均需预连接 -->
<link rel="preconnect" href="https://r2.337845818.best" crossorigin>
<link rel="preconnect" href="https://cdnjs.snrat.com" crossorigin>
@@ -185,15 +231,7 @@
<!-- 深色模式:html[data-theme="dark"] 时覆盖 UIkit 3.3.3 编译主题的关键颜色 -->
<style>
html[data-theme="dark"] {
--tb-bg: #1a1d23;
--tb-surface: #242830;
--tb-surface-2: #2d323c;
--tb-border: #3a404c;
--tb-text: #d8dce4;
--tb-text-muted: #8b93a1;
--tb-primary: #5c8dff;
}
/* 变量(--tb-*)已上移到 head 顶部的令牌块,亮暗两套同名常量在那里定义。 */
/* 根元素与 body 一起覆盖,确保整个视口(含内容不足一屏时的空白区)都是深色背景 */
html[data-theme="dark"],
html[data-theme="dark"] body {
@@ -331,6 +369,139 @@
html[data-theme="dark"] #theme-toggle-mobile .tb-icon-dark { display: inline; }
</style>
<!-- 基础质感层:只调整外观(圆角/投影/字体/数字对齐),不改任何结构与布局。
颜色一律取自头部令牌,亮暗两套自动生效,因此这里不需要再写 html[data-theme="dark"] 分支。 -->
<style>
/* 根元素与 body 同时上色:内容不足一屏时,body 之外的视口区域也要是同一底色 */
html,
body {
font-family: var(--tb-font);
background-color: var(--tb-bg);
color: var(--tb-text);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* 卡片:12px 圆角 + 一层极淡接触影 + 一层大扩散影(UIkit 默认的 0 5px 15px 偏硬) */
.uk-card {
border-radius: var(--tb-radius);
}
.uk-card-default {
background-color: var(--tb-surface);
box-shadow: var(--tb-shadow);
}
.uk-card-default.uk-card-hover:hover {
box-shadow: var(--tb-shadow-hover);
}
.uk-card-header {
border-radius: var(--tb-radius) var(--tb-radius) 0 0;
}
.uk-card-footer {
border-radius: 0 0 var(--tb-radius) var(--tb-radius);
}
.uk-card,
.uk-button,
.uk-alert,
.uk-label {
transition: box-shadow 0.18s ease, background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
/* 交互元素:统一 8px 圆角,标签 6px */
.uk-button {
border-radius: var(--tb-radius-sm);
}
.uk-input,
.uk-select,
.uk-textarea,
.uk-form-small,
.uk-search-input {
border-radius: var(--tb-radius-sm);
}
.uk-label {
border-radius: var(--tb-radius-xs);
}
.uk-alert {
border-radius: 10px;
}
.uk-modal-dialog {
border-radius: 14px;
}
.uk-dropdown,
.uk-navbar-dropdown {
border-radius: 10px;
box-shadow: var(--tb-shadow);
}
.uk-navbar-container:not(.uk-navbar-transparent) {
background-color: var(--tb-surface);
}
/* 键盘可达性:仅在键盘聚焦时出现描边,鼠标点击不出现 */
.uk-button:focus-visible,
.uk-navbar-nav > li > a:focus-visible {
outline: 2px solid var(--tb-primary);
outline-offset: 2px;
}
/* 次要文字统一走令牌,避免 #999 / #8a919c 混用 */
.uk-text-muted,
.uk-text-meta {
color: var(--tb-text-muted);
}
/* 统计/日期等数字列等宽对齐,避免刷新时左右跳动 */
.uk-table,
.tb-num {
font-variant-numeric: tabular-nums;
}
/* 图片上传条:原为 item/new-question 两处各写一份内联 style(写死 #f8f8f8,深色下露白),
收敛到一处并走令牌,亮暗自动适配 */
.tb-img-uploader {
width: 100%;
background-color: var(--tb-surface-2);
display: flex;
padding-top: 5px;
padding-bottom: 5px;
align-items: center;
justify-content: flex-start;
gap: 5px;
}
/* 背景图封面(提问箱主页):渐变遮罩,保证用户自选文字色叠加后仍可读。
默认浅色遮罩(页面 .uk-light 补丁把文字兜底成深色);若箱主选了浅色文字,
question/list.html 会按亮度加上 .tb-cover-dark 换成深色遮罩。 */
.tb-cover {
position: relative;
border-radius: var(--tb-radius) var(--tb-radius) 0 0;
overflow: hidden;
}
.tb-cover::after {
content: "";
position: absolute;
inset: 0;
z-index: 0;
background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.58) 55%, rgba(255, 255, 255, 0.84) 100%);
pointer-events: none;
}
.tb-cover.tb-cover-dark::after {
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.16) 45%, rgba(0, 0, 0, 0.46) 100%);
}
.tb-cover > * {
position: relative;
z-index: 1;
}
.tb-cover h3,
.tb-cover p {
text-shadow: 0 1px 10px rgba(255, 255, 255, 0.65);
}
.tb-cover.tb-cover-dark h3,
.tb-cover.tb-cover-dark p {
text-shadow: 0 1px 12px rgba(0, 0, 0, 0.45);
}
/* 尊重系统的减少动效设置 */
@media (prefers-reduced-motion: reduce) {
.uk-card,
.uk-button,
.emoji-placeholder {
transition: none;
animation: none;
}
}
</style>
<!-- 顶栏自适应:导航全部直接显示,窄屏时分级缩小字号/间距,保证英文/日文等长文字不溢出 -->
<style>
.uk-navbar-nav a {
@@ -830,8 +1001,7 @@ document.addEventListener("DOMContentLoaded", function() {
var expires = new Date(Date.now() + 365 * 24 * 3600 * 1000).toUTCString();
document.cookie = THEME_COOKIE + '=' + next + '; path=/; max-age=' + (365 * 24 * 3600) + '; SameSite=Lax';
}
// 首屏前应用,避免闪烁
applyTheme(getTheme());
// 首屏主题已由 <head> 顶部的内联脚本打过属性(避免白闪),这里只负责点击切换。
document.addEventListener('DOMContentLoaded', function() {
// 桌面顶栏按钮与移动端底部按钮都绑定
var buttons = document.querySelectorAll('#theme-toggle, #theme-toggle-mobile');