feat: 添加现代化布局和动画优化

- 新增 modern-enhancements.css 样式文件
  - Material Design 3 动画系统变量
  - 桌面端卡片悬停效果增强(阴影、位移、缩放)
  - 移动端触摸反馈优化(涟漪效果、按压缩放)
  - 滚动入场动画(文章列表、侧边栏交错入场)
  - 页面过渡效果(PJAX 加载动画)
  - 浮动按钮弹性动画
  - 顶栏滚动效果优化
  - 评论区入场动画
  - 表单元素聚焦动画
  - 滚动条美化
  - 减少动画偏好支持

- 新增 modern-enhancements.js 脚本文件
  - 触摸涟漪效果(移动端)
  - 图片懒加载动画
  - 滚动入场动画(Intersection Observer)
  - 页面加载进度条
  - PJAX 加载动画增强
  - 主题切换过渡动画

- 修改 header.php
  - 引入新的 CSS 和 JS 文件
This commit is contained in:
2026-01-16 00:33:43 +08:00
parent 8885a85ce2
commit 9a19ccb864
3 changed files with 1227 additions and 0 deletions

903
modern-enhancements.css Normal file
View File

@@ -0,0 +1,903 @@
/**
* Argon Theme - Modern UI Enhancements
* 现代化布局和动画优化
*
* 特性:
* - Material Design 3 动画系统
* - 桌面端悬停效果增强
* - 移动端触摸反馈优化
* - 滚动驱动动画
* - 页面过渡效果
*/
/* ========== 1. 增强动画变量 ========== */
:root {
/* 微交互时长 */
--micro-duration: 80ms;
/* 高级缓动函数 */
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
--ease-in-out-expo: cubic-bezier(0.87, 0, 0.13, 1);
--ease-elastic: cubic-bezier(0.68, -0.6, 0.32, 1.6);
--ease-back: cubic-bezier(0.34, 1.56, 0.64, 1);
/* 阴影层级 - Material 3 */
--shadow-1: 0 1px 2px rgba(0, 0, 0, 0.05), 0 1px 3px rgba(0, 0, 0, 0.1);
--shadow-2: 0 2px 4px rgba(0, 0, 0, 0.05), 0 4px 8px rgba(0, 0, 0, 0.1);
--shadow-3: 0 4px 8px rgba(0, 0, 0, 0.05), 0 8px 16px rgba(0, 0, 0, 0.1);
--shadow-4: 0 8px 16px rgba(0, 0, 0, 0.08), 0 16px 32px rgba(0, 0, 0, 0.12);
--shadow-5: 0 12px 24px rgba(0, 0, 0, 0.1), 0 24px 48px rgba(0, 0, 0, 0.15);
/* 悬停阴影 - 带主题色光晕 */
--shadow-hover: 0 8px 25px rgba(0, 0, 0, 0.1),
0 4px 10px rgba(var(--themecolor-rgbstr), 0.08);
--shadow-active: 0 2px 8px rgba(0, 0, 0, 0.08);
}
html.darkmode {
--shadow-1: 0 1px 2px rgba(0, 0, 0, 0.2), 0 1px 3px rgba(0, 0, 0, 0.3);
--shadow-2: 0 2px 4px rgba(0, 0, 0, 0.2), 0 4px 8px rgba(0, 0, 0, 0.3);
--shadow-3: 0 4px 8px rgba(0, 0, 0, 0.2), 0 8px 16px rgba(0, 0, 0, 0.3);
--shadow-4: 0 8px 16px rgba(0, 0, 0, 0.25), 0 16px 32px rgba(0, 0, 0, 0.35);
--shadow-5: 0 12px 24px rgba(0, 0, 0, 0.3), 0 24px 48px rgba(0, 0, 0, 0.4);
--shadow-hover: 0 8px 25px rgba(0, 0, 0, 0.35),
0 4px 10px rgba(var(--themecolor-rgbstr), 0.15);
}
/* ========== 2. 桌面端卡片悬停效果增强 ========== */
@media (hover: hover) and (pointer: fine) {
/* 文章卡片 - 高级悬停效果 */
article.post.card {
transition: transform var(--animation-normal) var(--ease-out-expo),
box-shadow var(--animation-normal) var(--ease-standard);
will-change: transform, box-shadow;
}
article.post.card:hover {
transform: translateY(-6px) scale(1.005);
box-shadow: var(--shadow-hover);
}
article.post.card:active {
transform: translateY(-2px) scale(0.995);
box-shadow: var(--shadow-active);
transition-duration: var(--micro-duration);
}
/* 缩略图悬停缩放 */
article.post.card .post-thumbnail {
transition: transform var(--animation-slow) var(--ease-out-expo);
will-change: transform;
}
article.post.card:hover .post-thumbnail {
transform: scale(1.05);
}
/* 通用卡片悬停 */
.card:not(article):not(.no-hover-effect) {
transition: transform var(--animation-normal) var(--ease-standard),
box-shadow var(--animation-normal) var(--ease-standard);
}
.card:not(article):not(.no-hover-effect):hover {
transform: translateY(-3px);
box-shadow: var(--shadow-3);
}
/* 侧边栏卡片悬停 */
#leftbar .card,
#rightbar .card {
transition: transform var(--animation-normal) var(--ease-standard),
box-shadow var(--animation-normal) var(--ease-standard),
border-color var(--animation-fast) var(--ease-standard);
}
#leftbar .card:hover,
#rightbar .card:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-2);
border-color: rgba(var(--themecolor-rgbstr), 0.15);
}
/* 按钮悬停效果增强 */
.btn {
transition: all var(--animation-fast) var(--ease-standard);
position: relative;
overflow: hidden;
}
.btn::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(180deg, rgba(255,255,255,0.15) 0%, transparent 100%);
opacity: 0;
transition: opacity var(--animation-fast) var(--ease-standard);
pointer-events: none;
}
.btn:hover::after {
opacity: 1;
}
.btn:hover {
transform: translateY(-1px);
}
.btn:active {
transform: translateY(0) scale(0.98);
transition-duration: var(--micro-duration);
}
/* 链接下划线动画 */
article .post-content a:not([class*="button"]):not(.no-underline) {
background-image: linear-gradient(var(--themecolor), var(--themecolor));
background-size: 0% 2px;
background-position: 0 100%;
background-repeat: no-repeat;
transition: background-size var(--animation-normal) var(--ease-out-expo);
}
article .post-content a:not([class*="button"]):not(.no-underline):hover {
background-size: 100% 2px;
}
/* 导航菜单项悬停 */
.navbar-nav .nav-link {
position: relative;
transition: color var(--animation-fast) var(--ease-standard);
}
.navbar-nav .nav-link::before {
content: "";
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 2px;
background: currentColor;
transition: width var(--animation-normal) var(--ease-out-expo),
left var(--animation-normal) var(--ease-out-expo);
border-radius: 1px;
}
.navbar-nav .nav-link:hover::before {
width: 100%;
left: 0;
}
/* 评论卡片悬停 */
.comment-item {
transition: transform var(--animation-normal) var(--ease-standard),
box-shadow var(--animation-normal) var(--ease-standard);
}
.comment-item:hover {
transform: translateX(4px);
box-shadow: -4px 0 0 var(--themecolor);
}
}
/* ========== 3. 滚动入场动画 ========== */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeInScale {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes slideInLeft {
from {
opacity: 0;
transform: translateX(-20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideInRight {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* 文章列表入场动画 */
.article-list article.post {
animation: fadeInUp var(--animation-slow) var(--ease-emphasized-decelerate) both;
}
.article-list article.post:nth-child(1) { animation-delay: 0ms; }
.article-list article.post:nth-child(2) { animation-delay: 50ms; }
.article-list article.post:nth-child(3) { animation-delay: 100ms; }
.article-list article.post:nth-child(4) { animation-delay: 150ms; }
.article-list article.post:nth-child(5) { animation-delay: 200ms; }
.article-list article.post:nth-child(6) { animation-delay: 250ms; }
.article-list article.post:nth-child(7) { animation-delay: 300ms; }
.article-list article.post:nth-child(8) { animation-delay: 350ms; }
.article-list article.post:nth-child(n+9) { animation-delay: 400ms; }
/* 侧边栏入场动画 */
#leftbar .card {
animation: slideInLeft var(--animation-slow) var(--ease-emphasized-decelerate) both;
}
#leftbar .card:nth-child(1) { animation-delay: 100ms; }
#leftbar .card:nth-child(2) { animation-delay: 150ms; }
#leftbar .card:nth-child(3) { animation-delay: 200ms; }
#leftbar .card:nth-child(4) { animation-delay: 250ms; }
#leftbar .card:nth-child(5) { animation-delay: 300ms; }
#rightbar .card {
animation: slideInRight var(--animation-slow) var(--ease-emphasized-decelerate) both;
}
#rightbar .card:nth-child(1) { animation-delay: 100ms; }
#rightbar .card:nth-child(2) { animation-delay: 150ms; }
#rightbar .card:nth-child(3) { animation-delay: 200ms; }
/* ========== 4. 页面过渡效果 ========== */
/* PJAX 页面切换动画 */
#primary.pjax-loading {
opacity: 0.6;
transform: translateY(10px);
pointer-events: none;
}
#primary {
transition: opacity var(--animation-normal) var(--ease-standard),
transform var(--animation-normal) var(--ease-standard);
}
/* 内容淡入效果 */
@keyframes contentFadeIn {
from {
opacity: 0;
transform: translateY(15px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
article.post.post-full {
animation: contentFadeIn var(--animation-slow) var(--ease-emphasized-decelerate);
}
/* ========== 5. 浮动按钮动画优化 ========== */
#float_action_buttons {
transition: transform var(--animation-normal) var(--ease-back),
opacity var(--animation-normal) var(--ease-standard);
}
#float_action_buttons .fabtn {
transition: transform var(--animation-fast) var(--ease-spring),
background var(--animation-fast) var(--ease-standard),
box-shadow var(--animation-fast) var(--ease-standard),
opacity var(--animation-normal) var(--ease-standard);
}
@media (hover: hover) {
#float_action_buttons .fabtn:hover {
transform: scale(1.1);
box-shadow: var(--shadow-3);
}
}
#float_action_buttons .fabtn:active {
transform: scale(0.9);
transition-duration: var(--micro-duration);
}
/* 浮动按钮入场动画 */
@keyframes fabtnBounceIn {
0% {
opacity: 0;
transform: scale(0.3);
}
50% {
transform: scale(1.05);
}
70% {
transform: scale(0.95);
}
100% {
opacity: 1;
transform: scale(1);
}
}
#float_action_buttons:not(.fabtns-unloaded) .fabtn:not(.fabtn-hidden) {
animation: fabtnBounceIn var(--animation-slow) var(--ease-spring) both;
}
#float_action_buttons .fabtn:nth-child(1) { animation-delay: 0ms; }
#float_action_buttons .fabtn:nth-child(2) { animation-delay: 50ms; }
#float_action_buttons .fabtn:nth-child(3) { animation-delay: 100ms; }
#float_action_buttons .fabtn:nth-child(4) { animation-delay: 150ms; }
#float_action_buttons .fabtn:nth-child(5) { animation-delay: 200ms; }
/* ========== 6. 顶栏动画优化 ========== */
#navbar-main {
transition: background-color var(--animation-normal) var(--ease-standard),
padding var(--animation-normal) var(--ease-standard),
box-shadow var(--animation-normal) var(--ease-standard),
transform var(--animation-normal) var(--ease-standard),
backdrop-filter var(--animation-normal) var(--ease-standard);
}
/* 顶栏滚动效果 */
#navbar-main:not(.navbar-ontop) {
box-shadow: var(--shadow-2);
}
/* 搜索框展开动画 */
#navbar_search_input_container .input-group {
transition: width var(--animation-normal) var(--ease-out-expo),
background var(--animation-fast) var(--ease-standard),
box-shadow var(--animation-fast) var(--ease-standard);
}
#navbar_search_input_container.open .input-group {
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}
/* ========== 7. 评论区动画 ========== */
.comment-item {
animation: fadeInUp var(--animation-normal) var(--ease-emphasized-decelerate) both;
}
/* 评论交错入场 */
.comment-item:nth-child(1) { animation-delay: 0ms; }
.comment-item:nth-child(2) { animation-delay: 30ms; }
.comment-item:nth-child(3) { animation-delay: 60ms; }
.comment-item:nth-child(4) { animation-delay: 90ms; }
.comment-item:nth-child(5) { animation-delay: 120ms; }
.comment-item:nth-child(n+6) { animation-delay: 150ms; }
/* 评论发送成功动画 */
@keyframes commentSuccess {
0% {
transform: scale(0.8);
opacity: 0;
}
50% {
transform: scale(1.02);
}
100% {
transform: scale(1);
opacity: 1;
}
}
.comment-item.new-comment {
animation: commentSuccess var(--animation-slow) var(--ease-spring);
}
/* ========== 8. 图片加载动画 ========== */
article img,
.post-thumbnail img {
transition: opacity var(--animation-normal) var(--ease-standard);
}
article img[loading="lazy"],
.post-thumbnail img[loading="lazy"] {
opacity: 0;
}
article img.loaded,
.post-thumbnail img.loaded,
article img:not([loading="lazy"]),
.post-thumbnail img:not([loading="lazy"]) {
opacity: 1;
}
/* ========== 9. 表单元素动画 ========== */
.form-control {
transition: border-color var(--animation-fast) var(--ease-standard),
box-shadow var(--animation-fast) var(--ease-standard),
background-color var(--animation-fast) var(--ease-standard);
}
.form-control:focus {
box-shadow: 0 0 0 3px rgba(var(--themecolor-rgbstr), 0.15);
border-color: var(--themecolor);
}
/* 输入框标签浮动效果 */
.form-group.floating-label {
position: relative;
}
.form-group.floating-label label {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
transition: all var(--animation-fast) var(--ease-standard);
pointer-events: none;
color: #999;
background: var(--color-foreground);
padding: 0 4px;
}
.form-group.floating-label .form-control:focus ~ label,
.form-group.floating-label .form-control:not(:placeholder-shown) ~ label {
top: 0;
font-size: 12px;
color: var(--themecolor);
}
/* ========== 10. 滚动条美化 ========== */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: rgba(var(--themecolor-rgbstr), 0.3);
border-radius: 4px;
border: 2px solid transparent;
background-clip: content-box;
transition: background var(--animation-fast) var(--ease-standard);
}
::-webkit-scrollbar-thumb:hover {
background: rgba(var(--themecolor-rgbstr), 0.5);
background-clip: content-box;
}
/* Firefox 滚动条 */
* {
scrollbar-width: thin;
scrollbar-color: rgba(var(--themecolor-rgbstr), 0.3) transparent;
}
/* ========== 11. 移动端触摸优化 ========== */
@media (hover: none) and (pointer: coarse) {
/* 移动端禁用悬停效果,优化触摸反馈 */
article.post.card:hover {
transform: none;
box-shadow: var(--shadow-1);
}
/* 触摸反馈 - 按下效果 */
article.post.card:active {
transform: scale(0.98);
transition-duration: var(--micro-duration);
}
.card:active {
transform: scale(0.99);
transition-duration: var(--micro-duration);
}
/* 按钮触摸反馈 */
.btn:active {
transform: scale(0.95);
transition-duration: var(--micro-duration);
}
/* 链接触摸反馈 */
a:active {
opacity: 0.7;
}
/* 移动端点击高亮禁用 */
* {
-webkit-tap-highlight-color: transparent;
}
/* 触摸涟漪效果基础样式 */
.touch-ripple {
position: absolute;
border-radius: 50%;
background: rgba(var(--themecolor-rgbstr), 0.25);
transform: scale(0);
animation: touchRipple 0.6s var(--ease-out-expo) forwards;
pointer-events: none;
}
@keyframes touchRipple {
to {
transform: scale(4);
opacity: 0;
}
}
}
/* ========== 12. 移动端侧边栏动画增强 ========== */
@media screen and (max-width: 900px) {
/* 侧边栏滑入动画 */
#leftbar {
transition: transform var(--animation-normal) var(--ease-out-expo),
box-shadow var(--animation-normal) var(--ease-standard);
transform: translateX(-100%);
box-shadow: none;
}
html.leftbar-opened #leftbar {
transform: translateX(0);
box-shadow: 4px 0 25px rgba(0, 0, 0, 0.15);
}
/* 遮罩层动画 */
#leftbar_backdrop {
transition: opacity var(--animation-normal) var(--ease-standard),
visibility var(--animation-normal);
}
/* 侧边栏内容入场动画 */
html.leftbar-opened .leftbar-mobile-profile {
animation: slideInDown var(--animation-normal) var(--ease-emphasized-decelerate) 0.1s both;
}
html.leftbar-opened .leftbar-mobile-search {
animation: fadeInUp var(--animation-normal) var(--ease-emphasized-decelerate) 0.15s both;
}
html.leftbar-opened .leftbar-mobile-menu-section {
animation: fadeInUp var(--animation-normal) var(--ease-emphasized-decelerate) 0.2s both;
}
html.leftbar-opened .leftbar-mobile-footer {
animation: fadeInUp var(--animation-normal) var(--ease-emphasized-decelerate) 0.25s both;
}
@keyframes slideInDown {
from {
opacity: 0;
transform: translateY(-15px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 移动端菜单项触摸反馈 */
.leftbar-mobile-menu-item > a {
transition: background var(--animation-fast) var(--ease-standard),
transform var(--micro-duration) var(--ease-standard);
}
.leftbar-mobile-menu-item > a:active {
background: rgba(var(--themecolor-rgbstr), 0.12);
transform: scale(0.98);
}
/* 移动端底部导航栏(如果有) */
.mobile-bottom-nav {
transition: transform var(--animation-normal) var(--ease-standard);
}
.mobile-bottom-nav.hidden {
transform: translateY(100%);
}
/* 移动端文章卡片优化 */
article.post.card {
transition: transform var(--micro-duration) var(--ease-standard),
box-shadow var(--animation-fast) var(--ease-standard);
}
article.post.card:active {
transform: scale(0.98);
}
/* 移动端顶栏优化 */
#navbar-main {
transition: transform var(--animation-normal) var(--ease-standard),
background-color var(--animation-fast) var(--ease-standard);
}
/* 移动端搜索框展开 */
#navbar_search_input_container {
transition: width var(--animation-normal) var(--ease-out-expo);
}
}
/* ========== 13. 骨架屏加载动画 ========== */
@keyframes skeletonPulse {
0% {
background-position: -200% 0;
}
100% {
background-position: 200% 0;
}
}
.skeleton {
background: linear-gradient(
90deg,
var(--color-border-on-foreground) 25%,
var(--color-border-on-foreground-deeper) 50%,
var(--color-border-on-foreground) 75%
);
background-size: 200% 100%;
animation: skeletonPulse 1.5s ease-in-out infinite;
border-radius: var(--card-radius);
}
/* ========== 14. 加载指示器 ========== */
@keyframes spinnerRotate {
to {
transform: rotate(360deg);
}
}
.loading-spinner {
width: 24px;
height: 24px;
border: 2px solid var(--color-border);
border-top-color: var(--themecolor);
border-radius: 50%;
animation: spinnerRotate 0.8s linear infinite;
}
/* 页面加载进度条 */
#page-loading-bar {
position: fixed;
top: 0;
left: 0;
height: 3px;
background: var(--themecolor-gradient);
z-index: 9999;
transition: width var(--animation-fast) var(--ease-out-expo);
box-shadow: 0 0 10px rgba(var(--themecolor-rgbstr), 0.5);
}
/* ========== 15. 模态框/弹窗动画 ========== */
.modal {
transition: opacity var(--animation-normal) var(--ease-standard);
}
.modal.show {
opacity: 1;
}
.modal-dialog {
transition: transform var(--animation-normal) var(--ease-emphasized-decelerate),
opacity var(--animation-normal) var(--ease-standard);
transform: scale(0.9) translateY(-20px);
opacity: 0;
}
.modal.show .modal-dialog {
transform: scale(1) translateY(0);
opacity: 1;
}
/* 底部弹出式模态框(移动端) */
@media screen and (max-width: 900px) {
.modal-dialog.modal-bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
margin: 0;
transform: translateY(100%);
border-radius: 20px 20px 0 0;
}
.modal.show .modal-dialog.modal-bottom {
transform: translateY(0);
}
}
/* ========== 16. 下拉菜单动画 ========== */
.dropdown-menu {
opacity: 0;
transform: translateY(-10px) scale(0.95);
transform-origin: top center;
transition: opacity var(--animation-fast) var(--ease-standard),
transform var(--animation-fast) var(--ease-emphasized-decelerate),
visibility var(--animation-fast);
visibility: hidden;
}
.dropdown-menu.show {
opacity: 1;
transform: translateY(0) scale(1);
visibility: visible;
}
.dropdown-item {
transition: background var(--animation-fast) var(--ease-standard),
color var(--animation-fast) var(--ease-standard);
}
/* ========== 17. 工具提示动画 ========== */
.tooltip {
opacity: 0;
transform: translateY(5px);
transition: opacity var(--animation-fast) var(--ease-standard),
transform var(--animation-fast) var(--ease-emphasized-decelerate);
}
.tooltip.show {
opacity: 1;
transform: translateY(0);
}
/* ========== 18. 标签和徽章动画 ========== */
.badge,
.tag {
transition: transform var(--animation-fast) var(--ease-spring),
background var(--animation-fast) var(--ease-standard);
}
@media (hover: hover) {
.badge:hover,
.tag:hover {
transform: scale(1.05);
}
}
.badge:active,
.tag:active {
transform: scale(0.95);
}
/* ========== 19. 分页动画 ========== */
.pagination .page-link {
transition: all var(--animation-fast) var(--ease-standard);
}
@media (hover: hover) {
.pagination .page-link:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-2);
}
}
.pagination .page-link:active {
transform: translateY(0) scale(0.95);
}
/* ========== 20. 目录导航动画 ========== */
.index-link {
transition: all var(--animation-fast) var(--ease-standard);
position: relative;
}
.index-link::before {
content: "";
position: absolute;
left: -8px;
top: 50%;
transform: translateY(-50%) scaleY(0);
width: 3px;
height: 60%;
background: var(--themecolor);
border-radius: 2px;
transition: transform var(--animation-normal) var(--ease-spring);
}
.index-item.current > .index-link::before {
transform: translateY(-50%) scaleY(1);
}
/* ========== 21. 时间线动画 ========== */
.timeline-item {
opacity: 0;
transform: translateX(-20px);
animation: timelineSlideIn var(--animation-slow) var(--ease-emphasized-decelerate) forwards;
}
@keyframes timelineSlideIn {
to {
opacity: 1;
transform: translateX(0);
}
}
.timeline-item:nth-child(1) { animation-delay: 0ms; }
.timeline-item:nth-child(2) { animation-delay: 100ms; }
.timeline-item:nth-child(3) { animation-delay: 200ms; }
.timeline-item:nth-child(4) { animation-delay: 300ms; }
.timeline-item:nth-child(5) { animation-delay: 400ms; }
.timeline-item:nth-child(n+6) { animation-delay: 500ms; }
/* ========== 22. 友链卡片动画 ========== */
.friend-link-item {
transition: transform var(--animation-normal) var(--ease-spring),
box-shadow var(--animation-normal) var(--ease-standard);
}
@media (hover: hover) {
.friend-link-item:hover {
transform: translateY(-5px) rotate(1deg);
box-shadow: var(--shadow-4);
}
.friend-link-item:hover .friend-link-avatar {
transform: scale(1.1) rotate(-5deg);
}
}
.friend-link-avatar {
transition: transform var(--animation-normal) var(--ease-spring);
}
/* ========== 23. 代码块动画 ========== */
.hljs-codeblock {
transition: box-shadow var(--animation-normal) var(--ease-standard);
}
@media (hover: hover) {
.hljs-codeblock:hover {
box-shadow: var(--shadow-3);
}
}
/* 代码复制按钮 */
.code-copy-btn {
opacity: 0;
transform: translateY(-5px);
transition: opacity var(--animation-fast) var(--ease-standard),
transform var(--animation-fast) var(--ease-standard),
background var(--animation-fast) var(--ease-standard);
}
.hljs-codeblock:hover .code-copy-btn {
opacity: 1;
transform: translateY(0);
}
/* ========== 24. 减少动画偏好支持 ========== */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
/* 保留必要的过渡 */
.card,
.btn,
a {
transition: none !important;
}
}
/* ========== 25. 打印样式优化 ========== */
@media print {
*,
*::before,
*::after {
animation: none !important;
transition: none !important;
}
}