t193:daemon UI 換 Wails——CIS 是硬要求,fyne 做不到
leo 2026-08-04 看過 v0.16.0 畫面後:
「功能都有了,但美感非常糟糕⋯⋯跟 CIS 完全無關,每個功能都開一個小小的 popup 視窗,
非常缺乏整體感,這要理解的是原始的技術選擇是否出錯?」
「我的要求是符合 CIS,在風格上跟 portal 一樣」
「CIS 已經提供規範,你做的連 Logo 都沒放上去,這跟美不美有關係嗎?
要求放進 CIS 是硬要求,你做為檢查有嗎?沒有怎麼交貨?」
## 我的兩個錯
1. **動工前沒提醒做不到**——decisions-summary.md:314 的 D-daemon-UI
是我 07-27 自己寫的調研(結論:fyne 全自繪、CSS 套不進去),寫完就沒再看。
今天動工前該查它卻直接開寫,浪費 leo 的時間與 token。
2. **沒做 CIS 檢查就交貨**——連 logo 都沒放。
## 換 Wails(WebView 殼)
前端就是 HTML/CSS ⇒ 可以直接用 portal 那份色票與 lockup。
- style.css 的色票/字體/紙張紋理**逐字取自** portal 的 :root
(matrix/arcrun:console-ui/public/portal/index.html),不自創任何顏色
- CIS lockup 官方 PNG,淺色 ink 版/深色 paper 版,切換規則同 portal
(避開 08-01 作廢的自產 SVG——字腔缺失)
- 對話框改**內嵌覆蓋層**,不再每個功能開一個小 popup
- 原生資料夾選擇器(macOS powerbox 會自動授予該資料夾存取權,
fyne 自繪 picker 拿不到;未來上 Mac App Store 是硬需求)
- 同步中的圓點會呼吸 ⇒ 看得出來在動(issue #17)
- 無帳號時是 onboarding 引導,不是空白面板
## 連線邏輯逐字沿用,不重寫
connect.go 的 normalizePortalURL/fetchConfigByLogin 取自 arcrun-tray/main.go,
含 t86 個資外洩事故的防線(不同實例=新增帳號,絕不覆蓋舊帳號的資料夾)。
今天已犯過一次「重寫別人修好的東西還修得更差」,不再犯第二次。
## 新增 check-cis.sh(交貨前必跑)
機械檢查六類:官方色票逐個到齊/**不准出現非 CIS 色**/logo 真的放進去/
不可用作廢 SVG/深色模式/字體與紙張紋理同 portal/app icon。
實跑 14 項全過。以後「沒跑過就不准交」。
⚠️ 未驗:實際畫面要 leo 開來看(我開不了視窗)。
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
/* Arcrun 桌面 App — 樣式(t193)
|
||||
*
|
||||
* 🔴 leo 2026-08-04:「我的要求是**符合 CIS**,在風格上**跟 portal 一樣**」
|
||||
* 「CIS 已經提供規範,你做的**連 Logo 都沒放上去**,這跟美不美有關係嗎?
|
||||
* 要求放進 CIS 是**硬要求**,你做為檢查有嗎?沒有怎麼交貨?」
|
||||
*
|
||||
* ⇒ 本檔的色票/字體/背景紋理**逐字取自 portal**
|
||||
* (matrix/arcrun:console-ui/public/portal/index.html 的 :root 區塊),
|
||||
* **不自創任何顏色**。要改就去改 portal 那份、再同步過來。
|
||||
*
|
||||
* 這也是換掉 fyne 的理由:fyne 全自繪、CSS 套不進去,
|
||||
* 換成 Wails(WebView)後 daemon 與 portal 才可能是**同一套視覺**。
|
||||
*/
|
||||
|
||||
:root {
|
||||
--paper-a: #FDFCFB; --paper-b: #F2F1ED;
|
||||
--ink: #17181A; --ink-rgb: 23,24,26;
|
||||
--amber: #B04A2F; --amber-rgb: 176,74,47;
|
||||
--ok: #1d7a48; --ok-rgb: 29,122,72;
|
||||
--err: #b03a26; --err-rgb: 176,58,38;
|
||||
--well: rgba(23,24,26,.06); --well2: rgba(23,24,26,.08);
|
||||
}
|
||||
:root[data-theme="dark"] {
|
||||
--paper-a: #1b1c1e; --paper-b: #1e1f21;
|
||||
--ink: #FDFCFB; --ink-rgb: 253,252,251;
|
||||
--amber: #D9784F; --amber-rgb: 217,120,79;
|
||||
--ok: #7fe0a8; --ok-rgb: 63,190,120;
|
||||
--err: #e58575; --err-rgb: 217,95,76;
|
||||
--well: rgba(0,0,0,.25); --well2: rgba(0,0,0,.3);
|
||||
}
|
||||
|
||||
/* portal 的紙張紋理背景——三站一致的識別(不是裝飾,是 CIS 的一部分) */
|
||||
html, body {
|
||||
margin: 0; height: 100%;
|
||||
background: repeating-linear-gradient(0deg,
|
||||
var(--paper-a) 0px, var(--paper-a) 3px,
|
||||
var(--paper-b) 3px, var(--paper-b) 4px);
|
||||
color: var(--ink);
|
||||
font-family: -apple-system, "IBM Plex Sans", "PingFang TC", "Noto Sans TC",
|
||||
"Microsoft JhengHei", system-ui, sans-serif;
|
||||
font-size: 16px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
overflow: hidden;
|
||||
}
|
||||
input, textarea, button, select { font-family: inherit; }
|
||||
::placeholder { color: rgba(var(--ink-rgb), .35); }
|
||||
input:focus, select:focus { outline: 2px solid rgba(var(--amber-rgb), .5); outline-offset: 1px; }
|
||||
a { color: var(--amber); }
|
||||
.muted { color: rgba(var(--ink-rgb), .55); }
|
||||
.dim { color: rgba(var(--ink-rgb), .4); }
|
||||
|
||||
/* ── 版面:上(品牌+狀態)/中(可捲清單)/下(動作列)── */
|
||||
#app { display: flex; flex-direction: column; height: 100vh; }
|
||||
|
||||
header {
|
||||
padding: 18px 24px 14px;
|
||||
border-bottom: 1px solid rgba(var(--ink-rgb), .1);
|
||||
display: flex; align-items: flex-start; gap: 20px;
|
||||
}
|
||||
/* CIS lockup:淺色用 ink 版、深色用 paper 版(與 portal 同一組 PNG、同一套切換規則)。
|
||||
⚠️ 不可用自產的 SVG 描邊版(字腔會缺,08-01 已作廢,見 arcrun-cis/README.md)。 */
|
||||
.brand img { height: 26px; display: block; }
|
||||
.brand .wm-paper { display: none; }
|
||||
:root[data-theme="dark"] .brand .wm-ink { display: none; }
|
||||
:root[data-theme="dark"] .brand .wm-paper { display: block; }
|
||||
|
||||
.status { flex: 1; min-width: 0; }
|
||||
.status .big { font-size: 17px; font-weight: 600; letter-spacing: .02em; }
|
||||
.status .sub { margin-top: 4px; font-size: 13.5px; color: rgba(var(--ink-rgb), .5); }
|
||||
/* 同步中會呼吸——「看得出來在動」(issue #17) */
|
||||
.status .big.syncing::after {
|
||||
content: ""; display: inline-block; width: 7px; height: 7px; margin-left: 9px;
|
||||
border-radius: 50%; background: var(--amber); vertical-align: middle;
|
||||
animation: pulse 1.1s ease-in-out infinite;
|
||||
}
|
||||
@keyframes pulse { 0%,100% { opacity: .25 } 50% { opacity: 1 } }
|
||||
|
||||
/* 按鈕:Relation 是**唯一重點色**,CIS 規定 ≤ 一個畫面的 5% ⇒ 只有主要動作用它 */
|
||||
button {
|
||||
border: 1px solid rgba(var(--ink-rgb), .16);
|
||||
background: transparent; color: var(--ink);
|
||||
padding: 8px 14px; border-radius: 8px; font-size: 14px; cursor: pointer;
|
||||
transition: background .12s, border-color .12s;
|
||||
}
|
||||
button:hover { background: var(--well); }
|
||||
button.primary {
|
||||
background: var(--amber); border-color: var(--amber);
|
||||
color: #FDFCFB; font-weight: 600;
|
||||
}
|
||||
button.primary:hover { filter: brightness(1.06); }
|
||||
button.ghost { border-color: transparent; color: rgba(var(--ink-rgb), .5); padding: 6px 8px; }
|
||||
button.ghost:hover { color: var(--err); background: transparent; }
|
||||
|
||||
/* ── 中:資料夾清單(leo:「幾十個,根本塞不下」⇒ 這一區才捲動)── */
|
||||
main { flex: 1; overflow-y: auto; padding: 6px 0; }
|
||||
|
||||
.acct {
|
||||
padding: 16px 24px 6px;
|
||||
display: flex; align-items: baseline; gap: 10px;
|
||||
}
|
||||
.acct .name { font-size: 15px; font-weight: 600; }
|
||||
.acct .host { font-size: 12.5px; color: rgba(var(--ink-rgb), .4); font-family: ui-monospace, Menlo, monospace; }
|
||||
|
||||
.folder {
|
||||
margin: 0 16px 6px; padding: 11px 14px;
|
||||
background: var(--well); border-radius: 10px;
|
||||
display: flex; align-items: center; gap: 12px;
|
||||
}
|
||||
.folder .path { flex: 1; min-width: 0; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.folder .tag { font-size: 12px; color: var(--ok); white-space: nowrap; }
|
||||
|
||||
/* 空狀態=onboarding(不是空白面板) */
|
||||
.empty { padding: 56px 32px; text-align: center; }
|
||||
.empty .t { font-size: 17px; font-weight: 600; margin-bottom: 10px; }
|
||||
.empty .d { font-size: 14px; color: rgba(var(--ink-rgb), .55); line-height: 1.9; margin-bottom: 22px; }
|
||||
|
||||
footer {
|
||||
padding: 12px 24px; border-top: 1px solid rgba(var(--ink-rgb), .1);
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
}
|
||||
footer .spacer { flex: 1; }
|
||||
footer .ver { font-size: 12.5px; color: rgba(var(--ink-rgb), .35); font-family: ui-monospace, Menlo, monospace; }
|
||||
|
||||
/* 對話框:**內嵌覆蓋層**,不是另開一個小 popup 視窗
|
||||
(leo:「每個功能都開一個小小的 popup 視窗,非常缺乏整體感」) */
|
||||
.overlay {
|
||||
position: fixed; inset: 0; background: rgba(0,0,0,.42);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
opacity: 0; pointer-events: none; transition: opacity .14s;
|
||||
}
|
||||
.overlay.on { opacity: 1; pointer-events: auto; }
|
||||
.sheet {
|
||||
width: min(520px, calc(100vw - 64px));
|
||||
background: var(--paper-a); color: var(--ink);
|
||||
border: 1px solid rgba(var(--ink-rgb), .12);
|
||||
border-radius: 14px; padding: 24px;
|
||||
box-shadow: 0 18px 50px rgba(0,0,0,.28);
|
||||
}
|
||||
.sheet h2 { margin: 0 0 6px; font-size: 17px; }
|
||||
.sheet p { margin: 0 0 16px; font-size: 14px; color: rgba(var(--ink-rgb), .55); line-height: 1.7; }
|
||||
.sheet label { display: block; font-size: 13px; margin: 12px 0 5px; color: rgba(var(--ink-rgb), .6); }
|
||||
.sheet input[type=text], .sheet input[type=password] {
|
||||
width: 100%; box-sizing: border-box; padding: 9px 11px; font-size: 14px;
|
||||
border: 1px solid rgba(var(--ink-rgb), .18); border-radius: 8px;
|
||||
background: var(--paper-b); color: var(--ink);
|
||||
}
|
||||
.sheet .radio { display: flex; align-items: flex-start; gap: 9px; margin: 10px 0; font-size: 14px; cursor: pointer; }
|
||||
.sheet .radio input { margin-top: 3px; }
|
||||
.sheet .acts { display: flex; justify-content: flex-end; gap: 8px; margin-top: 22px; }
|
||||
.sheet .err { color: var(--err); font-size: 13px; margin-top: 10px; }
|
||||
Reference in New Issue
Block a user