From b2bec0406fc5d12e06f14948e966cf70a2acbedf Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Sun, 24 May 2026 17:45:26 +0100 Subject: [PATCH] =?UTF-8?q?write(ui):=20=E5=85=A8=E5=A5=97=20dark=20?= =?UTF-8?q?=E4=B8=BB=E9=A2=98=EF=BC=8C=E9=85=8D=E8=89=B2=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=20notes=20/=20cube=20portal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 引入 :root --bg/--bg-elev/--bg-card/--border/--text/--accent 等 vars(跟 notes 一致) - 主要 surface:body / sidebar / editor / preview / input-bar / modal / mobile-bar - accent 紫 (#c084fc + #7c5cbf) 替代 #5566ee 蓝 - preview markdown:h2-h4 紫,inline code amber,pre block 加 border - splitter hover 用 accent-strong 紫 - 滚动条暗化 --- apps/write/frontend/src/styles.css | 177 ++++++++++++++++++----------- 1 file changed, 110 insertions(+), 67 deletions(-) diff --git a/apps/write/frontend/src/styles.css b/apps/write/frontend/src/styles.css index 4c809fb..d8caf07 100644 --- a/apps/write/frontend/src/styles.css +++ b/apps/write/frontend/src/styles.css @@ -1,17 +1,42 @@ +:root { + --bg: #0f0f0f; + --bg-elev: #161616; + --bg-card: #1a1a2e; + --bg-hover: #232342; + --bg-active: #2a1a3e; + --border: #2a2a3a; + --border-soft: #1f1f2a; + --text: #e0e0e0; + --text-dim: #a0a0a0; + --text-mute: #666; + --accent: #c084fc; + --accent-strong: #7c5cbf; + --accent-cyan: #06b6d4; + --accent-green: #4ade80; + --accent-amber: #f59e0b; + --accent-red: #ef4444; +} + * { box-sizing: border-box; } html, body, #app { height: 100%; margin: 0; width: 100%; overflow-x: hidden; } body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; - background: #fafafa; - color: #222; + background: var(--bg); + color: var(--text); font-size: 14px; + -webkit-font-smoothing: antialiased; } .app { max-width: 100vw; overflow-x: hidden; } button { font: inherit; cursor: pointer; } textarea, input { font: inherit; } +::-webkit-scrollbar { width: 8px; height: 8px; } +::-webkit-scrollbar-track { background: transparent; } +::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; } +::-webkit-scrollbar-thumb:hover { background: var(--text-mute); } + /* ====== layout ====== */ .app { @@ -21,8 +46,8 @@ textarea, input { font: inherit; } } .sidebar { - border-right: 1px solid #e5e5e5; - background: #fff; + border-right: 1px solid var(--border-soft); + background: var(--bg-elev); display: flex; flex-direction: column; min-width: 0; @@ -30,7 +55,7 @@ textarea, input { font: inherit; } .sidebar-header { padding: 14px 16px; - border-bottom: 1px solid #eee; + border-bottom: 1px solid var(--border-soft); display: flex; align-items: center; gap: 8px; @@ -38,13 +63,14 @@ textarea, input { font: inherit; } .sidebar-header h1 { margin: 0; font-size: 16px; font-weight: 600; } .sidebar-header .new-btn { margin-left: auto; - border: 1px solid #ddd; - background: #fff; + border: 1px solid var(--border); + background: var(--bg-elev); + color: var(--text-dim); padding: 4px 10px; border-radius: 6px; font-size: 13px; } -.sidebar-header .new-btn:hover { background: #f5f5f5; } +.sidebar-header .new-btn:hover { background: var(--bg-hover); color: var(--text); } .doc-list { flex: 1; overflow-y: auto; padding: 6px; } .doc-item { @@ -56,20 +82,21 @@ textarea, input { font: inherit; } display: flex; align-items: center; gap: 8px; + color: var(--text-dim); } -.doc-item:hover { background: #f3f3f3; } -.doc-item.active { background: #e8efff; } +.doc-item:hover { background: var(--bg-card); color: var(--text); } +.doc-item.active { background: var(--bg-active); color: var(--accent); } .doc-item .title { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } -.doc-item .meta { font-size: 11px; color: #888; } +.doc-item .meta { font-size: 11px; color: var(--text-mute); } .doc-item .del { border: none; background: transparent; - color: #c44; + color: var(--accent-red); font-size: 12px; visibility: hidden; } @@ -82,7 +109,7 @@ textarea, input { font: inherit; } grid-template-rows: 1fr 6px var(--input-h, 140px); min-width: 0; min-height: 0; - background: #fafafa; + background: var(--bg); overflow: hidden; } @@ -95,22 +122,18 @@ textarea, input { font: inherit; } grid-template-columns: var(--editor-fr, 1fr) 6px var(--preview-fr, 1fr); grid-template-rows: auto 1fr; min-height: 0; - border-bottom: 1px solid #e5e5e5; + border-bottom: 1px solid var(--border-soft); } /* 拖拽分隔条 */ .splitter { - background: #e5e5e5; + background: var(--border-soft); cursor: col-resize; transition: background 0.12s; user-select: none; } -.splitter:hover { background: #b0c5ff; } -.splitter-main { /* sidebar | workspace */ } -.splitter-editor { /* editor | preview */ } -.splitter-input { /* editor-pane | input-bar 横向分隔 */ - cursor: row-resize; -} +.splitter:hover { background: var(--accent-strong); } +.splitter-input { cursor: row-resize; } @media (max-width: 768px) { .splitter { display: none; } } @@ -118,8 +141,8 @@ textarea, input { font: inherit; } .title-row { grid-column: 1 / -1; padding: 10px 16px; - border-bottom: 1px solid #eee; - background: #fff; + border-bottom: 1px solid var(--border-soft); + background: var(--bg-elev); } .title-row input { width: 100%; @@ -128,7 +151,9 @@ textarea, input { font: inherit; } font-size: 16px; font-weight: 600; background: transparent; + color: var(--text); } +.title-row input::placeholder { color: var(--text-mute); } .editor, .preview { min-height: 0; @@ -136,10 +161,9 @@ textarea, input { font: inherit; } padding: 16px; } .editor { - border-right: 1px solid #e5e5e5; - background: #fff; + background: var(--bg-elev); + overflow-x: hidden; } -.editor { overflow-x: hidden; } .editor textarea { width: 100%; max-width: 100%; @@ -151,33 +175,40 @@ textarea, input { font: inherit; } font-size: 13px; line-height: 1.6; background: transparent; + color: var(--text); word-break: break-all; } +.editor textarea::placeholder { color: var(--text-mute); } .preview { - background: #fff; + background: var(--bg); + color: var(--text); line-height: 1.6; overflow-x: hidden; word-wrap: break-word; overflow-wrap: anywhere; } -.preview h1, .preview h2, .preview h3 { margin: 18px 0 8px; } +.preview h1, .preview h2, .preview h3 { margin: 18px 0 8px; color: var(--accent); } .preview p { margin: 8px 0; } +.preview a { color: var(--accent-cyan); } +.preview strong { color: var(--accent); } .preview pre { - background: #f5f5f5; padding: 10px; border-radius: 6px; + background: var(--bg-elev); padding: 10px; border-radius: 6px; font-size: 12px; overflow-x: auto; max-width: 100%; + border: 1px solid var(--border-soft); } -.preview code { background: #f5f5f5; padding: 1px 4px; border-radius: 3px; font-size: 12px; } -.preview pre code { background: transparent; padding: 0; word-wrap: normal; overflow-wrap: normal; } -.preview blockquote { border-left: 3px solid #ddd; margin: 8px 0; padding: 4px 12px; color: #555; } +.preview code { background: var(--bg-elev); padding: 1px 4px; border-radius: 3px; font-size: 12px; color: var(--accent-amber); } +.preview pre code { background: transparent; padding: 0; word-wrap: normal; overflow-wrap: normal; color: var(--text); } +.preview blockquote { border-left: 3px solid var(--accent-strong); margin: 8px 0; padding: 4px 12px; color: var(--text-dim); } .preview img { max-width: 100%; height: auto; } .preview table { display: block; max-width: 100%; overflow-x: auto; } +.preview hr { border: none; border-top: 1px solid var(--border); margin: 16px 0; } /* ====== input bar ====== */ .input-bar { - background: #fff; - border-top: 1px solid #e5e5e5; + background: var(--bg-elev); + border-top: 1px solid var(--border-soft); padding: 10px 12px; } .input-row { display: flex; gap: 8px; align-items: flex-end; min-width: 0; } @@ -185,39 +216,43 @@ textarea, input { font: inherit; } flex: 1 1 0; min-width: 0; min-height: 40px; - max-height: 160px; + max-height: 100%; resize: none; padding: 9px 12px; - border: 1px solid #ddd; + border: 1px solid var(--border); + background: var(--bg); + color: var(--text); border-radius: 8px; outline: none; font-size: 14px; line-height: 1.4; } -.input-row textarea:focus { border-color: #6b7cff; } +.input-row textarea::placeholder { color: var(--text-mute); } +.input-row textarea:focus { border-color: var(--accent-strong); } .btn { height: 40px; padding: 0 14px; border-radius: 8px; - border: 1px solid #ddd; - background: #fff; + border: 1px solid var(--border); + background: var(--bg-elev); + color: var(--text-dim); font-size: 14px; } -.btn:hover { background: #f5f5f5; } -.btn.primary { background: #5566ee; border-color: #4455dd; color: #fff; } -.btn.primary:hover { background: #4455dd; } -.btn.primary:disabled { background: #aaa; border-color: #aaa; cursor: not-allowed; } +.btn:hover { background: var(--bg-hover); color: var(--text); } +.btn.primary { background: var(--accent-strong); border-color: var(--accent-strong); color: #fff; } +.btn.primary:hover { background: var(--accent); border-color: var(--accent); color: #fff; } +.btn.primary:disabled { background: var(--bg-card); border-color: var(--border); color: var(--text-mute); cursor: not-allowed; } .btn.mic { width: 44px; padding: 0; } -.btn.mic.on { background: #ee5566; border-color: #dd4455; color: #fff; } +.btn.mic.on { background: var(--accent-red); border-color: var(--accent-red); color: #fff; } .status { font-size: 12px; - color: #666; + color: var(--text-mute); padding: 4px 4px 0; min-height: 18px; } -.status.err { color: #c44; } +.status.err { color: var(--accent-red); } /* ====== mobile-only chrome ====== */ @@ -226,14 +261,15 @@ textarea, input { font: inherit; } align-items: center; gap: 8px; padding: 8px 12px; - background: #fff; - border-bottom: 1px solid #e5e5e5; + background: var(--bg-elev); + border-bottom: 1px solid var(--border-soft); padding-top: max(8px, env(safe-area-inset-top)); } .mobile-bar .hamburger, .mobile-bar .pane-tabs button { - border: 1px solid #ddd; - background: #fff; + border: 1px solid var(--border); + background: var(--bg-elev); + color: var(--text-dim); border-radius: 6px; font-size: 14px; padding: 6px 10px; @@ -244,9 +280,9 @@ textarea, input { font: inherit; } gap: 4px; } .mobile-bar .pane-tabs button.active { - background: #5566ee; + background: var(--accent-strong); color: #fff; - border-color: #4455dd; + border-color: var(--accent-strong); } .mobile-bar .doc-title { flex: 1 1 0; @@ -257,12 +293,12 @@ textarea, input { font: inherit; } font-weight: 600; font-size: 14px; } -.mobile-bar .doc-title input { min-width: 0; } +.mobile-bar .doc-title input { min-width: 0; color: var(--text); } .sidebar-backdrop { display: none; position: fixed; inset: 0; - background: rgba(0,0,0,0.35); + background: rgba(0,0,0,0.55); z-index: 50; } @@ -283,24 +319,22 @@ textarea, input { font: inherit; } top: 0; left: 0; bottom: 0; width: 78vw; max-width: 320px; - border-right: 1px solid #e5e5e5; + border-right: 1px solid var(--border-soft); border-bottom: none; transform: translateX(-100%); transition: transform 0.2s ease; z-index: 60; - box-shadow: 2px 0 8px rgba(0,0,0,0.1); + box-shadow: 2px 0 8px rgba(0,0,0,0.5); } .app.drawer-open .sidebar { transform: translateX(0); } .app.drawer-open .sidebar-backdrop { display: block; } - /* workspace fills the screen; editor + preview overlay each other, - pane-tabs picks which one shows */ .editor-pane { grid-template-columns: 1fr; grid-template-rows: 1fr; position: relative; } - .title-row { display: none; } /* title shows in the mobile-bar instead */ + .title-row { display: none; } .editor, .preview { grid-column: 1; @@ -314,14 +348,13 @@ textarea, input { font: inherit; } .app.pane-editor .editor { display: block; } .app.pane-preview .preview { display: block; } - /* input bar honors safe area at bottom */ .input-bar { padding-bottom: max(10px, env(safe-area-inset-bottom)); } .input-row textarea { - font-size: 16px; /* iOS won't zoom in if >= 16px */ + font-size: 16px; } - .btn { height: 44px; } /* easier thumb target */ + .btn { height: 44px; } .btn.mic { width: 48px; } } @@ -329,17 +362,27 @@ textarea, input { font: inherit; } .modal-backdrop { position: fixed; inset: 0; - background: rgba(0,0,0,0.4); + background: rgba(0,0,0,0.7); display: flex; align-items: center; justify-content: center; z-index: 100; + backdrop-filter: blur(2px); } .modal { - background: #fff; padding: 20px; border-radius: 10px; + background: var(--bg-card); + border: 1px solid var(--border); + padding: 24px; + border-radius: 12px; width: 360px; max-width: 90vw; + box-shadow: 0 12px 40px rgba(0,0,0,0.5); } -.modal h2 { margin: 0 0 12px; font-size: 16px; } +.modal h2 { margin: 0 0 12px; font-size: 16px; color: var(--accent); } .modal input { - width: 100%; padding: 8px 10px; border: 1px solid #ddd; border-radius: 6px; + width: 100%; padding: 9px 12px; + border: 1px solid var(--border); + background: var(--bg-elev); + color: var(--text); + border-radius: 6px; margin-bottom: 12px; outline: none; } +.modal input:focus { border-color: var(--accent-strong); } .modal-actions { display: flex; gap: 8px; justify-content: flex-end; }