9cd0adab22
服務 J-1 / S6「我丟進去的檔案,查得到」的考題 G-6.2: 「要嘛查得到,要嘛**當場被告知這種檔案還不支援**,不准安靜地略過。」 本次只做後半句(轉檔本體另有人閘,等 leo 裁「那段 Go 住哪裡」)。 ## 真實現況比記載更糟 t16 寫的「PDF 被靜默略過」已不成立(t73 的轉檔層把 pdf/docx/xlsx/csv/pptx 都接上了,實測 2 頁中文 PDF 完整抽出)。**真正還在沉默的是別的東西**: 副檔名不在 allowedExt 的檔案在 scan.go 直接 `return nil`—— 不進事件、不進 manifest、不進 status、不進畫面。 使用者丟一份 .doc 進去,從頭到尾一個字都沒有。 實測基線(真檔):丟 .pdf/.md/.doc/.key/.jpg 進資料夾, `collector scan` 只吐出 pdf 與 md 兩個事件,另外三個檔沒留下任何痕跡。 ## 改了什麼 - scan.go:白名單閘不再是死巷。像文件的(.doc/.xls/.ppt/.pages/.key/ .numbers/.odt/.ods/.odp/.rtf/.epub/.wpd/.msg/.eml)逐檔留名; 其餘(圖片/影音/程式碼)只計總數——**避免 Obsidian 附件庫炸出幾百行噪音**。 - 兩個新欄位標 `json:"-"`:collector-trigger schema 是 additionalProperties:false,且 BuildSendablePayload 是淺拷貝 ⇒ 有 tag 就會漏到雲端被擋。這是給本機使用者看的,不上 wire。 - direct.go → status.json → App 首頁一張卡:講檔名與格式(「舊版報告.doc (舊版 Word)」),並告訴他不用重丟、也給替代路(另存成 PDF/.docx)。 - 刻意不進 manifest、不走 CarryForwardActivity:每輪由檔案系統重算, 不製造 t195 那種「跨輪欄位漏 carry 就靜默歸零」的債。 ## 順手修掉一個會讓驗收失效的回歸 同綑的 arcrun-collector 一路自稱 `dev`:退役 fyne 版 (arcrun-tray/build-mac.sh:24,t150/t72)本來就有版本注入, t194 換 Wails 時沒帶過來,Mac 與 Windows 兩邊都掉。 **幹活的是 collector**——它不報版本,就沒人能判斷修復有沒有到使用者手上。 ## 實測 - go test ./... 135 過 0 敗(新增 10 條:scan 5+首頁文案 5) - check-cis / check-render / check-tray 三閘全過;淺色深色都抓過畫面 - 從 **DMG 裡那支** collector 實跑:Info.plist 0.18.6、 collector 回報 v0.18.6 (build 20260806-0101)、 status.json 吐出 skipped_docs=[簡報.key, 舊版報告.doc]、other=1 ⚠️ 未出貨:推 bundles repo 在 GitHub,要 leo 開 D20 閘。 DMG 已備妥 dist/Arcrun-v0.18.6.dmg。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
223 lines
11 KiB
CSS
223 lines
11 KiB
CSS
/* Arcrun 桌面 App — **版面**樣式(t193)
|
||
*
|
||
* 🔴 色票/字體/紙張紋理**不在這裡**——那些在 `arcrun-cis.css`(唯一真相源
|
||
* = InkStoneCo/arcrun-cis/css/arcrun-cis.css,portal/landing/install 共用同一份)。
|
||
* leo 08-04:「不會這裡又寫了一個新的 CSS?前面剛剛才說過**不要創造新的**?」
|
||
* ⇒ 本檔**只准出現版面與元件**,一律用 var(--...),**不准寫任何 hex 色碼**。
|
||
*
|
||
* 版面(leo 08-04 指定,附 Google Drive 截圖):
|
||
* 「可以完全模仿 gdrive,**左方側邊欄,在右方替換頁面**,
|
||
* 你現在做成在底下產生 nav bar,幾乎沒看過這種 nav bar 在下方的,會令人十分不習慣」
|
||
*/
|
||
|
||
html, body { overflow: hidden; height: 100%; }
|
||
|
||
/* ── 骨架:左欄固定、右側換頁 ── */
|
||
#app { display: flex; height: 100vh; }
|
||
|
||
#side {
|
||
width: 216px; flex: none; /* 同 portal #sidenav */
|
||
display: flex; flex-direction: column;
|
||
padding: 22px 0 14px;
|
||
border-right: 2px solid rgba(var(--amber-rgb), .35); /* portal #sidenav 同款 */
|
||
}
|
||
/* 🔴 lockup(CIS,leo 三次點名)——**用裁淨版**,且**不要底板**:
|
||
① 官方原始 PNG(1840x560)**只有 32% 高度是實際字形**,上下大量留白
|
||
⇒ 同樣 height 看起來字很小,且留白會露出底板=leo 看到的白底。
|
||
portal 早就改用**裁淨版**(986x176,比例 5.602,四邊裁到字腔邊緣)。
|
||
⇒ 直接用 portal 那兩張(從它的 base64 抽出,存在 arcrun-cis/trimmed/)。
|
||
② 兩張裁淨版**都是透明底** ⇒ 深色模式**不需要**也**不可以**再墊 Ink 底板。
|
||
③ 尺寸/切換規則逐字照 portal 的 #sidenav .logo。 */
|
||
/* 🔴 leo:「這是 Logo 旁邊**大量空白**」——圖本身已裁淨(實測四邊留白 0),
|
||
空白來自**版面**:側欄 216px 扣 padding 剩 152px,而 logo 高 24px 時只有 134px。
|
||
⇒ 讓 lockup **填滿可用寬度**(高度由 5.602 的比例自動決定,約 27px),
|
||
並照 CIS「clear space = one chevron height」在下方留呼吸空間。 */
|
||
#side .brand { display: flex; color: var(--ink); padding: 0 32px 22px; }
|
||
#side .brand img { width: 100%; height: auto; display: block; }
|
||
#side .brand .wm-paper { display: none; }
|
||
:root[data-theme="dark"] #side .brand .wm-ink { display: none; }
|
||
:root[data-theme="dark"] #side .brand .wm-paper { display: block; }
|
||
|
||
/* 側邊欄選中態:**逐字照 portal 的 #sidenav .nav.on**
|
||
(leo:「參考現在 Portal 的格式⋯⋯這個比現在膠囊反紅精緻,
|
||
重點是**跟 portal 的形象符合**」)
|
||
= 不是膠囊實心,而是:amber 字色 + 8% amber 底 + 右側 2px amber 邊。 */
|
||
#side nav { display: flex; flex-direction: column; gap: 4px; }
|
||
#side .nav {
|
||
display: flex; align-items: center; gap: 10px;
|
||
padding: 13px 24px; font-size: 15px; letter-spacing: .08em;
|
||
color: rgba(var(--ink-rgb), .6);
|
||
border-right: 2px solid transparent;
|
||
cursor: pointer; user-select: none;
|
||
}
|
||
#side .nav:hover { color: var(--ink); }
|
||
#side .nav.on {
|
||
color: var(--amber);
|
||
background: rgba(var(--amber-rgb), .08);
|
||
border-right-color: var(--amber);
|
||
font-weight: 600;
|
||
}
|
||
#side .nav .ic { width: 17px; text-align: center; font-size: 14px; opacity: .85; }
|
||
#side .nav .cnt { margin-left: auto; font-size: 11.5px; opacity: .7; font-family: ui-monospace, Menlo, monospace; }
|
||
#side .nav .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
|
||
#side .side-foot { margin-top: auto; padding: 12px 22px 0; }
|
||
#side .ver { font-size: 12px; color: rgba(var(--ink-rgb), .35); font-family: ui-monospace, Menlo, monospace; }
|
||
|
||
#content { flex: 1; min-width: 0; display: flex; flex-direction: column; }
|
||
|
||
header {
|
||
padding: 22px 28px 16px;
|
||
display: flex; align-items: flex-start; gap: 18px;
|
||
border-bottom: 1px solid rgba(var(--ink-rgb), .1);
|
||
}
|
||
.status { flex: 1; min-width: 0; }
|
||
.status .big { font-size: 18px; font-weight: 600; letter-spacing: .02em; }
|
||
.status .sub { margin-top: 5px; 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 } }
|
||
|
||
main { flex: 1; overflow-y: auto; padding: 20px 28px 28px; }
|
||
|
||
/* ── 元件:規格**逐字對齊 portal**(leo:「網頁的按鈕比較精緻,跟現有的差異較大」)──
|
||
portal: .btn { padding:13px; font-size:16px; font-weight:600; border-radius:10px; border:none; background:var(--amber) }
|
||
.btn3 { padding:11px 16px; font-size:15px; border-radius:10px; border:1px solid rgba(ink,.25); background:none }
|
||
這裡只把 padding 依桌面視窗略收(網頁是手機優先、桌面不需要那麼大的點擊區)。 */
|
||
button {
|
||
padding: 10px 16px; font-size: 14.5px; border-radius: 10px;
|
||
border: 1px solid rgba(var(--ink-rgb), .25);
|
||
background: none; color: rgba(var(--ink-rgb), .7);
|
||
cursor: pointer; transition: background .12s, color .12s, border-color .12s;
|
||
}
|
||
button:hover { background: var(--well); color: var(--ink); }
|
||
button:disabled { opacity: .45; cursor: default; }
|
||
button.primary {
|
||
border: none; background: var(--amber); color: var(--knob); font-weight: 600;
|
||
}
|
||
button.primary:hover { filter: brightness(1.06); background: var(--amber); }
|
||
button.ghost {
|
||
border-color: transparent; background: none;
|
||
color: rgba(var(--ink-rgb), .45); padding: 7px 10px; font-size: 13px;
|
||
}
|
||
button.ghost:hover { color: var(--err); background: transparent; }
|
||
|
||
/* 主題切換(portal 有,daemon 也要有——leo:「它有淺色佈景?」
|
||
⇒ 是,portal **預設淺色**,深色由使用者切換並存 localStorage。 */
|
||
#themeBtn { padding: 7px 11px; font-size: 13px; }
|
||
|
||
.card {
|
||
background: var(--well); border-radius: 12px;
|
||
padding: 18px 20px; margin-bottom: 14px;
|
||
}
|
||
.card h3 { margin: 0 0 4px; font-size: 15px; }
|
||
.card .d { font-size: 13.5px; color: rgba(var(--ink-rgb), .55); line-height: 1.8; }
|
||
.card .row { display: flex; align-items: center; gap: 12px; }
|
||
.card .row .g { flex: 1; min-width: 0; }
|
||
|
||
/* 「這些檔案還讀不了」清單(G-6.2)。刻意**不用紅色/錯誤色**:
|
||
這不是使用者做錯了什麼,是我們還沒支援——語氣要是告知,不是指責。 */
|
||
.skiplist { margin: 10px 0 0; padding: 0; list-style: none; }
|
||
.skiplist li {
|
||
font-size: 13.5px; padding: 6px 0;
|
||
border-top: 1px solid rgba(var(--ink-rgb), .08);
|
||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||
}
|
||
.skiplist li.more { color: rgba(var(--ink-rgb), .45); }
|
||
|
||
.acct { padding: 4px 2px 8px; display: flex; align-items: baseline; gap: 10px; }
|
||
.acct .name { font-size: 14.5px; font-weight: 600; }
|
||
.acct .host { font-size: 12px; color: rgba(var(--ink-rgb), .4); font-family: ui-monospace, Menlo, monospace; }
|
||
|
||
.folder {
|
||
padding: 11px 15px; margin-bottom: 7px;
|
||
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; }
|
||
|
||
.big-num { font-size: 26px; font-weight: 600; letter-spacing: .01em; }
|
||
.kv { display: flex; gap: 26px; margin-top: 4px; }
|
||
.kv .k { font-size: 12.5px; color: rgba(var(--ink-rgb), .45); }
|
||
|
||
.empty { padding: 52px 24px; 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: 20px; }
|
||
|
||
label.radio { display: flex; align-items: flex-start; gap: 10px; margin: 12px 0; font-size: 14px; cursor: pointer; }
|
||
label.radio input { margin-top: 3px; }
|
||
input[type=text], input[type=password] {
|
||
width: 100%; box-sizing: border-box; padding: 9px 12px; font-size: 14px;
|
||
border: 1px solid rgba(var(--ink-rgb), .18); border-radius: 8px;
|
||
background: var(--paper-b); color: var(--ink);
|
||
}
|
||
.field { margin: 14px 0; }
|
||
.field .lb { font-size: 13px; margin-bottom: 6px; color: rgba(var(--ink-rgb), .6); }
|
||
.err { color: var(--err); font-size: 13px; margin-top: 10px; }
|
||
.acts { display: flex; gap: 8px; margin-top: 18px; }
|
||
|
||
/* 覆蓋層:只給「確認刪除」這類必須打斷的動作,設定頁一律走右側換頁 */
|
||
.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(460px, calc(100vw - 64px));
|
||
background: var(--paper-a); color: var(--ink);
|
||
border: 1px solid rgba(var(--ink-rgb), .12);
|
||
border-radius: 14px; padding: 22px 24px;
|
||
box-shadow: 0 18px 50px rgba(0,0,0,.28);
|
||
}
|
||
.sheet h2 { margin: 0 0 6px; font-size: 16.5px; }
|
||
.sheet p { margin: 0 0 4px; font-size: 14px; color: rgba(var(--ink-rgb), .55); line-height: 1.7; }
|
||
.sheet .acts { justify-content: flex-end; }
|
||
|
||
/* ── 每個知識庫一個獨立分頁(leo 08-04)──
|
||
「同步資料夾那個頁面如果有 2 個庫,每個庫有 30 個同步資料夾,**放得下嗎**?
|
||
應該**一個庫有一個頁簽**或是其他方法可以切換。」
|
||
「『加入資料夾』按下後**會加在哪個帳號**?**有必要每個帳號有獨立的一個頁面**。」
|
||
⇒ 側邊欄直接列出每個知識庫;點進去就是那個庫的頁,動作全部作用在它身上,不會加錯。 */
|
||
#side .sec {
|
||
padding: 16px 26px 6px; font-size: 11.5px; letter-spacing: .08em;
|
||
color: rgba(var(--ink-rgb), .35);
|
||
}
|
||
#side .nav .cnt {
|
||
margin-left: auto; font-size: 11.5px; opacity: .7;
|
||
font-family: ui-monospace, Menlo, monospace;
|
||
}
|
||
#side .nav .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
|
||
/* 每個庫的頁首:庫名+網址+「開啟知識庫網頁」(leo:不該放首頁,要在各庫上方) */
|
||
.libhead {
|
||
display: flex; align-items: center; gap: 14px;
|
||
padding-bottom: 14px; margin-bottom: 14px;
|
||
border-bottom: 1px solid rgba(var(--ink-rgb), .1);
|
||
}
|
||
.libhead .g { flex: 1; min-width: 0; }
|
||
.libhead .nm { font-size: 16px; font-weight: 600; }
|
||
.libhead .host {
|
||
font-size: 12px; color: rgba(var(--ink-rgb), .4);
|
||
font-family: ui-monospace, Menlo, monospace;
|
||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||
}
|
||
|
||
/* 狀態時間軸(leo:「如果看守、發現變化、萃取、上傳… 不同 status 在哪裡顯示?」) */
|
||
.steps { display: flex; flex-direction: column; gap: 2px; margin-top: 12px; }
|
||
.step { display: flex; align-items: center; gap: 11px; padding: 7px 0; font-size: 14px; }
|
||
.step .dot {
|
||
width: 9px; height: 9px; border-radius: 50%; flex: none;
|
||
background: rgba(var(--ink-rgb), .18);
|
||
}
|
||
.step.done .dot { background: var(--ok); }
|
||
.step.now .dot { background: var(--amber); animation: pulse 1.1s ease-in-out infinite; }
|
||
.step.now { font-weight: 600; }
|
||
.step .t { flex: 1; }
|
||
.step .m { font-size: 12.5px; color: rgba(var(--ink-rgb), .45); }
|