mirror of
https://github.com/hectorqin/reader.git
synced 2026-11-10 21:11:08 +08:00
feat(web): primary buttons fill with brand-text so they outweigh secondaries
The light themes' brand fill (#F2B79F etc.) is softer than the white secondary button beside it, so 保存/播放 read as the quieter choice. Primary buttons now use brand-text with bg on it, the same recipe as danger, and a pair the token spec already holds to 4.5:1 in every theme. brand stays for state fills (selected, progress, switches). Spec updated (rule 6). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
90e01fa518
commit
92cfabe740
6 files changed
+23
-15
No files matched your search
@@ -34,10 +34,10 @@ Reader V3 内置 4 个主题,每个主题含浅色和深色两套取值,共
|
||||
| ink | `--color-ink` | 正文与标题 |
|
||||
| muted | `--color-muted` | 次要文字、图标 |
|
||||
| line | `--color-line` | 分隔线、描边 |
|
||||
| brand | `--color-brand` | 主按钮底色、选中态、进度条填充(只作填充,不作文字色) |
|
||||
| brand | `--color-brand` | 选中态、进度条、开关等状态填充(只作填充,不作文字色) |
|
||||
| brand-soft | `--color-brand-soft` | 选中底色、标签底色 |
|
||||
| on-brand | `--color-on-brand` | 品牌色填充上的文字和图标 |
|
||||
| brand-text | `--color-brand-text` | 品牌色的文字、图标、链接(新增) |
|
||||
| brand-text | `--color-brand-text` | 品牌色的文字、图标、链接;主按钮底色(新增) |
|
||||
| ch-{read\|video\|music\|audio} | `--color-ch-read` 等 | 频道图标底色、进度条填充 |
|
||||
| ch-\*-soft | `--color-ch-read-soft` 等 | 继续卡片、频道入口底色 |
|
||||
| ch-\*-text | `--color-ch-read-text` 等 | 频道色的文字(新增) |
|
||||
@@ -153,9 +153,10 @@ Reader V3 内置 4 个主题,每个主题含浅色和深色两套取值,共
|
||||
3. 品牌色的文字、链接、选中态图标,用 brand-text;频道色的文字用 ch-*-text。不要直接把 brand 或 ch-* 当文字色,浅色主题下对比度不够。
|
||||
4. 继续卡片、频道入口的底色用 ch-*-soft,文字用 ink 或 ch-*-text。
|
||||
5. 选中的标签、分段控件用 brand-soft 底加 brand-text 文字。
|
||||
6. 抽屉、弹层的遮罩用 scrim。
|
||||
7. 影视、音乐播放页是固定深色沉浸界面,使用当前主题的深色取值,不随浅色切换。
|
||||
8. 不使用纯黑 `#000` 作背景;纯白只作浅色主题的 surface。
|
||||
6. 主按钮(每屏唯一的主要操作,如「保存」「播放」)用 brand-text 底加 bg 文字,与危险按钮(danger 底加 bg 文字)同一种画法。浅色主题的 brand 太淡,作主按钮底色时比旁边的白色次按钮还轻,看不出主次。brand 填充保留给选中、进度、开关这类状态。
|
||||
7. 抽屉、弹层的遮罩用 scrim。
|
||||
8. 影视、音乐播放页是固定深色沉浸界面,使用当前主题的深色取值,不随浅色切换。
|
||||
9. 不使用纯黑 `#000` 作背景;纯白只作浅色主题的 surface。
|
||||
|
||||
## 5. 对比度要求
|
||||
|
||||
@@ -165,7 +166,7 @@ Reader V3 内置 4 个主题,每个主题含浅色和深色两套取值,共
|
||||
| --- | --- |
|
||||
| ink 对 bg、surface | 4.5:1 以上 |
|
||||
| muted 对 bg、surface-2 | 4.5:1 以上 |
|
||||
| brand-text 对 brand-soft、bg | 4.5:1 以上 |
|
||||
| brand-text 对 brand-soft、bg(bg 文字在 brand-text 主按钮上即此组合) | 4.5:1 以上 |
|
||||
| on-brand 对 brand | 4.5:1 以上 |
|
||||
| ch-*-text 对 ch-*-soft | 4.5:1 以上 |
|
||||
| on-ch 对 ch-\* | 4.5:1 以上 |
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
.media-manager .media-library-row{padding:14px;border:1px solid var(--border,#dce2d4);border-radius:12px;background:var(--surface,#f0f0e8);gap:8px}.media-library-row strong{font-size:15px;font-weight:600}.media-library-row small{margin-top:5px}.media-manager .media-library-row button{background:color-mix(in srgb,var(--surface) 96%,var(--text));min-height:40px;font-size:13px}
|
||||
.media-manager .media-library-create,.media-manager .media-library-editor{border:1px solid var(--border,#dce2d4);border-radius:12px;padding:16px;margin:18px 0;background:var(--surface,#f0f0e8);box-sizing:border-box;max-width:100%}.media-manager .media-library-create h2,.media-manager .media-library-editor h2{margin:0 0 14px;font-size:16px}.media-manager .media-form{max-width:100%;margin:0;gap:12px}.media-manager .media-form label{font-size:13px;gap:6px}.media-manager .media-form input,.media-manager .media-form select{width:100%;box-sizing:border-box;background:color-mix(in srgb,var(--surface) 96%,var(--text));min-width:0}.media-manager .media-form small{font-size:12px;line-height:1.6;opacity:.7}.media-manager .media-form button[type=submit]{background:var(--media-fill);color:var(--media-on-accent);border-color:var(--media-fill);font-weight:600}
|
||||
@media(min-width:760px){.media-manager .media-library-row>span{flex-basis:auto}.media-manager .media-library-row button{flex:0 0 auto;min-width:66px}.media-manager .media-library-create,.media-manager .media-library-editor{max-width:720px}.media-manager .media-library-create .media-permission-fields{grid-template-columns:1fr 1fr;gap:14px 18px}.media-manager .media-library-create label:nth-child(2){grid-column:1/-1;grid-row:2}.media-manager .media-form button[type=submit]{justify-self:start;min-width:150px}}
|
||||
.media-album-playback .media-album-summary>button{font-size:12px;padding:4px 8px}.media-album-playback .media-album-actions>.media-primary{background:var(--media-fill);color:var(--media-on-accent);border-color:var(--media-fill)}
|
||||
.media-album-playback .media-album-summary>button{font-size:12px;padding:4px 8px}.media-album-playback .media-album-actions>.media-primary{background:var(--media-primary);color:var(--media-on-primary);border-color:var(--media-primary)}
|
||||
.media-album-summary{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:12px;min-height:24px}.media-album-summary>button{font-size:12px;padding:4px 8px}.media-album-actions{justify-content:flex-start;gap:8px}.media-album-start{font-size:12px;line-height:1.5}.media-album-playback .media-season-list{gap:0}.media-album-playback .media-album-disc{font-size:12px;margin:18px 0 4px;color:var(--muted);font-weight:500}.media-album-playback .media-season-row{padding:2px 0;gap:4px}.media-album-playback .media-season-row[data-selected=true]{background:var(--media-selection);border-radius:6px}.media-album-playback .media-album-track-link{display:flex;align-items:center;gap:8px;min-width:0;background:transparent;border:0;padding:8px 6px;min-height:44px}.media-album-number{flex:0 0 22px;text-align:center;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}.media-album-track-title{flex:1;min-width:0;overflow-wrap:anywhere;font-size:14px}.media-album-track-title>small{display:block;font-size:11px;color:var(--muted);margin-top:3px}.media-album-duration{flex-shrink:0;font-size:12px;font-variant-numeric:tabular-nums;color:var(--muted)}
|
||||
.media-grid.media-season-picker{grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}.media-season-picker .media-tile{display:grid;grid-template-columns:42px minmax(0,1fr);align-content:center;align-items:center;column-gap:10px;padding:8px;border:1px solid var(--border);border-radius:8px;background:var(--surface);min-height:80px}.media-season-picker .media-cover{grid-row:1 / span 3;width:42px;height:63px;min-width:42px;padding:3px;box-sizing:border-box;font-size:10px;line-height:1.4}.media-season-picker .media-cover-title{-webkit-line-clamp:3}.media-season-picker .media-tile>strong{margin:0;white-space:normal;overflow-wrap:anywhere;font-size:13px}.media-season-picker .media-tile>small{grid-column:2;margin-top:4px;min-width:0}.media-season-picker .media-tile>small:empty{display:none}@media(max-width:700px){.media-grid.media-season-picker{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}}
|
||||
.media-season-playback .media-toolbar>button{flex-shrink:0;white-space:nowrap}.media-season-playback .media-toolbar>span{min-width:0;overflow-wrap:anywhere}
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
--media-accent: var(--color-brand-text);
|
||||
--media-fill: var(--color-brand);
|
||||
--media-on-accent: var(--color-on-brand);
|
||||
--media-primary: var(--color-brand-text);
|
||||
--media-on-primary: var(--color-bg);
|
||||
--media-selection: var(--color-brand-soft);
|
||||
--media-error-ink: var(--color-danger);
|
||||
--media-error-background: var(--color-danger-soft);
|
||||
@@ -110,8 +112,8 @@ body:has(>#app>.media-screen) { background: var(--color-bg); }
|
||||
.media-cover.square {border-radius:6px}
|
||||
.media-hero {gap:26px;margin-top:24px}
|
||||
.media-hero .media-cover {width:170px;min-width:170px}
|
||||
.media-screen .media-primary {background:var(--media-fill);color:var(--media-on-accent)}
|
||||
.media-screen button.media-primary:hover:not(:disabled) {background:var(--media-fill);color:var(--media-on-accent);filter:brightness(.94)}
|
||||
.media-screen .media-primary {background:var(--media-primary);color:var(--media-on-primary)}
|
||||
.media-screen button.media-primary:hover:not(:disabled) {background:var(--media-primary);color:var(--media-on-primary);filter:brightness(.94)}
|
||||
.media-task-retry {display:inline-flex;align-items:center;justify-content:center;gap:5px;min-height:40px;padding:0 10px;border:1px solid var(--border);border-radius:8px;background:var(--media-selection);color:var(--media-accent);font-size:12px;font-weight:600}
|
||||
.media-task-retry:disabled {opacity:.5}
|
||||
@media(max-width:430px){.media-task-retry span{display:inline}.media-task-retry{min-width:64px}.media-scan-job .media-task-icon{min-width:40px}}
|
||||
@@ -765,7 +767,7 @@ body:has(>#app>.media-screen) { background: var(--color-bg); }
|
||||
.media-playback-problem>p {font-size:12px;line-height:1.8;margin:0;max-width:480px}
|
||||
.media-playback-problem>div {display:flex;justify-content:center;gap:10px;flex-wrap:wrap;margin-top:4px}
|
||||
.media-playback-problem button {font-size:12px}
|
||||
.media-video-workspace .media-playback-problem .media-primary {background:var(--media-fill);color:var(--media-on-accent)}
|
||||
.media-video-workspace .media-playback-problem .media-primary {background:var(--media-primary);color:var(--media-on-primary)}
|
||||
.media-video-controls .media-screen-error {margin:18px 0;font-size:12px}
|
||||
.media-video-controls .media-screen-error-actions {display:flex;gap:8px}
|
||||
.media-video-sheet .sheet-body {font-size:14px;line-height:1.6}
|
||||
|
||||
@@ -757,7 +757,7 @@
|
||||
.media-screen .media-browse-tools {height:auto;flex-wrap:wrap}
|
||||
.media-loading-status {color:var(--muted);font-size:13px;min-height:24px}
|
||||
.media-scan-job .media-task-retry {grid-column:1/-1;justify-self:start;min-height:44px}
|
||||
.media-player .media-playback-problem .media-primary {background:var(--media-fill);color:var(--media-on-accent)}
|
||||
.media-player .media-playback-problem .media-primary {background:var(--media-primary);color:var(--media-on-primary)}
|
||||
.media-player .dplayer-host .dplayer-bar-wrap .dplayer-played,.media-player .dplayer-host .dplayer-volume-bar-inner {background:var(--media-fill)!important}
|
||||
.media-player .dplayer-host .dplayer-setting-box,.media-player .dplayer-host .dplayer-setting-item {background:var(--media-paper);color:var(--text)}
|
||||
.media-player .dplayer-host .dplayer-setting-item:hover {background:var(--media-selection)}
|
||||
|
||||
@@ -698,10 +698,12 @@ book-content {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* The one action on a screen: the deep brand colour, so it outweighs the quiet secondary
|
||||
buttons beside it. The soft --reader-fill stays for states (selected, progress, on). */
|
||||
.button.primary {
|
||||
background: var(--reader-fill);
|
||||
border-color: var(--reader-fill);
|
||||
color: var(--reader-on-fill);
|
||||
background: var(--reader-primary);
|
||||
border-color: var(--reader-primary);
|
||||
color: var(--reader-on-primary);
|
||||
}
|
||||
|
||||
.button:disabled {
|
||||
@@ -812,7 +814,7 @@ book-content {
|
||||
}
|
||||
|
||||
.button.primary:hover {
|
||||
background: color-mix(in srgb, var(--reader-fill) 88%, var(--reader-ink));
|
||||
background: color-mix(in srgb, var(--reader-primary) 88%, var(--reader-ink));
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
@@ -288,6 +288,9 @@
|
||||
--reader-accent: var(--color-brand-text);
|
||||
--reader-fill: var(--color-brand);
|
||||
--reader-on-fill: var(--color-on-brand);
|
||||
/* Primary action: brand-text filled, bg on it (spec §5 already holds this pair to 4.5:1). */
|
||||
--reader-primary: var(--color-brand-text);
|
||||
--reader-on-primary: var(--color-bg);
|
||||
--reader-scrim: var(--color-scrim);
|
||||
}
|
||||
:root, [data-theme][data-mode="light"] { color-scheme: light; }
|
||||
|
||||
Reference in new issue
Block a user