Skip to content

Commit 232e0be

Browse files
committed
style(branding): 重设计 logo/favicon 为淡色磨砂卡片 + 品牌渐变笔划;
将品牌图标由「深紫渐变实心块 + 白色 >_ 笔划」反转为「#f5f6fb 淡色磨砂卡片 + 品牌紫渐变(#667eea→#764ba2) >_ 笔划 + 细描边环」,使图标轮廓成为视觉主角, 更简约、小尺寸下更清晰(Linear/Vercel 风),强化 Coding 意向。 - 新增 _LOGO_DEFS 共享品牌渐变 <defs>,作为 favicon SVG 与页面 logo 单一事实源 - _build_favicon_svg:浅底 + 品牌描边环 + url(#cpBrand) 笔划 - _build_favicon (ICO):浅底光栅 + brand_at 按对角 t 计算品牌渐变笔划 - .logo CSS:浅底 + 品牌描边环 + 辉光调淡;内联 SVG 注入 {{LOGO_DEFS}} - 保留 --gradient-primary 与 .vendor-avatar 不动(最小干预) 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
1 parent c8606eb commit 232e0be

1 file changed

Lines changed: 51 additions & 32 deletions

File tree

src/coding/proxy/server/dashboard.py

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,49 @@
1212
from ..logging.db import TimePeriod
1313

1414
# ── 品牌图标:Tabler terminal-2 核心笔划(> 与 _),不含外框 ──────────────
15-
# 外框由「蓝紫渐变圆角方块」容器承载(favicon SVG 的 <rect> 与页面 .logo 的 CSS
16-
# 渐变),保留 Tabler 原始外框笔划会双重描边、边缘发糊,故仅取 > 与 _ 两条。
17-
# 作为单一事实源,同时供 favicon SVG(f-string)与页面 logo({{TERMINAL2}} 模板替换)消费。
15+
# 容器为「淡色磨砂卡片」(#f5f6fb 浅底 + 品牌紫描边环),> 与 _ 笔划改用品牌渐变
16+
# (#667eea -> #764ba2)——色彩反转:品牌紫由背景迁移至图标笔划,轮廓成为视觉主角,
17+
# 更简约、小尺寸下更清晰(Linear/Vercel 风)。保留 Tabler 原始外框笔划会双重描边、
18+
# 边缘发糊,故仅取 > 与 _ 两条。
19+
# 单一事实源:_TERMINAL2_PATHS 与 _LOGO_DEFS 同时供 favicon SVG(f-string)与页面
20+
# logo({{TERMINAL2}} / {{LOGO_DEFS}} 模板替换)消费。
21+
_BRAND_FROM, _BRAND_TO = "#667eea", "#764ba2"
22+
_LOGO_DEFS = (
23+
'<defs><linearGradient id="cpBrand" x1="0" y1="0" x2="1" y2="1">'
24+
f'<stop offset="0" stop-color="{_BRAND_FROM}"/>'
25+
f'<stop offset="1" stop-color="{_BRAND_TO}"/>'
26+
"</linearGradient></defs>"
27+
)
1828
_TERMINAL2_PATHS = '<path d="M8 9l3 3l-3 3" /><path d="M13 15l3 0" />'
1929

2030

