450 lines
12 KiB
CSS
450 lines
12 KiB
CSS
|
|
/* ============================================================
|
|
* 响应式
|
|
* ============================================================ */
|
|
@media (max-width: 640px) {
|
|
.aksrt-lightbox__nav {
|
|
width: 36px;
|
|
height: 36px;
|
|
font-size: 18px;
|
|
}
|
|
|
|
.single-cover-slider__img {
|
|
height: 240px;
|
|
}
|
|
|
|
.single-cover-slider__title {
|
|
font-size: 18px;
|
|
}
|
|
|
|
.reward-modal__card {
|
|
padding: 24px;
|
|
}
|
|
|
|
.reward-modal__qr {
|
|
width: 160px;
|
|
height: 160px;
|
|
}
|
|
|
|
.aksrt-cover-cards {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.aksrt-cover-card {
|
|
min-height: 140px;
|
|
}
|
|
}
|
|
|
|
/* ============================================================
|
|
* 13. 无障碍:prefers-reduced-motion
|
|
* 用户系统设置"减少动画"时,禁用所有非必要动效
|
|
* ============================================================ */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
*,
|
|
*::before,
|
|
*::after {
|
|
animation-duration: 0.01ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
transition-duration: 0.01ms !important;
|
|
scroll-behavior: auto !important;
|
|
}
|
|
|
|
.aksrt-skeleton {
|
|
animation: none !important;
|
|
}
|
|
|
|
[data-aksrt-animate] {
|
|
opacity: 1 !important;
|
|
transform: none !important;
|
|
}
|
|
}
|
|
|
|
/* legacy lazySizes state and animation contract. */
|
|
.lazyloaded {
|
|
transition: 0.3s;
|
|
--lazy-animation: lazy_blur;
|
|
}
|
|
|
|
.lazyloaded.img-icon {
|
|
--lazy-animation: lazy_fade;
|
|
}
|
|
|
|
img.lazyloaded:not(.lazyloadafter) {
|
|
-webkit-animation: var(--lazy-animation) 0.6s;
|
|
animation: var(--lazy-animation) 0.6s;
|
|
}
|
|
|
|
@keyframes lazy_blur {
|
|
0% { filter: blur(5px); }
|
|
100% { filter: blur(0); }
|
|
}
|
|
|
|
@keyframes lazy_fade {
|
|
0% { opacity: 0; }
|
|
100% { opacity: 1; }
|
|
}
|
|
|
|
@keyframes lazy_scale {
|
|
0% { transform: scale(1.1); }
|
|
80% { transform: unset; }
|
|
}
|
|
|
|
/* ============================================================
|
|
* 15. 错误反馈 shake 动画
|
|
* 表单验证失败时的水平抖动效果
|
|
* ============================================================ */
|
|
@keyframes aksrtShake {
|
|
0%, 100% { transform: translateX(0); }
|
|
10%, 30%, 50%, 70%, 90% { transform: translateX(-4px); }
|
|
20%, 40%, 60%, 80% { transform: translateX(4px); }
|
|
}
|
|
|
|
.aksrt-shake {
|
|
animation: aksrtShake 0.4s ease-in-out;
|
|
}
|
|
|
|
/* 应用于 Naive UI 表单验证 */
|
|
.n-form-item--error .n-input,
|
|
.n-form-item--error .n-select,
|
|
.n-form-item--error .n-input-number {
|
|
animation: aksrtShake 0.3s ease-in-out;
|
|
}
|
|
|
|
/* ============================================================
|
|
* 16. FPS 加速模式:低端设备禁用 backdrop-filter
|
|
* 模仿 legacy 的 body.fps-accelerat 模式
|
|
* ============================================================ */
|
|
body.fps-accelerat .site-nav,
|
|
body.fps-accelerat .footer-tabbar,
|
|
body.fps-accelerat .float-right .float-btn,
|
|
body.fps-accelerat .aksrt-blur-bg {
|
|
backdrop-filter: none !important;
|
|
-webkit-backdrop-filter: none !important;
|
|
}
|
|
|
|
/* 模态框内禁用 backdrop-filter 避免渲染冲突 */
|
|
body.modal-open .site-nav,
|
|
body.dialog-open .site-nav {
|
|
backdrop-filter: none !important;
|
|
-webkit-backdrop-filter: none !important;
|
|
}
|
|
|
|
/* ============================================================
|
|
* 17. .blur-bg 通用工具类
|
|
* 模仿 legacy 的 .blur-bg,可在任意元素上应用毛玻璃效果
|
|
* ============================================================ */
|
|
.aksrt-blur-bg {
|
|
background: var(--blur-bg);
|
|
backdrop-filter: saturate(5) blur(20px);
|
|
-webkit-backdrop-filter: saturate(5) blur(20px);
|
|
}
|
|
|
|
/* ============================================================
|
|
* 18. 滚动触发动画延迟支持
|
|
* data-aksrt-delay 属性控制入场延迟
|
|
* ============================================================ */
|
|
[data-aksrt-animate][data-aksrt-delay="1"] { transition-delay: 0.1s; }
|
|
[data-aksrt-animate][data-aksrt-delay="2"] { transition-delay: 0.2s; }
|
|
[data-aksrt-animate][data-aksrt-delay="3"] { transition-delay: 0.3s; }
|
|
[data-aksrt-animate][data-aksrt-delay="4"] { transition-delay: 0.4s; }
|
|
[data-aksrt-animate][data-aksrt-delay="5"] { transition-delay: 0.5s; }
|
|
|
|
/* ============================================================
|
|
* 19. 全站动效节奏统一
|
|
* 模仿 legacy 的统一 hover / slide / blur / drawer 语言
|
|
* ============================================================ */
|
|
|
|
/* --- 全局过渡基线 --- */
|
|
a, button, input, select, textarea {
|
|
transition: border-color var(--dur-fast) var(--ease),
|
|
box-shadow var(--dur-fast) var(--ease),
|
|
background-color var(--dur-fast) var(--ease),
|
|
color var(--dur-fast) var(--ease);
|
|
}
|
|
|
|
/* --- 卡片 hover 统一 --- */
|
|
.post-card, .widget, .aksrt-theme-box, .theme-box,
|
|
.comment-body, .friend-card, .special-card,
|
|
.resource-download-box {
|
|
transition: box-shadow var(--dur) var(--ease),
|
|
border-color var(--dur) var(--ease),
|
|
transform var(--dur) var(--ease);
|
|
}
|
|
|
|
.post-card:hover, .widget:hover, .friend-card:hover, .special-card:hover {
|
|
box-shadow: none;
|
|
transform: none;
|
|
}
|
|
|
|
/* --- 按钮 hover 统一 --- */
|
|
.btn-primary, .btn-outline, .btn-lg, .btn-sm,
|
|
.n-button, .aksrt-button {
|
|
transition: all var(--dur-fast) var(--ease);
|
|
}
|
|
|
|
.btn-primary:hover, .n-button--primary-type:hover {
|
|
opacity: 0.85;
|
|
}
|
|
|
|
.btn-primary:active, .n-button--primary-type:active {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* --- 输入框 focus 统一 --- */
|
|
input:focus, textarea:focus, select:focus,
|
|
.n-input--focus, .n-select--focus {
|
|
box-shadow: var(--focus-ring);
|
|
transition: box-shadow var(--dur-fast) var(--ease);
|
|
}
|
|
|
|
/* --- 抽屉/模态框动效统一 --- */
|
|
.n-drawer, .n-modal, .n-dialog {
|
|
transition: all var(--dur) var(--ease-out);
|
|
}
|
|
|
|
.n-drawer-mask, .n-modal-mask, .n-dialog-mask {
|
|
transition: opacity var(--dur) var(--ease);
|
|
}
|
|
|
|
/* --- Tab 切换动效 --- */
|
|
.n-tabs-tab, .nav-tab, .aksrt-tab {
|
|
transition: color var(--dur-fast) var(--ease),
|
|
border-color var(--dur-fast) var(--ease),
|
|
background-color var(--dur-fast) var(--ease);
|
|
}
|
|
|
|
/* --- 下拉菜单动效 --- */
|
|
.n-dropdown-menu, .aksrt-dropdown {
|
|
transition: opacity var(--dur-fast) var(--ease),
|
|
transform var(--dur-fast) var(--ease-out);
|
|
transform-origin: top;
|
|
}
|
|
|
|
/* --- 骨架屏动效 --- */
|
|
.aksrt-skeleton {
|
|
animation: aksrtSkeletonShimmer 1.5s infinite linear;
|
|
background: linear-gradient(90deg, var(--skeleton-base) 25%, var(--skeleton-shine) 50%, var(--skeleton-base) 75%);
|
|
background-size: 200% 100%;
|
|
}
|
|
|
|
/* --- 页面切换动效 --- */
|
|
.fade-slide-enter-active,
|
|
.fade-slide-leave-active {
|
|
transition: opacity var(--dur) var(--ease),
|
|
transform var(--dur) var(--ease);
|
|
}
|
|
|
|
.fade-slide-enter-from {
|
|
opacity: 0;
|
|
transform: translateY(8px);
|
|
}
|
|
|
|
.fade-slide-leave-to {
|
|
opacity: 0;
|
|
transform: translateY(-8px);
|
|
}
|
|
|
|
/* --- 导航栏滚动动效 --- */
|
|
.site-nav {
|
|
transition: transform var(--dur) var(--ease),
|
|
background-color var(--dur) var(--ease),
|
|
box-shadow var(--dur) var(--ease);
|
|
}
|
|
|
|
.site-nav.aksrt-nav--hidden {
|
|
transform: translateY(-100%);
|
|
}
|
|
|
|
/* --- 浮层弹出动效 --- */
|
|
@keyframes aksrtPopIn {
|
|
0% { opacity: 0; transform: scale(0.95) translateY(-4px); }
|
|
100% { opacity: 1; transform: scale(1) translateY(0); }
|
|
}
|
|
|
|
@keyframes aksrtPopOut {
|
|
0% { opacity: 1; transform: scale(1) translateY(0); }
|
|
100% { opacity: 0; transform: scale(0.95) translateY(-4px); }
|
|
}
|
|
|
|
.aksrt-popover, .aksrt-tooltip, .aksrt-dropdown-panel {
|
|
animation: aksrtPopIn var(--dur-fast) var(--ease-out) forwards;
|
|
}
|
|
|
|
/* --- 滚动进度条动效 --- */
|
|
.reading-progress-bar {
|
|
transition: width 0.1s linear;
|
|
}
|
|
|
|
/* --- 移动端抽屉动效 --- */
|
|
@media (max-width: 767px) {
|
|
.n-drawer {
|
|
transition: transform var(--dur) var(--ease-out);
|
|
}
|
|
|
|
.site-nav .n-drawer-body {
|
|
transition: transform var(--dur) var(--ease-out);
|
|
}
|
|
}
|
|
|
|
/* --- 暗色模式切换动效 --- */
|
|
html.dark {
|
|
transition: background-color 0.3s var(--ease),
|
|
color 0.3s var(--ease);
|
|
}
|
|
|
|
html.dark * {
|
|
transition: background-color 0.3s var(--ease),
|
|
border-color 0.3s var(--ease),
|
|
color 0.3s var(--ease),
|
|
box-shadow 0.3s var(--ease);
|
|
}
|
|
|
|
/* ============================================================
|
|
* 18. 合作伙伴无缝滚动 (marquee)
|
|
* ============================================================ */
|
|
.aksrt-marquee {
|
|
position: relative;
|
|
overflow: hidden;
|
|
width: 100%;
|
|
}
|
|
|
|
.aksrt-marquee__inner {
|
|
display: flex;
|
|
gap: 24px;
|
|
white-space: nowrap;
|
|
will-change: transform;
|
|
}
|
|
|
|
.aksrt-marquee__inner > * {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.aksrt-marquee__inner {
|
|
animation: none !important;
|
|
transform: none !important;
|
|
}
|
|
}
|
|
|
|
/* ============================================================
|
|
* 19. 视频剧集切换按钮
|
|
* ============================================================ */
|
|
.switch-video,
|
|
.switch-iframe {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 6px 14px;
|
|
border: 1px solid var(--color-line, rgba(50, 50, 50, 0.1));
|
|
border-radius: var(--radius, 8px);
|
|
background: var(--surface-1, #fff);
|
|
color: var(--color-ink-2, #4e5358);
|
|
font-size: 13px;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.switch-video:hover,
|
|
.switch-iframe:hover {
|
|
border-color: var(--color-primary);
|
|
color: var(--color-primary);
|
|
}
|
|
|
|
.switch-video.is-active,
|
|
.switch-iframe.is-active {
|
|
background: var(--color-primary);
|
|
border-color: var(--color-primary);
|
|
color: #fff;
|
|
}
|
|
|
|
/* ============================================================
|
|
* 20. 一言轮播组件
|
|
* ============================================================ */
|
|
.aksrt-yiyan {
|
|
padding: 16px;
|
|
text-align: center;
|
|
}
|
|
|
|
.aksrt-yiyan__content {
|
|
min-height: 60px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.aksrt-yiyan__icon {
|
|
font-size: 20px;
|
|
color: var(--color-primary);
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.aksrt-yiyan__text {
|
|
font-size: 14px;
|
|
line-height: 1.8;
|
|
color: var(--color-ink-2, #4e5358);
|
|
margin: 0;
|
|
transition: opacity 0.2s ease;
|
|
font-style: italic;
|
|
}
|
|
|
|
.aksrt-yiyan__from {
|
|
font-size: 12px;
|
|
color: var(--color-ink-4, #999);
|
|
margin: 0;
|
|
}
|
|
|
|
.aksrt-yiyan__dots {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 6px;
|
|
margin-top: 12px;
|
|
}
|
|
|
|
.aksrt-yiyan__dot {
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
background: var(--color-line, rgba(50, 50, 50, 0.1));
|
|
transition: background 0.2s;
|
|
}
|
|
|
|
.aksrt-yiyan__dot.is-active {
|
|
background: var(--color-primary);
|
|
width: 16px;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
/* ============================================================
|
|
* 底部弹出 Sheet — 对齐 legacy .modal.bottom
|
|
* ============================================================ */
|
|
.aksrt-modal--bottom .aksrt-modal-auth__card,
|
|
.modal.bottom .modal-dialog {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
max-width: 100%;
|
|
width: 100%;
|
|
border-radius: var(--main-radius, 8px) var(--main-radius, 8px) 0 0;
|
|
transform: translateY(110%);
|
|
transition: transform 0.4s;
|
|
margin-bottom: 0;
|
|
padding-bottom: env(safe-area-inset-bottom);
|
|
}
|
|
|
|
.aksrt-modal--bottom.is-open .aksrt-modal-auth__card,
|
|
.modal.bottom.in .modal-dialog {
|
|
transform: translateY(0);
|
|
}
|
|
|
|
.aksrt-modal--bottom .aksrt-modal-auth__card,
|
|
.modal.bottom .modal-dialog .modal-content {
|
|
box-shadow: 0 -10px 50px rgba(0, 0, 0, 0.15);
|
|
}
|
|
|