Files
blog-code/src/styles/main.css
2025-12-08 19:39:17 +08:00

664 lines
21 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.

/* 导入相册样式 */
@import './albums.css';
/* 导入追番页面样式 */
@import './anime.css';
/* 导入动画样式 */
@import './transition.css';
@import './animation-enhancements.css';
/* 导入渐变按钮样式 */
@import './gradient-buttons.css';
/* 加密内容样式已移除,现在直接使用非加密文章的样式 */
/* 导入 ZenMaruGothic-Medium 字体 */
@font-face {
font-family: 'ZenMaruGothic-Medium';
src: url('/assets/font/ZenMaruGothic-Medium.woff2') format('woff2');
font-weight: 500;
font-display: swap;
}
@font-face {
font-family: 'XiangcuiDengcusong';
src: url('/assets/font/XiangcuiDengcusong.woff2') format('woff2');
font-weight: 400;
font-display: swap;
}
@tailwind base;
@tailwind components;
@tailwind utilities;
/* 确保平滑滚动 */
html {
scroll-behavior: smooth;
}
/* 页面顶部渐变高光效果 */
.top-gradient-highlight {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 180px;
background: linear-gradient(to bottom, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0.3) 30%, rgba(255, 255, 255, 0.15) 60%, rgba(255, 255, 255, 0.05) 80%, transparent 100%);
pointer-events: none;
z-index: 20;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 暗色主题下的渐变高光效果 */
:root.dark .top-gradient-highlight {
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.3) 30%, rgba(0, 0, 0, 0.15) 60%, rgba(0, 0, 0, 0.05) 80%, transparent 100%);
}
@layer components {
/* View Transitions API 主题切换动画 */
/* 为整个文档根元素设置视图过渡 */
::view-transition-old(root),
::view-transition-new(root) {
animation-duration: 0.5s;
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
/* 使用混合模式使颜色过渡更平滑 */
mix-blend-mode: normal;
}
/* 视图过渡组 - 使用交叉淡化效果 */
::view-transition-group(root) {
animation-duration: 0.5s;
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
/* 淡出旧视图 - 使用更平滑的曲线 */
::view-transition-old(root) {
animation-name: theme-fade-out;
/* 确保背景色同步切换 */
z-index: 2;
}
/* 淡入新视图 - 使用更平滑的曲线 */
::view-transition-new(root) {
animation-name: theme-fade-in;
/* 确保新视图在上层 */
z-index: 1;
}
/* 定义淡出动画 - 使用更平滑的缓动函数 */
@keyframes theme-fade-out {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
/* 定义淡入动画 - 从下层淡入 */
@keyframes theme-fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* 确保边框和分隔线元素在主题切换时有更明确的过渡时长 */
.transition,
[class*="border"],
[class*="transition"] {
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 0.15s;
}
/* 主题过渡保护类 - 仅在非 View Transitions 模式下使用 */
/* 当使用 View Transitions API 时,浏览器会自动处理过渡,不需要禁用 transition */
.is-theme-transitioning:not(.use-view-transition) *,
.is-theme-transitioning:not(.use-view-transition) *::before,
.is-theme-transitioning:not(.use-view-transition) *::after {
transition: none !important;
animation: none !important;
}
/* 在主题切换时禁用代码块的复杂效果以提升性能 */
/* 使用 View Transitions 时也需要禁用代码块动画,因为它们太多了 */
.is-theme-transitioning .expressive-code,
.is-theme-transitioning .expressive-code * {
transition: none !important;
animation: none !important;
will-change: auto !important;
}
/* 主题切换时临时隐藏代码块以提升性能 */
/* 这个行为可以通过配置文件中的 expressiveCodeConfig.hideDuringThemeTransition 控制 */
.is-theme-transitioning .expressive-code {
content-visibility: hidden !important;
/* 避免闪烁 */
opacity: 0.99;
}
/* 当禁用隐藏代码块功能时通过JavaScript动态控制 */
.is-theme-transitioning .expressive-code:not(.hide-during-transition) {
/* 保持代码块可见,但禁用过渡效果 */
content-visibility: visible !important;
opacity: 1 !important;
}
/* 禁用复杂选择器元素的过渡 - 仅在非 View Transitions 模式下 */
.is-theme-transitioning:not(.use-view-transition) .float-panel,
.is-theme-transitioning:not(.use-view-transition) .float-panel *,
.is-theme-transitioning:not(.use-view-transition) .music-player,
.is-theme-transitioning:not(.use-view-transition) .music-player *,
.is-theme-transitioning:not(.use-view-transition) .widget,
.is-theme-transitioning:not(.use-view-transition) .widget *,
.is-theme-transitioning:not(.use-view-transition) .dropdown-content,
.is-theme-transitioning:not(.use-view-transition) .dropdown-content * {
transition: none !important;
animation: none !important;
}
/* 强制使用 contain 隔离渲染上下文 - 仅在非 View Transitions 模式下 */
.is-theme-transitioning:not(.use-view-transition) .post-card,
.is-theme-transitioning:not(.use-view-transition) .widget,
.is-theme-transitioning:not(.use-view-transition) .float-panel {
contain: layout style paint !important;
}
/* 波浪效果精确同步处理 - 仅在非 View Transitions 模式下 */
.is-theme-transitioning:not(.use-view-transition) svg use {
/* 禁用过渡但保持动画 */
transition: none;
/* 强制立即继承页面背景色 */
fill: currentColor;
}
/* 导航栏主题切换保护 - 仅在非 View Transitions 模式下禁用过渡 */
.is-theme-transitioning:not(.use-view-transition) #navbar > div,
.is-theme-transitioning:not(.use-view-transition) #navbar[data-transparent-mode] > div,
.is-theme-transitioning:not(.use-view-transition) #navbar[data-transparent-mode].scrolled > div,
.is-theme-transitioning:not(.use-view-transition) body.wallpaper-transparent #navbar > div,
.is-theme-transitioning:not(.use-view-transition) body.wallpaper-transparent #navbar[data-transparent-mode] > div,
.is-theme-transitioning:not(.use-view-transition) body.wallpaper-transparent #navbar[data-transparent-mode].scrolled > div,
.is-theme-transitioning:not(.use-view-transition) #banner-wrapper ~ * #navbar > div,
.is-theme-transitioning:not(.use-view-transition) #banner-wrapper ~ * #navbar[data-transparent-mode] > div,
.is-theme-transitioning:not(.use-view-transition) body:has(#banner-wrapper) #navbar > div,
.is-theme-transitioning:not(.use-view-transition) body:has(#banner-wrapper) #navbar[data-transparent-mode] > div {
transition: none !important;
backdrop-filter: none !important;
}
/* 导航栏相关浮动面板的过渡禁用 */
.is-theme-transitioning .dropdown-content,
.is-theme-transitioning .float-panel,
.is-theme-transitioning #display-setting,
.is-theme-transitioning #nav-menu-panel,
.is-theme-transitioning #translate-panel,
.is-theme-transitioning #mobile-toc-panel,
.is-theme-transitioning #search-panel {
transition: none !important;
backdrop-filter: none !important;
}
/* 波浪容器的颜色传递 */
.is-theme-transitioning #header-waves {
/* 设置当前颜色为页面背景色供SVG继承 */
color: var(--page-bg);
/* 确保与页面在同一合成层 */
isolation: isolate;
/* 优化渲染性能 */
contain: layout style paint;
/* GPU层合成 */
transform: translateZ(0);
/* 确保没有背景色 */
background: transparent;
}
.is-theme-transitioning #header-waves use {
/* 保持动画连续性 */
will-change: transform;
/* GPU优化 */
transform: translateZ(0);
}
.card-base {
@apply rounded-[var(--radius-large)] overflow-hidden bg-[var(--card-bg)] transition-colors duration-150;
}
.card-base-transparent {
@apply rounded-[var(--radius-large)] overflow-hidden bg-[var(--card-bg-transparent)] backdrop-blur-sm transition-colors duration-150;
}
/* 全屏壁纸模式下的半透明效果 - 使用!important确保优先级 */
.wallpaper-transparent .card-base {
background: var(--card-bg-transparent) !important;
backdrop-filter: blur(8px) !important;
-webkit-backdrop-filter: blur(8px) !important;
}
body.wallpaper-transparent .card-base {
background: var(--card-bg-transparent) !important;
backdrop-filter: blur(8px) !important;
-webkit-backdrop-filter: blur(8px) !important;
}
/* 确保嵌套的卡片元素在全屏壁纸模式下也应用半透明效果 */
.wallpaper-transparent .card-base .card-base,
body.wallpaper-transparent .card-base .card-base {
background: var(--card-bg-transparent) !important;
backdrop-filter: blur(8px) !important;
-webkit-backdrop-filter: blur(8px) !important;
}
.wallpaper-transparent .float-panel {
@apply bg-[var(--card-bg-transparent)] backdrop-blur-sm;
}
.wallpaper-transparent #navbar > div {
@apply bg-[var(--card-bg-transparent)] backdrop-blur-sm;
}
.wallpaper-transparent .btn-card {
@apply bg-[var(--card-bg-transparent)] backdrop-blur-sm;
}
.wallpaper-transparent ~ * .music-player .mini-player,
.wallpaper-transparent ~ * .music-player .expanded-player,
.wallpaper-transparent ~ * .music-player .playlist-panel,
body.wallpaper-transparent .music-player .mini-player,
body.wallpaper-transparent .music-player .expanded-player,
body.wallpaper-transparent .music-player .playlist-panel {
background-color: var(--card-bg-transparent) !important;
backdrop-filter: blur(8px) !important;
}
h1, h2, h3, h4, h5, h6, p, a, span, li, ul, ol, blockquote, code, pre, table, th, td, strong {
@apply transition-colors duration-150;
}
.card-shadow {
@apply drop-shadow-[0_2px_4px_rgba(0,0,0,0.005)]
}
.expand-animation {
@apply relative before:ease-out before:duration-75 before:transition-all active:bg-none hover:before:bg-[var(--btn-plain-bg-hover)] active:before:bg-[var(--btn-plain-bg-active)] z-0
before:absolute before:rounded-[inherit] before:inset-0 before:scale-[0.85] hover:before:scale-100 before:-z-10
}
/* 主题切换时禁用按钮背景色过渡,确保立即更新 */
.is-theme-transitioning .expand-animation::before {
transition: transform 75ms ease-out !important;
}
.is-theme-transitioning .btn-plain {
transition: color 75ms ease-out !important;
}
.link {
@apply transition-colors duration-150 rounded-md p-1 -m-1 expand-animation;
}
.link-lg {
@apply transition-colors duration-150 rounded-md p-1.5 -m-1.5 expand-animation;
}
.float-panel {
@apply top-[5.25rem] rounded-[var(--radius-large)] overflow-hidden bg-[var(--float-panel-bg)] transition-colors duration-150 shadow-xl dark:shadow-none
}
.float-panel-closed {
@apply -translate-y-1 opacity-0 pointer-events-none
}
.search-panel mark {
@apply bg-transparent text-[var(--primary)]
}
.btn-card {
@apply transition-colors duration-150 flex items-center justify-center bg-[var(--card-bg)] hover:bg-[var(--btn-card-bg-hover)]
active:bg-[var(--btn-card-bg-active)]
}
.btn-card.disabled {
@apply pointer-events-none text-black/10 dark:text-white/10
}
.btn-plain {
@apply transition-colors duration-150 relative flex items-center justify-center bg-none
text-black/75 hover:text-[var(--primary)] dark:text-white/75 dark:hover:text-[var(--primary)];
&:not(.scale-animation) {
@apply hover:bg-[var(--btn-plain-bg-hover)] active:bg-[var(--btn-plain-bg-active)]
}
&.scale-animation {
@apply expand-animation;
}
}
.btn-regular {
@apply transition-colors duration-150 flex items-center justify-center bg-[var(--btn-regular-bg)] hover:bg-[var(--btn-regular-bg-hover)] active:bg-[var(--btn-regular-bg-active)]
text-[var(--btn-content)] dark:text-white/75
}
.link-underline {
@apply transition-colors duration-150 underline decoration-2 decoration-dashed decoration-[var(--link-underline)]
hover:decoration-[var(--link-hover)] active:decoration-[var(--link-active)] underline-offset-[0.25rem]
}
.toc-hide,
.toc-not-ready {
@apply opacity-0 pointer-events-none
}
/* #toc-inner-wrapper {
mask-image: linear-gradient(to bottom, transparent 0%, black 2rem, black calc(100% - 2rem), transparent 100%);
} */
.hide-scrollbar {
scrollbar-width: none;
-ms-overflow-style: none;
}
.hide-scrollbar::-webkit-scrollbar {
display: none;
}
.text-90 {
@apply text-black/90 dark:text-white/90
}
.text-75 {
@apply text-black/75 dark:text-white/75
}
.text-50 {
@apply text-black/50 dark:text-white/50
}
.text-30 {
@apply text-black/30 dark:text-white/30
}
.text-25 {
@apply text-black/25 dark:text-white/25
}
/* 下拉菜单样式 */
.dropdown-container {
@apply relative;
}
.dropdown-menu {
@apply absolute top-full left-0 pt-2 opacity-0 invisible pointer-events-none transition-all duration-200 ease-out transform translate-y-[-8px] z-50;
}
.dropdown-container:hover .dropdown-menu,
.dropdown-container:focus-within .dropdown-menu {
@apply opacity-100 visible pointer-events-auto translate-y-0;
}
.dropdown-container:hover .dropdown-arrow,
.dropdown-container:focus-within .dropdown-arrow {
@apply rotate-180;
}
.dropdown-content {
@apply bg-[var(--float-panel-bg)] rounded-[var(--radius-large)] shadow-xl dark:shadow-none border border-black/5 dark:border-white/10 py-2 min-w-[12rem];
}
.dropdown-item {
@apply flex items-center justify-between px-4 py-2.5 text-black/75 dark:text-white/75 hover:text-[var(--primary)] hover:bg-[var(--btn-plain-bg-hover)] transition-colors duration-150 font-medium;
}
.dropdown-item:first-child {
@apply rounded-t-[calc(var(--radius-large)-0.5rem)];
}
.dropdown-item:last-child {
@apply rounded-b-[calc(var(--radius-large)-0.5rem)];
}
/* 移动端菜单样式 */
.mobile-submenu {
@apply max-h-0 overflow-hidden transition-all duration-300 ease-in-out;
}
.mobile-dropdown[data-expanded="true"] .mobile-submenu {
@apply max-h-96;
}
.mobile-dropdown[data-expanded="true"] .mobile-dropdown-arrow {
@apply rotate-180;
}
/* 响应式隐藏 */
@media (max-width: 768px) {
.dropdown-container {
@apply hidden;
}
}
/* 无障碍支持 */
.dropdown-container:focus-within .dropdown-menu {
@apply opacity-100 visible pointer-events-auto translate-y-0;
}
.dropdown-item:focus {
@apply outline-none;
}
.mobile-dropdown button:focus {
@apply outline-none;
}
.meta-icon {
@apply w-8 h-8 transition-colors duration-150 rounded-md flex items-center justify-center bg-[var(--btn-regular-bg)]
text-[var(--btn-content)] mr-2
}
.with-divider {
@apply before:content-['/'] before:ml-1.5 before:mr-1.5 before:text-[var(--meta-divider)] before:text-sm
before:font-medium before:first-of-type:hidden before:transition-colors before:duration-150
}
.btn-regular-dark {
@apply flex items-center justify-center
bg-[oklch(0.45_0.01_var(--hue))] hover:bg-[oklch(0.50_0.01_var(--hue))] active:bg-[oklch(0.55_0.01_var(--hue))]
dark:bg-[oklch(0.30_0.02_var(--hue))] dark:hover:bg-[oklch(0.35_0.03_var(--hue))] dark:active:bg-[oklch(0.40_0.03_var(--hue))]
}
.btn-regular-dark.success {
@apply bg-[oklch(0.75_0.14_var(--hue))] dark:bg-[oklch(0.75_0.14_var(--hue))]
}
}
.custom-md img, #post-cover img {
@apply cursor-zoom-in
}
::selection {
background-color: var(--selection-bg);
color: inherit;
}
/* 白天模式下选中文本的颜色 */
:root:not(.dark) ::selection {
color: #000000;
}
/* 夜间模式下选中文本的颜色 */
:root.dark ::selection {
color: #ffffff;
}
.dash-line {
position: relative;
}
.dash-line::before {
content: "";
position: absolute;
width: 10%;
height: 100%;
left: calc(50% - 1px);
border-left: 2px dashed var(--line-color);
pointer-events: none;
transition: all 0.3s;
transform: translateY(-50%);
}
.collapsed {
height: var(--collapsedHeight);
}
/*剧透效果*/
.custom-md spoiler {
--_spoiler-mask: var(--primary);
@apply hover:bg-transparent px-1 py-0.5 overflow-hidden rounded-md transition-all duration-150;
background-color: var(--_spoiler-mask);
box-decoration-break: clone;
&:not(:hover) {
color: var(--_spoiler-mask);
* {
color: var(--_spoiler-mask);
}
}
}
/* 浅色模式:使用更浅的主题色且完全不透明 */
/* 文章列表布局切换样式 */
.post-list-container.grid-mode {
display: grid !important;
grid-template-columns: repeat(1, 1fr);
gap: 1rem;
}
@media (max-width: 768px) {
.post-list-container.grid-mode {
gap: 0.75rem;
}
}
@media (min-width: 768px) {
.post-list-container.grid-mode {
grid-template-columns: repeat(2, 1fr);
}
}
/* 网格模式下的文章卡片样式调整 */
.post-list-container.grid-mode .post-card-item {
width: 100%;
margin-bottom: 0;
}
.post-list-container.grid-mode .post-card-item a[href] {
font-size: 1.25rem;
line-height: 1.75rem;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.post-list-container.grid-mode .post-card-item .description {
font-size: 0.875rem;
margin-bottom: 0.5rem;
line-height: 1.25rem;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.post-list-container.grid-mode .post-card-item .stats {
font-size: 0.75rem;
}
.post-list-container.grid-mode .post-card-item .post-meta {
margin-bottom: 0.5rem;
}
/* CSS-only移动端优化 - 避免JavaScript闪烁 */
@media (max-width: 768px) {
/* 移动端强制列表模式,避免初始化闪烁 */
#post-list-container {
display: flex !important;
flex-direction: column !important;
gap: 0.5rem !important;
padding: 0 !important;
background: transparent !important;
}
/* 移动端网格模式也显示为列表 */
#post-list-container.grid-mode {
display: flex !important;
flex-direction: column !important;
gap: 0.5rem !important;
grid-template-columns: 1fr !important;
}
/* 移动端文章卡片间距优化 */
#post-list-container .post-card-item {
margin-bottom: 0 !important;
}
}
/* 桌面端样式 */
@media (min-width: 769px) {
/* 列表模式下的样式 */
.post-list-container.list-mode {
display: flex !important;
flex-direction: column;
gap: 0.75rem;
}
/* 网格模式下的样式 */
.post-list-container.grid-mode {
display: grid !important;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
}
}
/* 确保过渡动画平滑 */
.post-list-container {
transition: all 0.3s ease-in-out;
}
/* 文章列表布局切换样式 */
.post-list-container.grid-mode {
display: grid !important;
grid-template-columns: repeat(1, 1fr);
gap: 1.5rem;
}
@media (min-width: 768px) {
.post-list-container.grid-mode {
grid-template-columns: repeat(2, 1fr);
}
}
/* 网格模式下的文章卡片样式调整 */
.post-list-container.grid-mode .post-card-item {
width: 100%;
margin-bottom: 0;
}
.post-list-container.grid-mode .post-card-item a[href] {
font-size: 1.25rem;
line-height: 1.75rem;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.post-list-container.grid-mode .post-card-item .description {
font-size: 0.875rem;
margin-bottom: 0.5rem;
line-height: 1.25rem;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.post-list-container.grid-mode .post-card-item .stats {
font-size: 0.75rem;
}
.post-list-container.grid-mode .post-card-item .post-meta {
margin-bottom: 0.5rem;
}
/* 列表模式下的样式 */
.post-list-container.list-mode {
display: flex !important;
flex-direction: column;
gap: 1rem;
}
/* 确保过渡动画平滑 */
.post-list-container {
transition: all 0.3s ease-in-out;
}
:root:not(.dark) .custom-md spoiler {
--_spoiler-mask: color-mix(in oklch, var(--primary) 55%, white 45%);
}