Files
Clipboard/renderer/styles.css
2026-09-20 23:35:03 +08:00

1050 lines
26 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 现代简约样式 —— 通过 token 系统接入 6 主题 / 5 强调色 */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
background: var(--bg-base);
color: var(--text);
font-family: var(--font-ui);
font-size: var(--fs-base);
line-height: var(--lh-base);
letter-spacing: var(--tracking-cn);
/* Windows + CJK 小字清晰度关键设置:
* - 默认 subpixel-antialiased 保留 RGB 子像素渲染,对中文笔画描边至关重要;
* 之前强制 antialiased/grayscale 会让 12px 以下的汉字变成"雾蒙蒙"的灰块。
* - text-rendering 用 auto,让浏览器按字号自适应:中文小字走 subpixel,
* 英文大标题再走 optimizeLegibility 拿连字。
* - font-feature 只在 ≥14px 的西文场景开启,避免给小字号增加渲染负担。 */
-webkit-font-smoothing: subpixel-antialiased;
-moz-osx-font-smoothing: auto;
text-rendering: auto;
font-feature-settings: normal;
user-select: none;
}
/* 大字号西文(标题、关于页)单独开启连字,小字号不参与 */
#title, .about-name, .theme-preview-text {
-webkit-font-smoothing: subpixel-antialiased;
text-rendering: optimizeLegibility;
font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
}
#root {
display: flex;
flex-direction: column;
height: 100vh;
border: 1px solid var(--border);
border-radius: var(--radius-lg);
overflow: hidden;
}
/* ---------- 拖动区 ---------- */
#drag-bar {
-webkit-app-region: drag;
display: flex;
align-items: center;
gap: 6px;
padding: 8px 12px 7px;
border-bottom: 1px solid var(--border-soft);
background: var(--bg-base);
}
#title {
font-size: var(--fs-md);
font-weight: var(--fw-semibold);
color: var(--text);
letter-spacing: 0.2px;
/* 原本 margin-left: 4px 用来撑开标题与左边框的距离;
* 现在 #app-icon 在更左侧,由 #app-icon 的 margin-right 控制间隙更合理。 */
margin-left: 0;
/* 标题单行:body 的 line-height=1.6 在这里会撑出多余空白,
* 关掉让标题跟按钮在同一基线。 */
line-height: 1;
}
/* 标题栏左上角小图标:16×16 显示位,源是 32×32 PNG(主进程从 .ico resize
* 而来),对常见 1.0/1.25/1.5/2x 缩放都锐利。
* 父级 #drag-bar 已设 -webkit-app-region: drag,按住图标仍可拖动窗口。 */
#app-icon {
width: 16px;
height: 16px;
display: block;
flex-shrink: 0;
margin-right: 6px;
border-radius: 3px;
}
.spacer { flex: 1; }
.icon-btn {
-webkit-app-region: no-drag;
width: 26px;
height: 26px;
padding: 0;
background: transparent;
border: none;
border-radius: 6px;
color: var(--text-muted);
line-height: 1;
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
transition: background var(--transition-fast), color var(--transition-fast);
}
/* SVG 图标:颜色继承 currentColor,让 aria-pressed 状态色直接生效 */
.icon-btn svg {
display: block;
color: inherit;
}
.icon-btn:hover {
background: var(--bg-hover);
color: var(--text);
}
#close-btn:hover {
background: var(--danger-bg);
color: var(--danger);
}
/* 置顶开启:图标上色 + 轻微背景,关闭时回到 muted */
#pin-btn[aria-pressed="true"] {
color: var(--accent-fg);
background: var(--accent-soft);
}
#pin-btn[aria-pressed="true"]:hover {
/* 开启态下 hover 不要洗掉上色,只把背景加深一点 */
background: var(--accent-hover);
color: var(--accent-fg);
}
#refresh-btn.spinning svg {
animation: spin 0.8s linear infinite;
transform-origin: 50% 50%;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.ipc-dot {
display: inline-block;
width: 6px;
height: 6px;
margin: 0 4px 0 2px;
border-radius: 50%;
background: var(--text-muted);
transition: background var(--transition-base), box-shadow var(--transition-base);
}
.ipc-dot.connected {
background: var(--success);
box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.15);
}
.ipc-dot.error {
background: var(--danger);
box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.15);
}
/* ---------- Tab 栏 ---------- */
#tabs {
-webkit-app-region: no-drag;
display: flex;
gap: 2px;
padding: 0 12px;
background: var(--bg-base);
border-bottom: 1px solid var(--border-soft);
}
/* 历史窗口的 Tab —— 作用域限定到 #tabs,避免被下面 settings 面板的
* 通用 .tab 规则覆盖(同一文件后写的同优先级规则会赢,导致 padding /
* transition 跟设计稿不一致)。 */
#tabs .tab {
padding: 8px 10px 7px;
border: none;
border-radius: 6px 6px 0 0;
background: transparent;
color: var(--text-soft);
font-size: var(--fs-sm);
font-weight: var(--fw-medium);
cursor: pointer;
transition: background var(--transition-fast), color var(--transition-fast);
border-bottom: 2px solid transparent;
margin-bottom: -1px;
/* 与 #title 一致:行高压成 1,文字基线跟标题对齐;不要靠 padding 顶。 */
line-height: 1;
}
#tabs .tab:hover {
color: var(--text);
}
#tabs .tab.active {
color: var(--accent-fg);
border-bottom-color: var(--accent-fg);
}
.tab-count {
display: inline-block;
margin-left: 5px;
padding: 0 6px;
background: var(--bg-hover);
border-radius: 8px;
font-size: 10.5px;
color: var(--text-muted);
line-height: 16px;
height: 16px;
font-weight: var(--fw-medium);
vertical-align: 1px;
font-variant-numeric: tabular-nums;
transition: background var(--transition-fast), color var(--transition-fast);
}
#tabs .tab.active .tab-count {
background: var(--accent-soft);
color: var(--accent-fg);
}
/* ---------- 搜索 ---------- */
#search-row {
padding: 8px 12px 10px;
background: var(--bg-base);
}
#search-wrap {
position: relative;
display: flex;
align-items: center;
}
#search-icon {
position: absolute;
left: 10px;
color: var(--text-muted);
pointer-events: none;
transition: color var(--transition-fast);
}
#search {
-webkit-app-region: no-drag;
width: 100%;
height: 32px;
padding: 0 32px 0 32px;
background: var(--bg-soft);
border: 1px solid transparent;
border-radius: 8px;
color: var(--text);
font-size: var(--fs-base);
line-height: 1.4;
outline: none;
transition: background var(--transition-base), border-color var(--transition-base), box-shadow var(--transition-base);
}
#search:focus {
background: var(--bg-overlay);
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-soft);
}
/* 只有搜索图标随聚焦高亮。之前还有一条 #search:focus + #search-clear,
* 会让清空按钮在输入全程保持 accent 色 —— 一个次要的 × 按钮不该比输入框
* 本身更抢眼,且与 #search-clear 自身的 muted 设计矛盾,已移除。 */
#search-wrap:focus-within #search-icon {
color: var(--accent-fg);
}
#search::placeholder {
color: var(--text-muted);
}
#search-clear {
-webkit-app-region: no-drag;
position: absolute;
right: 4px;
top: 50%;
transform: translateY(-50%);
width: 24px;
height: 24px;
padding: 0;
background: transparent;
border: none;
border-radius: 50%;
color: var(--text-muted);
line-height: 1;
cursor: pointer;
display: none;
align-items: center;
justify-content: center;
transition: background var(--transition-fast), color var(--transition-fast);
}
#search-clear.visible {
display: inline-flex;
}
#search-clear:hover {
background: var(--bg-hover);
color: var(--text);
}
/* ---------- 列表 ---------- */
#list-wrap {
flex: 1;
overflow-y: auto;
padding: 8px 12px 8px;
background: var(--bg-base);
scroll-behavior: smooth;
}
#list {
list-style: none;
display: flex;
flex-direction: column;
gap: 6px;
}
/* 自定义滚动条 */
#list-wrap::-webkit-scrollbar {
width: 8px;
}
#list-wrap::-webkit-scrollbar-track {
background: transparent;
}
#list-wrap::-webkit-scrollbar-thumb {
background: var(--border);
border-radius: 4px;
border: none;
}
#list-wrap::-webkit-scrollbar-thumb:hover {
background: var(--text-muted);
}
/* ---------- 卡片 ---------- */
.card {
background: var(--bg-base);
border: 1px solid var(--border-soft);
border-radius: var(--radius-md);
padding: 9px 12px 10px;
cursor: pointer;
transition: background var(--transition-base), border-color var(--transition-base), box-shadow var(--transition-base), transform var(--transition-fast);
outline: none;
position: relative;
}
.card:hover {
background: var(--bg-soft);
border-color: var(--border);
box-shadow: var(--shadow-sm);
}
.card.selected {
background: var(--bg-overlay);
border-color: var(--border-strong);
border-left: 2px solid var(--accent);
padding-left: 11px;
}
.card.selected:hover {
border-color: var(--accent);
}
/* .card 设过 outline:none,必须用等效焦点指示补回(卡片本身 tabindex=0) */
.card:focus-visible {
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-soft);
}
.card-head {
display: flex;
align-items: center;
gap: 6px;
margin-bottom: 4px;
}
.time {
font-size: var(--fs-xs);
color: var(--text-soft);
font-family: var(--font-mono);
font-variant-numeric: tabular-nums;
}
.badge {
display: inline-flex;
align-items: center;
gap: 3px;
/* 徽标含中文(文本/图片):tokens 自定标准 --fs-xs=11px 是 CJK 清晰下限,
* 之前 10.5px 与自己的标准矛盾,小字中文发糊。 */
font-size: var(--fs-xs);
color: var(--text-soft);
background: var(--bg-hover);
border-radius: 4px;
padding: 1px 6px 1px 5px;
font-weight: var(--fw-medium);
line-height: 1.5;
letter-spacing: 0;
}
.badge svg {
display: block;
flex-shrink: 0;
opacity: 0.75;
}
.badge-image {
color: var(--accent-fg);
}
.badge-image svg {
color: var(--accent-fg);
opacity: 0.85;
}
.slot {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 20px;
height: 20px;
padding: 0 5px;
font-size: 11px;
font-weight: var(--fw-semibold);
color: var(--accent-text);
background: var(--accent);
border-radius: 5px;
letter-spacing: 0;
font-family: var(--font-mono);
line-height: 1;
}
.action {
-webkit-app-region: no-drag;
display: inline-flex;
align-items: center;
gap: 4px;
font-size: var(--fs-xs);
color: var(--text-muted);
background: transparent;
border: none;
padding: 4px 8px;
border-radius: 6px;
cursor: pointer;
opacity: 0;
/* 只设 opacity:0 的按钮「看不见但点得着」:点卡片头部想选中时会误触
* 透明的 ★/删除;键盘 Tab 也会聚焦到隐形按钮。visibility 进 transition
* 是离散动画:出现时立即可见 + opacity 淡入,消失时等淡出结束才隐藏。 */
visibility: hidden;
line-height: 1;
transition: opacity var(--transition-fast), background var(--transition-fast), color var(--transition-fast), visibility var(--transition-fast);
}
.action svg {
display: block;
flex-shrink: 0;
}
.card:hover .action,
.card.selected .action,
.action:focus-visible {
opacity: 1;
visibility: visible;
}
.action:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 1px;
}
.action:hover {
color: var(--text);
background: var(--bg-hover);
}
.action.copy {
color: var(--accent-fg);
padding-right: 10px;
}
.action.copy:hover {
color: var(--accent-fg);
background: var(--accent-hover);
}
.action.fav {
padding: 5px 7px;
color: var(--text-muted);
}
.action.fav svg {
fill: none;
transition: fill var(--transition-fast), color var(--transition-fast);
}
.action.fav.favorited {
color: var(--warn);
}
.action.fav.favorited svg {
fill: var(--warn);
}
.action.fav:hover {
color: var(--warn);
background: var(--warn-bg);
}
.action.delete {
padding: 5px 7px;
}
.action.delete:hover {
color: var(--danger);
background: var(--danger-bg);
}
.card-body {
display: flex;
align-items: center;
gap: 10px;
}
.text-preview {
flex: 1;
min-width: 0;
font-size: var(--fs-base);
color: var(--text);
/* 中文正文行高 ≥1.55 才不会出现笔画"黏连",这里设 1.6 让 13px 中文清爽 */
line-height: 1.6;
/* 超长无空格串(URL/路径)能断行,但不像 word-break:break-all 那样把
* 普通英文单词从中间生硬截断;中文本身任意位置可断,不受影响。 */
overflow-wrap: anywhere;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
user-select: text;
cursor: text;
}
.image-preview {
width: 88px;
height: 88px;
border-radius: 8px;
border: 1px solid var(--border-soft);
object-fit: contain;
background:
linear-gradient(45deg, var(--bg-soft) 25%, transparent 25%),
linear-gradient(-45deg, var(--bg-soft) 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, var(--bg-soft) 75%),
linear-gradient(-45deg, transparent 75%, var(--bg-soft) 75%);
background-size: 12px 12px;
background-position: 0 0, 0 6px, 6px -6px, -6px 0;
cursor: zoom-in;
}
/* 缩略图可聚焦(buildCard 里设了 role=button + tabindex),补键盘焦点指示 */
.image-preview:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 1px;
}
/* ---------- 图片大图预览 ---------- */
#lightbox {
position: fixed;
inset: 0;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.72);
cursor: zoom-out;
}
/* 焦点放在遮罩上只为接 Esc,不需要焦点描边 */
#lightbox:focus { outline: none; }
#lightbox:not(.hidden) {
animation: lightbox-in var(--transition-fast);
}
@keyframes lightbox-in {
from { opacity: 0; }
}
#lightbox-img {
max-width: 92vw;
max-height: 88vh;
object-fit: contain;
border-radius: 8px;
box-shadow: 0 8px 40px rgba(0, 0, 0, 0.5);
/* 与 .image-preview 同款棋盘格底;深色遮罩上换成浅色格子,透明 PNG 才看得清 */
background:
linear-gradient(45deg, rgba(255, 255, 255, 0.14) 25%, transparent 25%),
linear-gradient(-45deg, rgba(255, 255, 255, 0.14) 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, rgba(255, 255, 255, 0.14) 75%),
linear-gradient(-45deg, transparent 75%, rgba(255, 255, 255, 0.14) 75%);
background-size: 16px 16px;
background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}
/* ---------- 空状态 ---------- */
#empty {
text-align: center;
padding: 64px 24px 56px;
color: var(--text-soft);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.empty-icon {
color: var(--text-muted);
opacity: 0.55;
margin-bottom: 14px;
}
.empty-title {
font-size: var(--fs-md);
color: var(--text-soft);
font-weight: var(--fw-medium);
margin-bottom: 6px;
}
#empty .muted {
font-size: var(--fs-sm);
color: var(--text-muted);
line-height: 1.5;
}
.hidden { display: none !important; }
/* ---------- 状态栏 ---------- */
#status {
display: flex;
justify-content: space-between;
align-items: center;
padding: 7px 14px;
border-top: 1px solid var(--border-soft);
background: var(--bg-base);
font-size: var(--fs-xs);
line-height: 1.4;
color: var(--text-muted);
user-select: none;
}
#status-left {
color: var(--text-soft);
}
.shortcuts {
display: inline-flex;
align-items: center;
gap: 4px;
flex-wrap: nowrap;
white-space: nowrap;
overflow: hidden;
}
.shortcuts .dot {
color: var(--text-muted);
opacity: 0.5;
margin: 0 1px;
}
kbd {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 18px;
height: 18px;
padding: 0 5px;
font-family: var(--font-mono);
font-size: 10.5px;
font-weight: var(--fw-medium);
color: var(--text-soft);
background: var(--bg-soft);
border: 1px solid var(--border);
border-radius: 4px;
line-height: 1;
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.04);
}
/* ---------- 设置面板 ---------- */
#settings-body {
flex: 1;
min-height: 0;
overflow: hidden;
padding: 0;
background: var(--bg-base);
display: flex;
flex-direction: column;
}
/* ---------- 设置面板:标签栏 ---------- */
/* 用 #tab-bar 前缀隔离:上面「历史/收藏」Tab 也用 .tab,但 padding/transition
* 跟设置页 Tab 不一样。两份样式同特异性时位置靠后的赢,会把主窗口 Tab
* 的 padding 从 5px 12px 改成 6px 10px 5px —— 显式框死作用域避免串味。 */
#tab-bar {
display: flex;
gap: 2px;
padding: 0 12px;
background: var(--bg-base);
border-bottom: 1px solid var(--border-soft);
}
#tab-bar .tab {
appearance: none;
background: transparent;
border: none;
border-bottom: 2px solid transparent;
padding: 8px 10px 7px;
font-family: inherit;
font-size: var(--fs-sm);
color: var(--text-soft);
cursor: pointer;
line-height: 1;
margin-bottom: -1px;
/* 与全局动效 token 统一(--transition-fast = 100ms ease-out),不再散写 0.12s ease */
transition: color var(--transition-fast), border-color var(--transition-fast);
}
#tab-bar .tab:hover { color: var(--text); }
#tab-bar .tab[aria-selected="true"] {
color: var(--text);
/* 与 #tabs .tab.active 一致:文字/下划线指示都走 --accent-fg,
* light 主题亮色系 accent 下划线才够清晰。 */
border-bottom-color: var(--accent-fg);
font-weight: var(--fw-semibold);
}
#tab-bar .tab:focus-visible { outline: 1px solid var(--accent); outline-offset: -2px; }
.tab-panel {
flex: 1;
min-height: 0;
overflow-y: auto;
padding: 14px 16px;
display: flex;
flex-direction: column;
gap: 8px;
}
/* 面板滚动条 —— 跟主列表统一 */
.tab-panel::-webkit-scrollbar { width: 8px; }
.tab-panel::-webkit-scrollbar-track { background: transparent; }
.tab-panel::-webkit-scrollbar-thumb {
background: var(--border);
border-radius: 4px;
}
.tab-panel::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
.tab-panel[hidden] { display: none !important; }
.setting-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 11px 14px;
border: 1px solid var(--border-soft);
border-radius: var(--radius-md);
background: var(--bg-base);
line-height: 1.4;
transition: border-color var(--transition-fast);
}
.setting-row:hover {
border-color: var(--border);
}
.setting-row.column {
flex-direction: column;
align-items: stretch;
gap: 8px;
}
.setting-label { font-size: var(--fs-base); color: var(--text); font-weight: var(--fw-medium); }
.setting-row select {
height: 30px;
padding: 0 28px 0 10px;
border: 1px solid var(--border);
border-radius: 6px;
background: var(--bg-soft);
color: var(--text);
font-size: var(--fs-base);
line-height: 1.4;
outline: none;
cursor: pointer;
transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
appearance: none;
-webkit-appearance: none;
background-image:
linear-gradient(45deg, transparent 50%, var(--text-muted) 50%),
linear-gradient(-45deg, transparent 50%, var(--text-muted) 50%);
background-position: calc(100% - 13px) 12px, calc(100% - 8px) 12px;
background-size: 5px 5px, 5px 5px;
background-repeat: no-repeat;
}
.setting-row select:hover { border-color: var(--border-strong); }
.setting-row select:focus {
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-soft);
}
.path-box {
margin-top: 4px;
padding: 9px 11px;
background: var(--bg-soft);
border-radius: 6px;
border: 1px solid var(--border-soft);
}
.path-text { font-size: var(--fs-sm); color: var(--text-soft); word-break: break-all; user-select: text; font-family: var(--font-mono); }
.btn-row { display: flex; gap: 8px; margin-top: 4px; }
.btn {
height: 30px;
padding: 0 12px;
border: 1px solid var(--border);
border-radius: 6px;
background: var(--bg-base);
color: var(--text);
font-size: var(--fs-sm);
line-height: 1;
cursor: pointer;
transition: background var(--transition-fast), border-color var(--transition-fast);
font-weight: var(--fw-medium);
}
.btn:hover { background: var(--bg-hover); border-color: var(--border-strong); }
.btn:active { background: var(--bg-soft); }
.btn-danger { color: var(--danger); border-color: var(--danger-bg); background: var(--danger-bg); }
/* hover 是「红底白字」:不能用 --accent-text(它随 accent 色系自适应,
* green/orange accent 下是深色字,红底深字对比度崩塌),这里恒为白。 */
.btn-danger:hover { background: var(--danger); color: #FFFFFF; border-color: var(--danger); }
.danger-zone { border-color: var(--danger-bg); }
.danger-zone:hover { border-color: var(--danger-border); }
/* 开关 */
.switch { position: relative; display: inline-block; width: 36px; height: 20px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.slider-track {
position: absolute; inset: 0; cursor: pointer;
background: var(--border-strong); border-radius: 20px;
transition: background var(--transition-base);
}
.slider-track::before {
content: ""; position: absolute; height: 16px; width: 16px; left: 2px; top: 2px;
background: var(--bg-overlay); border-radius: 50%;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
transition: transform var(--transition-base);
}
.switch input:checked + .slider-track { background: var(--accent); }
.switch input:checked + .slider-track::before { transform: translateX(16px); }
.switch input:focus-visible + .slider-track { box-shadow: 0 0 0 3px var(--accent-soft); }
/* 主题网格 */
.theme-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
margin-top: 4px;
}
.theme-card {
cursor: pointer;
border: 2px solid var(--border-soft);
border-radius: var(--radius-md);
padding: 6px;
background: var(--bg-base);
transition: border-color var(--transition-base), transform var(--transition-fast), box-shadow var(--transition-base);
text-align: left;
}
.theme-card:hover {
border-color: var(--border-strong);
transform: translateY(-1px);
box-shadow: var(--shadow-sm);
}
.theme-card.active {
border-color: var(--accent);
box-shadow: 0 0 0 1px var(--accent) inset;
}
.theme-preview {
position: relative;
height: 56px;
border-radius: var(--radius-sm);
display: flex;
align-items: center;
justify-content: flex-start;
padding: 8px 12px;
border: 1px solid transparent;
overflow: hidden;
}
.theme-preview-text {
font-family: var(--font-ui);
font-weight: var(--fw-semibold);
font-size: 22px;
letter-spacing: -0.5px;
}
.theme-preview-accent {
position: absolute;
right: 10px;
top: 10px;
width: 12px;
height: 12px;
border-radius: 50%;
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.1);
}
.theme-info {
margin-top: 7px;
}
.theme-name {
font-size: var(--fs-sm);
color: var(--text);
font-weight: var(--fw-medium);
}
.theme-desc {
font-size: 11px;
color: var(--text-muted);
margin-top: 1px;
}
/* 强调色 */
.accent-grid {
display: flex;
gap: 10px;
margin-top: 4px;
}
.accent-swatch {
width: 28px;
height: 28px;
border-radius: 50%;
border: 2px solid var(--border-soft);
cursor: pointer;
padding: 0;
position: relative;
transition: transform var(--transition-fast), box-shadow var(--transition-base);
}
.accent-swatch:hover {
transform: scale(1.08);
}
.accent-swatch.active {
box-shadow: 0 0 0 2px var(--bg-base), 0 0 0 4px var(--text);
}
.accent-swatch.active::after {
content: "";
position: absolute;
inset: 0;
border-radius: 50%;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3.5 8.5l3 3 6-6.5'/></svg>");
background-size: 16px 16px;
background-position: center;
background-repeat: no-repeat;
}
/* ---------- 设置面板:关于页 ---------- */
.about-head {
text-align: center;
padding: 18px 0 8px;
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
}
.about-icon {
width: 44px;
height: 44px;
border-radius: 10px;
/* 立体渐变 = 实色 accent 上叠一层 白→黑 overlay(设计系统标准做法)。
* 之前渐变末端用 --accent-hover,那是个 20% 透明度的 hover 底色 token,
* 图标右下角几乎全透明、透出卡片底色,像褪了一块色。 */
background: var(--accent);
background: linear-gradient(135deg, rgba(255, 255, 255, 0.16), rgba(0, 0, 0, 0.14)), var(--accent);
display: flex;
align-items: center;
justify-content: center;
color: var(--accent-text);
margin-bottom: 6px;
box-shadow: 0 2px 8px var(--accent-soft);
}
.about-icon svg {
display: block;
}
.about-name {
font-size: var(--fs-lg);
font-weight: var(--fw-semibold);
color: var(--text);
letter-spacing: 0.2px;
}
.about-tagline {
font-size: var(--fs-xs);
color: var(--text-muted);
margin-top: 2px;
}
.about-devline {
display: flex;
align-items: baseline;
flex-wrap: wrap;
gap: 10px;
margin-top: 4px;
}
.about-dev { font-size: var(--fs-base); color: var(--text); }
.ext-link {
font-size: var(--fs-sm);
color: var(--accent-fg);
text-decoration: none;
word-break: break-all;
cursor: pointer;
transition: opacity var(--transition-fast);
}
.ext-link:hover { text-decoration: underline; opacity: 0.85; }
/* ---------- 键盘焦点可见性(:focus-visible) ----------
* 全局面控件统一的键盘焦点指示。:focus-visible 只在键盘导航时触发,
* 鼠标点击不出现描边,不影响现有观感。
* (.card / .action / #tab-bar .tab / .switch / select 已在各自区块定义。) */
.icon-btn:focus-visible,
#search-clear:focus-visible,
.btn:focus-visible,
#tabs .tab:focus-visible,
.theme-card:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 1px;
}
/* 圆形色板用双层 ring(与 .active 选中态同构,区别在 accent 色) */
.accent-swatch:focus-visible {
box-shadow: 0 0 0 2px var(--bg-base), 0 0 0 4px var(--accent);
}