From 8ac43bf5cfcecf4911bb663f417712e3db36a12f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B?= <955555@gmail.com> Date: Mon, 20 Jul 2026 09:54:41 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E5=85=A8=E7=AB=99=E5=8D=87?= =?UTF-8?q?=E7=BA=A7=E4=B8=BA=E9=9B=85=E8=87=B4=E7=BB=BF=E9=87=91=E4=B8=BB?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 墨绿为主、暖白为底、香槟金点缀(Elegant Green Gold),覆盖前台目录、 精品详情、速览、登录页与后台七模块。 - tokens.css 全量重写为绿金令牌,移除暗色媒体块,固定单一浅色主题 - 前台:搜索/分页/视图切换改墨绿,访问按钮绿系次按钮,精品卡改金细边+ 顶部短金线+浅金徽章(正文深色),到期状态改 30/7 天两级警示 - 后台:登录页深绿场景左右分栏白卡,侧栏深墨绿渐变+active 金短条, 统计卡语义细线与数值色,表格米白表头,UV 折线修复不可见 bug(白→金) - accent_color 重做:applyAccentColor 整套派生 brand 色链,历史默认色 视为未定制;0022 迁移把历史默认值归一为 #133429 - 品牌资产同步:favicon/manifest/theme-color/精品 OG 图改绿金 - CSS 清理:删除黑金/暖金历史死类与棕色系硬编码阴影,app.css 2110→1936 行,前台 CSS 产物 100.6→90.0KB - SSR 详情页同步删除遗留英文 kicker,与客户端一致 - 视觉基线 22 张按新主题重建,滚动收敛逻辑加固,全套 30 E2E 通过 Co-Authored-By: Claude Fable 5 --- HANDOFF.md | 14 +- README.md | 9 +- design.md | 72 +++- index.html | 2 +- migrations/0022_elegant_green_accent.sql | 5 + public/favicon.svg | 6 +- public/manifest.webmanifest | 4 +- src/client/components/DomainCard.tsx | 2 +- src/client/lib/accent-color.ts | 51 +++ src/client/pages/admin/AdminApp.tsx | 35 +- .../pages/public/FeaturedDomainPage.tsx | 1 + src/client/pages/public/PublicPage.tsx | 3 +- src/client/styles/admin.css | 335 ++++++++-------- src/client/styles/app.css | 361 +++++------------- src/worker/routes/public/og.ts | 12 +- src/worker/services/featured-domain.ts | 4 +- .../admin-domains-1024-chromium-win32.png | Bin 122397 -> 117346 bytes .../admin-domains-1440-chromium-win32.png | Bin 145982 -> 138429 bytes .../admin-domains-390-chromium-win32.png | Bin 52998 -> 53866 bytes .../admin-overview-1024-chromium-win32.png | Bin 61362 -> 85608 bytes .../admin-overview-1440-chromium-win32.png | Bin 65217 -> 83923 bytes .../admin-overview-390-chromium-win32.png | Bin 44121 -> 55565 bytes tests/e2e/visual-baseline.spec.ts | 29 +- .../featured-detail-1024-chromium-win32.png | Bin 89780 -> 82039 bytes .../featured-detail-1440-chromium-win32.png | Bin 91447 -> 98135 bytes .../featured-detail-1920-chromium-win32.png | Bin 99185 -> 108967 bytes .../featured-detail-320-chromium-win32.png | Bin 68015 -> 67072 bytes .../featured-detail-375-chromium-win32.png | Bin 71614 -> 70388 bytes .../featured-detail-390-chromium-win32.png | Bin 72642 -> 71004 bytes .../featured-detail-430-chromium-win32.png | Bin 73856 -> 71914 bytes .../featured-detail-768-chromium-win32.png | Bin 84399 -> 89002 bytes .../home-1024-chromium-win32.png | Bin 242303 -> 266133 bytes .../home-1440-chromium-win32.png | Bin 256413 -> 278960 bytes .../home-1920-chromium-win32.png | Bin 264967 -> 286604 bytes .../home-320-chromium-win32.png | Bin 202523 -> 223632 bytes .../home-375-chromium-win32.png | Bin 206445 -> 228490 bytes .../home-390-chromium-win32.png | Bin 206651 -> 228706 bytes .../home-430-chromium-win32.png | Bin 204705 -> 226667 bytes .../home-768-chromium-win32.png | Bin 210406 -> 232361 bytes tests/unit/accent-color.test.ts | 63 +++ tokens.css | 139 +++---- 41 files changed, 558 insertions(+), 589 deletions(-) create mode 100644 migrations/0022_elegant_green_accent.sql create mode 100644 src/client/lib/accent-color.ts create mode 100644 tests/unit/accent-color.test.ts diff --git a/HANDOFF.md b/HANDOFF.md index ff537ae..97cfcd9 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -1,6 +1,18 @@ # WanMi HANDOFF -## 最新进度(2026-07-17 · wanmi-final-prompt 方案落地) +## 最新进度(2026-07-20 · Elegant Green Gold 雅致绿金主题) + +- 全站由浅色暖金升级为「雅致绿金」:墨绿 `#133429` 为品牌主色(主按钮/激活态/链接/侧栏/登录场景),暖白 `#f6f5f0`/`#fefdfa` 为底,香槟金 `#c89848` 降级为精品与重点资产专用(≤2% 面积)。`tokens.css` 全量重写并**移除暗色 `prefers-color-scheme` 媒体块**(按要求固定单一浅色)。 +- 前台:搜索按钮/分页当前页/视图切换器改墨绿实心白字;「访问域名」由金字金边改为绿字绿边次按钮;精品卡身份改由金细边 + 顶部 44×2px 短金线 + 浅金底「★精选」徽章表达(正文保持深色);到期状态改三级(≤30 天警告、≤7 天与已过期危险,文案「已过期」);速览弹窗白面板 + 深绿遮罩,QR/价值维度低饱和底保留。 +- 精品详情页:大标题由亮金改深色,访问按钮改实心墨绿,kicker 改中文「★ 精品域名」金棕字;Worker SSR 模板同步删掉遗留的 FEATURED DOMAIN ASSET / DISCOVER MORE 英文 kicker(上一轮只删了客户端侧)。 +- 后台:登录页重做为深墨绿场景 + 左右分栏白卡(左品牌介绍区深绿 + 金点缀、右白表单,手机自动单栏);侧栏深墨绿渐变(从 `--brand` color-mix 派生,accent 覆盖时整体跟随),active 为白 10% 底 + 左侧 3px 香槟金短条 + 金图标;概览统计卡白卡 + 顶部语义细线(总数墨绿/展示绿/隐藏灰/精品金)+ 语义数值色;表头米白 `--background-soft`、行悬停 `--surface-hover`。admin.css 的黑金基础层与浅色覆盖层合并为单层。 +- 概览 PV/UV 图修复既有 bug:UV 线原用 `var(--ink)`(浅色主题下=白色,白卡上不可见),改香槟金 `--gold-deep` 作第二数据线。 +- accent_color 机制重做:新增 `src/client/lib/accent-color.ts`,历史默认色(含黑金 `#d8b638`、暖金 `#c4a242` 等 5 个)视为「未定制」清除覆盖;真自定义色整套派生 brand/strong/hover/bg/bg-strong/border/ring,配 5 项单测。新增迁移 `0022_elegant_green_accent.sql` 把历史默认值归一为 `#133429`(沿 0014 惯例,不动真自定义色)。**远程执行该迁移会把生产 accent_color 从 `#c4a242` 更新为 `#133429`,属主题配套变更。** +- 品牌资产同步:`favicon.svg` 墨绿底白菱金芯;`manifest.webmanifest` theme_color `#133429`;`index.html` theme-color `#f6f5f0`;精品 OG 图由黑底金字改墨绿底金字。 +- CSS 清理:删除 hero-*、header-discover、premium-corner、copy-button、group-tabs、section-kicker、mobile-stats、domain-featured-dot、keyword-pill/domain-keywords、copy-filter-link、contact-modal/contact-list/qr-code、domain-list-head、catalogue-intro、row-details、integration-details、bulk-keywords、status-list、highlighted 等确认死类(TSX 全量交叉验证,含动态拼接 `density-${…}`/`badge-…` 检查后保留活类);棕色系历史阴影(rgba(64,42,20) 等 6 处)与纯黑阴影全部换绿倾向令牌;`--cream-*`、`--glow-gold`、`--gold-muted`、`--premium-fg`、`--ink`、`--foreground` 等死令牌删除;`--fg-3` 补定义(原引用 8 处但从未定义)。app.css 2110→1936 行,前台 CSS 产物 100.63→90.00KB(gzip 17.68→15.85)。 +- 已知限制:管理员在站点设置输入过浅的自定义强调色仍可能破坏主按钮白字对比度(schema 仅校验 hex 格式);`--gold-bg`/`--gold-soft`/`--brand-secondary` 等主题 API 令牌暂无 CSS 引用,保留作设计系统接口。 + +## 前序进度(2026-07-17 · wanmi-final-prompt 方案落地) - 依用户提供的最终优化方案执行,先逐项核实再实施;两项方案内容已过时(列表页 ItemList JSON-LD 与卡片 hover 位移均已存在),一项明确拒绝:LXGW WenKai(楷体风格与目录信息密度矛盾,3MB + font-display:optional 意味着慢网用户白下载还看不到;保持系统中文字体回退)。 - 字体替换:display 字体 Instrument Serif → Cormorant Garamond(tokens/--font-display、fonts.css 由 fetch-fonts 重新生成、og.ts 的 TTF 与 font-family、api.test.ts 同步、旧文件删除、OFL 补齐)。fetch-fonts.ts 新增 EXTRA_TTF:用旧版 UA 请求 css2 拿 gstatic 静态 Regular TTF(290KB,google/fonts 仓库只有 1.1MB 变量字体,resvg 吃静态更稳)。 diff --git a/README.md b/README.md index 2a76a5c..d8a725b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ - D1:`wanmi-db`(绑定 `DB`) - R2:`wanmi-assets`(绑定 `UPLOADS`) - Cron:每天 `01:00 UTC`,即 `Asia/Shanghai 09:00` -- 当前设计基线:单一浅色暖金主题(2026-07-17,由黑金改版);域名简介为纯手动维护(AI 生成已于同日移除) +- 当前设计基线:Elegant Green Gold 雅致绿金主题(2026-07-20,由浅色暖金改版)——墨绿为主、暖白为底、香槟金点缀;域名简介为纯手动维护(AI 生成已于 2026-07-17 移除) 权威业务源为 `data/source/WanMi.csv`:859 条有效唯一记录。生产库还保留 3 条历史人工域名,因此线上合计 862 条;本次迁移与发布不得覆盖或归档这 3 条记录。 @@ -26,10 +26,11 @@ ## 设计系统 -- 仅提供单一黑金主题,不提供明暗主题切换,也不读取系统配色偏好。 +- 仅提供单一浅色「雅致绿金」主题,不提供明暗主题切换,也不读取系统配色偏好。 - 根目录 `tokens.css` 是唯一设计令牌源;组件与运行时样式只引用 CSS 变量,不硬编码色值。 -- 背景使用纯黑 OLED `#000000`,表面依次使用 `#151515`、`#1a1a1a`、`#1e1e1e`,唯一强调色为香槟金 `#d8b638`。 -- 主、次、三级文字依次使用 `#f5f5f7`、`#a1a1a6`、`#6e6e73`。 +- 暖白背景 `#f6f5f0`、奶油白卡片 `#fefdfa`,品牌主色为深墨绿 `#133429`(hover `#1e6b59`),香槟金 `#c89848` 仅表达精品与重点资产(占比 ≤2%),浅底金色小字一律 `--gold-text #79551f`。 +- 主、次、三级文字依次使用 `#1f2a24`、`#5d675f`、`#7e877f`;卡片阴影统一为绿倾向低透明度令牌,禁止纯黑阴影。 +- 站点设置 `accent_color` 由 `applyAccentColor` 整套派生(主色/hover/bg/border/ring 同步),历史默认值视为未定制。 - 保留 `prefers-reduced-motion` 与 `prefers-reduced-transparency` 退化;完整规范见 [`design.md`](design.md)。 ## 公开站点 diff --git a/design.md b/design.md index b19f55e..3b22af6 100644 --- a/design.md +++ b/design.md @@ -1,56 +1,85 @@ # Design — WanMi / 玩米 -本系统为浅色暖金主题(2026-07-17 由黑金改版),暗色跟随系统 prefers-color-scheme 自动切换(无手动开关),仅颜色令牌分主题。所有组件引用 `tokens.css` 变量,禁止硬编码色值。 +本系统为 **Elegant Green Gold 雅致绿金** 主题(2026-07-20 由浅色暖金改版):墨绿为主、暖白为底、香槟金点缀。单一浅色主题——不提供暗色模式,不读取系统深浅色偏好(`color-scheme: light` 固定)。所有组件引用根目录 `tokens.css` 变量,禁止硬编码色值。 这是 WanMi 前台、后台与移动端共享的锁定设计系统。后续页面先读取本文件,保持产品一致性。 ## Genre -modern-minimal,结构优先,采用米白纸感底色、纯白卡片与暖金强调的克制规则;暗色下为近黑底与亮金。 +modern-minimal,结构优先;暖白纸感底色、奶油白卡片、深墨绿品牌色与克制的香槟金,呈现专业、稳重、高级、干净的管理系统质感。 ## Macrostructure - 前台:Catalogue;真实域名库存为主体,桌面自适应多列、手机单列。 -- 后台:Workbench;侧轨、指标、表单和数据记录承担视觉结构。 -- 速览与登录:延续 Catalogue/Workbench 的字体、规则和控件语言。 +- 后台:Workbench;深墨绿侧轨、暖白工作区、指标卡、表单和数据记录承担视觉结构。 +- 速览与登录:延续 Catalogue/Workbench 的字体、规则和控件语言;登录页为深墨绿场景 + 左右分栏白卡。 -## Theme — Warm Light +## Theme — Elegant Green Gold -- Background:`#f7f7f5`(米白纸感)/ `#efefed`(次级底) -- Surface:`#ffffff`(卡片)/ `#f3f3f1`(次级表面) -- Brand Gold:`#c4a242`(浅色主题)/ `#d4b252`(暗色主题),唯一强调色 -- Border:`rgba(0,0,0,.08)`,强调边 `rgba(184,149,48,.28)` -- 禁止大面积金色渐变、重玻璃拟态、持续模糊、装饰光晕和渐变文字。 +色彩比例:暖白米白 ≈70%、墨绿 ≈20%、灰米辅助 ≈8%、香槟金 ≤2%。 -## Motion(2026-07-17 · 依 Emil Kowalski 设计工程原则) +| 语义 | 令牌 | 值 | +| --- | --- | --- | +| 页面背景 | `--background` / `--background-soft` | `#f6f5f0` / `#f1efe8` | +| 卡片表面 | `--surface` / `--surface-secondary` / `--surface-elevated` / `--surface-hover` | `#fefdfa` / `#f4f2ec` / `#ffffff` / `#efede6` | +| 品牌绿 | `--brand-primary` / `-strong` / `-hover` / `-secondary` | `#133429` / `#0f3c32` / `#1e6b59` / `#2d4f40` | +| 品牌绿派生 | `--brand-bg` / `--brand-bg-strong` / `--brand-border` / `--brand-ring` | rgba(19,52,41) 8%/14%/26% 与 rgba(30,107,89) 20% | +| 香槟金 | `--gold` / `--gold-deep` / `--gold-bright` / `--gold-soft` | `#c89848` / `#b88038` / `#d8b66f` / `#e8d8b8` | +| 金色文字 | `--gold-text` | `#79551f`(浅底金色小字唯一合法色) | +| 金色派生 | `--gold-bg` / `--gold-bg-strong` / `--gold-border` / `--gold-divider` | rgba(200,152,72) 11%/18% 与 rgba(184,128,56) 38%/30% | +| 文字 | `--text-primary` / `-secondary` / `-tertiary` / `-inverse` / `--text-on-brand` | `#1f2a24` / `#5d675f` / `#7e877f` / `#ffffff` / `#ffffff` | +| 边框 | `--border-subtle` / `--border` / `--border-strong` | rgba(31,42,36) 6%/10%/17% | +| 语义色 | `--success` / `--warning` / `--danger` / `--info` | `#34745a` / `#a76b22` / `#b95343` / `#4e7469` | +| 阴影 | `--shadow-card` / `-hover` / `--shadow-panel` / `--shadow-modal` | 绿倾向 rgba(17,38,30…),禁止纯黑阴影 | + +## 颜色使用规则 + +1. **墨绿**承担:品牌、主按钮、激活状态、主数据线、链接与聚焦环、当前分页、深色侧栏与登录场景。 +2. **香槟金只表达精品与重点资产**:精品星标徽章、精品卡金细边与顶部短金线、精品详情 kicker、后台精品统计卡与精品开关、图表第二数据线、侧栏 active 左侧 3px 金短条、Logo 内芯。 +3. 金色**禁止**用于:普通正文、普通分类、普通筛选按钮、TLD 标签、大面积卡片背景、全部菜单激活态。 +4. 浅色背景上的金色小字一律 `--gold-text`(`#79551f`),不得直接用 `--gold`/`--gold-bright`;亮金仅可用于深绿底(侧栏、登录介绍区、OG 图)。 +5. 卡片阴影统一走 `--shadow-*` 令牌(绿倾向);禁止 `rgba(0,0,0,…)` 纯黑阴影。 +6. 禁止霓虹绿、高饱和荧光色、黑金夜店风、重玻璃拟态与大面积渐变;大面积渐变仅限登录页场景、后台侧栏与深绿总览卡。 +7. 普通小字号文本必须满足 WCAG AA。 +8. 到期状态分级:>30 天次级文字色、≤30 天 `--warning`、≤7 天与已过期 `--danger`(文案「已过期」)。 + +## 动态 accent_color + +站点设置的 `accent_color` 经 `src/client/lib/accent-color.ts` 的 `applyAccentColor` 应用: + +- 命中历史各轮默认色(`#f97316`/`#e85d2a`/`#d8b638`/`#b89530`/`#c4a242`/`#133429`)视为「未定制」,清除覆盖走 CSS 静态令牌(人工调校观感最优); +- 真正的自定义色会整套派生 `--brand`/`-strong`/`-hover`/`-bg`/`-bg-strong`/`-border`/`-ring`(color-mix),侧栏渐变亦从 `--brand` 派生,不会出现「按钮新色、分页旧色」的割裂; +- 迁移 `0022_elegant_green_accent.sql` 已把历史默认值归一为 `#133429`(沿用 0014 惯例,不动管理员自定义色); +- 管理员输入过浅的自定义色可能破坏主按钮白字对比度,UI 未做强校验,属已知限制。 + +## Motion(依 Emil Kowalski 设计工程原则) - easing 令牌:`--ease: cubic-bezier(.22,1,.36,1)`(强 ease-out,进入/退出/交互一律用它);`--ease-in-out` 仅用于屏上移动。禁止 `ease-in`。 - 时长令牌:150/200/250ms 三档,UI 动画不得超过 300ms。 - 一律 `transition` 指定具体属性,禁止 `transition: all`。 - 可按元素必须有按压反馈:`:active { transform: scale(.92–.97) }`(元素越小 scale 越深)。 - 位移类 hover(translateY 悬浮)必须包在 `@media (hover: hover) and (pointer: fine)` 内;颜色类 hover 不限。 -- 模态用 `@starting-style` 做 `scale(.96)+opacity` 进入,`transform-origin` 保持居中(模态不做 origin-aware);禁止从 `scale(0)` 出现。 -- 高频操作(每日百次级)不加动画;仅动画 `transform`/`opacity`。 +- 模态用 `@starting-style` 做 `scale(.96)+opacity` 进入,`transform-origin` 保持居中;禁止从 `scale(0)` 出现。 +- 高频操作(每日百次级)不加动画;仅动画 `transform`/`opacity`。禁止持续闪烁/呼吸/循环透明度动画。 ## Typography -- 英文、数字、UI:Manrope;display 标题与域名大字:Cormorant Garamond(Instrument Serif 已于 2026-07-17 替换)。 +- 英文、数字、UI:Manrope;display 标题与域名大字:Cormorant Garamond。 - 中文与通用 UI:Noto Sans SC,正文不小于 14px。 - 技术数据:IBM Plex Mono,仅用于域名元数据与日志。 - 标题使用正体,不使用斜体标题。 ## Search and card actions -- 搜索框占满可用宽度;搜索按钮固定在最右侧,桌面和手机宽度均不超过 80px。 -- 域名卡片只显示三枚小图标:收藏、复制、速览。 +- 搜索框占满可用宽度;搜索按钮固定在最右侧(深墨绿底白字),桌面和手机宽度均不超过 80px。 +- 域名卡片操作为「访问域名」次按钮(绿字绿边)+ 复制、速览两枚图标。 - 图标按钮必须有 `aria-label` 和 `title`,但不可显示中文文字。 -- 不允许出现“我想要”、求购或报价按钮。 +- 不允许出现"我想要"、求购或报价按钮。 ## Spacing, motion and performance - 4px 命名间距,统一来自 `tokens.css`。 -- 控件半径 6–15px,目录卡片 17–19px;主要手机触控目标至少 44px。 -- 动画仅用于短暂状态反馈;常态卡片不做逐项入场动画、位移悬停或大面积阴影。 +- 控件半径 6–15px,目录卡片 17–19px,登录卡 22px;主要手机触控目标至少 44px。 - 长列表使用服务端分页与 `content-visibility`,移动底栏不使用 `backdrop-filter`。 - `prefers-reduced-motion` 和 `prefers-reduced-transparency` 必须有无动画/无透明度退化。 @@ -58,8 +87,9 @@ modern-minimal,结构优先,采用米白纸感底色、纯白卡片与暖金 - 必须验证 320、375、390、430、768、1024、1440 和 1920px。 - `html` 和 `body` 使用 `overflow-x: clip`,不得横向溢出。 -- 前台手机单列并保留底部导航;速览使用适配手机的原生对话框。 -- 后台七个模块在手机端完整可达,不以横向滚动隐藏核心功能。 +- 前台手机单列并保留底部导航;速览使用适配手机的原生对话框(底部抽屉式)。 +- 后台七个模块在手机端完整可达(侧栏折叠为顶部深绿网格导航),不以横向滚动隐藏核心功能。 +- 登录页手机端自动单栏,品牌介绍区压缩置顶,登录按钮至少 44px 高。 ## Product boundary diff --git a/index.html b/index.html index 25a56e7..7c23580 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ - + diff --git a/migrations/0022_elegant_green_accent.sql b/migrations/0022_elegant_green_accent.sql new file mode 100644 index 0000000..0683e23 --- /dev/null +++ b/migrations/0022_elegant_green_accent.sql @@ -0,0 +1,5 @@ +-- 雅致绿金主题:将历史各轮默认强调色(珊瑚橙/黑金/暖金)归一为墨绿品牌色。 +-- 仅匹配历史默认值,不覆盖管理员真正自定义的主题色(与 0014 同一惯例)。 +UPDATE site_settings +SET accent_color = '#133429', updated_at = CURRENT_TIMESTAMP +WHERE accent_color IN ('#f97316', '#e85d2a', '#d8b638', '#b89530', '#c4a242'); diff --git a/public/favicon.svg b/public/favicon.svg index d7b3383..b527a11 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1,5 +1,5 @@ - - - + + + diff --git a/public/manifest.webmanifest b/public/manifest.webmanifest index acefc8b..37158ff 100644 --- a/public/manifest.webmanifest +++ b/public/manifest.webmanifest @@ -5,8 +5,8 @@ "lang": "zh-CN", "start_url": "/", "display": "standalone", - "background_color": "#f7f7f5", - "theme_color": "#b89530", + "background_color": "#f6f5f0", + "theme_color": "#133429", "icons": [ { "src": "/favicon.svg", diff --git a/src/client/components/DomainCard.tsx b/src/client/components/DomainCard.tsx index ded164d..d7b0cef 100644 --- a/src/client/components/DomainCard.tsx +++ b/src/client/components/DomainCard.tsx @@ -47,7 +47,7 @@ function DomainCardComponent({ domain, onCopy, onQuickView }: DomainCardProps) {
- {remaining !== null && } + {remaining !== null && }
{lifespan &&
{lifespan}
}
diff --git a/src/client/lib/accent-color.ts b/src/client/lib/accent-color.ts new file mode 100644 index 0000000..018aafb --- /dev/null +++ b/src/client/lib/accent-color.ts @@ -0,0 +1,51 @@ +/* 站点设置 accent_color 的运行时应用。 + 雅致绿金主题的默认品牌色链在 tokens.css / app.css 中静态调校(观感最优); + 管理员自定义颜色时必须整套派生 strong/hover/bg/border/ring, + 只覆盖一个 --brand 会出现「按钮新色、分页/聚焦环仍是旧色」的割裂。 */ + +/** 当前主题的默认品牌色(tokens.css --brand-primary)。 */ +export const THEME_BRAND_HEX = "#133429"; + +/* 历史各轮主题的默认 accent(珊瑚橙 → 黑金 → 暖金 → 雅致绿金)。 + 命中即视为「管理员未定制」,走 CSS 静态令牌;仅真正的自定义色才做动态派生。 */ +const HISTORICAL_DEFAULT_ACCENTS = new Set([ + "#f97316", + "#e85d2a", + "#d8b638", + "#b89530", + "#c4a242", + THEME_BRAND_HEX, +]); + +const ACCENT_PROPERTIES = [ + "--brand", + "--brand-strong", + "--brand-hover", + "--brand-bg", + "--brand-bg-strong", + "--brand-border", + "--brand-ring", +] as const; + +function isValidHex(value: string): boolean { + return /^#[0-9a-f]{6}$/i.test(value); +} + +/** 应用(或清除)管理员自定义强调色;派生规则与 tokens.css 的绿金默认链保持同一透明度节奏。 */ +export function applyAccentColor(accent: string | null | undefined): void { + const root = document.documentElement.style; + const normalized = accent?.trim().toLowerCase() ?? ""; + + if (!isValidHex(normalized) || HISTORICAL_DEFAULT_ACCENTS.has(normalized)) { + for (const property of ACCENT_PROPERTIES) root.removeProperty(property); + return; + } + + root.setProperty("--brand", normalized); + root.setProperty("--brand-strong", `color-mix(in oklab, ${normalized} 90%, #04120d)`); + root.setProperty("--brand-hover", `color-mix(in oklab, ${normalized} 72%, #ffffff)`); + root.setProperty("--brand-bg", `color-mix(in oklab, ${normalized} 8%, transparent)`); + root.setProperty("--brand-bg-strong", `color-mix(in oklab, ${normalized} 14%, transparent)`); + root.setProperty("--brand-border", `color-mix(in oklab, ${normalized} 26%, transparent)`); + root.setProperty("--brand-ring", `color-mix(in oklab, ${normalized} 20%, transparent)`); +} diff --git a/src/client/pages/admin/AdminApp.tsx b/src/client/pages/admin/AdminApp.tsx index 4c53fc1..eb92a37 100644 --- a/src/client/pages/admin/AdminApp.tsx +++ b/src/client/pages/admin/AdminApp.tsx @@ -94,15 +94,24 @@ function LoginPage({ onLogin }: { onLogin: (user: AdminUser) => void }) { return (
- 玩米 -
安全管理控制台

欢迎回来

请使用管理员账号继续。

-
- - - {error &&
{error}
} - -
- ← 返回域名展示页 + +
+
安全管理控制台

欢迎回来

请使用管理员账号继续。

+
+ + + {error &&
{error}
} + +
+ ← 返回域名展示页 +
); @@ -120,12 +129,12 @@ function OverviewView({ onTldClick, onDomainClick }: { onTldClick: (tld: string) }, []); if (error) return
{error}
; if (!data) return
正在读取真实统计…
; - const cards = [ - ["域名总数", data.counts.total], ["前台展示", data.counts.listed], ["已隐藏", data.counts.hidden], ["精品域名", data.counts.featured], + const cards: Array<[string, number, string]> = [ + ["域名总数", data.counts.total, "total"], ["前台展示", data.counts.listed, "listed"], ["已隐藏", data.counts.hidden, "hidden"], ["精品域名", data.counts.featured, "featured"], ]; return
-
{cards.map(([label, value]) =>
{label}{value}
)}
-
今日 PV{data.stats.today.pv ?? 0}
今日 UV{data.stats.today.uv ?? 0}
域名点击{data.stats.topDomains.reduce((total, item) => total + Number(item.clicks || 0), 0)}
+
{cards.map(([label, value, tone]) =>
{label}{value}
)}
+
今日 PV{data.stats.today.pv ?? 0}
今日 UV{data.stats.today.uv ?? 0}
域名点击{data.stats.topDomains.reduce((total, item) => total + Number(item.clicks || 0), 0)}
{data.stats.topDomains.length ? data.stats.topDomains.map((item) => ) :
尚无域名点击
}
{data.stats.countries.map((item) =>
{item.country}{item.visitors}
)}
{data.tlds.slice(0, 12).map((item) => onTldClick(item.tld)} role="button" tabIndex={0} onKeyDown={(event) => { if (event.key === "Enter") onTldClick(item.tld); }}>.{item.tld}
{item.count}
)}
diff --git a/src/client/pages/public/FeaturedDomainPage.tsx b/src/client/pages/public/FeaturedDomainPage.tsx index c933514..eeeeef9 100644 --- a/src/client/pages/public/FeaturedDomainPage.tsx +++ b/src/client/pages/public/FeaturedDomainPage.tsx @@ -56,6 +56,7 @@ export function FeaturedDomainPage() {
← 返回域名目录
+ ★ 精品域名

{domain.domain}

{categories.length > 0 &&
{categories.map((category) => {category})}
} {domain.description &&

{domain.description}

} diff --git a/src/client/pages/public/PublicPage.tsx b/src/client/pages/public/PublicPage.tsx index d1d9332..e2d2bf1 100644 --- a/src/client/pages/public/PublicPage.tsx +++ b/src/client/pages/public/PublicPage.tsx @@ -7,6 +7,7 @@ import { PublicBottomNav } from "../../components/PublicBottomNav"; import { Toast, type ToastMessage } from "../../components/Toast"; import { useSearchHistory } from "../../hooks/useSearchHistory"; import { useTracker } from "../../hooks/useTracker"; +import { applyAccentColor } from "../../lib/accent-color"; import { api } from "../../lib/api"; import { clearCatalogueCache, loadCatalogue } from "../../lib/catalogue-cache"; import { copyText } from "../../lib/clipboard"; @@ -200,7 +201,7 @@ export function PublicPage() { if (!active) return; if (settingsResult.status === "fulfilled") { setSettings(settingsResult.value); - document.documentElement.style.setProperty("--brand", settingsResult.value.accent_color); + applyAccentColor(settingsResult.value.accent_color); document.title = `${settingsResult.value.site_name} · 域名展示`; const description = document.querySelector('meta[name="description"]'); description?.setAttribute("content", settingsResult.value.site_description); diff --git a/src/client/styles/admin.css b/src/client/styles/admin.css index 3395a70..055ce0e 100644 --- a/src/client/styles/admin.css +++ b/src/client/styles/admin.css @@ -1,11 +1,12 @@ /* 玩米后台样式:由 app.css 拆出,仅 /admin 路由加载。 拆分依据是在真实页面上做 DOM 探测:只有「前台完全不匹配、仅后台匹配」的选择器才搬到这里, 因此前台文件与本文件的选择器不重叠,本文件的加载顺序不会影响前台层叠。 - 共享控件(.brand/.secondary-button/.pagination 等)与基础层留在 app.css,后台同样会加载。 */ + 共享控件(.brand/.secondary-button/.pagination 等)与基础层留在 app.css,后台同样会加载。 + 主题:Elegant Green Gold 雅致绿金 —— 深墨绿侧栏与主按钮、暖白内容区、 + 香槟金仅用于精品语义与 active 菜单短条。 */ - -.stat-card strong, .kpi-list b, .admin-table td strong { font-family: var(--font-display); } +.stat-card strong, .kpi-list b { font-family: var(--font-display); } .mono, .log-table time { font-family: var(--font-mono); } .primary-button { @@ -15,15 +16,15 @@ transition: transform var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease), background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease); } .primary-button { - color: oklch(100% 0 0); - background: linear-gradient(180deg, color-mix(in oklab, var(--brand) 86%, oklch(100% 0 0)), var(--brand) 62%, color-mix(in oklab, var(--brand) 82%, oklch(0% 0 0))); - box-shadow: inset 0 1px 0 color-mix(in oklab, oklch(100% 0 0) 32%, transparent), var(--shadow-s), var(--glow); + color: var(--text-on-brand); + background: linear-gradient(180deg, color-mix(in oklab, var(--brand) 88%, oklch(100% 0 0)), var(--brand) 62%, color-mix(in oklab, var(--brand) 84%, oklch(0% 0 0))); + box-shadow: inset 0 1px 0 color-mix(in oklab, oklch(100% 0 0) 22%, transparent), var(--shadow-s); } .primary-button:active { transform: scale(.97); filter: brightness(.96); } .primary-button:disabled { opacity: .55; cursor: not-allowed; transform: none; } .danger-text { color: var(--danger) !important; } .admin-toolbar select, .admin-toolbar input { - height: 36px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface-2); + height: 36px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface-elevated); padding: 0 30px 0 11px; color: var(--fg-2); outline: none; font-size: 12px; transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease); } @@ -31,113 +32,141 @@ .keywords-cell { min-width: 220px; max-width: 320px; } .keywords-cell > div { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 6px; } +/* ---------- 登录:深墨绿场景 + 左右分栏白卡 ---------- */ + .login-shell { min-height: 100vh; display: grid; place-items: center; padding: 24px; background: - radial-gradient(circle at 50% 8%, color-mix(in oklab, var(--brand) 12%, transparent), transparent 42%), - radial-gradient(circle at 12% 88%, color-mix(in oklab, var(--brand) 6%, transparent), transparent 40%), - var(--surface-1); + radial-gradient(circle at 82% 12%, rgba(200, 152, 72, 0.10), transparent 34%), + radial-gradient(circle at 8% 92%, rgba(30, 107, 89, 0.22), transparent 46%), + linear-gradient(165deg, var(--brand-primary), #0b2b23); } .login-card { - width: min(420px, 100%); padding: 36px; - background: color-mix(in oklab, var(--surface-2) 92%, transparent); - backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); - border: 1px solid var(--border); border-radius: var(--radius-xl); - box-shadow: var(--shadow-l); + width: min(880px, 100%); padding: 0; overflow: hidden; + display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); + background: var(--surface-elevated); + border: 1px solid rgba(255, 255, 255, 0.14); border-radius: var(--radius-xl); + box-shadow: var(--shadow-modal); animation: pop-in var(--dur-3) var(--ease); } -.login-brand { margin-bottom: 38px; } -.login-heading > span { color: var(--brand); font-size: 10px; letter-spacing: .16em; font-weight: 700; } +.login-intro { + display: flex; flex-direction: column; gap: 26px; padding: 38px 34px; + color: rgba(255, 255, 255, 0.86); + background: + radial-gradient(circle at 90% 0%, rgba(200, 152, 72, 0.14), transparent 40%), + linear-gradient(180deg, var(--brand-primary), #0b2b23); +} +.login-intro .brand { color: #ffffff; } +.login-intro-body { margin-top: auto; } +.login-intro-body h2 { margin: 0 0 10px; font-size: 24px; letter-spacing: -.02em; color: #ffffff; } +.login-intro-body p { margin: 0; font-size: 13px; line-height: 1.7; color: rgba(255, 255, 255, 0.66); } +.login-intro-foot { margin-top: auto; color: var(--gold-bright); font-family: var(--font-mono); font-size: 10px; letter-spacing: .14em; } +.login-form-side { padding: 38px 36px; } +.login-brand { margin-bottom: 0; } +.login-heading > span { color: var(--brand-primary-hover); font-size: 10px; letter-spacing: .16em; font-weight: 700; } .login-heading h1 { font-size: 30px; letter-spacing: -.04em; margin: 9px 0 4px; } .login-heading p { margin: 0 0 25px; color: var(--muted); font-size: 13px; } .login-card form { display: grid; gap: 15px; } .login-card label, .settings-form label, .security-form label { display: grid; gap: 6px; color: var(--fg-2); font-size: 11px; font-weight: 600; } .login-card input, .settings-form input, .settings-form select, .security-form input, .notification-stack input { height: 42px; border: 1px solid var(--border); border-radius: 10px; padding: 0 12px; outline: none; - background: var(--surface-2); color: var(--fg); + background: var(--surface-elevated); color: var(--fg); transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease); } .login-card input:focus, .settings-form input:focus, .settings-form select:focus, .security-form input:focus, .notification-stack input:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-ring); } .login-button { height: 44px; margin-top: 4px; } .back-link { display: block; margin-top: 25px; text-align: center; color: var(--muted); font-size: 11px; transition: color var(--dur-1) var(--ease); } -.back-link:hover { color: var(--brand); } +.back-link:hover { color: var(--brand-hover); } -.admin-shell { min-height: 100vh; background: var(--surface-1); display: grid; grid-template-columns: 228px minmax(0, 1fr); } +@media (max-width: 720px) { + .login-shell { padding: 16px; } + .login-card { grid-template-columns: 1fr; } + .login-intro { flex-direction: column; gap: 14px; padding: 22px 22px 18px; } + .login-intro-body { margin-top: 0; } + .login-intro-body h2 { font-size: 19px; } + .login-intro-foot { display: none; } + .login-form-side { padding: 24px 20px 28px; } +} + +/* ---------- 后台骨架:深墨绿侧栏 + 暖白工作区 ---------- */ + +.admin-shell { min-height: 100vh; background: var(--background); display: grid; grid-template-columns: 220px minmax(0, 1fr); } .admin-sidebar { position: sticky; top: 0; height: 100vh; padding: 22px 13px 14px; - display: flex; flex-direction: column; color: oklch(100% 0 0); - background: - radial-gradient(circle at 0% 0%, color-mix(in oklab, var(--brand) 16%, transparent), transparent 46%), - linear-gradient(180deg, var(--sidebar-bg-a), var(--sidebar-bg-b)); + display: flex; flex-direction: column; color: var(--sidebar-fg); + background: linear-gradient(180deg, var(--sidebar-bg-a), var(--sidebar-bg-b)); } -.admin-brand { padding: 0 9px 22px; font-size: 18px; } -.admin-brand .brand-mark { box-shadow: inset 0 1px 0 color-mix(in oklab, oklch(100% 0 0) 35%, transparent); } +.admin-brand { padding: 0 9px 22px; font-size: 18px; color: #ffffff; } +.admin-brand .brand-mark { background: var(--gold); color: var(--brand-primary); box-shadow: none; } .admin-sidebar nav { display: grid; gap: 4px; } .admin-sidebar nav button { - height: 41px; border: 0; background: transparent; color: var(--sidebar-fg); border-radius: 10px; + position: relative; + min-height: 44px; border: 0; background: transparent; color: var(--sidebar-fg); border-radius: 8px; display: flex; align-items: center; gap: 11px; padding: 0 11px; cursor: pointer; font-size: 12.5px; text-align: left; transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease); } .admin-sidebar nav button > svg { width: 18px; height: 18px; flex: 0 0 18px; text-align: center; font-size: 15px; } -.admin-sidebar nav button:hover { background: color-mix(in oklab, oklch(100% 0 0) 6%, transparent); color: oklch(92% .008 85); } -.admin-sidebar nav button.active { background: linear-gradient(180deg, var(--sidebar-active-a), var(--sidebar-active-b)); color: var(--sidebar-active-fg); font-weight: 650; box-shadow: 0 6px 16px color-mix(in oklab, oklch(0% 0 0) 28%, transparent); } -.sidebar-user { margin-top: auto; border-top: 1px solid color-mix(in oklab, oklch(100% 0 0) 10%, transparent); padding: 14px 4px 0; position: relative; min-width: 0; } +.admin-sidebar nav button:hover { background: var(--sidebar-hover-bg); color: rgba(255, 255, 255, 0.92); } +.admin-sidebar nav button.active { background: var(--sidebar-active-bg); color: var(--sidebar-active-fg); font-weight: 650; box-shadow: none; } +.admin-sidebar nav button.active::before { content: ""; position: absolute; inset: 9px auto 9px 0; width: 3px; background: var(--sidebar-active-mark); border-radius: 0 2px 2px 0; } +.admin-sidebar nav button.active > svg { color: var(--gold-bright); } +.sidebar-user { margin-top: auto; border-top: 1px solid rgba(255, 255, 255, 0.10); padding: 14px 4px 0; position: relative; min-width: 0; color: rgba(255, 255, 255, 0.85); } .sidebar-user summary { list-style: none; display: grid; grid-template-columns: 32px minmax(0, 1fr) 16px; align-items: center; gap: 8px; cursor: pointer; } .sidebar-user summary::-webkit-details-marker { display: none; } .sidebar-user summary > span:nth-child(2) { display: grid; min-width: 0; } .sidebar-user summary strong { overflow: hidden; text-overflow: ellipsis; font-size: 11px; } .sidebar-user summary small { color: var(--sidebar-muted); font-size: 10px; } -.user-avatar { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; background: var(--brand); color: white; font-weight: 800; } -.user-menu { position: absolute; bottom: calc(100% + 8px); inset-inline: 0; padding: 6px; border-radius: 10px; background: var(--sidebar-active-a); box-shadow: var(--shadow); display: grid; gap: 3px; } -.user-menu button { display: flex; align-items: center; gap: 8px; padding: 9px; color: var(--sidebar-fg); } +.user-avatar { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; background: rgba(255, 255, 255, 0.12); color: #ffffff; font-weight: 800; } +.user-menu { position: absolute; bottom: calc(100% + 8px); inset-inline: 0; padding: 6px; border-radius: 10px; background: color-mix(in oklab, var(--sidebar-bg-b) 86%, #ffffff); box-shadow: var(--shadow-panel); display: grid; gap: 3px; } +.user-menu button { display: flex; align-items: center; gap: 8px; padding: 9px; color: rgba(255, 255, 255, 0.85); border-radius: 7px; } .user-menu svg { width: 15px; height: 15px; } .sidebar-user > div { min-width: 0; flex: 1; display: grid; gap: 2px; } .sidebar-user strong { overflow: hidden; text-overflow: ellipsis; font-size: 10px; font-weight: 600; } .sidebar-user span { color: var(--sidebar-fg); font-size: 9px; } .sidebar-user button { width: 30px; height: 30px; border: 0; border-radius: 8px; background: transparent; color: var(--sidebar-fg); cursor: pointer; transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease); } -.sidebar-user button:hover { background: color-mix(in oklab, oklch(100% 0 0) 8%, transparent); color: oklch(100% 0 0); } +.sidebar-user button:hover { background: var(--sidebar-hover-bg); color: #ffffff; } .admin-main { min-width: 0; } .admin-header { height: 76px; padding: 0 30px; position: sticky; top: 0; z-index: 20; - background: color-mix(in oklab, var(--surface-1) 72%, transparent); - backdrop-filter: blur(14px) saturate(1.4); -webkit-backdrop-filter: blur(14px) saturate(1.4); + background: var(--surface); border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; gap: 12px; } .admin-header > div:first-child span { color: var(--muted); font-size: 9px; text-transform: uppercase; letter-spacing: .12em; } .admin-header h1 { margin: 2px 0 0; font-size: 22px; letter-spacing: -.03em; } .admin-header a { color: var(--muted); font-size: 11px; transition: color var(--dur-1) var(--ease); } -.admin-header a:hover { color: var(--brand); } +.admin-header a:hover { color: var(--brand-hover); } .admin-header-actions { display: flex; align-items: center; gap: 12px; } -.admin-main > main { padding: 24px 30px 60px; } +.admin-main > main { padding: 24px 30px 60px; max-width: 1640px; } .admin-main input:not([type="checkbox"]):not([type="radio"]):not([type="color"]):not([type="file"]), .admin-main select { font-size: 11.5px; } .admin-main input::placeholder { color: var(--faint); font-size: 10.5px; opacity: 1; } .admin-stack { display: grid; gap: 18px; } -.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; } +/* ---------- 概览统计卡:白卡 + 顶部语义细线 + 语义数值色 ---------- */ + +.stat-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; } .stat-card { position: relative; min-height: 112px; padding: 18px; overflow: hidden; - background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-l); + background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md); display: flex; flex-direction: column; justify-content: space-between; - box-shadow: var(--shadow-s); - transition: transform var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease); - animation: card-in var(--dur-3) var(--ease) backwards; + box-shadow: var(--shadow-card); } -.stat-card:nth-child(2) { animation-delay: .05s; } -.stat-card:nth-child(3) { animation-delay: .1s; } -.stat-card:nth-child(4) { animation-delay: .15s; } .stat-card::before { content: ""; position: absolute; inset: 0 auto auto 0; height: 3px; width: 100%; - background: linear-gradient(90deg, var(--brand), color-mix(in oklab, var(--brand) 20%, transparent) 70%, transparent); - opacity: .85; + background: var(--stat-accent, var(--brand)); + opacity: .9; } .stat-card span { font-size: 11px; color: var(--muted); } -.stat-card strong { font-size: 30px; letter-spacing: -.04em; font-variant-numeric: tabular-nums; } +.stat-card strong { font-size: 30px; letter-spacing: -.04em; font-variant-numeric: tabular-nums; font-family: var(--font-ui); font-weight: 720; line-height: 1.2; color: var(--stat-value, var(--fg)); } +.stat-total { --stat-accent: var(--brand); --stat-value: var(--brand-strong); } +.stat-listed { --stat-accent: var(--success); --stat-value: var(--success); } +.stat-hidden { --stat-accent: var(--text-tertiary); --stat-value: var(--fg-2); } +.stat-featured { --stat-accent: var(--gold); --stat-value: var(--gold-text); } -.admin-panel { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-l); padding: 20px; min-width: 0; box-shadow: var(--shadow-s); animation: fade-up var(--dur-3) var(--ease) backwards; } +.admin-panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 20px; min-width: 0; box-shadow: var(--shadow-card); animation: fade-up var(--dur-3) var(--ease) backwards; } .panel-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; margin-bottom: 18px; } .panel-heading h2 { margin: 0; font-size: 18px; letter-spacing: -.025em; } .panel-heading p { margin: 5px 0 0; color: var(--muted); font-size: 12px; } @@ -148,59 +177,61 @@ .distribution-list > a { display: grid; grid-template-columns: 72px 1fr 34px; gap: 9px; align-items: center; font-size: 10.5px; border-radius: 6px; padding: 2px 4px; } .distribution-list > a { cursor: pointer; transition: background var(--dur-1) var(--ease); } .distribution-list > a:hover { background: var(--brand-soft); } -.distribution-list .bar { height: 6px; border-radius: 99px; background: var(--surface-1); overflow: hidden; } -.distribution-list i { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, color-mix(in oklab, var(--brand) 75%, oklch(100% 0 0)), var(--brand)); box-shadow: 0 0 6px color-mix(in oklab, var(--brand) 40%, transparent); } +.distribution-list .bar { height: 6px; border-radius: 99px; background: var(--background-soft); overflow: hidden; } +.distribution-list i { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--brand-primary-hover), var(--brand)); } .distribution-list strong { text-align: right; font-variant-numeric: tabular-nums; } .infra-list { display: grid; gap: 9px; } -.infra-list > div { display: flex; justify-content: space-between; padding: 10px 12px; border-radius: 9px; background: var(--surface-1); border: 1px solid color-mix(in oklab, var(--border) 60%, transparent); font-size: 11px; } +.infra-list > div { display: flex; justify-content: space-between; padding: 10px 12px; border-radius: 9px; background: var(--surface-secondary); border: 1px solid var(--border-subtle); font-size: 11px; } .activity-list { display: grid; gap: 11px; } .activity-list > div { display: flex; align-items: flex-start; gap: 9px; } .activity-list > div > div { display: grid; gap: 2px; } .activity-list strong { font-size: 10.5px; font-weight: 600; } .activity-list small { color: var(--muted); font-size: 10.5px; } -.dot-success { width: 7px; height: 7px; background: var(--success); border-radius: 50%; margin-top: 4px; flex: none; box-shadow: 0 0 0 3px color-mix(in oklab, var(--success) 15%, transparent); } +.dot-success { width: 7px; height: 7px; background: var(--success); border-radius: 50%; margin-top: 4px; flex: none; box-shadow: 0 0 0 3px var(--success-bg); } .empty-inline { color: var(--muted); font-size: 11px; line-height: 1.55; padding: 14px 0; } .kpi-list { display: grid; gap: 8px; } -.kpi-list > div { display: flex; justify-content: space-between; align-items: center; padding: 9px 11px; background: var(--surface-1); border-radius: 8px; font-size: 11px; } +.kpi-list > div { display: flex; justify-content: space-between; align-items: center; padding: 9px 11px; background: var(--surface-secondary); border-radius: 8px; font-size: 11px; } .kpi-list b { font-family: var(--font-mono); font-size: 11.5px; } -.admin-toolbar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding: 10px; background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--radius-m); margin-bottom: 11px; } +.admin-toolbar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding: 10px; background: var(--surface-secondary); border: 1px solid var(--border); border-radius: var(--radius-sm); margin-bottom: 11px; } .admin-toolbar input { width: min(280px, 38vw); } .admin-toolbar span { margin-left: auto; color: var(--muted); font-size: 10.5px; font-variant-numeric: tabular-nums; } .file-button { position: relative; overflow: hidden; } .file-button input { position: absolute; opacity: 0; inset: 0; cursor: pointer; } .column-picker { position: relative; } -.column-picker summary { list-style: none; cursor: pointer; height: 36px; display: inline-flex; align-items: center; padding: 0 12px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface-2); font-size: 12px; color: var(--fg-2); } +.column-picker summary { list-style: none; cursor: pointer; height: 36px; display: inline-flex; align-items: center; padding: 0 12px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface-elevated); font-size: 12px; color: var(--fg-2); } .column-picker > div { position: absolute; z-index: 30; right: 0; top: 42px; width: 190px; padding: 10px; - background: var(--surface-3); border: 1px solid var(--border); border-radius: 11px; box-shadow: var(--shadow-l); + background: var(--surface-elevated); border: 1px solid var(--border); border-radius: 11px; box-shadow: var(--shadow-panel); display: grid; gap: 7px; animation: pop-in var(--dur-1) var(--ease); } .column-picker label { display: flex; gap: 8px; align-items: center; font-size: 11.5px; cursor: pointer; } .column-picker input { accent-color: var(--brand); } -.admin-table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-m); } +/* ---------- 数据表格:米白表头 + 暖白行 + 浅绿悬停 ---------- */ + +.admin-table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); } .admin-table { width: 100%; min-width: 980px; border-collapse: collapse; font-size: 12px; } -.admin-table th { text-align: left; height: 38px; padding: 0 10px; color: var(--muted); background: var(--surface-1); border-bottom: 1px solid var(--border); font-weight: 600; letter-spacing: .02em; white-space: nowrap; } +.admin-table th { text-align: left; height: 38px; padding: 0 10px; color: var(--muted); background: var(--background-soft); border-bottom: 1px solid var(--border); font-weight: 600; letter-spacing: .02em; white-space: nowrap; } .admin-table th.sortable { cursor: pointer; user-select: none; } .admin-table th.sortable:hover { color: var(--fg); } -.admin-table td { padding: 9px 10px; border-bottom: 1px solid color-mix(in oklab, var(--border) 55%, transparent); vertical-align: middle; } +.admin-table td { padding: 9px 10px; border-bottom: 1px solid var(--border-subtle); vertical-align: middle; } .admin-table tbody tr { transition: background var(--dur-1) var(--ease); } -.admin-table tbody tr:hover { background: color-mix(in oklab, var(--brand) 2.5%, var(--surface-2)); } +.admin-table tbody tr:hover { background: var(--surface-hover); } .admin-table tr:last-child td { border-bottom: 0; } .virtual-spacer td { padding: 0; border: 0; } .domains-table.is-virtualized .keywords-cell > div { flex-wrap: nowrap; overflow: hidden; } .infinite-sentinel { display: flex; align-items: center; justify-content: center; min-height: 44px; padding: 12px 0; color: var(--muted); font-size: 11px; } -.admin-table td strong { display: block; font-size: 12.5px; font-family: var(--font-mono); font-weight: 600; letter-spacing: -.02em; } +.admin-table td strong { display: block; font-size: 12.5px; font-family: var(--font-mono); font-weight: 600; letter-spacing: -.02em; line-height: 1.35; } .admin-table td small { display: block; color: var(--faint); margin-top: 2px; font-size: 10px; } -.table-link { min-height: 30px; border: 0; background: var(--surface-1); border-radius: 7px; padding: 4px 9px; font-size: 10.5px; cursor: pointer; transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease); } +.table-link { min-height: 30px; border: 0; background: var(--surface-secondary); border-radius: 7px; padding: 4px 9px; font-size: 10.5px; cursor: pointer; transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease); } .table-link:active { transform: scale(.97); } .table-link:hover { background: var(--brand-soft); color: var(--brand-strong); } .switch { width: 34px; height: 20px; padding: 2px; border: 0; border-radius: 99px; background: var(--border-strong); cursor: pointer; transition: background var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease); } -.switch i { display: block; width: 16px; height: 16px; background: oklch(100% 0 0); border-radius: 50%; box-shadow: 0 1px 3px color-mix(in oklab, oklch(0% 0 0) 25%, transparent); transition: transform var(--dur-1) var(--ease); } -.switch.on { background: var(--brand); box-shadow: inset 0 1px 2px color-mix(in oklab, oklch(0% 0 0) 12%, transparent), 0 0 8px color-mix(in oklab, var(--brand) 35%, transparent); } -.switch.on.gold { background: var(--premium); box-shadow: inset 0 1px 2px color-mix(in oklab, oklch(0% 0 0) 12%, transparent), 0 0 8px color-mix(in oklab, var(--premium) 40%, transparent); } +.switch i { display: block; width: 16px; height: 16px; background: #ffffff; border-radius: 50%; box-shadow: 0 1px 3px rgba(17, 38, 30, 0.25); transition: transform var(--dur-1) var(--ease); } +.switch.on { background: var(--brand); } +.switch.on.gold { background: var(--gold-deep); } .switch.on i { transform: translateX(14px); } .admin-pagination { padding-top: 18px; } @@ -214,55 +245,61 @@ .upload-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; } .upload-card { min-height: 100px; padding: 14px; cursor: pointer; - border: 1px dashed var(--border-strong); border-radius: var(--radius-m); background: var(--surface-1); + border: 1px dashed var(--border-strong); border-radius: var(--radius-sm); background: var(--surface-secondary); display: flex !important; flex-direction: column; justify-content: center; transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease); } -.upload-card:hover { border-color: color-mix(in oklab, var(--brand) 50%, var(--border-strong)); background: color-mix(in oklab, var(--brand) 3%, var(--surface-1)); } +.upload-card:hover { border-color: color-mix(in oklab, var(--brand) 50%, var(--border-strong)); background: color-mix(in oklab, var(--brand) 3%, var(--surface-secondary)); } .upload-card small { color: var(--muted); font-weight: 400; } .upload-card input { height: auto; padding: 8px 0 0; border: 0; background: transparent; font-size: 9px; } +.upload-card img { width: 52px; height: 52px; object-fit: contain; border-radius: 8px; } .notification-stack { display: grid; gap: 12px; } -.reminder-editor { display: grid; grid-template-columns: minmax(140px, .7fr) 2fr auto; gap: 16px; align-items: center; padding: 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); } +.notification-stack > label { display: grid; gap: 6px; color: var(--fg-2); font-size: 11px; font-weight: 600; } +.reminder-editor { display: grid; grid-template-columns: minmax(140px, .7fr) 2fr auto; gap: 16px; align-items: center; padding: 16px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); } .reminder-editor > div:first-child { display: grid; gap: 3px; } .reminder-editor small { color: var(--fg-3); } .reminder-chips { display: flex; flex-wrap: wrap; gap: 7px; } -.reminder-chips button { border: 1px solid color-mix(in oklab, var(--brand) 30%, var(--border)); background: var(--brand-soft); color: var(--brand); padding: 6px 10px; border-radius: 999px; font-weight: 700; } +.reminder-chips button { border: 1px solid var(--brand-border); background: var(--brand-soft); color: var(--brand-strong); padding: 6px 10px; border-radius: 999px; font-weight: 700; } .reminder-chips .add-chip { background: transparent; border-style: dashed; color: var(--fg-2); } .test-badge { color: var(--fg-3); font-size: 11px; } +.test-badge.ok { color: var(--success); } +.test-badge.failed, .status-error { color: var(--danger); } .settings-sections { display: grid; gap: 18px; } -.settings-sections fieldset { border: 1px solid var(--border); border-radius: var(--radius); padding: 18px; display: grid; gap: 16px; } +.settings-sections fieldset { border: 1px solid var(--border); border-radius: var(--radius-md); padding: 18px; display: grid; gap: 16px; } .settings-sections legend { padding: 0 8px; font-family: var(--font-heading); font-size: 17px; font-weight: 700; } .status-badge { display: inline-flex; align-items: center; min-height: 24px; padding: 3px 8px; border: 1px solid var(--border); border-radius: var(--radius-pill); font-size: 9px !important; font-weight: 700; } .status-badge.success { color: var(--success); border-color: color-mix(in oklab, var(--success) 35%, var(--border)); background: var(--success-bg); } .status-badge.warning { color: var(--warning); border-color: color-mix(in oklab, var(--warning) 35%, var(--border)); background: var(--warning-bg); } .color-field { display: flex; align-items: center; gap: 10px; } .color-field input { width: 54px; padding: 3px; } -.site-preview { border-radius: var(--radius); padding: 18px; background: color-mix(in oklab, var(--preview-accent) 10%, var(--bg)); border-left: 4px solid var(--preview-accent); } +/* --preview-accent 由站点设置表单以内联样式注入,仅影响本预览块 */ +.site-preview { border-radius: var(--radius-md); padding: 18px; background: color-mix(in oklab, var(--preview-accent, var(--brand)) 10%, var(--bg)); border-left: 4px solid var(--preview-accent, var(--brand)); } .site-preview span { color: var(--fg-3); font-size: 10px; text-transform: uppercase; letter-spacing: .12em; } .site-preview strong { display: block; margin-top: 8px; font-family: var(--font-heading); font-size: 24px; } .password-strength { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; } .password-strength i { height: 3px; border-radius: 999px; background: var(--border); } -.stats-overview { display: grid; grid-template-columns: minmax(250px, .7fr) minmax(0, 1.3fr); gap: 18px; padding: 18px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); } +.password-strength i.active { background: var(--brand); } +.stats-overview { display: grid; grid-template-columns: minmax(250px, .7fr) minmax(0, 1.3fr); gap: 18px; padding: 18px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); } .stats-kpis { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; } -.stats-kpis > div { display: grid; align-content: center; gap: 5px; padding: 12px; border-radius: 9px; background: var(--surface-1); } +.stats-kpis > div { display: grid; align-content: center; gap: 5px; padding: 12px; border-radius: 9px; background: var(--surface-secondary); } .stats-kpis span { color: var(--fg-3); font-size: 10px; } .stats-kpis strong { font-family: var(--font-mono); font-size: 22px; } .stats-chart { min-width: 0; } @media (max-width: 760px) { .stats-overview { grid-template-columns: 1fr; } .stats-kpis { grid-template-columns: repeat(3, 1fr); } } @media (max-width: 720px) { .reminder-editor { grid-template-columns: 1fr; } } -.channel-card { min-height: 58px; display: grid; grid-template-columns: 120px minmax(180px, 1fr) auto; align-items: center; gap: 10px; padding: 9px 12px; border: 1px solid var(--border); border-radius: var(--radius-m); transition: border-color var(--dur-1) var(--ease); } +.channel-card { min-height: 58px; display: grid; grid-template-columns: 120px minmax(180px, 1fr) auto; align-items: center; gap: 10px; padding: 9px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); transition: border-color var(--dur-1) var(--ease); } .channel-card:hover { border-color: var(--border-strong); } .channel-card label { font-size: 11px; font-weight: 600; } .channel-card label input { height: auto; width: auto; margin-right: 7px; accent-color: var(--brand); } -.channel-card button { border: 1px solid var(--border); background: var(--surface-2); border-radius: 8px; padding: 6px 10px; font-size: 10px; cursor: pointer; box-shadow: var(--shadow-s); transition: border-color var(--dur-1) var(--ease); } +.channel-card button { border: 1px solid var(--border); background: var(--surface-elevated); border-radius: 8px; padding: 6px 10px; font-size: 10px; cursor: pointer; box-shadow: var(--shadow-s); transition: border-color var(--dur-1) var(--ease); } .channel-card button:hover { border-color: var(--faint); } .align-start { justify-self: start; } .security-form { display: grid; grid-template-columns: 1fr 1fr auto; gap: 12px; align-items: end; } .security-form button { margin-bottom: 1px; } .session-list { display: grid; gap: 8px; } -.session-list > div { display: flex; align-items: center; gap: 12px; justify-content: space-between; border: 1px solid var(--border); border-radius: var(--radius-m); padding: 11px 12px; transition: border-color var(--dur-1) var(--ease); } +.session-list > div { display: flex; align-items: center; gap: 12px; justify-content: space-between; border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 11px 12px; transition: border-color var(--dur-1) var(--ease); } .session-list > div:hover { border-color: var(--border-strong); } .session-list > div > div { min-width: 0; display: grid; gap: 2px; } .session-list strong { font-size: 11px; } @@ -270,104 +307,61 @@ .session-list small { color: var(--muted); font-size: 10px; } .session-list button { border: 0; background: transparent; cursor: pointer; font-size: 10px; } -.log-trend { display: grid; grid-template-columns: minmax(200px, .7fr) minmax(0, 1.3fr); gap: 18px; margin-bottom: 16px; padding: 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); } +.log-trend { display: grid; grid-template-columns: minmax(200px, .7fr) minmax(0, 1.3fr); gap: 18px; margin-bottom: 16px; padding: 16px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); } .log-trend-groups { display: grid; grid-template-columns: repeat(auto-fit, minmax(74px, 1fr)); gap: 8px; align-content: start; } -.log-trend-groups > div { min-width: 0; padding: 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface-1); } +.log-trend-groups > div { min-width: 0; padding: 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface-secondary); } .log-trend-groups span { display: block; color: var(--muted); font-size: 10px; } .log-trend-groups strong { display: block; margin-top: 3px; font-family: var(--font-display); font-size: 19px; font-variant-numeric: tabular-nums; } -.log-trend-groups > div.log-trend-total { border-color: color-mix(in oklab, var(--brand) 35%, var(--border)); } -.log-trend-total strong { color: var(--brand); } +.log-trend-groups > div.log-trend-total { border-color: var(--brand-border); } +.log-trend-total strong { color: var(--brand-strong); } .log-trend-chart { min-width: 0; } @media (max-width: 760px) { .log-trend { grid-template-columns: 1fr; } } .log-filter { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 13px; } -.log-filter input, .log-filter select { height: 34px; border: 1px solid var(--border); border-radius: 8px; padding: 0 10px; background: var(--surface-2); color: var(--fg); outline: none; font-size: 11.5px; } +.log-filter input, .log-filter select { height: 34px; border: 1px solid var(--border); border-radius: 8px; padding: 0 10px; background: var(--surface-elevated); color: var(--fg); outline: none; font-size: 11.5px; } .log-filter input:focus, .log-filter select:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-ring); } +.log-filter > span { margin-left: auto; color: var(--muted); font-size: 10px; } .log-table { display: grid; } -.log-table > div { display: grid; grid-template-columns: 8px 140px 180px 1fr; gap: 10px; align-items: center; min-height: 42px; border-bottom: 1px solid color-mix(in oklab, var(--border) 55%, transparent); font-size: 11px; } +.log-table > div { display: grid; grid-template-columns: 8px 140px 180px 1fr; gap: 10px; align-items: center; min-height: 42px; border-bottom: 1px solid var(--border-subtle); font-size: 11px; } .log-table time { color: var(--muted); font-variant-numeric: tabular-nums; font-family: var(--font-mono); font-size: 10px; } +.log-table-enhanced { overflow-x: auto; border: 1px solid var(--border); border-radius: 11px; background: var(--surface); } +.log-table-enhanced > header, .log-table-enhanced > div:not(.empty-inline) { + min-width: 940px; display: grid; grid-template-columns: 62px 142px 160px 135px 190px minmax(250px, 1fr); + gap: 10px; align-items: center; padding: 0 10px; +} +.log-table-enhanced > header { position: sticky; top: 0; min-height: 36px; color: var(--muted); background: var(--background-soft); font-size: 10px; font-weight: 650; } +.log-table-enhanced > div:not(.empty-inline) { min-height: 46px; border-top: 1px solid var(--border-subtle); font-size: 10.5px; } +.log-table-enhanced time { font-size: 10px; } +.log-table-enhanced > div > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.log-result { width: fit-content; padding: 3px 7px; border-radius: 999px; font-size: 9px; font-weight: 700; } +.log-result.success { color: var(--success); background: var(--success-bg); } + .tag-grid { display: flex; gap: 8px; flex-wrap: wrap; } -.tag-pill { display: inline-flex; align-items: center; gap: 8px; padding: 7px 8px 7px 14px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface-1); font-size: 12px; } +.tag-pill { display: inline-flex; align-items: center; gap: 8px; padding: 7px 8px 7px 14px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface-secondary); font-size: 12px; } .tag-pill em { font-style: normal; color: var(--faint); font-size: 10px; } .tag-pill small { color: var(--brand-strong); font-size: 9px; font-weight: 650; } -.tag-pill.tag-auto { border-color: color-mix(in oklab, var(--brand) 24%, var(--border)); background: var(--brand-soft); } +.tag-pill.tag-auto { border-color: var(--brand-border); background: var(--brand-soft); } .tag-form { display: flex; gap: 8px; margin-top: 16px; } -.tag-form input { height: 36px; border: 1px solid var(--border); border-radius: 9px; padding: 0 11px; background: var(--surface-2); color: var(--fg); outline: none; flex: 0 1 240px; } +.tag-form input { height: 36px; border: 1px solid var(--border); border-radius: 9px; padding: 0 11px; background: var(--surface-elevated); color: var(--fg); outline: none; flex: 0 1 240px; } .tag-form input:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-ring); } -@media (hover: hover) and (pointer: fine) { - .primary-button:hover { transform: translateY(-1px); box-shadow: inset 0 1px 0 color-mix(in oklab, oklch(100% 0 0) 32%, transparent), var(--shadow-s), 0 12px 30px color-mix(in oklab, var(--brand) 34%, transparent); } - .stat-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-m); } -} -@media (prefers-reduced-transparency: reduce) { - .admin-header, .login-card { backdrop-filter: none; -webkit-backdrop-filter: none; } - .admin-header, .login-card { background: var(--surface-2); } +@media (hover: hover) and (pointer: fine) { + .primary-button:hover { transform: translateY(-1px); background: linear-gradient(180deg, color-mix(in oklab, var(--brand-hover) 92%, oklch(100% 0 0)), var(--brand-hover)); box-shadow: inset 0 1px 0 color-mix(in oklab, oklch(100% 0 0) 22%, transparent), var(--shadow-m); } + .stat-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-card-hover); } } @media (prefers-contrast: more) { - .admin-header, .admin-panel { background: var(--surface-2); border-color: var(--fg-2); } + .admin-header, .admin-panel { background: var(--surface-secondary); border-color: var(--fg-2); } } -@media (max-width: 1000px) { +@media (max-width: 1080px) { .stat-grid { grid-template-columns: 1fr 1fr; } .admin-two-columns { grid-template-columns: 1fr; } - .admin-shell { grid-template-columns: 188px minmax(0, 1fr); } - .admin-main > main { padding-left: 20px; padding-right: 20px; } -} - -@media (max-width: 720px) { - .admin-shell { display: block; } - .admin-sidebar { position: fixed; z-index: 50; left: 0; right: 0; bottom: 0; top: auto; height: 68px; padding: 6px; display: block; overflow-x: auto; scrollbar-width: none; background: linear-gradient(180deg, var(--sidebar-bg-a), var(--sidebar-bg-b)); } - .admin-sidebar::-webkit-scrollbar { display: none; } - .admin-brand, .sidebar-user { display: none; } - .admin-sidebar nav { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(64px, 1fr); gap: 3px; min-width: max-content; } - .admin-sidebar nav button { width: 64px; height: 56px; padding: 0 4px; justify-content: center; flex-direction: column; gap: 2px; font-size: 9px; border-radius: 9px; } - .admin-sidebar nav button > svg { width: 14px; height: 14px; flex-basis: 14px; font-size: 14px; } - .admin-sidebar nav button.active { box-shadow: none; } - .admin-header { height: 66px; padding: 0 15px; } - .admin-main > main { padding: 15px 12px 90px; } - .stat-grid { gap: 8px; } - .stat-card { min-height: 94px; padding: 13px; } - .stat-card strong { font-size: 24px; } - .admin-panel { padding: 14px; } - .panel-heading { flex-direction: column; } - .panel-actions { width: 100%; justify-content: flex-start; } - .form-grid, .upload-grid { grid-template-columns: 1fr; } - .form-grid .wide { grid-column: auto; } - .channel-card, .security-form { grid-template-columns: 1fr; } - .log-table > div { grid-template-columns: 8px 1fr; padding: 8px 0; } - .log-table time, .log-table strong { grid-column: 2; } -} - -.admin-shell { grid-template-columns: 220px minmax(0, 1fr); background: var(--surface-1); } -.admin-sidebar { - background: var(--surface-2); - color: var(--fg); - border-right: 1px solid var(--border); - box-shadow: none; -} -.admin-sidebar nav button { min-height: 44px; border-radius: 5px; color: var(--fg-2); } -.admin-sidebar nav button:hover { background: var(--brand-soft); color: var(--fg); } -.admin-sidebar nav button.active { position: relative; background: var(--brand-soft); color: var(--brand-strong); box-shadow: none; } -.admin-sidebar nav button.active::before { content: ""; position: absolute; inset: 8px auto 8px -1px; width: 3px; background: var(--brand); border-radius: 0 2px 2px 0; } -.admin-brand, .sidebar-user { color: var(--fg); border-color: var(--border); } -.admin-header { background: var(--surface-2); border-bottom: 1px solid var(--border); box-shadow: none; backdrop-filter: none; } -.admin-main > main { max-width: 1640px; } -.stat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; border-block: 1px solid var(--border); } -.stat-card { min-height: 112px; padding: 20px; border: 0; border-right: 1px solid var(--border); border-radius: 0; background: transparent; box-shadow: none; } -.stat-card:last-child { border-right: 0; } -.stat-card::before { display: none; } -.stat-card strong { font-family: var(--font-sans); font-weight: 720; line-height: 1.2; } -.admin-panel { border-radius: 8px; box-shadow: none; } -.admin-table-wrap { border-radius: 6px; } -.admin-table td strong { font-family: var(--font-mono); line-height: 1.35; } - -@media (max-width: 1080px) { .admin-shell { grid-template-columns: 190px minmax(0, 1fr); } + .admin-main > main { padding-left: 20px; padding-right: 20px; } } @media (max-width: 720px) { - .admin-shell { display: block; } .admin-sidebar { position: static; @@ -375,30 +369,40 @@ height: auto; padding: 7px; overflow: visible; + display: block; border: 0; - border-bottom: 1px solid var(--border); - background: var(--surface-2); + border-bottom: 1px solid rgba(255, 255, 255, 0.12); + background: linear-gradient(180deg, var(--sidebar-bg-a), var(--sidebar-bg-b)); } + .admin-brand, .sidebar-user { display: none; } .admin-sidebar nav { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); grid-auto-flow: row; gap: 3px; min-width: 0; } - .admin-sidebar nav button { width: auto; min-width: 0; height: 48px; padding: 4px 2px; justify-content: center; flex-direction: column; gap: 1px; font-size: 9px; border-radius: 4px; } + .admin-sidebar nav button { width: auto; min-width: 0; height: 48px; padding: 4px 2px; justify-content: center; flex-direction: column; gap: 1px; font-size: 9px; border-radius: 6px; } .admin-sidebar nav button > svg { width: 13px; height: 13px; flex-basis: 13px; font-size: 13px; } - .admin-sidebar nav button.active::before { inset: auto 8px -1px; width: auto; height: 3px; } + .admin-sidebar nav button.active { box-shadow: none; } + .admin-sidebar nav button.active::before { inset: auto 8px -1px; width: auto; height: 3px; border-radius: 2px 2px 0 0; } .admin-header { height: 62px; padding: 0 13px; } .admin-header h1 { font-size: 19px; } .admin-header-actions { gap: 7px; } .admin-main > main { padding: 14px 11px 40px; } - .stat-grid { grid-template-columns: 1fr 1fr; } - .stat-card { min-height: 90px; padding: 13px; border-bottom: 1px solid var(--border); } - .stat-card:nth-child(2n) { border-right: 0; } - .stat-card:nth-last-child(-n + 2) { border-bottom: 0; } + .stat-grid { grid-template-columns: 1fr 1fr; gap: 8px; } + .stat-card { min-height: 90px; padding: 13px; } + .stat-card strong { font-size: 24px; } .admin-panel { padding: 13px; } + .panel-heading { flex-direction: column; } + .panel-actions { width: 100%; justify-content: flex-start; } + .form-grid, .upload-grid { grid-template-columns: 1fr; } + .form-grid .wide { grid-column: auto; } + .channel-card, .security-form { grid-template-columns: 1fr; } + .log-table > div { grid-template-columns: 8px 1fr; padding: 8px 0; } + .log-table time, .log-table strong { grid-column: 2; } .admin-toolbar { align-items: stretch; } .admin-toolbar input, .admin-toolbar select { min-height: 44px; } - .domains-table-wrap { overflow: visible; border: 0; } + .admin-toolbar button { min-height: 44px; } + .domains-table-wrap { overflow: visible; border: 0; background: transparent; } .domains-table { display: block; min-width: 0; } .domains-table thead { display: none; } .domains-table tbody { display: grid; gap: 10px; } - .domains-table tr { display: grid; grid-template-columns: 1fr 1fr; padding: 12px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface-2); } + .domains-table tr { display: grid; grid-template-columns: 1fr 1fr; padding: 12px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); } .domains-table td { display: flex; min-width: 0; padding: 7px 5px; gap: 8px; align-items: flex-start; justify-content: space-between; border: 0; } .domains-table td::before { content: attr(data-label); flex: 0 0 auto; color: var(--muted); font-size: 10px; } .domains-table td:first-child { grid-column: 1 / -1; justify-content: flex-start; } @@ -413,16 +417,3 @@ .domains-table tr { grid-template-columns: 1fr; } .domains-table td, .domains-table td:first-child, .domains-table td:nth-child(2), .domains-table td:last-child { grid-column: 1; } } - -.log-filter > span { margin-left: auto; color: var(--muted); font-size: 10px; } -.log-table-enhanced { overflow-x: auto; border: 1px solid var(--border); border-radius: 11px; } -.log-table-enhanced > header, .log-table-enhanced > div:not(.empty-inline) { - min-width: 940px; display: grid; grid-template-columns: 62px 142px 160px 135px 190px minmax(250px, 1fr); - gap: 10px; align-items: center; padding: 0 10px; -} -.log-table-enhanced > header { position: sticky; top: 0; min-height: 36px; color: var(--muted); background: var(--surface-1); font-size: 10px; font-weight: 650; } -.log-table-enhanced > div:not(.empty-inline) { min-height: 46px; border-top: 1px solid color-mix(in oklab, var(--border) 60%, transparent); font-size: 10.5px; } -.log-table-enhanced time { font-size: 10px; } -.log-table-enhanced > div > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } -.log-result { width: fit-content; padding: 3px 7px; border-radius: 999px; font-size: 9px; font-weight: 700; } -.log-result.success { color: var(--success); background: color-mix(in oklab, var(--success) 12%, transparent); } diff --git a/src/client/styles/app.css b/src/client/styles/app.css index 39451b2..42fc59d 100644 --- a/src/client/styles/app.css +++ b/src/client/styles/app.css @@ -4,18 +4,19 @@ /* ============================================================ - WanMi Design System · 单一黑金主题 + WanMi Design System · Elegant Green Gold 雅致绿金 —— 颜色/圆角/阴影/动效全部由 token 驱动,组件内禁止硬编码色值 - —— --brand 由站点设置动态注入(hex 覆盖),其余派生色 color-mix - —— 不提供明暗切换,根目录 tokens.css 是唯一设计令牌源 + —— --brand 可由站点设置 accent_color 动态覆盖;覆盖时 applyAccentColor + 会同步派生 strong/hover/bg/border/ring,保证整套主题一致 + —— 单一浅色主题,根目录 tokens.css 是唯一设计令牌源 ============================================================ */ :root { - /* 品牌与状态 */ - --brand: var(--gold); - --brand-strong: var(--gold-bright); + /* 品牌与状态:品牌绿承担主按钮/激活态/链接;香槟金仅表达精品资产 */ + --brand: var(--brand-primary); + --brand-strong: var(--brand-primary-strong); + --brand-hover: var(--brand-primary-hover); --premium: var(--gold); - --premium-fg: var(--gold-bright); /* 中性面板:三层表面 */ --bg: var(--background); @@ -24,35 +25,34 @@ --surface-3: var(--surface-elevated); --fg: var(--text-primary); --fg-2: var(--text-secondary); + --fg-3: var(--text-tertiary); --muted: var(--text-secondary); --faint: var(--text-tertiary); - /* 固定黑金侧边栏 */ - --sidebar-bg-a: var(--surface); - --sidebar-bg-b: var(--background-soft); - --sidebar-fg: var(--text-secondary); - --sidebar-active-a: var(--gold); - --sidebar-active-b: var(--gold-soft); - --sidebar-active-fg: var(--text-inverse); - - /* 派生 */ - --brand-soft: var(--gold-bg); - --brand-ring: var(--gold-border); - --shadow-color: var(--background); + /* 深墨绿侧边栏:从 --brand 派生,accent_color 覆盖时整体跟随 */ + --sidebar-bg-a: var(--brand); + --sidebar-bg-b: color-mix(in oklab, var(--brand) 72%, #04120d); + --sidebar-fg: rgba(255, 255, 255, 0.70); + --sidebar-muted: rgba(255, 255, 255, 0.44); + --sidebar-hover-bg: rgba(255, 255, 255, 0.06); + --sidebar-active-bg: rgba(255, 255, 255, 0.10); + --sidebar-active-fg: #ffffff; + --sidebar-active-mark: var(--gold); + + /* 派生(--brand-bg/--brand-ring 等最终值在 tokens.css;此处仅保留兼容别名) */ + --brand-soft: var(--brand-bg); + --shadow-color: #11261e; --shadow-s: var(--shadow-card); --shadow-m: var(--shadow-card); --shadow-l: var(--shadow-card-hover); - --glow: var(--glow-gold); + --glow: 0 0 0 transparent; /* 雅致绿金不做光晕;保留占位供多值 box-shadow 引用 */ - /* 公共组件语义别名,保持黑金目录与后台工作台共享同一令牌源。 */ - --foreground: var(--text-primary); + /* 公共组件语义别名,前台目录与后台工作台共享同一令牌源。 */ --shadow: var(--shadow-m); --radius: var(--radius-md); --font-heading: var(--font-display); - --ink: var(--text-inverse); /* 圆角 / 动效 / 字体 */ - --radius-s: var(--radius-sm); --radius-m: var(--radius-md); --radius-l: var(--radius-lg); --font-sans: var(--font-ui); @@ -89,7 +89,6 @@ a { color: inherit; text-decoration: none; } font-variant-numeric: lining-nums; font-feature-settings: "lnum" 1; } -.record-content, .whois-list b { font-family: var(--font-mono); } @keyframes fade-up { from { opacity: 0; transform: translateY(14px); } } @keyframes fade-in { from { opacity: 0; } } @@ -133,11 +132,9 @@ a { color: inherit; text-decoration: none; } font-size: 10px; font-weight: 600; letter-spacing: .02em; background: var(--surface-1); border: 1px solid var(--border); color: var(--muted); } -.chip-brand { background: var(--brand-soft); border-color: color-mix(in oklab, var(--brand) 28%, transparent); color: color-mix(in oklab, var(--brand) 78%, var(--fg)); } .badge-status { display: inline-flex; align-items: center; height: 20px; padding: 0 8px; border-radius: 999px; font-size: 10px; font-weight: 600; } -.badge-listed { background: color-mix(in oklab, var(--success) 14%, transparent); color: var(--success); } -.badge-warning { background: color-mix(in oklab, var(--warning) 16%, transparent); color: color-mix(in oklab, var(--warning) 70%, var(--fg)); } -.badge-danger { background: color-mix(in oklab, var(--danger) 13%, transparent); color: var(--danger); } +.badge-listed { background: var(--success-bg); color: var(--success); } +.badge-warning { background: var(--warning-bg); color: var(--warning); } /* ---------- 前台 ---------- */ @@ -171,20 +168,11 @@ a { color: inherit; text-decoration: none; } /* 页首统计(导航内,"域名"链接左侧) */ .domain-section { max-width: 1460px; margin: auto; padding: 24px 42px 84px; scroll-margin-top: 84px; animation: fade-up var(--dur-3) var(--ease) backwards; } -.section-kicker { display: inline-flex; align-items: center; gap: 8px; font-size: 10px; font-weight: 700; letter-spacing: .24em; color: var(--brand); } .section-heading { display: flex; align-items: flex-end; justify-content: space-between; margin-bottom: 16px; } .section-heading h2 { margin: 8px 0 0; font-size: 28px; letter-spacing: -.035em; } .result-count { color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; } -/* 分组 tabs 与排序 chips */ -.group-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; } -.group-tabs button { - height: 32px; padding: 0 14px; border-radius: 999px; cursor: pointer; font-size: 12px; font-weight: 550; - border: 1px solid var(--border); background: var(--surface-2); color: var(--fg-2); - transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease), color var(--dur-1) var(--ease); -} -.group-tabs button:hover { border-color: color-mix(in oklab, var(--brand) 40%, var(--border)); } -.group-tabs button.active { background: var(--fg); border-color: var(--fg); color: var(--bg); } +/* 排序 chips */ .sort-row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; font-size: 11px; color: var(--muted); } .sort-row button { height: 26px; padding: 0 11px; border-radius: 999px; cursor: pointer; font-size: 11px; @@ -227,8 +215,6 @@ a { color: inherit; text-decoration: none; } transition: transform var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease); } .filter-search button:active { transform: scale(.97); } -.featured-toggle { display: flex; gap: 7px; align-items: center; font-size: 12px; color: var(--fg-2); margin-left: 3px; cursor: pointer; } -.featured-toggle input { accent-color: var(--brand); } .clear-filter { margin-left: auto; border: 0; background: transparent; font-size: 12px; color: var(--muted); cursor: pointer; transition: color var(--dur-1) var(--ease); } .clear-filter:hover { color: var(--brand); } @@ -241,8 +227,8 @@ a { color: inherit; text-decoration: none; } display: flex; flex-direction: column; gap: 14px; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), - 0 1px 2px rgba(0, 0, 0, 0.04), - 0 4px 12px rgba(0, 0, 0, 0.04); + 0 1px 2px rgba(17, 38, 30, 0.04), + 0 4px 12px rgba(17, 38, 30, 0.04); transition: transform var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease); animation: card-in var(--dur-3) var(--ease) backwards; } @@ -264,17 +250,18 @@ a { color: inherit; text-decoration: none; } display: inline-flex; align-items: center; gap: 3px; padding: 3px 8px; border-radius: 999px; font-size: 10px; font-weight: 700; letter-spacing: .04em; - color: white; background: linear-gradient(135deg, var(--gold-bright), var(--gold-soft)); - box-shadow: 0 2px 6px color-mix(in oklab, var(--premium) 30%, transparent); + color: var(--gold-text); background: var(--gold-bg-strong); + border: 1px solid var(--gold-border); + box-shadow: 0 2px 6px color-mix(in oklab, var(--premium) 18%, transparent); } .domain-featured-badge svg { width: 10px; height: 10px; fill: currentColor; } -.domain-featured-dot { display: none; } .domain-name { display: flex; align-items: baseline; gap: 1px; } .domain-name a { display: inline-flex; align-items: baseline; transition: color var(--dur-1) var(--ease); } .domain-name strong { font-family: var(--font-display); font-size: clamp(22px, 2.2vw, 28px); font-weight: 600; letter-spacing: -.025em; color: var(--fg); } .domain-tld { font-family: var(--font-display); font-size: clamp(18px, 1.8vw, 22px); font-weight: 500; color: var(--muted); letter-spacing: -.02em; } .domain-name a:hover { color: var(--brand); } -.domain-card.featured .domain-name strong { color: color-mix(in oklab, var(--premium) 80%, var(--fg)); } +/* 精品域名正文保持深色高对比;精品身份由星标徽章、金细边与顶部短金线表达 */ +.domain-card.featured .domain-name strong { color: var(--fg); } /* 复制/速览随访问按钮同排:footer 左访问、右图标(原为绝对定位右上角) */ .domain-card-footer { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; } .domain-card-footer .domain-visit { align-self: auto; } @@ -292,7 +279,6 @@ a { color: inherit; text-decoration: none; } .domain-actions svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; } .domain-description { margin: 0; color: var(--fg-2); font-size: 13px; line-height: 1.55; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; min-height: 2.6em; } .domain-description.placeholder { color: var(--muted); font-style: italic; opacity: 0.7; } -.domain-divider { display: none; } .domain-card-meta { display: flex; flex-direction: column; gap: 6px; margin-top: auto; } .meta-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; } /* 剩余天数贴行右端,与后缀两端呼应 */ @@ -324,21 +310,7 @@ a { color: inherit; text-decoration: none; } .description-cell { min-width: 220px; max-width: 320px; } .description-cell > span { display: block; min-height: 1.3em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .detail-description { white-space: pre-wrap; overflow-wrap: anywhere; color: var(--muted); line-height: 1.7; } -.premium-corner { - position: absolute; top: -1px; right: -1px; z-index: 2; - padding: 3px 9px 4px 12px; border-radius: 0 var(--radius-l) 0 12px; - font-size: 9px; font-weight: 700; letter-spacing: .08em; color: oklch(30% .08 75); - background: linear-gradient(135deg, color-mix(in oklab, var(--premium) 80%, oklch(100% 0 0)), var(--premium)); - box-shadow: inset 0 1px 0 color-mix(in oklab, oklch(100% 0 0) 50%, transparent); -} .card-cover { position: absolute; inset: 0; z-index: 1; border-radius: inherit; } -.copy-button { - position: absolute; right: 9px; bottom: 9px; z-index: 2; - border: 0; background: transparent; cursor: pointer; - width: 26px; height: 26px; border-radius: 7px; display: grid; place-items: center; - color: var(--faint); font-size: 13px; opacity: 0; transform: translateX(4px); - transition: opacity var(--dur-1) var(--ease), transform var(--dur-1) var(--ease), background var(--dur-1) var(--ease), color var(--dur-1) var(--ease); -} .density-compact .domain-card { padding: 12px 13px 10px; gap: 8px; } .density-spacious .domain-card { padding: 22px 17px 17px; gap: 15px; } @@ -385,13 +357,7 @@ a { color: inherit; text-decoration: none; } .detail-head h1 span { color: var(--faint); font-weight: 500; } .detail-badges { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-bottom: 22px; } .detail-grid { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 18px; align-items: start; } -.detail-panel { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-l); padding: 20px; box-shadow: var(--shadow-s); } -.detail-panel h2 { margin: 0 0 14px; font-size: 15px; letter-spacing: -.02em; } .detail-actions { display: grid; gap: 9px; } -.whois-list { display: grid; gap: 9px; font-size: 12px; } -.whois-list > div { display: flex; justify-content: space-between; gap: 14px; padding: 9px 11px; background: var(--surface-1); border-radius: 8px; } -.whois-list span { color: var(--muted); flex: none; } -.whois-list b { font-weight: 550; text-align: right; word-break: break-all; font-family: var(--font-mono); font-size: 11px; } .related-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 9px; margin-top: 12px; } .related-grid a { border: 1px solid var(--border); border-radius: 11px; padding: 12px; background: var(--surface-2); @@ -410,14 +376,6 @@ a { color: inherit; text-decoration: none; } display: grid; place-items: center; animation: fade-in var(--dur-1) var(--ease); } -.contact-modal { - position: relative; width: min(450px, 100%); padding: 30px; - background: var(--surface-3); border: 1px solid var(--border); border-radius: var(--radius-xl); - box-shadow: var(--shadow-l); - animation: pop-in var(--dur-2) var(--ease); -} -.contact-modal h2 { margin: 8px 0; letter-spacing: -.03em; } -.contact-modal > p { color: var(--muted); font-size: 13px; } .domain-edit-modal { position: relative; width: min(680px, 100%); max-height: calc(100vh - 40px); overflow: auto; padding: 28px; background: var(--surface-3); border: 1px solid var(--border); border-radius: var(--radius-xl); box-shadow: var(--shadow-l); animation: pop-in var(--dur-2) var(--ease); } .domain-edit-modal h2 { margin: 5px 0 4px; letter-spacing: -.03em; } .domain-edit-modal > div > p { margin: 0; color: var(--muted); font-size: 12px; } @@ -431,10 +389,6 @@ a { color: inherit; text-decoration: none; } .domain-edit-grid .domain-edit-field > small { color: var(--muted); font-size: 10px; font-weight: 450; } .domain-edit-grid textarea { resize: vertical; min-height: 94px; } .domain-edit-grid input:focus, .domain-edit-grid select:focus, .domain-edit-grid textarea:focus, .domain-edit-grid .domain-edit-field > input:focus, .domain-edit-grid .domain-edit-field > textarea:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-ring); } -.bulk-keywords-modal { width: min(520px, 100%); } -.bulk-keywords-form { grid-template-columns: 1fr; } -.bulk-keywords-preview { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--space-sm); } -.bulk-keywords-modal .inline-error { margin-top: var(--space-sm); } .compact-confirm-modal { width: min(480px, 100%); } .compact-confirm-modal .inline-error { margin-top: var(--space-sm); } .primary-button.danger-button { background: var(--danger); border-color: var(--danger); color: var(--text-primary); } @@ -445,25 +399,18 @@ a { color: inherit; text-decoration: none; } transition: background var(--dur-1) var(--ease), transform var(--dur-1) var(--ease); } .modal-close:active { transform: scale(.94); } -.contact-list { display: grid; gap: 9px; margin-top: 22px; } -.contact-list a, .contact-list button { - border: 1px solid var(--border); background: var(--surface-2); border-radius: var(--radius-m); - padding: 13px 14px; display: flex; justify-content: space-between; cursor: pointer; font-size: 12px; - transition: border-color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease); -} -.qr-code { width: 160px; height: 160px; object-fit: contain; border: 1px solid var(--border); border-radius: var(--radius-m); margin: 8px auto 0; } .toast { position: fixed; z-index: 200; left: 50%; bottom: 28px; transform: translateX(-50%); display: flex; gap: 8px; align-items: center; padding: 11px 16px; - background: color-mix(in oklab, oklch(22% .012 55) 94%, var(--brand)); color: oklch(96% .005 85); - border: 1px solid color-mix(in oklab, oklch(100% 0 0) 8%, transparent); border-radius: var(--radius-m); - box-shadow: var(--shadow-l); font-size: 12px; + background: var(--brand-primary-strong); color: var(--text-on-brand); + border: 1px solid rgba(255, 255, 255, 0.10); border-radius: var(--radius-m); + box-shadow: var(--shadow-panel); font-size: 12px; transition: opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--ease); @starting-style { opacity: 0; transform: translate(-50%, 100%); } } -.toast > span { color: var(--success); } -.toast-error > span { color: color-mix(in oklab, var(--danger) 75%, oklch(100% 0 0)); } +.toast > span { color: var(--gold-bright); } +.toast-error > span { color: color-mix(in oklab, var(--danger) 55%, #ffffff); } /* ---------- 登录 ---------- */ .notification-stack > label { display: grid; gap: 6px; color: var(--fg-2); font-size: 11px; font-weight: 600; } @@ -476,8 +423,6 @@ a { color: inherit; text-decoration: none; } .admin-main textarea::placeholder { color: var(--faint); font-size: 10.5px; opacity: 1; } .stat-card small { color: var(--faint); font-size: 9.5px; } .distribution-list > div { display: grid; grid-template-columns: 72px 1fr 34px; gap: 9px; align-items: center; font-size: 10.5px; border-radius: 6px; padding: 2px 4px; } -.status-list { display: grid; gap: 9px; } -.status-list > div { display: flex; justify-content: space-between; padding: 10px 12px; border-radius: 9px; background: var(--surface-1); border: 1px solid color-mix(in oklab, var(--border) 60%, transparent); font-size: 11px; } .status-ok { color: var(--success); } .dot-error { width: 7px; height: 7px; background: var(--success); border-radius: 50%; margin-top: 4px; flex: none; box-shadow: 0 0 0 3px color-mix(in oklab, var(--success) 15%, transparent); } .dot-error { background: var(--danger); box-shadow: 0 0 0 3px color-mix(in oklab, var(--danger) 15%, transparent); } @@ -501,17 +446,9 @@ a { color: inherit; text-decoration: none; } .bulk-confirm-summary span { color: var(--muted); font-size: 11px; } .bulk-confirm-summary strong { font-size: 13px; } -.row-details { position: relative; } -.row-details summary { cursor: pointer; color: var(--brand); list-style: none; } -.row-details > div { position: absolute; z-index: 10; right: 0; top: 25px; width: 250px; padding: 12px; background: var(--surface-3); border: 1px solid var(--border); color: var(--fg); border-radius: 10px; display: grid; gap: 5px; box-shadow: var(--shadow-l); animation: pop-in var(--dur-1) var(--ease); } -.row-details span { word-break: break-all; } .test-badge.ok { color: var(--success); } .test-badge.failed, .status-error { color: var(--danger); } .upload-card img { width: 52px; height: 52px; object-fit: contain; border-radius: 8px; } -.password-strength i.active { background: var(--brand); } -.integration-details > summary { cursor: pointer; padding: 13px 15px; border: 1px solid var(--border); border-radius: 9px; font-weight: 700; } -.integration-details[open] > summary { margin-bottom: 16px; border-color: var(--brand); color: var(--brand); } -.integration-details .admin-panel { box-shadow: none; } .kpi-list button { width: 100%; display: grid; grid-template-columns: 1fr auto auto; gap: 10px; align-items: center; text-align: left; } .domain-name a { position: relative; z-index: 3; display: inline-flex; } .public-footer.footer-grid { display: grid; grid-template-columns: minmax(180px, 1fr) auto minmax(180px, 1fr); align-items: center; gap: 24px; } @@ -545,12 +482,9 @@ a { color: inherit; text-decoration: none; } .filter-search button:hover { transform: translateY(-1px); box-shadow: var(--shadow-m); } .domain-card:hover { transform: translateY(-3px); border-color: color-mix(in oklab, var(--brand) 48%, var(--border)); box-shadow: 0 3px 8px color-mix(in oklab, var(--shadow-color) 5%, transparent), 0 18px 40px color-mix(in oklab, var(--brand) 13%, color-mix(in oklab, var(--shadow-color) 6%, transparent)); z-index: 5; } .domain-card.featured:hover { border-color: color-mix(in oklab, var(--premium) 70%, var(--border)); } - .domain-card:hover .copy-button { opacity: 1; transform: translateX(0); } - .copy-button:hover { background: var(--brand-soft); color: var(--brand); } .domain-card:hover .domain-name span { color: color-mix(in oklab, var(--brand) 70%, var(--faint)); } .pagination button:hover:not(:disabled) { border-color: var(--faint); transform: translateY(-1px); } .related-grid a:hover { border-color: color-mix(in oklab, var(--brand) 45%, var(--border)); transform: translateY(-2px); } - .contact-list a:hover, .contact-list button:hover { border-color: color-mix(in oklab, var(--brand) 45%, var(--border)); transform: translateY(-1px); box-shadow: var(--shadow-s); } .modal-close:hover { background: var(--border); transform: rotate(90deg); } } @@ -611,7 +545,6 @@ a { color: inherit; text-decoration: none; } .brand-mark { border-radius: 6px; background: var(--brand); color: white; box-shadow: none; font-family: var(--font-cjk); font-weight: 800; } .public-header nav { gap: clamp(13px, 1.8vw, 26px); } .admin-link { min-height: 40px; border-radius: 6px; box-shadow: none; } -.mobile-stats { display: none; } .domain-section { max-width: 1540px; padding: 34px clamp(20px, 3vw, 48px) 96px; } .filter-bar { @@ -642,17 +575,6 @@ a { color: inherit; text-decoration: none; } .public-header nav { gap: 8px; } .public-header .brand > span:last-child { font-size: 18px; } .public-header .admin-link { padding-inline: 10px; } - .mobile-stats { - display: grid; - grid-template-columns: repeat(4, auto); - justify-content: space-between; - gap: 8px; - padding: 13px 14px; - border-bottom: 1px solid var(--border); - color: var(--muted); - font-size: 10px; - } - .mobile-stats strong { color: var(--fg); font-family: var(--font-mono); } .domain-section { padding: 18px 14px 58px; } .filter-bar { gap: 8px; padding-bottom: 14px; } .filter-search { flex-basis: 100%; } @@ -672,8 +594,6 @@ a { color: inherit; text-decoration: none; } } @media (max-width: 390px) { - .mobile-stats { grid-template-columns: repeat(3, auto); } - .mobile-stats span:last-child { display: none; } .public-header nav .text-button { display: none; } } @@ -683,11 +603,11 @@ a { color: inherit; text-decoration: none; } /* 2026 public bento catalogue */ .catalogue-layout { display: block; max-width: 1320px; padding-top: 26px; } -.view-switch { display: inline-flex; padding: 3px; border: 1px solid var(--border); border-radius: 999px; background: color-mix(in oklab, var(--surface-1) 50%, transparent); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.04); } +.view-switch { display: inline-flex; padding: 3px; border: 1px solid var(--border); border-radius: 999px; background: color-mix(in oklab, var(--surface-1) 50%, transparent); box-shadow: inset 0 1px 2px rgba(17, 38, 30, 0.04); } .view-switch button { padding: 5px 12px; border-radius: 999px; font-size: 11px; font-weight: 600; letter-spacing: .02em; color: var(--muted); transition: color var(--dur-1) var(--ease), background var(--dur-1) var(--ease), transform var(--dur-1) var(--ease); } .view-switch button:active { transform: scale(.95); } .view-switch button:hover { color: var(--fg); } -.view-switch button.active { color: var(--text-inverse); background: var(--fg); box-shadow: 0 2px 6px color-mix(in oklab, var(--fg) 30%, transparent); } +.view-switch button.active { color: var(--text-on-brand); background: var(--brand); box-shadow: 0 2px 6px color-mix(in oklab, var(--brand) 30%, transparent); } .domain-list.card-view { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; border: 0; } .domain-list.card-view .domain-card { position: relative; display: flex; min-height: 190px; padding: 20px; flex-direction: column; align-items: stretch; gap: 14px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); box-shadow: var(--shadow); } .domain-list.card-view .domain-tld, .domain-list.card-view .domain-length { display: none; } @@ -765,9 +685,6 @@ a { color: inherit; text-decoration: none; } } .domain-section { max-width: none; margin: 0; padding: 0; } -.catalogue-intro { margin-bottom: 24px; } -.catalogue-intro h1 { margin: 0; font-size: clamp(28px, 3vw, 40px); line-height: 1.25; letter-spacing: -.04em; } -.catalogue-intro p { max-width: 720px; margin: 8px 0 0; color: var(--muted); font-size: 14px; line-height: 1.6; } .filter-search { display: grid; grid-template-columns: 20px minmax(0, 520px) auto auto; @@ -804,7 +721,7 @@ a { color: inherit; text-decoration: none; } font-size: 14px; font-weight: 650; } -.filter-search .search-submit:hover { filter: brightness(.95); transform: none; } +.filter-search .search-submit:hover { background: var(--brand-hover); border-color: var(--brand-hover); transform: none; } .catalogue-toolbar { display: grid; @@ -829,14 +746,12 @@ a { color: inherit; text-decoration: none; } .clear-filter { min-height: 36px; padding: 0 8px; border: 0; color: var(--fg-2); background: transparent; font-size: 12px; text-decoration: underline; text-underline-offset: 3px; } .domain-list { border-bottom: 1px solid var(--border); } -.domain-list-head, .domain-card { +.domain-card { display: grid; grid-template-columns: minmax(250px, 2fr) minmax(72px, .55fr) minmax(56px, .4fr) minmax(170px, 1.2fr) minmax(174px, auto); align-items: center; column-gap: 18px; } -.domain-list-head { min-height: 42px; padding: 0 14px; color: var(--muted); border-bottom: 1px solid var(--border); font-size: 11px; } -.domain-list-head span:last-child { text-align: center; } .domain-card { position: relative; min-height: 84px; @@ -861,7 +776,7 @@ a { color: inherit; text-decoration: none; } .domain-name span { color: var(--fg-2); font-weight: 600; } .domain-tags { display: flex; gap: 6px; min-height: 20px; margin-top: 6px; } .chip { display: inline-flex; align-items: center; min-height: 20px; padding: 2px 7px; border: 0; border-radius: 4px; color: var(--fg-2); background: var(--surface-1); font-family: var(--font-cjk); font-size: 10px; } -.chip-featured { color: white; background: var(--brand); } +.chip-featured { color: var(--gold-text); background: var(--gold-bg-strong); border: 1px solid var(--gold-border); } .domain-tld, .domain-length { color: var(--fg-2); font-family: var(--font-mono); font-size: 12px; } .domain-description { min-height: 0; margin: 0; color: var(--fg-2); font-size: 13px; line-height: 1.45; overflow-wrap: anywhere; } .domain-actions { position: relative; z-index: 2; display: flex; justify-content: flex-end; gap: 8px; } @@ -907,15 +822,13 @@ a { color: inherit; text-decoration: none; } .public-footer > div { display: flex; align-items: center; gap: 16px; } .public-footer strong { color: var(--fg); font-size: 14px; } .public-footer button { display: inline-flex; align-items: center; gap: 8px; min-height: 40px; border: 0; color: var(--fg-2); background: transparent; } -.modal-backdrop { background: rgba(12, 14, 17, .48); backdrop-filter: blur(3px); } -.contact-modal { border-radius: 12px; box-shadow: 0 24px 64px rgba(12, 14, 17, .22); } -.contact-modal h2 { margin-top: 0; } +.modal-backdrop { background: rgba(15, 45, 36, 0.42); backdrop-filter: blur(3px); } @media (max-width: 1120px) { .catalogue-layout { grid-template-columns: 188px minmax(0, 1fr); gap: 28px; } .catalogue-toolbar { grid-template-columns: 1fr auto; } .toolbar-summary { grid-column: 1 / -1; justify-content: flex-start; } - .domain-list-head, .domain-card { grid-template-columns: minmax(210px, 2fr) 64px 48px minmax(130px, 1fr) 86px; } + .domain-card { grid-template-columns: minmax(210px, 2fr) 64px 48px minmax(130px, 1fr) 86px; } .contact-row-button { display: none !important; } } @@ -925,7 +838,6 @@ a { color: inherit; text-decoration: none; } .header-actions { grid-column: 2; } .header-actions .admin-link { display: none; } .catalogue-layout { display: block; padding: 24px 14px 52px; } - .catalogue-intro h1 { font-size: 28px; } .filter-search { grid-template-columns: 20px minmax(0, 1fr) auto auto; } .filter-search .search-submit { min-width: 68px; } .catalogue-toolbar { display: flex; align-items: stretch; flex-direction: column; gap: 12px; } @@ -936,7 +848,6 @@ a { color: inherit; text-decoration: none; } .sort-row { padding-bottom: 2px; overflow-x: auto; } .toolbar-summary { justify-content: space-between; } .domain-list { border-top: 0; } - .domain-list-head { display: none; } .domain-card { grid-template-columns: minmax(0, 1fr); grid-template-areas: "primary" "description" "meta" "footer"; @@ -957,7 +868,6 @@ a { color: inherit; text-decoration: none; } @media (max-width: 390px) { .public-header { padding-inline: 14px; } - .catalogue-intro h1 { font-size: 26px; } .filter-search { padding-left: 10px; } .filter-search input { padding-inline: 8px; } .filter-search .search-submit { min-width: 62px; } @@ -984,7 +894,7 @@ a { color: inherit; text-decoration: none; } .public-shell .public-header { border-bottom: 0; background: color-mix(in oklab, var(--surface-2) 88%, transparent); - box-shadow: 0 1px 0 color-mix(in oklab, var(--border) 54%, transparent), 0 16px 42px -34px rgba(64, 42, 20, .35); + box-shadow: 0 1px 0 color-mix(in oklab, var(--border) 54%, transparent), 0 16px 42px -34px rgba(17, 38, 30, 0.30); backdrop-filter: none; -webkit-backdrop-filter: none; } @@ -993,7 +903,7 @@ a { color: inherit; text-decoration: none; } max-width: none; border-color: color-mix(in oklab, var(--border-strong) 68%, transparent); border-radius: 15px; - box-shadow: 0 12px 32px -28px rgba(56, 37, 18, .5); + box-shadow: 0 12px 32px -28px rgba(17, 38, 30, 0.42); overflow: hidden; } .public-shell .filter-search .search-submit { border-radius: 0 14px 14px 0; } @@ -1005,7 +915,7 @@ a { color: inherit; text-decoration: none; } border-radius: 20px; padding: 13px 15px; background: color-mix(in oklab, var(--surface-1) 60%, var(--surface-2)); - box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--border) 46%, transparent), 0 16px 36px -34px rgba(54, 35, 18, .42); + box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--border) 46%, transparent), 0 16px 36px -34px rgba(17, 38, 30, 0.36); } .public-shell .catalogue-toolbar .filter-search { grid-column: 1 / -1; } .public-shell .catalogue-toolbar .toolbar-filters { grid-column: 1; } @@ -1016,14 +926,14 @@ a { color: inherit; text-decoration: none; } .public-shell .domain-list.card-view .domain-card { border-color: transparent; border-radius: 19px; - box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--border) 58%, transparent), 0 14px 36px -31px rgba(50, 34, 19, .48); + box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--border) 58%, transparent), 0 14px 36px -31px rgba(17, 38, 30, 0.40); transition: transform 190ms var(--ease), box-shadow 190ms var(--ease), background 190ms var(--ease); } .public-shell .domain-list.card-view .domain-card:hover { transform: translateY(-3px); border-color: transparent; background: color-mix(in oklab, var(--brand-soft) 34%, var(--surface-2)); - box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--brand) 30%, transparent), 0 22px 45px -31px rgba(75, 43, 13, .48); + box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--brand) 30%, transparent), 0 22px 45px -31px rgba(17, 38, 30, 0.40); } .public-shell .domain-list.card-view .domain-card.featured { border: 0; @@ -1038,7 +948,7 @@ a { color: inherit; text-decoration: none; } border: 0; border-radius: 26px; background: color-mix(in oklab, var(--surface-1) 62%, var(--surface-2)); - box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--border) 42%, transparent), 0 22px 52px -44px rgba(55, 35, 17, .4); + box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--border) 42%, transparent), 0 22px 52px -44px rgba(17, 38, 30, 0.34); } @media (max-width: 780px) { @@ -1070,36 +980,8 @@ a { color: inherit; text-decoration: none; } color: var(--brand-strong); font-family: var(--font-mono); font-size: 9px; } .header-actions { display: flex; align-items: center; gap: 9px; } -.header-discover { - min-height: 36px; padding: 0 13px; border: 1px solid color-mix(in oklab, var(--brand) 30%, var(--border)); - border-radius: 999px; background: var(--brand-soft); color: color-mix(in oklab, var(--brand) 72%, var(--fg)); - font-size: 12px; font-weight: 700; cursor: pointer; - transition: transform var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease); -} -.header-discover:active { transform: scale(.97); } .public-shell .catalogue-layout { max-width: 1380px; padding: 28px clamp(16px, 3vw, 46px) 84px; } -.hero-composition { position: relative; z-index: 1; } -.hero-eyebrow { display: block; margin-bottom: 11px; color: var(--brand-strong); font-family: var(--font-mono); font-size: 10px; letter-spacing: .18em; } -.hero-value strong { text-shadow: 0 2px 20px color-mix(in oklab, var(--brand) 20%, transparent); } -.hero-composition { grid-column: 1 / -1; display: grid; gap: 10px; } -.hero-bar { display: flex; height: 8px; overflow: hidden; border-radius: 999px; background: var(--surface-1); } -.hero-bar i { min-width: 2px; background: linear-gradient(180deg, var(--gold), var(--gold-soft)); transition: transform .3s ease, opacity .3s ease; transform-origin: bottom; } -.hero-bar i:nth-child(2) { opacity: .91; } -.hero-bar i:nth-child(3) { opacity: .82; } -.hero-bar i:nth-child(4) { opacity: .73; } -.hero-bar i:nth-child(5) { opacity: .64; } -.hero-bar i:nth-child(6) { opacity: .55; } -.hero-bar:hover i { opacity: .92; transform: scaleY(1.18); } -.hero-bar i:nth-child(2) { filter: hue-rotate(12deg) saturate(.82); } -.hero-bar i:nth-child(3) { filter: hue-rotate(25deg) saturate(.68); } -.hero-bar i:nth-child(4) { filter: hue-rotate(38deg) saturate(.56); } -.hero-bar i:nth-child(5) { filter: hue-rotate(52deg) saturate(.46); } -.hero-bar i:nth-child(6) { filter: hue-rotate(68deg) saturate(.38); } -.hero-legend { display: flex; flex-wrap: wrap; gap: 8px 18px; } -.hero-legend span { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: 10px; } -.hero-legend span > i { width: 6px; height: 6px; border-radius: 999px; background: var(--gold); } -.hero-legend b { color: var(--fg-2); font-family: var(--font-mono); font-weight: 550; } .public-shell .catalogue-toolbar { position: relative; grid-template-columns: minmax(300px, 1fr) auto auto; overflow: visible; @@ -1112,7 +994,7 @@ a { color: inherit; text-decoration: none; } grid-template-columns: 20px minmax(0, 1fr) auto auto; transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease); } -.public-shell .filter-search:focus-within { transform: none; border-color: var(--gold); box-shadow: 0 0 0 3px color-mix(in oklab, var(--gold) 14%, transparent); } +.public-shell .filter-search:focus-within { transform: none; border-color: var(--brand-hover); box-shadow: 0 0 0 3px var(--brand-ring); } .public-shell .filter-search input { min-height: 46px; font-size: 16px; } .public-shell .filter-search .search-submit { grid-column: -2 / -1; @@ -1162,14 +1044,6 @@ a { color: inherit; text-decoration: none; } .public-shell .domain-name { letter-spacing: .02em; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .public-shell .domain-name a { max-width: 100%; } .public-shell .domain-name strong { overflow: hidden; text-overflow: ellipsis; } -.domain-keywords, .detail-keywords { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; min-width: 0; } -.keyword-pill { - display: inline-flex; align-items: center; max-width: 100%; min-height: 22px; padding: 2px 8px; - overflow: hidden; border: 1px solid color-mix(in oklab, var(--gold) 30%, transparent); border-radius: var(--radius-pill); - color: var(--gold-bright); background: none; font-family: var(--font-cjk); font-size: 10px; line-height: 1.35; - text-overflow: ellipsis; white-space: nowrap; -} -.detail-keywords { margin: 0 0 18px; } .public-shell .domain-description { min-height: 3.2em; line-height: 1.6; letter-spacing: .01em; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; white-space: normal !important; overflow: hidden; } .domain-card-meta { display: flex; align-items: stretch; gap: 8px; margin-top: auto; color: var(--muted); font-family: var(--font-mono); font-size: 10px; } .public-shell .domain-list.card-view .domain-actions { align-self: flex-end; margin-top: 0; opacity: 1; display: grid; grid-template-columns: repeat(3, 38px); justify-content: end; gap: 6px; } @@ -1200,13 +1074,13 @@ a { color: inherit; text-decoration: none; } .pagination { flex-wrap: wrap; } .pagination > div { display: flex; align-items: center; gap: 5px; } .pagination button { min-width: 40px; } -.pagination button.active { color: var(--brand-strong); border-color: var(--brand); background: var(--brand-soft); box-shadow: 0 0 12px color-mix(in oklab, var(--gold) 24%, transparent); } +.pagination button.active { color: var(--text-on-brand); border-color: var(--brand); background: var(--brand); } .pagination > div span { min-width: 24px; text-align: center; } .domain-detail-dialog { width: min(760px, calc(100vw - 32px)); max-height: min(860px, calc(100vh - 40px)); padding: 0; - border: 1px solid color-mix(in oklab, var(--gold) 24%, var(--border)); border-radius: 24px; - color: var(--fg); background: var(--surface-elevated); box-shadow: 0 36px 100px rgba(0, 0, 0, .36); overflow-x: hidden; overflow-y: auto; + border: 1px solid var(--border-strong); border-radius: 24px; + color: var(--fg); background: var(--surface-elevated); box-shadow: var(--shadow-modal); overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; } /* 模态从中心轻微放大进入(modal 不做 origin-aware,保持居中);从 scale(0) 出现违背物理直觉 */ @@ -1220,7 +1094,7 @@ a { color: inherit; text-decoration: none; } transition: opacity var(--dur-2) var(--ease); @starting-style { opacity: 0; } } -.domain-detail-dialog::backdrop { background: rgba(9, 9, 8, .62); backdrop-filter: blur(8px); } +.domain-detail-dialog::backdrop { background: rgba(15, 45, 36, 0.48); backdrop-filter: blur(8px); } .domain-detail-dialog > section { position: relative; padding: clamp(24px, 5vw, 44px); } .detail-kicker { display: block; margin-bottom: 10px; color: var(--brand-strong); font-family: var(--font-mono); font-size: 10px; letter-spacing: .16em; } .domain-detail-dialog h2 { max-width: calc(100% - 42px); margin: 0; overflow-wrap: anywhere; font-family: var(--font-display); font-size: clamp(30px, 6vw, 54px); line-height: 1.08; letter-spacing: .01em; } @@ -1249,7 +1123,7 @@ a { color: inherit; text-decoration: none; } .quick-qr-download { flex: 0 0 auto; color: var(--brand-strong); font-size: 9px; font-weight: 700; } .quick-qr-frame { display: grid; width: 130px; height: 130px; margin: 13px auto 0; place-items: center; overflow: hidden; border: 1px solid var(--border); border-radius: 11px; background: #fff; } .quick-qr-frame img { display: block; width: 128px; height: 128px; } -.quick-qr-frame span { padding: 12px; color: #6b6860; font-size: 9px; text-align: center; } +.quick-qr-frame span { padding: 12px; color: var(--text-tertiary); font-size: 9px; text-align: center; } .quick-external-links { display: grid; gap: 7px; margin-top: 13px; } .quick-external-links a { display: flex; min-width: 0; min-height: 39px; padding: 0 12px; align-items: center; justify-content: space-between; gap: 10px; border: 1px solid var(--border); border-radius: 10px; color: var(--fg-2); background: var(--surface); font-size: 10px; } .quick-external-links a:hover { border-color: var(--brand); color: var(--brand-strong); } @@ -1268,10 +1142,6 @@ a { color: inherit; text-decoration: none; } .public-bottom-nav { display: none; } -@media (hover: hover) and (pointer: fine) { - .header-discover:hover { transform: translateY(-1px); border-color: var(--brand); } -} - @media (max-width: 1023px) { .public-shell .domain-list.card-view { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; } .public-shell .domain-list.compact-view .domain-card { grid-template-columns: minmax(180px, 1fr) minmax(150px, .8fr) auto; } @@ -1288,7 +1158,6 @@ a { color: inherit; text-decoration: none; } .public-shell .catalogue-toolbar { padding: 12px; gap: 10px; } .public-shell .filter-search { min-height: 48px; } .toolbar-filters { display: grid; grid-template-columns: 1fr 1fr; } - .advanced-kind { grid-column: 1 / -1; } .public-shell .toolbar-summary { flex-wrap: wrap; } .public-shell .domain-list.card-view { grid-template-columns: 1fr; } .public-shell .domain-list.card-view .domain-card { min-height: 184px; padding: 16px; border-radius: 17px; contain-intrinsic-size: 0 184px; } @@ -1313,7 +1182,7 @@ a { color: inherit; text-decoration: none; } .pagination > div { max-width: 100%; overflow-x: auto; } .pagination > div button { min-width: 40px; flex: 0 0 40px; } .domain-detail-dialog { - width: 100%; max-width: none; max-height: min(88dvh, 820px); margin: auto 0 0; border: 0; border-top: 1px solid color-mix(in oklab, var(--gold) 28%, var(--border)); + width: 100%; max-width: none; max-height: min(88dvh, 820px); margin: auto 0 0; border: 0; border-top: 1px solid var(--border-strong); border-radius: 24px 24px 0 0; padding-bottom: env(safe-area-inset-bottom); } .domain-detail-dialog > section { padding: 27px 18px 24px; } @@ -1333,7 +1202,7 @@ a { color: inherit; text-decoration: none; } border-top: 1px solid color-mix(in oklab, var(--border) 75%, transparent); background: var(--background); backdrop-filter: none; -webkit-backdrop-filter: none; - box-shadow: 0 -18px 45px -34px rgba(0, 0, 0, .5); + box-shadow: 0 -18px 45px -34px rgba(17, 38, 30, 0.40); } .public-bottom-nav button { min-width: 0; min-height: 56px; border: 0; border-radius: 12px; display: grid; place-items: center; align-content: center; gap: 1px; @@ -1348,7 +1217,6 @@ a { color: inherit; text-decoration: none; } @media (max-width: 430px) { .public-shell .filter-search .search-submit { min-width: 62px; } - .advanced-kind { grid-column: auto; } .public-shell .domain-list.card-view .domain-actions { gap: 4px; } .public-shell .domain-actions button { padding-inline: 5px; } .domain-detail-dialog > section { padding-inline: 15px; } @@ -1357,7 +1225,6 @@ a { color: inherit; text-decoration: none; } } @media (prefers-reduced-motion: reduce) { - .hero-bar i, .domain-card.highlighted { transform: none !important; animation: none !important; } .public-shell .skeleton-list .domain-card { animation: none !important; background: var(--surface-1); } .quick-qr-section, .quick-qr-frame, .quick-qr-frame img { animation: none !important; transition: none !important; } } @@ -1365,7 +1232,6 @@ a { color: inherit; text-decoration: none; } @media (prefers-reduced-transparency: reduce) { .public-bottom-nav, .domain-detail-dialog::backdrop { backdrop-filter: none; -webkit-backdrop-filter: none; } .public-bottom-nav { background: var(--background); } - .keyword-pill { border-color: var(--gold-muted); } } /* Admin CSV preview and auditable log table. */ @@ -1433,16 +1299,17 @@ a { color: inherit; text-decoration: none; } .featured-detail-kicker { display: block; margin-bottom: 22px; - color: var(--brand-strong); + color: var(--gold-text); font-family: var(--font-mono); font-size: 10px; font-weight: 700; letter-spacing: .28em; } +/* 精品详情大标题用深色保证清晰;精品身份靠金色 kicker、标签与徽章表达 */ .featured-detail-hero h1 { max-width: 100%; margin: 0; - color: var(--gold-bright); + color: var(--fg); font-family: var(--font-display); font-size: clamp(64px, 10vw, 138px); font-weight: 400; @@ -1450,7 +1317,7 @@ a { color: inherit; text-decoration: none; } letter-spacing: -.045em; overflow-wrap: anywhere; text-wrap: balance; - text-shadow: 0 8px 46px color-mix(in oklab, var(--brand) 17%, transparent); + text-shadow: 0 8px 46px color-mix(in oklab, var(--brand) 12%, transparent); } .featured-detail-tags { margin: 34px auto 0; display: flex; justify-content: center; gap: 8px; flex-wrap: wrap; } .featured-detail-tags span { @@ -1482,14 +1349,14 @@ a { color: inherit; text-decoration: none; } justify-content: center; border: 1px solid var(--brand); border-radius: 999px; - background: var(--brand-soft); - color: var(--brand-strong); + background: var(--brand); + color: var(--text-on-brand); font-size: 13px; font-weight: 700; box-shadow: 0 16px 40px -28px var(--brand); - transition: transform var(--dur-1) var(--ease), background var(--dur-1) var(--ease); + transition: transform var(--dur-1) var(--ease), background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease); } -.featured-detail-visit:hover { transform: translateY(-2px); background: color-mix(in oklab, var(--brand) 17%, var(--surface-1)); } +.featured-detail-visit:hover { transform: translateY(-2px); background: var(--brand-hover); border-color: var(--brand-hover); } .featured-related { margin-top: 104px; padding-top: 52px; border-top: 1px solid var(--border); } .featured-related-heading { margin-bottom: 34px; text-align: center; } @@ -1674,26 +1541,29 @@ a { color: inherit; text-decoration: none; } transform: none; } .public-shell .domain-list.card-view .domain-card:active { transform: none; } +/* 精品卡:主体仍是暖白卡片,靠金细边 + 顶部短金线 + 极轻金晕表达稀缺身份 */ .public-shell .domain-list.card-view .domain-card.featured { - border: 1px solid var(--border); + border: 1px solid var(--gold-border); background: var(--surface); - box-shadow: var(--shadow-card); + box-shadow: var(--shadow-card), 0 10px 26px -20px rgba(184, 128, 56, 0.55); } .public-shell .domain-list.card-view .domain-card.featured:hover, .public-shell .domain-list.card-view .domain-card.featured:focus-within { - border-color: var(--gold-border); + border-color: var(--gold-deep); background: var(--surface); - box-shadow: var(--shadow-card-hover); + box-shadow: var(--shadow-card-hover), 0 14px 30px -20px rgba(184, 128, 56, 0.55); } .public-shell .domain-list.card-view .domain-card::before { content: none; } -.domain-featured-dot { +/* 下方 featured::before 为精品卡顶部短金线 */ +.public-shell .domain-list.card-view .domain-card.featured::before { + content: ""; position: absolute; - top: var(--space-xs); - left: var(--space-xs); - width: var(--space-3xs); - height: var(--space-3xs); - border-radius: var(--radius-pill); - background: var(--gold); + inset: 0 auto auto 20px; + width: 44px; + height: 2px; + border-radius: 0 0 2px 2px; + background: linear-gradient(90deg, var(--gold), var(--gold-bright)); + opacity: 1; } .public-shell .domain-list.card-view .domain-primary { grid-area: primary; @@ -1726,17 +1596,6 @@ a { color: inherit; text-decoration: none; } font-weight: 700; } .public-shell .domain-list.card-view .domain-card:hover .domain-name span { color: var(--text-secondary); } -.domain-divider { - grid-area: divider; - width: 32px; - height: 1px; - justify-self: start; - background: var(--gold-divider); -} -.public-shell .domain-list.card-view .domain-keywords { - grid-area: keywords; - align-self: start; -} .public-shell .domain-list.card-view .domain-card-meta { grid-area: meta; min-width: 0; @@ -1775,9 +1634,9 @@ a { color: inherit; text-decoration: none; } justify-content: center; justify-self: end; gap: var(--space-2xs); - border: 1px solid var(--gold-border); + border: 1px solid var(--brand-border); border-radius: var(--radius-sm); - color: var(--gold-bright); + color: var(--brand-strong); background: transparent; font-family: var(--font-ui); font-size: 12px; @@ -1788,8 +1647,8 @@ a { color: inherit; text-decoration: none; } } .domain-visit:hover, .domain-visit:focus-visible { - border-color: var(--gold); - background: var(--gold-bg); + border-color: var(--brand); + background: var(--brand-bg); } .domain-visit svg { width: 16px; @@ -1849,8 +1708,8 @@ a { color: inherit; text-decoration: none; } } .public-shell .domain-list.compact-view .domain-card { - grid-template-columns: minmax(190px, 1.2fr) minmax(180px, 1fr) minmax(220px, auto) auto auto; - grid-template-areas: "primary keywords meta actions visit"; + grid-template-columns: minmax(190px, 1.5fr) minmax(220px, auto) auto auto; + grid-template-areas: "primary meta actions visit"; border-color: var(--border); box-shadow: none; animation: none; @@ -1859,24 +1718,13 @@ a { color: inherit; text-decoration: none; } .public-shell .domain-list.compact-view .domain-card:hover, .public-shell .domain-list.compact-view .domain-card:active { transform: none; } .public-shell .domain-list.compact-view .domain-primary { grid-area: primary; } -.public-shell .domain-list.compact-view .domain-divider { display: none; } -.public-shell .domain-list.compact-view .domain-keywords { grid-area: keywords; } .public-shell .domain-list.compact-view .domain-card-meta { grid-area: meta; display: flex; margin: 0; } .public-shell .domain-list.compact-view .domain-actions { grid-area: actions; min-width: 126px; } .public-shell .domain-list.compact-view .domain-visit { grid-area: visit; opacity: 1; pointer-events: auto; transform: none; } -.public-shell .domain-list.card-view .domain-card.highlighted, -.public-shell .domain-list.compact-view .domain-card.highlighted { animation: domain-highlight 1.7s var(--ease); } @media (max-width: 1023px) { - .public-shell .domain-list.compact-view .domain-card, - .public-shell .domain-list.compact-view .domain-card:has(.domain-keywords) { + .public-shell .domain-list.compact-view .domain-card { grid-template-columns: minmax(0, 1fr) auto; - grid-template-areas: - "primary actions" - "keywords keywords" - "meta visit"; - } - .public-shell .domain-list.compact-view .domain-card:not(:has(.domain-keywords)) { grid-template-areas: "primary actions" "meta visit"; @@ -1918,29 +1766,7 @@ a { color: inherit; text-decoration: none; } } } -/* Search discovery controls: shareable sorting, history, and useful empty states. */ -.copy-filter-link { - min-height: 38px; - padding: 0 13px; - border: 1px solid var(--border); - border-radius: var(--radius-pill); - display: inline-flex; - align-items: center; - gap: 7px; - color: var(--text-secondary); - background: var(--surface); - font-size: 12px; - cursor: pointer; - transition: border-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease), background var(--dur-1) var(--ease), transform var(--dur-1) var(--ease); -} -.copy-filter-link:hover, -.copy-filter-link:focus-visible { - border-color: var(--gold-border); - color: var(--gold-bright); - background: var(--surface-2); -} -.copy-filter-link:active { transform: scale(.96); } -.copy-filter-link svg, +/* Search discovery controls: history and useful empty states. */ .clear-search-history svg { width: 16px; height: 16px; @@ -1997,7 +1823,6 @@ a { color: inherit; text-decoration: none; } } @media (max-width: 780px) { - .copy-filter-link { min-height: 40px; padding-inline: 11px; } .toolbar-filters .sort-control { grid-column: 1 / -1; } .toolbar-filters .sort-control select { min-width: 0; } .public-shell .catalogue-toolbar .toolbar-summary { justify-content: space-between; } @@ -2011,7 +1836,6 @@ a { color: inherit; text-decoration: none; } .toolbar-filters select, .search-area, .search-history { min-width: 0; max-width: 100%; } - .copy-filter-link { font-size: 11px; } } /* ============================================================ @@ -2106,5 +1930,6 @@ a { color: inherit; text-decoration: none; } } } -/* 到期临近(≤90 天)的剩余天数以警示色提示 */ -.meta-chip-warning { color: var(--warning); border-color: color-mix(in oklab, var(--warning) 36%, var(--border)); background: color-mix(in oklab, var(--warning) 8%, transparent); } +/* 到期状态分级:≤30 天警告、≤7 天与已过期危险;其余保持次级文字色 */ +.meta-chip-warning { color: var(--warning); border-color: color-mix(in oklab, var(--warning) 36%, var(--border)); background: var(--warning-bg); } +.meta-chip-danger { color: var(--danger); border-color: color-mix(in oklab, var(--danger) 36%, var(--border)); background: var(--danger-bg); } diff --git a/src/worker/routes/public/og.ts b/src/worker/routes/public/og.ts index 2909942..4dc642a 100644 --- a/src/worker/routes/public/og.ts +++ b/src/worker/routes/public/og.ts @@ -60,12 +60,12 @@ export async function renderFeaturedDomainOg(c: Context): Promise - - - - ${safeDomain} - - 玩米 · 精选域名资产 + + + + ${safeDomain} + + 玩米 · 精选域名资产 `; const resvg = await Resvg.async(svg, { fitTo: { mode: "width", value: 1200 }, diff --git a/src/worker/services/featured-domain.ts b/src/worker/services/featured-domain.ts index 8368440..650d8ab 100644 --- a/src/worker/services/featured-domain.ts +++ b/src/worker/services/featured-domain.ts @@ -152,7 +152,7 @@ export function renderFeaturedDomainSsr(detail: FeaturedDomainDetail): string {
← 返回域名目录 diff --git a/tests/e2e/visual-baseline-admin.spec.ts-snapshots/admin-domains-1024-chromium-win32.png b/tests/e2e/visual-baseline-admin.spec.ts-snapshots/admin-domains-1024-chromium-win32.png index 5678131ea91c197259b4ad6cf41c696f5a44e1f0..ff774a9115a44ab8c24ea8ef311d5d31c60cd5db 100644 GIT binary patch literal 117346 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

$h&54i7l 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