2131
# ── Favicon (SVG, 现代浏览器主选) ──────────────────────────────────────────
2232
def _build_favicon_svg() -> str:
23-
"""生成 24×24 SVG favicon:品牌渐变圆角方块 + 白色 terminal-2 笔划.
33+
"""生成 24×24 SVG favicon:淡色磨砂卡片 + 品牌渐变 terminal-2 笔划.
2434
25-
独立 SVG 文档无 CSS 上下文,``currentColor`` 不可靠,故笔划硬编码 ``#ffffff``。
35+
容器为 ``#f5f6fb`` 浅底圆角方块 + 品牌紫描边环;``>`` 与 ``_`` 笔划由白色改为品牌
36+
渐变(``url(#cpBrand)``),使图标轮廓成为主角。独立 SVG 文档无 CSS 上下文,
37+
``currentColor`` 不可靠,故颜色硬编码;``<defs>`` 复用 ``_LOGO_DEFS`` 单一事实源。
2638
"""
2739
return (
2840
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">'
29-
'<defs><linearGradient id="g" x1="0" y1="0" x2="1" y2="1">'
30-
'<stop offset="0" stop-color="#667eea"/>'
31-
'<stop offset="1" stop-color="#764ba2"/>'
32-
"</linearGradient></defs>"
33-
'<rect x="1" y="1" width="22" height="22" rx="6" fill="url(#g)"/>'
34-
f'<g fill="none" stroke="#ffffff" stroke-width="2" '
41+
f"{_LOGO_DEFS}"
42+
'<rect x="1" y="1" width="22" height="22" rx="6" fill="#f5f6fb" '
43+
'stroke="#667eea" stroke-opacity=".18" stroke-width="1"/>'
44+
f'<g fill="none" stroke="url(#cpBrand)" stroke-width="2" '
3545
f'stroke-linecap="round" stroke-linejoin="round">{_TERMINAL2_PATHS}</g>'
3646
"</svg>"
3747
)
3848

3949

4050
# ── Favicon (ICO, 32×32 光栅回退) ─────────────────────────────────────────
4151
def _build_favicon() -> bytes:
42-
"""程序化生成 32×32 ICO:品牌渐变圆角方块 + 白色 terminal-2 笔划(旧浏览器/Safari 回退).
52+
"""程序化生成 32×32 ICO:淡色磨砂卡片 + 品牌渐变 terminal-2 笔划(旧浏览器/Safari 回退).
4353
44-
项目无 Pillow/cairosvg 等图像库,故以纯 Python 按像素光栅化:渐变圆角方块背景
45-
+ 白色 ``>`` 折线与 ``_`` 下划线。沿用原实现「全零 AND-mask + per-pixel alpha」
46-
的圆角透明方案(现代渲染器按 alpha 通道处理透明)。
54+
项目无 Pillow/cairosvg 等图像库,故以纯 Python 按像素光栅化:``#f5f6fb`` 浅底圆角
55+
方块 + 品牌渐变(#667eea -> #764ba2)``>`` 折线与 ``_`` 下划线。沿用原实现「全零
56+
AND-mask + per-pixel alpha」的圆角透明方案(现代渲染器按 alpha 通道处理透明)。
57+
32px 下细描边环易锯齿,故 ICO 仅保留浅底 + 渐变笔划,精修外观由 SVG 承载。
4758
"""
4859
import math
4960
import struct
@@ -52,8 +63,11 @@ def _build_favicon() -> bytes:
5263
radius = 8
5364
scale = width / 24.0 # SVG 24 单位 -> 像素
5465

55-
r0, g0, b0 = 0x66, 0x7E, 0xEA # #667eea
56-
r1, g1, b1 = 0x76, 0x4B, 0xA2 # #764ba2
66+
# 图标笔划品牌渐变:#667eea -> #764ba2(与 _LOGO_DEFS 同源)
67+
r0, g0, b0 = 0x66, 0x7E, 0xEA
68+
r1, g1, b1 = 0x76, 0x4B, 0xA2
69+
# 容器底色:#f5f6fb(近白、极浅冷蓝紫)
70+
tile_r, tile_g, tile_b = 0xF5, 0xF6, 0xFB
5771

5872
def inside(x: int, y: int) -> bool:
5973
"""满铺圆角方块(四角半径 radius)包含判定."""
@@ -68,30 +82,34 @@ def inside(x: int, y: int) -> bool:
6882
[[0, 0, 0, 0] for _ in range(width)] for _ in range(height)
6983
]
7084

71-
# 1) 对角渐变圆角背景(左上 #667eea -> 右下 #764ba2
85+
# 1) 浅底圆角背景(扁平 #f5f6fb
7286
for y in range(height):
7387
for x in range(width):
7488
if not inside(x, y):
7589
continue
76-
t = (x + y) / (width + height - 2)
77-
buf[y][x] = [
78-
int(b0 + (b1 - b0) * t),
79-
int(g0 + (g1 - g0) * t),
80-
int(r0 + (r1 - r0) * t),
81-
255,
82-
]
90+
buf[y][x] = [tile_b, tile_g, tile_r, 255]
91+
92+
def brand_at(px: float, py: float) -> tuple[int, int, int]:
93+
"""按对角参数 t 返回 (px,py) 处的品牌渐变 RGB(与 SVG url(#cpBrand) 同向)."""
94+
t = (px + py) / (width + height - 2)
95+
return (
96+
int(r0 + (r1 - r0) * t),
97+
int(g0 + (g1 - g0) * t),
98+
int(b0 + (b1 - b0) * t),
99+
)
83100

84101
def stamp(px: float, py: float) -> None:
85-
"""以 (px, py) 为中心盖 ~3px 白色方块(笔划加粗,保证小尺寸可辨识)."""
102+
"""以 (px, py) 为中心盖 ~3px 品牌渐变方块(笔划加粗,保证小尺寸可辨识)."""
86103
ix, iy = int(round(px)), int(round(py))
104+
cr, cg, cb = brand_at(px, py)
87105
for oy in (-1, 0, 1):
88106
for ox in (-1, 0, 1):
89107
nx, ny = ix + ox, iy + oy
90108
if 0 <= nx < width and 0 <= ny < height:
91-
buf[ny][nx] = [255, 255, 255, 255]
109+
buf[ny][nx] = [cb, cg, cr, 255]
92110

93111
def line(x0: float, y0: float, x1: float, y1: float) -> None:
94-
"""稠密采样 + stamp 形成白色粗线段."""
112+
"""稠密采样 + stamp 形成品牌渐变粗线段."""
95113
dist = math.hypot(x1 - x0, y1 - y0)
96114
steps = max(1, int(dist * 3))
97115
for i in range(steps + 1):
@@ -204,10 +222,11 @@ def line(x0: float, y0: float, x1: float, y1: float) -> None:
204222
.header-left { display: flex; align-items: center; gap: 12px; }
205223
.logo {
206224
width: 32px; height: 32px;
207-
background: var(--gradient-primary);
225+
background: #f5f6fb;
226+
border: 1px solid rgba(102,126,234,.18);
208227
border-radius: 10px;
209228
display: flex; align-items: center; justify-content: center;
210-
box-shadow: 0 4px 12px rgba(102,126,234,.25);
229+
box-shadow: 0 4px 12px rgba(102,126,234,.18);
211230
}
212231
.logo svg { width: 20px; height: 20px; display: block; }
213232
h1 { font-size: 18px; font-weight: 600; color: var(--text-primary); letter-spacing: -.3px; }
@@ -799,7 +818,7 @@ def line(x0: float, y0: float, x1: float, y1: float) -> None:
799818
<body>
800819
<header>
801820
<div class="header-left">
802-
<div class="logo"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">{{TERMINAL2}}</svg></div>
821+
<div class="logo"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="url(#cpBrand)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">{{LOGO_DEFS}}{{TERMINAL2}}</svg></div>
803822
<h1>Coding Proxy Dashboard</h1>
804823
<span class="badge" id="version-badge">v-.-.-</span>
805824
</div>
@@ -2333,7 +2352,7 @@ def line(x0: float, y0: float, x1: float, y1: float) -> None:
23332352
</script>
23342353
</body>
23352354
</html>
2336-
""".replace("{{TERMINAL2}}", _TERMINAL2_PATHS)
2355+
""".replace("{{TERMINAL2}}", _TERMINAL2_PATHS).replace("{{LOGO_DEFS}}", _LOGO_DEFS)
23372356

23382357

23392358
# ── 数据计算工具 ──────────────────────────────────────────────────────────

0 commit comments

Comments
 (0)