Files
openless/openless-all/app/src/styles/global.css
T
sim c4290071b0 fix(update-button): 检查更新按钮旋转方向与尺寸稳定
- ol-spin 改为逆时针,与 refresh(ccw)图标方向一致
- 按钮固定宽度 + 内容居中;图标固定 14x14 容器,check/refresh 切换与旋转时不再跳动
2026-08-03 11:15:30 +08:00

305 lines
9.6 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.
html, body, #root {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
background: transparent;
overflow: hidden;
}
html[data-ol-platform="linux"],
html[data-ol-platform="linux"] body,
html[data-ol-platform="linux"] #root {
background: var(--ol-surface);
}
html[data-ol-platform="android"],
html[data-ol-platform="android"] body,
html[data-ol-platform="android"] #root {
background: var(--ol-surface);
}
html {
color-scheme: light dark;
}
body {
background: transparent;
user-select: none;
-webkit-user-select: none;
}
#root {
display: flex;
isolation: isolate;
}
button {
font-family: inherit;
cursor: pointer;
border: none;
background: transparent;
color: inherit;
padding: 0;
/* Windows Chromium / WebView2 默认 user-agent style 会给 <button> 加 OS-native
appearance(outset 边框 + 内阴影)、min-width / min-height(让 button 至少容下
系统外观)、:focus 时的实线 outline。这些在 Vocab 词条这种嵌套 button 上叠加
起来变成一圈灰色"大圈"。macOS WKWebView 处理较弱所以看不出来。一次性清掉。
键盘焦点指示统一走 .ol-focus-ring + :focus-visible 走 box-shadow(不受 outline:0 影响)。 */
appearance: none;
-webkit-appearance: none;
outline: none;
min-width: 0;
min-height: 0;
box-sizing: border-box;
}
@keyframes ol-select-pop {
from { opacity: 0; transform: translateY(-4px) scale(.98); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
/* SelectLite popover 关闭动画 —— 反向收缩 + 淡出 + 上移,跟入场对偶。 */
@keyframes ol-select-pop-out {
from { opacity: 1; transform: translateY(0) scale(1); }
to { opacity: 0; transform: translateY(-4px) scale(.98); }
}
/* 键盘焦点指示:鼠标点击 (:focus) 不显示,键盘 Tab (:focus-visible) 才显示。
用 box-shadow 而非 outline 是因为组件内联 style 可能用 outline:none
把默认 ring 干掉,box-shadow 不受影响仍能上色。配合 pr-agent #407 的 a11y 要求。 */
.ol-focus-ring:focus-visible {
box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.45);
}
input, textarea {
font-family: inherit;
user-select: text;
-webkit-user-select: text;
}
a { color: inherit; text-decoration: none; }
@keyframes ol-window-enter {
from {
opacity: 0;
transform: translate3d(0, 8px, 0) scale(0.992);
filter: blur(8px);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
filter: blur(0);
}
}
/* 弹窗动画统一入口 —— 纯 opacity / transform,合成器友好。
背景不再逐帧动画 backdrop-filter(会卡顿、闪烁);模糊由宿主元素静态设定,
动画只负责淡入淡出。设置弹窗 / 各市场弹窗 / GitHub 登录弹窗共用这套。 */
@keyframes ol-modal-backdrop-in {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes ol-modal-backdrop-out {
from { opacity: 1; }
to { opacity: 0; }
}
@keyframes ol-modal-card-in {
from { opacity: 0; transform: translateY(8px) scale(0.985); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
/* 设置弹窗切换 tab 时右侧内容的轻微淡入。 */
@keyframes ol-tab-fade {
from { opacity: 0; transform: translateY(4px); }
to { opacity: 1; transform: translateY(0); }
}
/* 通用旋转 —— 「检查更新」按钮检查中的转圈动画等。
refresh 图标是逆时针(ccw)箭头,旋转方向与其一致,避免视觉上"反着转"。 */
@keyframes ol-spin {
to { transform: rotate(-360deg); }
}
@keyframes ol-modal-drawer-in {
from {
opacity: 0;
transform: translate3d(12px, 0, 0) scale(0.985);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
}
}
@keyframes ol-modal-drawer-out {
from {
opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
}
to {
opacity: 0;
transform: translate3d(12px, 0, 0) scale(0.985);
}
}
/* 风格市场全高抽屉从右缘滑入(MarketplaceModal 引用此名)。 */
@keyframes ol-drawer-in-right {
from { opacity: 0; transform: translateX(48px); }
to { opacity: 1; transform: translateX(0); }
}
/* ── 假毛玻璃面(qa 追问框 / capsule 语音胶囊等透明浮窗)─────────────────────
webview 拿不到透明窗口背后的桌面像素 —— CSS backdrop-filter 模糊不了桌面,
是 Tauri 已知的上游限制(issue #2827 / #10064 / #6876)。所以这里**不做
真实高斯模糊**:宿主元素保留半透明白底,这层 ::before 叠一张细颗粒噪点纹理
(磨砂质感来源);内描边高光与柔和阴影由宿主自带的 box-shadow 提供。
纯静态 CSS,零运行时 / 动画开销。Linux 主动禁用透明窗口后走纯不透明面。
宿主元素自带 border-radius 即可,::before 噪点层 inherit 圆角;宿主不要再设
backdrop-filter(死代码)。 */
.ol-frost {
position: relative;
isolation: isolate;
background: var(--ol-frost-bg);
}
.ol-frost::before {
content: '';
position: absolute;
inset: 0;
z-index: -1;
border-radius: inherit;
/* 不透明灰度噪点,normal 混合 —— 这是"磨砂颗粒"的来源。opacity 直接等于颗粒
强度:0.1 几乎看不见,0.32 能明显看出磨砂质感又不脏。要更糙往 0.45 调。 */
background-image: var(--ol-frost-grain);
/* tile 与 SVG 视口同尺寸(100),stitchTiles 的无缝拼接才成立 */
background-size: 100px 100px;
opacity: 0.32;
pointer-events: none;
}
html[data-ol-platform="linux"] .ol-frost {
background: var(--ol-surface);
}
html[data-ol-platform="linux"] .ol-frost::before {
content: none;
}
html[data-ol-platform="android"] .ol-frost {
background: var(--ol-surface);
}
html[data-ol-platform="android"] .ol-frost::before {
content: none;
}
.ol-app-shell-bg {
background: var(--ol-app-shell-bg);
}
.ol-panel-surface {
background: var(--ol-panel-bg);
border: 0.5px solid var(--ol-panel-border);
box-shadow: var(--ol-panel-shadow);
}
.ol-card-surface {
background: var(--ol-card-bg);
border: 0.5px solid var(--ol-card-border);
box-shadow: var(--ol-card-shadow);
}
.ol-settings-surface {
background: var(--ol-settings-content-bg);
}
.ol-settings-surface[data-ol-mobile="true"] {
border-radius: var(--ol-panel-radius) var(--ol-panel-radius) 0 0;
}
.ol-capsule-pill {
background: var(--ol-capsule-pill-bg) !important;
border-color: var(--ol-capsule-pill-border) !important;
}
html[data-ol-platform="linux"] .ol-capsule-pill,
html[data-ol-platform="android"] .ol-capsule-pill {
background: var(--ol-capsule-pill-bg) !important;
}
/* ── 滚动边缘渐隐(.ol-scroll-fade)──────────────────────────────────────────
参照 shadcn scroll-fade 工具的行为,纯 CSS scroll-driven animations 实现:
静止在顶部时顶缘清晰、底缘 28px 渐隐提示「下面还有内容」;滚动中双边渐隐;
滚到底部时底缘恢复清晰。两个注册的 <length> 自定义属性充当 mask 渐变里的
动画插值目标(初始值 = 静止在顶部的状态)。 */
@property --ol-sf-t {
syntax: '<length>';
inherits: false;
initial-value: 0px;
}
@property --ol-sf-b {
syntax: '<length>';
inherits: false;
initial-value: 28px;
}
/* 三层 mask 取交集:顶缘渐隐层 ∩ 底缘渐隐层 ∩ 全黑兜底层。
-webkit-mask-composite: source-in 等价于标准 mask-composite: intersect;
两者都写、标准属性在后 —— 新引擎用标准值,老 WebKit 走前缀值。 */
.ol-scroll-fade {
-webkit-mask-image:
linear-gradient(to bottom, transparent, black var(--ol-sf-t)),
linear-gradient(to top, transparent, black var(--ol-sf-b)),
linear-gradient(black, black);
mask-image:
linear-gradient(to bottom, transparent, black var(--ol-sf-t)),
linear-gradient(to top, transparent, black var(--ol-sf-b)),
linear-gradient(black, black);
-webkit-mask-composite: source-in;
mask-composite: intersect;
}
@supports (animation-timeline: scroll(self y)) {
/* 滚动驱动:开头 96px 行程里顶缘渐隐 0 → 28px,末尾 96px 行程里底缘
渐隐 28px → 0,fill both 在行程外保持端点值。
注意:animation-timeline / animation-range 必须写在 animation 简写之后,
简写会把它们重置回初始值。
已知限制:内容不溢出时 scroll(self y) 时间线不激活,自定义属性回落到
初始值 —— 底缘仍有 28px 渐隐轻微作用在不可滚动容器的末端(通常落在
内边距上几乎不可见),与下方静态降级的限制一致,接受。 */
.ol-scroll-fade {
animation:
ol-sf-top linear both,
ol-sf-bottom linear both;
animation-timeline: scroll(self y);
animation-range: 0 96px, calc(100% - 96px) 100%;
}
@keyframes ol-sf-top {
from { --ol-sf-t: 0px; }
to { --ol-sf-t: 28px; }
}
@keyframes ol-sf-bottom {
from { --ol-sf-b: 28px; }
to { --ol-sf-b: 0px; }
}
}
/* 降级(macOS 现行 WKWebView 尚无 scroll-driven animations):静态双边渐隐,
不随滚动位置变化;单层 mask 无需分层合成,把 composite 重置回默认,
规避老 WebKit 单层 + source-in 的兼容怪癖。限制同上:不可滚动的容器
两缘也会有 28px 轻微渐隐。 */
@supports not (animation-timeline: scroll(self y)) {
.ol-scroll-fade {
-webkit-mask-image: linear-gradient(to bottom, transparent, black 28px, black calc(100% - 28px), transparent);
mask-image: linear-gradient(to bottom, transparent, black 28px, black calc(100% - 28px), transparent);
-webkit-mask-composite: source-over;
mask-composite: add;
}
}