5a48abb784
## ① logo 比例不對+深色仍有白底+旁邊大量空白
三個症狀同一個根:**我用的是未裁淨的原始 PNG**。
portal 的註解早就寫著:原始 1840x560 **只有 32% 高度是實際字形**,上下大留白
⇒ 同 height 字看起來很小;留白處露出 paper-on-ink 自帶的 Ink 底板=白底。
portal 用的是裁淨版(986x176),但**只內嵌在它的 HTML base64 裡**,我抄不到才用了原始圖。
修:
- 從 portal 的 base64 抽出兩張裁淨版,存成 arcrun-cis/trimmed/ 供全站共用
- 兩張**都是透明底**(實測四邊留白 0)⇒ 深色模式**拿掉 Ink 底板**
- 空白是**版面**造成:側欄 232px 扣 padding 剩 184px,logo 高 24px 只有 134px ⇒ 空 50px
⇒ 側欄對齊 portal 的 216px,logo 改 width:100% 填滿可用寬度
實測(渲染後量像素):
logo 26px 高 × 151px 寬,右側剩餘空白 1px(原本 50px)
深色:側欄底(18,18,18) vs logo 上下皆(18,18,18) ⇒ 落差 0,無白底
## ② 側邊欄選中態太粗糙
leo:「參考現在 Portal 的格式⋯⋯這個比現在膠囊反紅精緻,重點是跟 portal 的形象符合」
修:逐字照 portal 的 #sidenav .nav.on ——
**不是實心膠囊**,而是 amber 字色 + 8% amber 底 + 右側 2px amber 邊。
側欄右緣也照 portal 用 2px amber 35%。
實測:選中列底(237,228,222)=amber 8%、右緣(176,74,47)=Relation、未選(242,241,237)=Canvas。
## 機械閘加三項守衛
- 不准用未裁淨的原始 lockup(字會太小)
- 選中態必須有 border-right-color: var(--amber)
- 不准再出現 border-radius:999px(膠囊,leo 已否決)
兩支閘全過;style.css 仍 0 個 hex。
75 lines
3.9 KiB
Bash
Executable File
75 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# check-render.sh — **看得見的驗收**:用 headless Chrome 真的渲染一次並量像素(t193)
|
||
#
|
||
# 🔴 leo 2026-08-04:「既然是 Web,你做的時候**無法檢視**?例如用 chrome dev tool mcp?」
|
||
# ⇒ 對,可以。以後改完 UI 就跑這支,不要再拿沒看過的畫面交件。
|
||
#
|
||
# 它驗兩件肉眼容易漏、但機器一量就知道的事:
|
||
# ① lockup 底板與品牌區背景是否接合(paper-on-ink.png 自帶不透明 Ink 底板,
|
||
# 背景不對就會出現一個突兀方塊——leo 截圖裡看到的就是它)
|
||
# ② 深色模式的規則有沒有真的進到 build(曾發生 dist 是舊的、我卻對著舊圖除錯)
|
||
set -uo pipefail
|
||
cd "$(dirname "$0")"
|
||
CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
||
[ -x "$CHROME" ] || { echo "❌ 找不到 Chrome,跳過渲染檢查"; exit 0; }
|
||
[ -d frontend/dist ] || { echo "❌ 沒有 frontend/dist——先 wails build"; exit 1; }
|
||
|
||
W=$(mktemp -d); trap 'rm -rf "$W"; kill %1 2>/dev/null' EXIT
|
||
cp -R frontend/dist/* "$W/"
|
||
cat > "$W/mock.js" <<'JS'
|
||
window.go={main:{App:{GetState:async()=>({version:'v0',statusBig:'看守中',statusSub:'',
|
||
syncing:false,engine:'workers-ai',geminiKey:'',extractedOK:0,accounts:[]}),
|
||
SyncNow:async()=>{},PickFolder:async()=>'',AddFolder:async()=>{},RemoveFolder:async()=>{},
|
||
SetAI:async()=>{},OpenURL:()=>{},Connect:async()=>{},CheckUpdate:async()=>({})}}};
|
||
JS
|
||
python3 - "$W" <<'PY'
|
||
import re,sys
|
||
p=sys.argv[1]+'/index.html'; s=open(p,encoding='utf-8').read()
|
||
s=s.replace('src="/assets/','src="./assets/').replace('href="/assets/','href="./assets/')
|
||
s=s.replace('<script type="module"','<script src="./mock.js"></script>\n<script type="module"',1)
|
||
s=re.sub(r'<html[^>]*>','<html lang="zh-Hant" data-theme="dark">',s,count=1)
|
||
open(p,'w',encoding='utf-8').write(s)
|
||
PY
|
||
(cd "$W" && python3 -m http.server 8799 >/dev/null 2>&1) &
|
||
sleep 2
|
||
"$CHROME" --headless --disable-gpu --screenshot="$W/s.png" --window-size=1120,780 \
|
||
--hide-scrollbars --virtual-time-budget=3000 "http://localhost:8799/index.html" >/dev/null 2>&1
|
||
|
||
python3 - "$W/s.png" <<'PY'
|
||
import zlib,struct,sys
|
||
d=open(sys.argv[1],'rb').read(); pos=8; idat=b''; w=h=ct=0
|
||
while pos<len(d):
|
||
ln=struct.unpack('>I',d[pos:pos+4])[0]; t=d[pos+4:pos+8]
|
||
if t==b'IHDR': w,h,_,ct=struct.unpack('>IIBB',d[pos+8:pos+18])
|
||
if t==b'IDAT': idat+=d[pos+8:pos+8+ln]
|
||
pos+=12+ln
|
||
raw=zlib.decompress(idat); ch=4 if ct==6 else 3; stride=w*ch+1
|
||
rows=[]; prev=bytearray(w*ch)
|
||
for y in range(h):
|
||
f=raw[y*stride]; line=bytearray(raw[y*stride+1:(y+1)*stride])
|
||
for i in range(len(line)):
|
||
a=line[i-ch] if i>=ch else 0; b=prev[i]; c=prev[i-ch] if i>=ch else 0
|
||
if f==1: line[i]=(line[i]+a)&255
|
||
elif f==2: line[i]=(line[i]+b)&255
|
||
elif f==3: line[i]=(line[i]+(a+b)//2)&255
|
||
elif f==4:
|
||
pp=a+b-c; pa,pb,pc=abs(pp-a),abs(pp-b),abs(pp-c)
|
||
pr=a if (pa<=pb and pa<=pc) else (b if pb<=pc else c)
|
||
line[i]=(line[i]+pr)&255
|
||
rows.append(bytes(line)); prev=line
|
||
px=lambda x,y:tuple(rows[y][x*ch:x*ch+3])
|
||
# logo 現在用**裁淨版透明底** ⇒ 品牌區四周應該就是頁面底色,不該出現任何色塊。
|
||
# 取 logo 上方與下方各一點:若與側欄底色不同,代表又墊了底板或圖沒裁淨。
|
||
side = px(10, 300) # 側欄純底色
|
||
above, below = px(150, 6), px(150, 62)
|
||
worst = max(max(abs(a-b) for a,b in zip(side,p)) for p in (above, below))
|
||
print(f" 側欄底色 {side} / logo 上方 {above} / 下方 {below} / 最大落差 {worst}")
|
||
if worst > 10:
|
||
print(" ❌ logo 周圍出現色塊——底板沒去掉或用到未裁淨的圖"); sys.exit(1)
|
||
print(" ✅ logo 透明底、周圍無色塊")
|
||
# 深色模式有沒有生效:整體應該偏暗
|
||
if sum(px(600,400))/3 > 120:
|
||
print(" ❌ 深色模式沒生效(右側內容區偏亮)"); sys.exit(1)
|
||
print(" ✅ 深色模式生效")
|
||
PY
|