1212from ..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, 现代浏览器主选) ──────────────────────────────────────────
2232def _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 光栅回退) ─────────────────────────────────────────
4151def _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