feat(display): falling snow in three depth layers with wind, mouse and bullet time; appearance panel; dark glass tinted from the background [CI SKIP]
This commit is contained in:
1 parent
f8e8bb8acb
commit
e49990776b
10 files changed
+1003
-7
No files matched your search
@@ -1012,6 +1012,8 @@
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
pointer-events: none;
|
||||
/* 在预先模糊的基础上再模糊多少,右下角「外观」里调;默认 none */
|
||||
filter: var(--bg-filter, none);
|
||||
}
|
||||
|
||||
:root {
|
||||
@@ -1382,3 +1384,276 @@ input {
|
||||
height: 20px;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
/* 天气(雪、雨):铺满窗口,和背景图同一层(在背景图后面画、所有内容的下面),不接收鼠标;所以卡片的毛玻璃会把它一起模糊,不会挡住任何组件 */
|
||||
.weather-layer {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
/* 滤色:粒子只会把背后的图提亮,边缘羽化的地方自然融进图里 */
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
|
||||
@media (max-width: 640px), ((pointer: coarse) and (max-width: 900px)) {
|
||||
.weather-layer {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── 右下角的「外观」:玻璃小按钮,点开是带分类的设置面板(亚克力同一套变量);手机上不画雪也不能晃背景,这个也不显示 ── */
|
||||
.appearance {
|
||||
position: fixed;
|
||||
right: 16px;
|
||||
bottom: 16px;
|
||||
z-index: 35;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.appearance-fab {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: 50%;
|
||||
color: var(--app-ink-muted);
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: var(--glass-filter);
|
||||
box-shadow:
|
||||
inset 0 0 0 1px var(--glass-ring),
|
||||
inset 0 1px 0 var(--glass-top),
|
||||
var(--glass-drop);
|
||||
cursor: pointer;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
|
||||
.appearance-fab svg {
|
||||
transition: transform 0.35s cubic-bezier(0.34, 1.4, 0.64, 1);
|
||||
}
|
||||
|
||||
.appearance-fab:hover,
|
||||
.appearance-fab[aria-expanded='true'] {
|
||||
color: var(--app-ink);
|
||||
}
|
||||
|
||||
.appearance-fab[aria-expanded='true'] svg {
|
||||
transform: rotate(60deg);
|
||||
}
|
||||
|
||||
/* 面板:从按钮的位置(右下角)展开 / 收起;一直在 DOM 里,用 data-open 切换,这样收起的时候也有动画 */
|
||||
.appearance-panel {
|
||||
width: 300px;
|
||||
padding: 14px 16px 16px;
|
||||
border-radius: var(--r-card);
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: var(--glass-filter);
|
||||
box-shadow:
|
||||
inset 0 0 0 1px var(--glass-ring),
|
||||
inset 0 1px 0 var(--glass-top),
|
||||
var(--glass-drop);
|
||||
color: var(--app-ink);
|
||||
font-size: 13px;
|
||||
transform-origin: bottom right;
|
||||
transition:
|
||||
opacity 0.22s ease,
|
||||
transform 0.28s cubic-bezier(0.2, 0.9, 0.3, 1.15),
|
||||
visibility 0s linear 0.28s;
|
||||
}
|
||||
|
||||
.appearance-panel[data-open='false'] {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateY(10px) scale(0.92);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.appearance-panel[data-open='true'] {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: none;
|
||||
transition-delay: 0s;
|
||||
}
|
||||
|
||||
.appearance-tabs {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
margin-bottom: 12px;
|
||||
padding: 3px;
|
||||
border-radius: var(--r-pill);
|
||||
background: color-mix(in srgb, var(--app-ink) 8%, transparent);
|
||||
}
|
||||
|
||||
/* 选中的那一格的底:随选中的分类滑过去 */
|
||||
.appearance-tabs::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
bottom: 3px;
|
||||
left: 3px;
|
||||
width: calc(50% - 3px);
|
||||
border-radius: var(--r-pill);
|
||||
background: var(--app-card);
|
||||
box-shadow: 0 1px 3px color-mix(in srgb, var(--glass-shade) 25%, transparent);
|
||||
transform: translateX(var(--tab-offset, 0));
|
||||
transition: transform 0.28s cubic-bezier(0.3, 0.9, 0.3, 1.1);
|
||||
}
|
||||
|
||||
.appearance-tabs[data-tab='background']::before {
|
||||
--tab-offset: 100%;
|
||||
}
|
||||
|
||||
.appearance-tabs button {
|
||||
position: relative;
|
||||
padding: 5px 0;
|
||||
border: 0;
|
||||
border-radius: var(--r-pill);
|
||||
color: var(--app-ink-muted);
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.appearance-tabs button[aria-selected='true'] {
|
||||
color: var(--app-ink);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 切换分类时内容淡入、轻轻上浮;每一行再错开一点 */
|
||||
.appearance-body {
|
||||
display: grid;
|
||||
gap: 9px;
|
||||
}
|
||||
|
||||
.appearance-body > * {
|
||||
animation: appearance-in 0.32s ease both;
|
||||
}
|
||||
|
||||
.appearance-body > :nth-child(2) { animation-delay: 0.03s; }
|
||||
.appearance-body > :nth-child(3) { animation-delay: 0.06s; }
|
||||
.appearance-body > :nth-child(4) { animation-delay: 0.09s; }
|
||||
.appearance-body > :nth-child(5) { animation-delay: 0.12s; }
|
||||
.appearance-body > :nth-child(6) { animation-delay: 0.15s; }
|
||||
.appearance-body > :nth-child(7) { animation-delay: 0.18s; }
|
||||
.appearance-body > :nth-child(8) { animation-delay: 0.21s; }
|
||||
.appearance-body > :nth-child(9) { animation-delay: 0.24s; }
|
||||
|
||||
@keyframes appearance-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(6px);
|
||||
}
|
||||
}
|
||||
|
||||
.appearance-body[data-off='true'] .appearance-row:not(.appearance-master) {
|
||||
opacity: 0.45;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.appearance-row {
|
||||
display: grid;
|
||||
grid-template-columns: 52px 1fr 44px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.appearance-row-switch {
|
||||
grid-template-columns: 1fr auto;
|
||||
}
|
||||
|
||||
.appearance-row output {
|
||||
text-align: right;
|
||||
color: var(--app-ink-muted);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.appearance-row input[type='range'] {
|
||||
width: 100%;
|
||||
accent-color: var(--app-primary);
|
||||
}
|
||||
|
||||
.appearance-switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 34px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.appearance-switch input {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
margin: 0;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.appearance-switch span {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 10px;
|
||||
background: color-mix(in srgb, var(--app-ink) 22%, transparent);
|
||||
pointer-events: none;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.appearance-switch span::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
background: var(--app-card);
|
||||
transition: transform 0.25s cubic-bezier(0.34, 1.4, 0.64, 1);
|
||||
}
|
||||
|
||||
.appearance-switch input:checked + span {
|
||||
background: var(--app-primary);
|
||||
}
|
||||
|
||||
.appearance-switch input:checked + span::after {
|
||||
transform: translateX(14px);
|
||||
}
|
||||
|
||||
.appearance-reset {
|
||||
margin-top: 12px;
|
||||
width: 100%;
|
||||
padding: 6px 0;
|
||||
border: 0;
|
||||
border-radius: var(--r-pill);
|
||||
color: var(--app-ink-muted);
|
||||
background: color-mix(in srgb, var(--app-ink) 8%, transparent);
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.appearance-reset:disabled {
|
||||
opacity: 0.4;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.appearance-panel,
|
||||
.appearance-tabs::before,
|
||||
.appearance-body > *,
|
||||
.appearance-fab svg,
|
||||
.appearance-switch span::after {
|
||||
animation: none;
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px), ((pointer: coarse) and (max-width: 900px)) {
|
||||
.appearance {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user