diff --git a/frontend/src/style.css b/frontend/src/style.css index 548b72f..e90dba6 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -1,10 +1,46 @@ +/* ============================================================ + * Diary News · Web 全局样式 + * + * 主题色(与 Android 端对齐):暖色木色调 + * --color-primary: #8B6B45 木色 primary + * --color-bg: #F5E9D0 米色背景 + * --color-surface: #FBEFD7 卡片表面(略浅米色) + * --color-letter: #3E2A1E 深棕文字 + * --color-text-muted: #8B6B45 暗木色(副标题/时间) + * --color-divider: #E8D4A8 中木色分隔 + * + * 设计原则: + * - 标题用 serif(衬线感,与木质积木字"D"呼应) + * - 正文用 sans-serif,行高 1.7 阅读舒适 + * - 评论钩子统一为淡木色背景 + 木色左边框 + * ============================================================ */ + :root { --max-width: 1200px; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', - Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; + + /* 主题色板 */ + --color-primary: #8B6B45; + --color-primary-hover: #6B4F30; + --color-primary-soft: rgba(139, 107, 69, 0.12); + --color-bg: #F5E9D0; + --color-bg-soft: #FBEFD7; + --color-surface: #FBEFD7; + --color-surface-variant: #E8D4A8; + --color-letter: #3E2A1E; + --color-text-muted: #8B6B45; + --color-text-faint: #A8825A; + --color-divider: #E8D4A8; + --color-link: #8B6B45; + + /* 字体栈 */ + --font-serif: Georgia, 'Times New Roman', 'Songti SC', 'Source Han Serif SC', serif; + --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', + 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Roboto, sans-serif; + + font-family: var(--font-sans); line-height: 1.6; - color: #1f2328; - background: #fafbfc; + color: var(--color-letter); + background: var(--color-bg); } * { box-sizing: border-box; } @@ -13,31 +49,51 @@ html, body, #app { margin: 0; padding: 0; min-height: 100vh; + background: var(--color-bg); } -a { color: inherit; text-decoration: none; } -a:hover { color: #2080f0; } +a { color: var(--color-link); text-decoration: none; transition: color 0.15s; } +a:hover { color: var(--color-primary-hover); } img { max-width: 100%; } -.n-card.article-card { - margin-bottom: 16px; - transition: box-shadow 0.15s; -} -.n-card.article-card:hover { - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); +/* ===== 排版基础 ===== */ +h1, h2, h3, h4 { + font-family: var(--font-serif); + color: var(--color-letter); + margin: 0; } -/* === 文章正文容器(项目级固定 CSS,排版版译文用)=== +h1 { font-size: 28px; font-weight: 700; line-height: 1.3; } +h2 { font-size: 22px; font-weight: 700; line-height: 1.35; } +h3 { font-size: 18px; font-weight: 700; line-height: 1.4; } + +/* ===== 文章卡片 ===== */ +.n-card.article-card { + margin-bottom: 16px; + border-radius: 12px !important; + border: 1px solid var(--color-divider) !important; + background: var(--color-surface) !important; + transition: box-shadow 0.18s ease, transform 0.18s ease; +} +.n-card.article-card:hover { + box-shadow: 0 6px 16px rgba(107, 79, 48, 0.12); + transform: translateY(-1px); +} +.n-card.article-card .n-card__content { + padding: 16px 18px !important; +} + +/* ===== 文章正文容器(项目级固定 CSS,排版版译文用)=== * 后端 enrichment 也会在容器 div 上内联同样的属性;这里做兜底, * 万一 inline style 被 sanitizer 剥掉,样式仍生效。 * 与 backend/app/services/llm/enrichment.py 里的常量保持一致。 */ .article-body { - font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif; + font-family: var(--font-sans); font-size: 17px; line-height: 1.7; - color: #3e3e3e; + color: var(--color-letter); } .article-body p { margin: 0 0 1.5em 0; @@ -46,15 +102,60 @@ img { max-width: 100%; } margin-bottom: 0; } -/* === 排版段落(.diary-para)兜底规则 === - * 后端 enrichment._wrap_article_body 会内联 style 到

; - * 这里做兜底,保证 v-html 渲染时一定有合理的行距和段距。 - */ +/* ===== 排版段落(.diary-para)兜底规则 ===== */ .diary-para { margin: 0 0 1.5em 0; line-height: 1.7; - color: #3e3e3e; + color: var(--color-letter); + font-size: 17px; } .diary-para:last-child { margin-bottom: 0; } + +/* ===== TopBar / NavBar 主题色 ===== */ +.n-layout-header, +.n-layout-header.n-layout-header--absolute-positioned { + background: var(--color-primary) !important; + color: #fff !important; +} + +/* ===== Button 主按钮(主题色)===== */ +.n-button.n-button--primary-type:not(.n-button--disabled) { + background: var(--color-primary) !important; + color: #fff !important; + border-color: var(--color-primary) !important; +} +.n-button.n-button--primary-type:not(.n-button--disabled):hover { + background: var(--color-primary-hover) !important; + border-color: var(--color-primary-hover) !important; +} + +/* ===== Pagination 当前页 ===== */ +.n-pagination .n-pagination-item--active { + background: var(--color-primary) !important; + color: #fff !important; + border-color: var(--color-primary) !important; +} + +/* ===== 空状态 / Loading 文字颜色 ===== */ +.n-empty .n-empty__description, +.n-skeleton { + color: var(--color-text-muted) !important; +} + +/* ===== 全局滚动条(木色风格)===== */ +::-webkit-scrollbar { + width: 10px; + height: 10px; +} +::-webkit-scrollbar-thumb { + background: var(--color-surface-variant); + border-radius: 5px; +} +::-webkit-scrollbar-thumb:hover { + background: var(--color-primary); +} +::-webkit-scrollbar-track { + background: var(--color-bg-soft); +} \ No newline at end of file diff --git a/frontend/src/views/ArticleDetail.vue b/frontend/src/views/ArticleDetail.vue index 8540e83..e91937d 100644 --- a/frontend/src/views/ArticleDetail.vue +++ b/frontend/src/views/ArticleDetail.vue @@ -2,7 +2,7 @@ import { onMounted, ref, computed } from 'vue' import { useRoute, useRouter } from 'vue-router' import { - NCard, NSpace, NTag, NText, NButton, NSpin, NEmpty, NDivider, NAlert, NSkeleton, NImage, useMessage, + NCard, NSpace, NTag, NText, NButton, NSpin, NEmpty, NAlert, NSkeleton, NImage, useMessage, } from 'naive-ui' import { articlesApi, adminApi, type ArticleDetail } from '@/api/articles' import { http } from '@/api/client' @@ -103,51 +103,92 @@ onMounted(load)