mirror of
https://github.com/StepanovPlaton/AboutMe.git
synced 2026-04-06 13:50:50 +04:00
Initial commit
This commit is contained in:
246
src/styles/albums.css
Normal file
246
src/styles/albums.css
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* 相册模块样式
|
||||
*/
|
||||
|
||||
|
||||
/* 相册卡片动画 */
|
||||
.album-card {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.album-card:hover {
|
||||
translate: 0 -4px;
|
||||
}
|
||||
|
||||
|
||||
/* 照片网格布局 */
|
||||
.photo-gallery {
|
||||
animation: fadeInUp 0.6s ease-out;
|
||||
}
|
||||
|
||||
.photo-item {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
|
||||
/* 瀑布流布局优化 */
|
||||
.masonry-layout .photo-item {
|
||||
page-break-inside: avoid;
|
||||
break-inside: avoid;
|
||||
}
|
||||
|
||||
|
||||
/* 照片悬停效果 */
|
||||
.photo-container {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.photo-image {
|
||||
transition: transform 0.3s ease;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.photo-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.photo-item:hover .photo-overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.photo-info {
|
||||
translate: 0 100%;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.photo-item:hover .photo-info {
|
||||
translate: 0 0;
|
||||
}
|
||||
|
||||
|
||||
/* 灯箱样式 */
|
||||
.lightbox {
|
||||
backdrop-filter: blur(8px);
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.lightbox-content {
|
||||
max-width: 95vw;
|
||||
max-height: 95vh;
|
||||
}
|
||||
|
||||
.lightbox-image-container {
|
||||
min-height: 60vh;
|
||||
}
|
||||
|
||||
#lightbox-image {
|
||||
max-width: 100%;
|
||||
max-height: 80vh;
|
||||
object-fit: contain;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
|
||||
/* 灯箱按钮 */
|
||||
.lightbox button {
|
||||
backdrop-filter: blur(4px);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.lightbox button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
scale: 1.05;
|
||||
}
|
||||
|
||||
|
||||
/* 灯箱信息面板 */
|
||||
#lightbox-info {
|
||||
backdrop-filter: blur(8px);
|
||||
border-radius: 0.5rem;
|
||||
max-height: 30vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.albums-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.masonry-layout {
|
||||
columns: 1;
|
||||
}
|
||||
|
||||
.photo-gallery[data-columns="3"],
|
||||
.photo-gallery[data-columns="4"] {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.lightbox-content {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
#lightbox-prev,
|
||||
#lightbox-next {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
#lightbox-info {
|
||||
position: static;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 512px) {
|
||||
.photo-gallery {
|
||||
grid-template-columns: 1fr !important;
|
||||
}
|
||||
|
||||
.masonry-layout {
|
||||
columns: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 加载动画 */
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: 0 30px;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 图片懒加载占位符 */
|
||||
.photo-image[loading="lazy"] {
|
||||
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: loading 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
100% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 深色模式适配 */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.photo-image[loading="lazy"] {
|
||||
background: linear-gradient(90deg, #2a2a2a 25%, #1a1a1a 50%, #2a2a2a 75%);
|
||||
background-size: 200% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 标签筛选动画 */
|
||||
.album-filter-tag {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.album-filter-tag::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
.album-filter-tag:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
|
||||
/* 相册卡片内容对齐 */
|
||||
.album-card .p-4 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.album-card h3 {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
|
||||
/* 打印样式 */
|
||||
@media print {
|
||||
.lightbox,
|
||||
.album-filter-tag,
|
||||
button {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.photo-gallery {
|
||||
display: block !important;
|
||||
columns: 2;
|
||||
column-gap: 1rem;
|
||||
}
|
||||
|
||||
.photo-item {
|
||||
break-inside: avoid;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
361
src/styles/anime.css
Normal file
361
src/styles/anime.css
Normal file
@@ -0,0 +1,361 @@
|
||||
@reference "tailwindcss";
|
||||
|
||||
/* 追番页面专用样式 - 使用页面特定的选择器避免全局影响 */
|
||||
|
||||
/* 只在包含 anime-page 类的页面中应用这些样式 */
|
||||
.anime-page .anime-header {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--line-divider);
|
||||
position: relative;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
/* 统计卡片样式 */
|
||||
.anime-page .stat-card {
|
||||
@apply bg-white/50 dark:bg-white/5 backdrop-blur-xs rounded-xl p-4 flex items-center gap-3 transition-all duration-300 hover:scale-105 hover:shadow-lg;
|
||||
border: 1px solid var(--line-divider);
|
||||
background: linear-gradient(135deg, var(--card-bg) 0%, var(--card-bg-transparent) 100%);
|
||||
}
|
||||
|
||||
.anime-page .stat-card:hover {
|
||||
translate: 0 -2px;
|
||||
scale: 1.02;
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.anime-page .stat-icon {
|
||||
@apply w-12 h-12 rounded-lg flex items-center justify-center text-white text-xl font-bold shadow-md;
|
||||
background: linear-gradient(135deg, var(--primary), oklch(from var(--primary) calc(l + 0.1) c calc(h + 30)));
|
||||
}
|
||||
|
||||
.anime-page .stat-content {
|
||||
@apply flex-1;
|
||||
}
|
||||
|
||||
.anime-page .stat-number {
|
||||
@apply text-2xl font-bold text-black/90 dark:text-white/90;
|
||||
background: linear-gradient(135deg, var(--primary), oklch(from var(--primary) calc(l + 0.1) c calc(h + 30)));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.anime-page .stat-label {
|
||||
@apply text-sm text-black/75 dark:text-white/75;
|
||||
}
|
||||
|
||||
/* 动漫网格布局 */
|
||||
.anime-page .anime-grid {
|
||||
@apply grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6;
|
||||
}
|
||||
|
||||
/* 动漫卡片样式 */
|
||||
.anime-page .anime-card {
|
||||
@apply relative overflow-hidden transition-all duration-500 hover:scale-[1.02];
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--line-divider);
|
||||
border-radius: var(--radius-large);
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.anime-page .anime-card:hover {
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.anime-page .anime-card-inner {
|
||||
@apply p-0;
|
||||
}
|
||||
|
||||
/* 封面容器 */
|
||||
.anime-page .anime-cover-container {
|
||||
@apply relative overflow-hidden;
|
||||
aspect-ratio: 16/9;
|
||||
background: linear-gradient(135deg, var(--primary)/10, var(--primary)/5);
|
||||
}
|
||||
|
||||
.anime-page .anime-cover-link {
|
||||
@apply block w-full h-full relative overflow-hidden;
|
||||
}
|
||||
|
||||
.anime-page .anime-cover {
|
||||
@apply w-full h-full object-cover transition-all duration-700;
|
||||
filter: brightness(0.9) contrast(1.1);
|
||||
}
|
||||
|
||||
.anime-page .anime-cover-link:hover .anime-cover {
|
||||
@apply scale-110;
|
||||
}
|
||||
|
||||
.anime-page .anime-cover-overlay {
|
||||
@apply absolute inset-0 bg-linear-to-t from-black/60 via-transparent to-transparent opacity-0 transition-all duration-500 flex items-center justify-center;
|
||||
}
|
||||
|
||||
.anime-page .anime-cover-link:hover .anime-cover-overlay {
|
||||
@apply opacity-100;
|
||||
}
|
||||
|
||||
.anime-page .play-button {
|
||||
@apply w-16 h-16 rounded-full bg-white/20 backdrop-blur-xs flex items-center justify-center text-white scale-75 transition-all duration-500;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.anime-page .anime-cover-link:hover .play-button {
|
||||
@apply scale-100;
|
||||
}
|
||||
|
||||
.anime-page .play-button:hover {
|
||||
background: var(--primary);
|
||||
scale: 1.1;
|
||||
}
|
||||
|
||||
/* 状态标签 */
|
||||
.anime-page .anime-status {
|
||||
@apply absolute top-3 left-3 px-3 py-1 rounded-full text-xs font-medium flex items-center gap-1 backdrop-blur-xs;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.anime-page .status-icon {
|
||||
@apply text-xs;
|
||||
}
|
||||
|
||||
.anime-page .status-text {
|
||||
@apply font-medium;
|
||||
}
|
||||
|
||||
/* 评分标签 */
|
||||
.anime-page .anime-rating {
|
||||
@apply absolute top-3 right-3 bg-black/50 backdrop-blur-xs text-white px-2 py-1 rounded-full text-sm flex items-center gap-1;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.anime-page .rating-text {
|
||||
@apply font-medium;
|
||||
}
|
||||
|
||||
/* 内容区域 */
|
||||
.anime-page .anime-content {
|
||||
@apply p-6;
|
||||
background: linear-gradient(to bottom, transparent, var(--card-bg)/50);
|
||||
}
|
||||
|
||||
.anime-page .anime-title {
|
||||
@apply text-xl font-bold text-black/90 dark:text-white/90 mb-2;
|
||||
background: linear-gradient(135deg, var(--deep-text), var(--primary));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.anime-page .anime-description {
|
||||
@apply text-black/75 dark:text-white/75 text-sm mb-4;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 进度条 */
|
||||
.anime-page .anime-progress {
|
||||
@apply mb-4;
|
||||
}
|
||||
|
||||
.anime-page .progress-info {
|
||||
@apply flex justify-between items-center mb-2 text-sm;
|
||||
}
|
||||
|
||||
.anime-page .progress-text {
|
||||
@apply text-black/75 dark:text-white/75 font-medium;
|
||||
}
|
||||
|
||||
.anime-page .progress-percent {
|
||||
@apply text-(--primary) font-bold;
|
||||
}
|
||||
|
||||
.anime-page .progress-bar {
|
||||
@apply w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden;
|
||||
background: linear-gradient(90deg, var(--btn-regular-bg), var(--btn-regular-bg-hover));
|
||||
}
|
||||
|
||||
.anime-page .progress-fill {
|
||||
@apply h-full transition-all duration-1000 ease-out;
|
||||
background: linear-gradient(90deg, var(--primary), oklch(from var(--primary) calc(l + 0.1) c calc(h + 30)));
|
||||
box-shadow: 0 0 10px var(--primary)/50;
|
||||
}
|
||||
|
||||
/* 元信息 */
|
||||
.anime-page .anime-meta {
|
||||
@apply space-y-2 text-sm;
|
||||
}
|
||||
|
||||
.anime-page .meta-row {
|
||||
@apply flex items-center justify-between;
|
||||
}
|
||||
|
||||
.anime-page .meta-label {
|
||||
@apply text-black/50 dark:text-white/50 font-medium;
|
||||
}
|
||||
|
||||
.anime-page .meta-value {
|
||||
@apply text-black/75 dark:text-white/75;
|
||||
}
|
||||
|
||||
.anime-page .genre-tags {
|
||||
@apply flex gap-1 flex-wrap;
|
||||
}
|
||||
|
||||
.anime-page .genre-tag {
|
||||
@apply px-2 py-1 bg-(--btn-regular-bg) text-black/75 dark:text-white/75 rounded-md text-xs font-medium transition-all duration-300 hover:bg-(--primary) hover:text-white;
|
||||
border: 1px solid var(--line-divider);
|
||||
}
|
||||
|
||||
.anime-page .genre-tag:hover {
|
||||
translate: 0 -1px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 768px) {
|
||||
.anime-page .anime-grid {
|
||||
@apply grid-cols-1;
|
||||
}
|
||||
|
||||
.anime-page .stat-card {
|
||||
@apply p-3;
|
||||
}
|
||||
|
||||
.anime-page .stat-icon {
|
||||
@apply w-10 h-10 text-lg;
|
||||
}
|
||||
|
||||
.anime-page .stat-number {
|
||||
@apply text-xl;
|
||||
}
|
||||
|
||||
.anime-page .anime-content {
|
||||
@apply p-4;
|
||||
}
|
||||
|
||||
.anime-page .anime-title {
|
||||
@apply text-lg;
|
||||
}
|
||||
}
|
||||
|
||||
/* 暗色主题优化 */
|
||||
:root.dark .anime-page .anime-card {
|
||||
@apply shadow-lg shadow-black/20;
|
||||
background: linear-gradient(135deg, var(--card-bg), var(--card-bg-transparent));
|
||||
}
|
||||
|
||||
:root.dark .anime-page .anime-cover-overlay {
|
||||
@apply bg-linear-to-t from-black/80 via-black/20 to-transparent;
|
||||
}
|
||||
|
||||
:root.dark .anime-page .stat-card {
|
||||
background: linear-gradient(135deg, var(--card-bg)/80, var(--card-bg-transparent));
|
||||
border-color: var(--line-divider);
|
||||
}
|
||||
|
||||
/* 动画效果 */
|
||||
.anime-page .anime-card {
|
||||
animation: fadeInUp 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
|
||||
opacity: 0;
|
||||
translate: 0 30px;
|
||||
}
|
||||
|
||||
.anime-page .anime-card:nth-child(1) { animation-delay: 0.1s; }
|
||||
.anime-page .anime-card:nth-child(2) { animation-delay: 0.2s; }
|
||||
.anime-page .anime-card:nth-child(3) { animation-delay: 0.3s; }
|
||||
.anime-page .anime-card:nth-child(4) { animation-delay: 0.4s; }
|
||||
.anime-page .anime-card:nth-child(5) { animation-delay: 0.5s; }
|
||||
.anime-page .anime-card:nth-child(6) { animation-delay: 0.6s; }
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: 0 30px;
|
||||
scale: 0.95;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
scale: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 统计卡片动画 */
|
||||
.anime-page .stat-card {
|
||||
animation: slideInLeft 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
|
||||
opacity: 0;
|
||||
translate: -30px 0;
|
||||
}
|
||||
|
||||
.anime-page .stat-card:nth-child(1) { animation-delay: 0.1s; }
|
||||
.anime-page .stat-card:nth-child(2) { animation-delay: 0.2s; }
|
||||
.anime-page .stat-card:nth-child(3) { animation-delay: 0.3s; }
|
||||
.anime-page .stat-card:nth-child(4) { animation-delay: 0.4s; }
|
||||
|
||||
@keyframes slideInLeft {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: -30px 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 特殊效果 */
|
||||
.anime-page .anime-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, var(--primary), transparent);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.anime-page .anime-card:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 毛玻璃效果增强 */
|
||||
.anime-page .anime-header,
|
||||
.anime-page .stat-card,
|
||||
.anime-page .anime-card {
|
||||
backdrop-filter: blur(20px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||
}
|
||||
|
||||
/* 渐变边框效果 */
|
||||
.anime-page .anime-card {
|
||||
position: relative;
|
||||
background: var(--card-bg);
|
||||
}
|
||||
|
||||
.anime-page .anime-card::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
padding: 1px;
|
||||
background: linear-gradient(135deg, var(--primary)/20, transparent, var(--primary)/20);
|
||||
border-radius: inherit;
|
||||
mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
mask-composite: xor;
|
||||
-webkit-mask-composite: xor;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.anime-page .anime-card:hover::after {
|
||||
opacity: 1;
|
||||
}
|
||||
483
src/styles/banner.css
Normal file
483
src/styles/banner.css
Normal file
@@ -0,0 +1,483 @@
|
||||
/*
|
||||
* Banner 组件样式
|
||||
* Banner Component Styles
|
||||
* 包含 Banner 模式下的所有响应式样式和动画效果
|
||||
*/
|
||||
|
||||
/**
|
||||
* 基础样式
|
||||
*/
|
||||
|
||||
/* 淡入上移动画 */
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: 0 30px;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 初始加载中且未开始恢复时,高度归零;退出 Banner 模式时,高度归零 */
|
||||
html.is-loading:not(.banner-restoring) #banner-wrapper,
|
||||
html.banner-transitioning #banner-wrapper,
|
||||
html.banner-hiding #banner-wrapper {
|
||||
height: 0 !important;
|
||||
}
|
||||
|
||||
/* 退出动画时,强制子组件同步上移,避免主内容区域出现“两段式”位移 */
|
||||
html.banner-hiding #main-grid {
|
||||
translate: none !important;
|
||||
}
|
||||
html.banner-hiding #top-row {
|
||||
height: 0 !important;
|
||||
}
|
||||
html.banner-hiding #sidebar-sticky {
|
||||
top: 1rem !important;
|
||||
}
|
||||
|
||||
/* 切换模式时隐藏标题,以便后续触发动画 */
|
||||
html.banner-transitioning .banner-title,
|
||||
html.banner-transitioning .banner-subtitle {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
/* 标题样式 */
|
||||
.banner-title {
|
||||
text-shadow: 0px 3px 12px rgba(0, 0, 0, 0.36), 0 0 24px color-mix(in srgb, var(--primary), transparent 48%);
|
||||
font-weight: bold;
|
||||
opacity: 0;
|
||||
}
|
||||
.banner-subtitle {
|
||||
text-shadow: 0px 3px 6px rgba(0, 0, 0, 0.36), 0 0 12px color-mix(in srgb, var(--primary), transparent 48%);
|
||||
opacity: 0;
|
||||
}
|
||||
/* 标题动画 */
|
||||
.show-initial-animation .banner-title,
|
||||
.show-banner-animation .banner-title {
|
||||
animation: fadeInUp 1s ease-out forwards;
|
||||
}
|
||||
.show-initial-animation .banner-subtitle,
|
||||
.show-banner-animation .banner-subtitle {
|
||||
animation: fadeInUp 1s ease-out 0.3s both;
|
||||
}
|
||||
/* 动画结束后的状态 */
|
||||
html:not(.is-loading):not(.show-initial-animation):not(.show-banner-animation) .banner-title,
|
||||
html:not(.is-loading):not(.show-initial-animation):not(.show-banner-animation) .banner-subtitle {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 页面背景平滑过渡(Fullscreen 与 Banner 模式切换时) */
|
||||
body {
|
||||
transition: background-color 0.6s ease, background-image 0.6s ease;
|
||||
}
|
||||
html.is-wallpaper-transitioning body {
|
||||
transition: background-color 0.6s ease, background-image 0.6s ease !important;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
/* Ken Burns 效果 */
|
||||
@keyframes ken-burns {
|
||||
from {
|
||||
scale: 1.0;
|
||||
translate: 0 0 0;
|
||||
}
|
||||
to {
|
||||
scale: 1.2;
|
||||
translate: 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 桌面端 */
|
||||
@media (min-width: 1280px) {
|
||||
.banner-text-overlay {
|
||||
align-items: center !important; /* 垂直居中 */
|
||||
justify-content: center !important; /* 水平居中 */
|
||||
padding: 2rem !important;
|
||||
text-align: center !important; /* 文字居中对齐 */
|
||||
}
|
||||
.banner-text-overlay > div {
|
||||
margin-bottom: 0 !important;
|
||||
width: 75% !important;
|
||||
text-align: center !important; /* 确保文字居中 */
|
||||
}
|
||||
|
||||
/* 确保轮播容器有正确的 overflow 设置 */
|
||||
#banner-carousel {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
/* 图片容器 */
|
||||
.carousel-item img,
|
||||
#banner img {
|
||||
object-position: center center !important; /* 确保图片居中显示 */
|
||||
transition: transform 1.2s ease-out !important;
|
||||
}
|
||||
/* 轮播图片过渡 */
|
||||
.carousel-item {
|
||||
transition: opacity 1.2s ease-in-out !important;
|
||||
}
|
||||
.carousel-item.ken-burns-enabled {
|
||||
transform-origin: center center !important; /* 确保缩放从中心开始 */
|
||||
scale: 1.0;
|
||||
translate: 0 0 0;
|
||||
}
|
||||
.carousel-item.ken-burns-enabled.is-animating {
|
||||
animation: ken-burns 12s linear forwards !important;
|
||||
}
|
||||
.carousel-item:not(.ken-burns-enabled) {
|
||||
scale: 1.0;
|
||||
translate: 0 0 0; /* 取消默认缩放 */
|
||||
}
|
||||
/* 当前图片缩放效果 */
|
||||
.carousel-item.opacity-100 {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
/* 非当前图片缩放效果 */
|
||||
.carousel-item.opacity-0 {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 移动端轮播图片 */
|
||||
@media (max-width: 1279px) {
|
||||
/* 确保轮播容器有正确的 overflow 设置 */
|
||||
#banner-carousel {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
/* 图片容器 */
|
||||
.carousel-item img,
|
||||
#banner img {
|
||||
object-position: center center !important; /* 确保图片居中显示 */
|
||||
transition: transform 1.2s ease-out !important;
|
||||
}
|
||||
/* 轮播图片过渡 */
|
||||
.carousel-item {
|
||||
transition: opacity 1.2s ease-in-out !important;
|
||||
}
|
||||
.carousel-item.ken-burns-enabled {
|
||||
transform-origin: center center !important; /* 确保缩放从中心开始 */
|
||||
scale: 1.0;
|
||||
}
|
||||
.carousel-item.ken-burns-enabled.is-animating {
|
||||
animation: ken-burns 12s linear forwards !important;
|
||||
}
|
||||
.carousel-item:not(.ken-burns-enabled) {
|
||||
scale: 1.0; /* 取消默认缩放 */
|
||||
}
|
||||
/* 当前图片缩放效果 */
|
||||
.carousel-item.opacity-100 {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
/* 非当前图片缩放效果 */
|
||||
.carousel-item.opacity-0 {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 移动端 banner 性能 */
|
||||
@media (max-width: 1279px) {
|
||||
.banner-container {
|
||||
/* 启用硬件加速 */
|
||||
translate: 0 0 0;
|
||||
will-change: transform, opacity;
|
||||
/* 渲染性能 */
|
||||
contain: layout style paint;
|
||||
/* 减少重绘 */
|
||||
backface-visibility: hidden;
|
||||
-webkit-backface-visibility: hidden;
|
||||
}
|
||||
/* 图片 */
|
||||
.banner-container img {
|
||||
/* 图片渲染 */
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
image-rendering: crisp-edges;
|
||||
/* 防止图片拖拽 */
|
||||
-webkit-user-drag: none;
|
||||
-khtml-user-drag: none;
|
||||
-moz-user-drag: none;
|
||||
-o-user-drag: none;
|
||||
/* 触摸 */
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.banner-text-overlay {
|
||||
/* 文字渲染 */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
/* 减少重排 */
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
.carousel-item.ken-burns-enabled {
|
||||
/* 硬件加速与缩放维持 */
|
||||
scale: 1.0;
|
||||
translate: 0 0 0;
|
||||
will-change: transform, opacity;
|
||||
/* 触摸响应 */
|
||||
touch-action: pan-y;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.carousel-item:not(.ken-burns-enabled) {
|
||||
scale: 1.0;
|
||||
translate: 0 0 0;
|
||||
will-change: transform, opacity;
|
||||
/* 触摸响应 */
|
||||
touch-action: pan-y;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* 轮播指示器 */
|
||||
.carousel-indicators {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
left: 50%;
|
||||
translate: -50% 0;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.carousel-indicator {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
.carousel-indicator.active {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
scale: 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
/* 移动端暗色模式 */
|
||||
@media (max-width: 1279px) and (prefers-color-scheme: dark) {
|
||||
.banner-text-overlay {
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
rgba(0, 0, 0, 0.8) 0%,
|
||||
rgba(0, 0, 0, 0.4) 50%,
|
||||
transparent 100%
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* 移动端横屏 */
|
||||
@media (max-width: 1279px) and (orientation: landscape) {
|
||||
.banner-text-overlay {
|
||||
padding: 1rem 1.5rem;
|
||||
align-items: center !important; /* 垂直居中 */
|
||||
justify-content: center !important; /* 水平居中 */
|
||||
text-align: center !important; /* 文字居中对齐 */
|
||||
}
|
||||
|
||||
.banner-title {
|
||||
font-size: 2.2rem !important; /* 增大字体大小 */
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.banner-subtitle {
|
||||
font-size: 0.9rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* 平板 */
|
||||
@media (min-width: 768px) and (max-width: 1279px) {
|
||||
/* 横幅文本覆盖层 */
|
||||
.banner-text-overlay {
|
||||
align-items: center !important; /* 垂直居中 */
|
||||
justify-content: center !important; /* 水平居中 */
|
||||
padding: 2rem !important;
|
||||
text-align: center !important; /* 文字居中对齐 */
|
||||
}
|
||||
/* 文本容器 */
|
||||
.banner-text-overlay > div {
|
||||
margin-bottom: 0 !important; /* 移除底部边距,保持居中 */
|
||||
width: 85% !important;
|
||||
text-align: center !important; /* 确保文字居中 */
|
||||
}
|
||||
|
||||
/* 标题文本 */
|
||||
.banner-title {
|
||||
font-size: 4rem !important;
|
||||
line-height: 1.1 !important;
|
||||
margin-bottom: 1rem !important;
|
||||
}
|
||||
|
||||
/* 副标题文本 */
|
||||
.banner-subtitle {
|
||||
font-size: 1.5rem !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 中屏手机 */
|
||||
@media (min-width: 513px) and (max-width: 768px) {
|
||||
/* 横幅文本覆盖层 */
|
||||
.banner-text-overlay {
|
||||
align-items: center !important; /* 垂直居中 */
|
||||
justify-content: center !important; /* 水平居中 */
|
||||
padding: 1.5rem !important;
|
||||
text-align: center !important; /* 文字居中对齐 */
|
||||
}
|
||||
/* 文本容器 */
|
||||
.banner-text-overlay > div {
|
||||
margin-bottom: 0 !important; /* 移除底部边距,保持居中 */
|
||||
width: 90% !important;
|
||||
text-align: center !important; /* 确保文字居中 */
|
||||
}
|
||||
|
||||
/* 标题文本 */
|
||||
.banner-title {
|
||||
font-size: 3.8rem !important; /* 增大字体大小 */
|
||||
line-height: 1.1 !important;
|
||||
margin-bottom: 0.75rem !important;
|
||||
}
|
||||
|
||||
/* 副标题文本 */
|
||||
.banner-subtitle {
|
||||
font-size: 1.125rem !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 小屏手机 */
|
||||
@media (max-width: 512px) {
|
||||
/* 横幅文本覆盖层 */
|
||||
.banner-text-overlay {
|
||||
align-items: center !important; /* 垂直居中 */
|
||||
justify-content: center !important; /* 水平居中 */
|
||||
padding: 1rem !important;
|
||||
text-align: center !important; /* 文字居中对齐 */
|
||||
}
|
||||
/* 文本容器 */
|
||||
.banner-text-overlay > div {
|
||||
margin-bottom: 0 !important; /* 移除底部边距,保持居中 */
|
||||
width: 95% !important; /* 增加文本宽度利用率 */
|
||||
text-align: center !important; /* 确保文字居中 */
|
||||
}
|
||||
|
||||
/* 标题文本 */
|
||||
.banner-title {
|
||||
font-size: 3.2rem !important; /* 增大字体大小 */
|
||||
line-height: 1.1 !important;
|
||||
margin-bottom: 0.5rem !important;
|
||||
}
|
||||
|
||||
/* 副标题文本 */
|
||||
.banner-subtitle {
|
||||
font-size: 1rem !important;
|
||||
line-height: 1.3 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 波浪
|
||||
*/
|
||||
|
||||
/* 波浪动画 */
|
||||
@keyframes wave {
|
||||
0% {
|
||||
translate: -90px 0 0;
|
||||
}
|
||||
100% {
|
||||
translate: 85px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 波浪与背景同步切换 */
|
||||
#header-waves {
|
||||
/* 确保波浪容器与页面背景在同一合成层 */
|
||||
isolation: isolate;
|
||||
/* 优化渲染性能 - 移除 strict containment 改用 none */
|
||||
contain: none;
|
||||
/* 精确对齐 */
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
/* 统一波浪动画 */
|
||||
#header-waves .parallax use {
|
||||
animation-name: wave;
|
||||
animation-duration: 25s;
|
||||
animation-timing-function: cubic-bezier(0.5, 0.5, 0.45, 0.5);
|
||||
animation-iteration-count: infinite;
|
||||
transform: translateZ(0);
|
||||
will-change: transform;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
/* 分层动画时序(替代内联 style) */
|
||||
#header-waves .parallax use:nth-child(1) {
|
||||
animation-duration: 7s;
|
||||
animation-delay: -2s;
|
||||
}
|
||||
#header-waves .parallax use:nth-child(2) {
|
||||
animation-duration: 10s;
|
||||
animation-delay: -3s;
|
||||
}
|
||||
#header-waves .parallax use:nth-child(3) {
|
||||
animation-duration: 13s;
|
||||
animation-delay: -4s;
|
||||
}
|
||||
#header-waves .parallax use:nth-child(4) {
|
||||
animation-duration: 20s;
|
||||
animation-delay: -5s;
|
||||
}
|
||||
|
||||
#header-waves .waves {
|
||||
/* 确保 SVG 完整渲染(svg 本身即为 .waves) */
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
/* 确保水波纹完整显示 */
|
||||
overflow: visible;
|
||||
z-index: 5;
|
||||
/* 硬件加速,确保与背景同步渲染 */
|
||||
transform: translateZ(0);
|
||||
will-change: transform;
|
||||
backface-visibility: hidden;
|
||||
/* 优化渲染性能 - 移除 strict containment 改用 none */
|
||||
contain: none;
|
||||
}
|
||||
|
||||
/* 波浪填充色主题切换 */
|
||||
#header-waves .waves use {
|
||||
/* 确保填充色与页面背景同步更新 */
|
||||
will-change: fill;
|
||||
}
|
||||
|
||||
/* 主题切换时的额外保护 */
|
||||
.theme-changing #header-waves,
|
||||
.theme-changing #header-waves svg,
|
||||
.theme-changing #header-waves use {
|
||||
/* 在主题切换期间禁用所有可能的渲染延迟 */
|
||||
will-change: auto;
|
||||
transform: translateZ(0);
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
/* 移动端水波纹特殊 */
|
||||
@media (max-width: 1023px) {
|
||||
#header-waves {
|
||||
/* 确保水波纹容器不被裁剪 */
|
||||
overflow: visible;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
#header-waves .waves {
|
||||
/* 移动端SVG */
|
||||
min-height: 60px;
|
||||
}
|
||||
}
|
||||
11
src/styles/expressive-code.css
Normal file
11
src/styles/expressive-code.css
Normal file
@@ -0,0 +1,11 @@
|
||||
@reference "tailwindcss";
|
||||
|
||||
.expressive-code {
|
||||
.frame {
|
||||
@apply shadow-none!;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-family: "JetBrains Mono Variable", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
}
|
||||
121
src/styles/fancybox.css
Normal file
121
src/styles/fancybox.css
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* Fancybox 自定义样式
|
||||
*/
|
||||
|
||||
.fancybox__container {
|
||||
--fancybox-bg: rgba(0, 0, 0, 0.9);
|
||||
--fancybox-thumbs-width: 64px;
|
||||
--fancybox-thumbs-ratio: 1;
|
||||
--fancybox-thumbs-border-radius: 4px;
|
||||
}
|
||||
|
||||
.fancybox__toolbar {
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.7), transparent);
|
||||
padding: 8px;
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
.fancybox__caption {
|
||||
background: linear-gradient(to top, rgba(0, 0, 0, 0.8), transparent);
|
||||
color: white;
|
||||
font-size: 1rem;
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
backdrop-filter: blur(4px);
|
||||
border-radius: 8px;
|
||||
margin: 0 1rem 1rem 1rem;
|
||||
}
|
||||
|
||||
.fancybox__nav {
|
||||
--carousel-button-svg-width: 24px;
|
||||
--carousel-button-svg-height: 24px;
|
||||
}
|
||||
|
||||
.fancybox__thumbs {
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
padding: 2px;
|
||||
border-radius: 8px;
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
.fancybox__thumb {
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
border: 2px solid transparent;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.fancybox__thumb.is-loading {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.fancybox__thumb:hover {
|
||||
border-color: rgba(255, 255, 255, 0.5);
|
||||
scale: 1.05;
|
||||
}
|
||||
.fancybox__thumb.is-active {
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
.fancybox__button {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-radius: 50%;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
transition: all 0.2s ease;
|
||||
backdrop-filter: blur(4px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.fancybox__button:hover {
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
scale: 1.1;
|
||||
border-color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
.fancybox__button svg {
|
||||
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5));
|
||||
}
|
||||
|
||||
.fancybox__infobar {
|
||||
color: white;
|
||||
font-size: 0.9rem;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应式设计
|
||||
*/
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.fancybox__toolbar {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.fancybox__button {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.fancybox__caption {
|
||||
font-size: 0.9rem;
|
||||
padding: 0.5rem;
|
||||
margin: 0 0.5rem 0.5rem 0.5rem;
|
||||
}
|
||||
|
||||
.fancybox__thumbs {
|
||||
--fancybox-thumbs-width: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.fancybox__button {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.fancybox__caption {
|
||||
font-size: 0.8rem;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
|
||||
.fancybox__thumbs {
|
||||
--fancybox-thumbs-width: 40px;
|
||||
}
|
||||
}
|
||||
71
src/styles/grid.css
Normal file
71
src/styles/grid.css
Normal file
@@ -0,0 +1,71 @@
|
||||
/* 当banner被禁用时的布局样式 */
|
||||
.no-banner-layout {
|
||||
top: 5.5rem !important;
|
||||
min-height: calc(100vh - 5.5rem) !important;
|
||||
}
|
||||
|
||||
/* 隐藏已收起横幅或非横幅模式时的图片版权描述 */
|
||||
.no-banner-layout #banner-credit {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
/* 手机端无侧边栏布局优化 */
|
||||
@media (max-width: 768px) {
|
||||
.mobile-no-sidebar {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.mobile-no-sidebar main {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
margin: 0 !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
.mobile-no-sidebar #content-wrapper {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
/* 修复双侧边栏模式在移动端的布局问题 */
|
||||
.mobile-both-sidebar {
|
||||
/* 确保在移动端使用单列布局 */
|
||||
grid-template-columns: 1fr !important;
|
||||
/* 确保左右padding对称 */
|
||||
padding-left: 1rem !important;
|
||||
padding-right: 1rem !important;
|
||||
}
|
||||
/* 确保移动端主内容区域居中且全宽 */
|
||||
.mobile-both-sidebar main {
|
||||
grid-column: 1 / -1 !important;
|
||||
width: 100% !important;
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
/* 移动端footer也要居中 */
|
||||
.mobile-both-sidebar .footer {
|
||||
grid-column: 1 / -1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 小屏手机无侧边栏布局优化 */
|
||||
@media (max-width: 512px) {/* 修复双侧边栏模式在移动端的布局问题 */
|
||||
.mobile-both-sidebar {
|
||||
/* 确保在移动端使用单列布局 */
|
||||
grid-template-columns: 1fr !important;
|
||||
/* 确保左右padding对称 */
|
||||
padding-left: 0.75rem !important;
|
||||
padding-right: 0.75rem !important;
|
||||
}
|
||||
/* 确保移动端主内容区域居中且全宽 */
|
||||
.mobile-both-sidebar main {
|
||||
grid-column: 1 / -1 !important;
|
||||
width: 100% !important;
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
/* 移动端footer也要居中 */
|
||||
.mobile-both-sidebar .footer {
|
||||
grid-column: 1 / -1 !important;
|
||||
}
|
||||
}
|
||||
700
src/styles/main.css
Normal file
700
src/styles/main.css
Normal file
@@ -0,0 +1,700 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
/* 导入相册样式 */
|
||||
@import './albums.css' layer(base);
|
||||
/* 导入追番页面样式 */
|
||||
@import './anime.css' layer(base);
|
||||
/* 导入动过渡样式 */
|
||||
@import './transition.css' layer(base);
|
||||
|
||||
@plugin '@tailwindcss/typography';
|
||||
|
||||
|
||||
@theme {
|
||||
--breakpoint-sm: 512px;
|
||||
--breakpoint-md: 768px;
|
||||
--breakpoint-lg: 1280px;
|
||||
--breakpoint-xl: 1920px;
|
||||
|
||||
--transition-duration-300: 300ms;
|
||||
--transition-duration-600: 600ms;
|
||||
}
|
||||
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
|
||||
/*
|
||||
The default border color has changed to `currentcolor` in Tailwind CSS v4,
|
||||
so we've added these compatibility styles to make sure everything still
|
||||
looks the same as it did with Tailwind CSS v3.
|
||||
|
||||
If we ever want to remove these styles, we need to add an explicit border
|
||||
color utility to any element that depends on these defaults.
|
||||
*/
|
||||
@layer base {
|
||||
*,
|
||||
::after,
|
||||
::before,
|
||||
::backdrop,
|
||||
::file-selector-button {
|
||||
border-color: var(--color-gray-200, currentcolor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@utility is-theme-transitioning {
|
||||
/* 主题过渡保护类 - 临时禁用所有过渡动画 */
|
||||
& * {
|
||||
transition: none !important;
|
||||
}
|
||||
& *::before {
|
||||
transition: none !important;
|
||||
}
|
||||
& *::after {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
/* 波浪效果精确同步处理 */
|
||||
& svg use {
|
||||
/* 禁用过渡但保持动画 */
|
||||
transition: none;
|
||||
/* 强制立即继承页面背景色 */
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
/* 导航栏主题切换保护 - 完全禁用过渡以确保性能 */
|
||||
& #navbar > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& #navbar[data-transparent-mode] > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& #navbar[data-transparent-mode].scrolled > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& body.wallpaper-transparent #navbar > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& body.wallpaper-transparent #navbar[data-transparent-mode] > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& body.wallpaper-transparent #navbar[data-transparent-mode].scrolled > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& #banner-wrapper ~ * #navbar > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& #banner-wrapper ~ * #navbar[data-transparent-mode] > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& body:has(#banner-wrapper) #navbar > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& body:has(#banner-wrapper) #navbar[data-transparent-mode] > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
|
||||
/* 导航栏相关浮动面板的过渡禁用 */
|
||||
& .dropdown-content {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& .float-panel {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& #display-setting {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& #nav-menu-panel {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& #translate-panel {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
& #search-panel {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
|
||||
/* 波浪容器的颜色传递 */
|
||||
& #header-waves {
|
||||
/* 设置当前颜色为页面背景色,供SVG继承 */
|
||||
color: var(--page-bg);
|
||||
/* 确保与页面在同一合成层 */
|
||||
isolation: isolate;
|
||||
/* 优化渲染性能 - 移除 strict containment 改用 none */
|
||||
contain: none;
|
||||
/* GPU层合成 */
|
||||
translate: 0 0 0;
|
||||
/* 确保没有背景色 */
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
& #header-waves use {
|
||||
/* 保持动画连续性 */
|
||||
will-change: transform;
|
||||
/* GPU优化 */
|
||||
translate: 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@utility scrolled {
|
||||
.is-theme-transitioning &#navbar[data-transparent-mode] > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
|
||||
.is-theme-transitioning
|
||||
body.wallpaper-transparent
|
||||
&#navbar[data-transparent-mode]
|
||||
> div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@utility wallpaper-transparent {
|
||||
.is-theme-transitioning &body #navbar > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
|
||||
.is-theme-transitioning &body #navbar[data-transparent-mode] > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
|
||||
.is-theme-transitioning &body #navbar[data-transparent-mode].scrolled > div {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
|
||||
/* 全屏壁纸模式下的半透明效果 */
|
||||
& .card-base {
|
||||
@apply bg-(--card-bg-transparent);
|
||||
}
|
||||
|
||||
& .float-panel {
|
||||
@apply bg-(--card-bg-transparent);
|
||||
}
|
||||
|
||||
& #navbar > div {
|
||||
@apply bg-(--card-bg-transparent) backdrop-blur-xs;
|
||||
}
|
||||
|
||||
& .btn-card {
|
||||
@apply bg-(--card-bg-transparent);
|
||||
}
|
||||
|
||||
& ~ * .music-player .mini-player {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
& ~ * .music-player .expanded-player {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
& ~ * .music-player .playlist-panel {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
& body .music-player .mini-player {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
& body .music-player .expanded-player {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
& body .music-player .playlist-panel {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@utility dropdown-content {
|
||||
/* 导航栏相关浮动面板的过渡禁用 */
|
||||
.is-theme-transitioning & {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
@apply bg-(--float-panel-bg) rounded-(--radius-large) shadow-xl dark:shadow-none border border-black/5 dark:border-white/10 py-2 min-w-48;
|
||||
}
|
||||
|
||||
@utility float-panel {
|
||||
.is-theme-transitioning & {
|
||||
transition: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
|
||||
.wallpaper-transparent & {
|
||||
@apply bg-(--card-bg-transparent);
|
||||
}
|
||||
@apply top-21 rounded-(--radius-large) overflow-hidden bg-(--float-panel-bg) transition-colors duration-150 shadow-xl dark:shadow-none;
|
||||
}
|
||||
|
||||
@utility card-base {
|
||||
@apply rounded-(--radius-large) overflow-hidden bg-(--card-bg) transition-colors duration-150;
|
||||
|
||||
/* 全屏壁纸模式下的半透明效果 */
|
||||
.wallpaper-transparent & {
|
||||
@apply bg-(--card-bg-transparent);
|
||||
}
|
||||
}
|
||||
|
||||
@utility card-base-transparent {
|
||||
@apply rounded-(--radius-large) overflow-hidden bg-(--card-bg-transparent) backdrop-blur-xs transition-colors duration-150;
|
||||
}
|
||||
|
||||
@utility btn-card {
|
||||
.wallpaper-transparent & {
|
||||
@apply bg-(--card-bg-transparent);
|
||||
}
|
||||
@apply transition-colors duration-150 flex items-center justify-center bg-(--card-bg) hover:bg-(--btn-card-bg-hover)
|
||||
active:bg-(--btn-card-bg-active);
|
||||
&.disabled {
|
||||
@apply pointer-events-none text-black/10 dark:text-white/10;
|
||||
}
|
||||
}
|
||||
|
||||
@utility music-player {
|
||||
.wallpaper-transparent ~ * & .mini-player {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
.wallpaper-transparent ~ * & .expanded-player {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
.wallpaper-transparent ~ * & .playlist-panel {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
body.wallpaper-transparent & .mini-player {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
body.wallpaper-transparent & .expanded-player {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
body.wallpaper-transparent & .playlist-panel {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@utility mini-player {
|
||||
.wallpaper-transparent ~ * .music-player & {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
body.wallpaper-transparent .music-player & {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@utility expanded-player {
|
||||
.wallpaper-transparent ~ * .music-player & {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
body.wallpaper-transparent .music-player & {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@utility playlist-panel {
|
||||
.wallpaper-transparent ~ * .music-player & {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
|
||||
body.wallpaper-transparent .music-player & {
|
||||
background-color: var(--card-bg-transparent) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@utility card-shadow {
|
||||
@apply drop-shadow-sm;
|
||||
}
|
||||
|
||||
@utility expand-animation {
|
||||
@apply relative before:ease-out before:transition active:bg-none hover:before:bg-(--btn-plain-bg-hover) active:before:bg-(--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;
|
||||
}
|
||||
|
||||
@utility link {
|
||||
@apply transition-colors duration-150 rounded-md p-1 -m-1 expand-animation;
|
||||
}
|
||||
|
||||
@utility link-lg {
|
||||
@apply transition-colors duration-150 rounded-md p-1.5 -m-1.5 expand-animation;
|
||||
}
|
||||
|
||||
@utility float-panel-closed {
|
||||
@apply -translate-y-1 opacity-0 pointer-events-none;
|
||||
}
|
||||
|
||||
@utility search-panel {
|
||||
& mark {
|
||||
@apply bg-transparent text-(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
@utility disabled {
|
||||
&.btn-card {
|
||||
@apply pointer-events-none text-black/10 dark:text-white/10;
|
||||
}
|
||||
}
|
||||
|
||||
@utility btn-plain {
|
||||
@apply transition-colors duration-150 relative flex items-center justify-center bg-none
|
||||
text-black/75 hover:text-(--primary) dark:text-white/75 dark:hover:text-(--primary);
|
||||
&:not(.scale-animation) {
|
||||
@apply hover:bg-(--btn-plain-bg-hover) active:bg-(--btn-plain-bg-active);
|
||||
}
|
||||
&.scale-animation {
|
||||
@apply expand-animation;
|
||||
}
|
||||
&:hover .iconify {
|
||||
@apply text-(--primary)!;
|
||||
}
|
||||
&:hover svg {
|
||||
@apply text-(--primary)!;
|
||||
}
|
||||
&:hover span {
|
||||
@apply text-(--primary)!;
|
||||
}
|
||||
}
|
||||
|
||||
@utility iconify {
|
||||
.btn-plain:hover & {
|
||||
@apply text-(--primary)!;
|
||||
}
|
||||
.current-theme-btn & {
|
||||
@apply text-(--primary)!;
|
||||
}
|
||||
}
|
||||
|
||||
@utility btn-regular {
|
||||
@apply transition-colors duration-150 flex items-center justify-center bg-(--btn-regular-bg) hover:bg-(--btn-regular-bg-hover) active:bg-(--btn-regular-bg-active)
|
||||
text-(--btn-content) dark:text-white/75;
|
||||
}
|
||||
|
||||
@utility current-theme-btn {
|
||||
@apply text-(--primary)! bg-(--btn-plain-bg-hover)! hover:bg-(--btn-plain-bg-hover)! active:bg-(--btn-plain-bg-hover)!;
|
||||
& .iconify {
|
||||
@apply text-(--primary)!;
|
||||
}
|
||||
& svg {
|
||||
@apply text-(--primary)!;
|
||||
}
|
||||
& span {
|
||||
@apply text-(--primary)!;
|
||||
}
|
||||
& .text-sm {
|
||||
@apply text-(--primary)!;
|
||||
}
|
||||
& .text-lg {
|
||||
@apply text-(--primary)!;
|
||||
}
|
||||
}
|
||||
|
||||
@utility text-sm {
|
||||
.current-theme-btn & {
|
||||
@apply text-(--primary)!;
|
||||
}
|
||||
}
|
||||
|
||||
@utility text-lg {
|
||||
.current-theme-btn & {
|
||||
@apply text-(--primary)!;
|
||||
}
|
||||
}
|
||||
|
||||
@utility link-underline {
|
||||
@apply transition-colors duration-150 underline decoration-2 decoration-dashed decoration-(--link-underline)
|
||||
hover:decoration-(--link-hover) active:decoration-(--link-active) underline-offset-4;
|
||||
}
|
||||
|
||||
@utility hide-scrollbar {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@utility text-90 {
|
||||
@apply text-black/90 dark:text-white/90;
|
||||
}
|
||||
|
||||
@utility text-75 {
|
||||
@apply text-black/75 dark:text-white/75;
|
||||
}
|
||||
|
||||
@utility text-50 {
|
||||
@apply text-black/50 dark:text-white/50;
|
||||
}
|
||||
|
||||
@utility text-30 {
|
||||
@apply text-black/30 dark:text-white/30;
|
||||
}
|
||||
|
||||
@utility text-25 {
|
||||
@apply text-black/25 dark:text-white/25;
|
||||
}
|
||||
|
||||
@utility dropdown-container {
|
||||
/* 下拉菜单样式 */
|
||||
@apply relative;
|
||||
|
||||
&:hover .dropdown-menu {
|
||||
@apply opacity-100 visible pointer-events-auto translate-y-0;
|
||||
}
|
||||
|
||||
&:focus-within .dropdown-menu {
|
||||
@apply opacity-100 visible pointer-events-auto translate-y-0;
|
||||
}
|
||||
|
||||
&:hover .dropdown-arrow {
|
||||
@apply rotate-180;
|
||||
}
|
||||
|
||||
&:focus-within .dropdown-arrow {
|
||||
@apply rotate-180;
|
||||
}
|
||||
|
||||
/* 无障碍支持 */
|
||||
&:focus-within .dropdown-menu {
|
||||
@apply opacity-100 visible pointer-events-auto translate-y-0;
|
||||
}
|
||||
}
|
||||
|
||||
@utility dropdown-menu {
|
||||
@apply absolute top-full left-0 pt-2 opacity-0 invisible pointer-events-none transition-all duration-200 ease-out translate-y-[-8px] z-50;
|
||||
|
||||
.dropdown-container:hover & {
|
||||
@apply opacity-100 visible pointer-events-auto translate-y-0;
|
||||
}
|
||||
|
||||
.dropdown-container:focus-within & {
|
||||
@apply opacity-100 visible pointer-events-auto translate-y-0;
|
||||
}
|
||||
|
||||
/* 无障碍支持 */
|
||||
.dropdown-container:focus-within & {
|
||||
@apply opacity-100 visible pointer-events-auto translate-y-0;
|
||||
}
|
||||
}
|
||||
|
||||
@utility dropdown-arrow {
|
||||
.dropdown-container:hover & {
|
||||
@apply rotate-180;
|
||||
}
|
||||
|
||||
.dropdown-container:focus-within & {
|
||||
@apply rotate-180;
|
||||
}
|
||||
}
|
||||
|
||||
@utility dropdown-item {
|
||||
@apply flex items-center justify-between px-4 py-2.5 text-black/75 dark:text-white/75 hover:text-(--primary) hover:bg-(--btn-plain-bg-hover) transition-colors duration-150 font-medium;
|
||||
|
||||
&:first-child {
|
||||
@apply rounded-t-[calc(var(--radius-large)-0.5rem)];
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
@apply rounded-b-[calc(var(--radius-large)-0.5rem)];
|
||||
}
|
||||
|
||||
&:focus {
|
||||
@apply outline-hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@utility mobile-submenu {
|
||||
/* 移动端菜单样式 */
|
||||
@apply max-h-0 overflow-hidden transition-all duration-300 ease-in-out;
|
||||
|
||||
.mobile-dropdown[data-expanded='true'] & {
|
||||
@apply max-h-96;
|
||||
}
|
||||
}
|
||||
|
||||
@utility mobile-dropdown {
|
||||
&[data-expanded='true'] .mobile-submenu {
|
||||
@apply max-h-96;
|
||||
}
|
||||
|
||||
&[data-expanded='true'] .mobile-dropdown-arrow {
|
||||
@apply rotate-180;
|
||||
}
|
||||
|
||||
& button:focus {
|
||||
@apply outline-hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@utility mobile-dropdown-arrow {
|
||||
.mobile-dropdown[data-expanded='true'] & {
|
||||
@apply rotate-180;
|
||||
}
|
||||
}
|
||||
|
||||
@utility meta-icon {
|
||||
@apply w-8 h-8 transition-colors duration-150 rounded-md flex items-center justify-center bg-(--btn-regular-bg)
|
||||
text-(--btn-content) mr-2;
|
||||
}
|
||||
|
||||
@utility with-divider {
|
||||
@apply before:content-['/'] before:ml-1.5 before:mr-1.5 before:text-(--meta-divider) before:text-sm
|
||||
before:font-medium first-of-type:before:hidden before:transition-colors before:duration-150;
|
||||
}
|
||||
|
||||
@utility 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))];
|
||||
&.success {
|
||||
@apply bg-[oklch(0.75_0.14_var(--hue))] dark:bg-[oklch(0.75_0.14_var(--hue))];
|
||||
}
|
||||
}
|
||||
|
||||
@utility success {
|
||||
&.btn-regular-dark {
|
||||
@apply bg-[oklch(0.75_0.14_var(--hue))] dark:bg-[oklch(0.75_0.14_var(--hue))];
|
||||
}
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
/* 确保平滑滚动并隐藏原生滚动条 */
|
||||
html,
|
||||
body {
|
||||
scroll-behavior: smooth;
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
}
|
||||
|
||||
html::-webkit-scrollbar,
|
||||
body::-webkit-scrollbar {
|
||||
display: none; /* Chrome, Safari and Opera */
|
||||
}
|
||||
|
||||
/* 页面顶部渐变高光效果 */
|
||||
.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 {
|
||||
h1, h2, h3, h4, h5, h6, p, a, span, li, ul, ol, blockquote, code, pre, table, th, td, strong {
|
||||
@apply transition-colors duration-150;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-md img, #post-cover img {
|
||||
@apply cursor-zoom-in
|
||||
}
|
||||
|
||||
::selection {
|
||||
background-color: var(--selection-bg)
|
||||
}
|
||||
|
||||
.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;
|
||||
translate: 0 -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);
|
||||
|
||||
&:not(:hover) {
|
||||
color: var(--_spoiler-mask);
|
||||
* {
|
||||
color: var(--_spoiler-mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 浅色模式:使用更浅的主题色且完全不透明 */
|
||||
:root:not(.dark) .custom-md spoiler {
|
||||
--_spoiler-mask: color-mix(in oklch, var(--primary) 55%, white 45%);
|
||||
}
|
||||
343
src/styles/markdown-extend.styl
Normal file
343
src/styles/markdown-extend.styl
Normal file
@@ -0,0 +1,343 @@
|
||||
.custom-md
|
||||
|
||||
blockquote.admonition
|
||||
.bdm-title
|
||||
display: flex
|
||||
align-items: center
|
||||
margin-bottom: -.9rem
|
||||
font-weight: bold
|
||||
|
||||
&:before
|
||||
content: ' '
|
||||
display: inline-block
|
||||
font-size: inherit
|
||||
overflow: visible
|
||||
margin-right: .6rem
|
||||
height: 1em
|
||||
width: 1em
|
||||
vertical-align: -.126em
|
||||
mask-size: contain
|
||||
mask-position: center
|
||||
mask-repeat: no-repeat
|
||||
translate: 0 -0.0625rem
|
||||
&.bdm-tip
|
||||
.bdm-title
|
||||
color: var(--admonitions-color-tip)
|
||||
|
||||
&:before
|
||||
background: var(--admonitions-color-tip)
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath d='M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z'%3E%3C/path%3E%3C/svg%3E")
|
||||
|
||||
&:before
|
||||
background: var(--admonitions-color-tip)
|
||||
&.bdm-note
|
||||
.bdm-title
|
||||
color: var(--admonitions-color-note)
|
||||
|
||||
&:before
|
||||
background: var(--admonitions-color-note)
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath fill='var(--admonitions-color-tip)' d='M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z'%3E%3C/path%3E%3C/svg%3E")
|
||||
|
||||
&:before
|
||||
background: var(--admonitions-color-note)
|
||||
&.bdm-important
|
||||
.bdm-title
|
||||
color: var(--admonitions-color-important)
|
||||
|
||||
&:before
|
||||
background: var(--admonitions-color-important)
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath d='M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'%3E%3C/path%3E%3C/svg%3E")
|
||||
|
||||
&:before
|
||||
background: var(--admonitions-color-important)
|
||||
&.bdm-warning
|
||||
.bdm-title
|
||||
color: var(--admonitions-color-warning)
|
||||
|
||||
&:before
|
||||
background: var(--admonitions-color-warning)
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath d='M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'%3E%3C/path%3E%3C/svg%3E")
|
||||
|
||||
&:before
|
||||
background: var(--admonitions-color-warning)
|
||||
&.bdm-caution
|
||||
.bdm-title
|
||||
color: var(--admonitions-color-caution)
|
||||
|
||||
&:before
|
||||
background: var(--admonitions-color-caution)
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath d='M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z'%3E%3C/path%3E%3C/svg%3E")
|
||||
|
||||
&:before
|
||||
background: var(--admonitions-color-caution)
|
||||
|
||||
img
|
||||
border-radius: 0.75rem
|
||||
|
||||
hr
|
||||
border-color: var(--line-divider)
|
||||
border-style: dashed
|
||||
|
||||
iframe
|
||||
border-radius: 0.75rem
|
||||
margin-left: auto
|
||||
margin-right: auto
|
||||
max-width: 100%
|
||||
|
||||
|
||||
a.card-github
|
||||
display: block
|
||||
background: var(--license-block-bg)
|
||||
position: relative
|
||||
margin: 0.5rem 0
|
||||
padding: 1.1rem 1.5rem 1.1rem 1.5rem
|
||||
color: var(--tw-prose-body)
|
||||
border-radius: var(--radius-large)
|
||||
text-decoration-thickness: 0px
|
||||
text-decoration-line: none
|
||||
|
||||
&:hover
|
||||
background-color: var(--btn-regular-bg-hover)
|
||||
|
||||
.gc-titlebar
|
||||
color: var(--btn-content)
|
||||
|
||||
.gc-stars, .gc-forks, .gc-license, .gc-description
|
||||
color: var(--tw-prose-headings)
|
||||
|
||||
&:before
|
||||
background-color: var(--tw-prose-headings)
|
||||
|
||||
&:active
|
||||
scale: .98
|
||||
background-color: var(--btn-regular-bg-active);
|
||||
|
||||
.gc-titlebar
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: space-between
|
||||
margin-bottom: 0.5rem
|
||||
color: var(--tw-prose-headings)
|
||||
font-size: 1.25rem
|
||||
font-weight: 500
|
||||
|
||||
.gc-titlebar-left
|
||||
display: flex
|
||||
flex-flow: row nowrap
|
||||
gap: 0.5rem
|
||||
|
||||
.gc-repo
|
||||
font-weight: bold
|
||||
|
||||
.gc-owner
|
||||
font-weight: 300
|
||||
position: relative
|
||||
display: flex
|
||||
flex-flow: row nowrap
|
||||
gap: 0.5rem
|
||||
align-items: center
|
||||
|
||||
.gc-avatar
|
||||
display: block
|
||||
overflow: hidden
|
||||
width: 1.5rem
|
||||
height: 1.5rem
|
||||
margin-top: -0.1rem
|
||||
background-color: var(--primary)
|
||||
background-size: cover
|
||||
border-radius: 50%
|
||||
|
||||
.gc-description
|
||||
margin-bottom: 0.7rem
|
||||
font-size: 1rem
|
||||
font-weight: 300
|
||||
line-height: 1.5rem
|
||||
color: var(--tw-prose-body)
|
||||
|
||||
.gc-infobar
|
||||
display: flex
|
||||
flex-flow: row nowrap
|
||||
gap: 1.5rem
|
||||
color: var(--tw-prose-body)
|
||||
width: fit-content
|
||||
|
||||
.gc-language
|
||||
display: none
|
||||
|
||||
.gc-stars, .gc-forks, .gc-license, .github-logo
|
||||
font-weight: 500
|
||||
font-size: 0.875rem
|
||||
opacity: 0.9;
|
||||
|
||||
&:before
|
||||
content: ' '
|
||||
display: inline-block
|
||||
height: 1.3em
|
||||
width: 1.3em
|
||||
margin-right: .4rem
|
||||
vertical-align: -.24em
|
||||
font-size: inherit
|
||||
background-color: var(--tw-prose-body)
|
||||
overflow: visible
|
||||
mask-size: contain
|
||||
mask-position: center
|
||||
mask-repeat: no-repeat
|
||||
transition-property: background-color, background;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1)
|
||||
transition-duration: 0.15s
|
||||
|
||||
.gc-stars
|
||||
&:before
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z'%3E%3C/path%3E%3C/svg%3E")
|
||||
|
||||
.gc-license
|
||||
&:before
|
||||
margin-right: .5rem
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z'%3E%3C/path%3E%3C/svg%3E")
|
||||
|
||||
.gc-forks
|
||||
&:before
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z'%3E%3C/path%3E%3C/svg%3E")
|
||||
|
||||
.github-logo
|
||||
font-size: 1.25rem
|
||||
|
||||
&:before
|
||||
background-color: var(--tw-prose-headings)
|
||||
margin-right: 0
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='31' height='32' viewBox='0 0 496 512'%3E%3Cpath fill='%23a1f7cb' d='M165.9 397.4c0 2-2.3 3.6-5.2 3.6c-3.3.3-5.6-1.3-5.6-3.6c0-2 2.3-3.6 5.2-3.6c3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9c2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9c.3 2 2.9 3.3 5.9 2.6c2.9-.7 4.9-2.6 4.6-4.6c-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2c12.8 2.3 17.3-5.6 17.3-12.1c0-6.2-.3-40.4-.3-61.4c0 0-70 15-84.7-29.8c0 0-11.4-29.1-27.8-36.6c0 0-22.9-15.7 1.6-15.4c0 0 24.9 2 38.6 25.8c21.9 38.6 58.6 27.5 72.9 20.9c2.3-16 8.8-27.1 16-33.7c-55.9-6.2-112.3-14.3-112.3-110.5c0-27.5 7.6-41.3 23.6-58.9c-2.6-6.5-11.1-33.3 2.6-67.9c20.9-6.5 69 27 69 27c20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27c13.7 34.7 5.2 61.4 2.6 67.9c16 17.7 25.8 31.5 25.8 58.9c0 96.5-58.9 104.2-114.8 110.5c9.2 7.9 17 22.9 17 46.4c0 33.7-.3 75.4-.3 83.6c0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252C496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2c1.6 1.6 3.9 2.3 5.2 1c1.3-1 1-3.3-.7-5.2c-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9c1.6 1 3.6.7 4.3-.7c.7-1.3-.3-2.9-2.3-3.9c-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2c2.3 2.3 5.2 2.6 6.5 1c1.3-1.3.7-4.3-1.3-6.2c-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9c1.6 2.3 4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2c-1.4-2.3-4-3.3-5.6-2'/%3E%3C/svg%3E")
|
||||
|
||||
a.card-github.fetch-waiting
|
||||
pointer-events: none
|
||||
opacity: 0.7
|
||||
transition: opacity 0.15s ease-in-out
|
||||
|
||||
.gc-description, .gc-infobar, .gc-avatar
|
||||
background-color: var(--tw-prose-body)
|
||||
color: transparent
|
||||
opacity: 0.5;
|
||||
animation: pulsate 2s infinite linear
|
||||
user-select: none
|
||||
|
||||
&:before
|
||||
background-color: transparent
|
||||
|
||||
.gc-repo
|
||||
margin-left: -0.1rem
|
||||
|
||||
.gc-description, .gc-infobar
|
||||
border-radius: 0.5rem
|
||||
|
||||
a.card-github.fetch-error
|
||||
pointer-events: all
|
||||
opacity: 1
|
||||
|
||||
.card-github, .gc-description, .gc-titlebar, .gc-stars, .gc-forks, .gc-license, .gc-avatar, .github-logo
|
||||
transition-property: all
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1)
|
||||
transition-duration: 0.15s
|
||||
|
||||
|
||||
.mermaid-wrapper
|
||||
padding: 1.5rem
|
||||
text-align: center
|
||||
|
||||
|
||||
.mermaid
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
min-height: 100px
|
||||
font-family: inherit
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
svg
|
||||
max-width: 100%
|
||||
height: auto
|
||||
border-radius: 0.5rem
|
||||
user-select: none;
|
||||
pointer-events: all;
|
||||
|
||||
|
||||
// 响应式设计
|
||||
@media (max-width: 768px)
|
||||
.mermaid-wrapper
|
||||
padding: 1rem
|
||||
|
||||
.mermaid svg
|
||||
max-height: 400px
|
||||
|
||||
|
||||
.mermaid-error
|
||||
color: var(--admonitions-color-warning)
|
||||
background: rgba(239, 68, 68, 0.1)
|
||||
border: 1px solid var(--admonitions-color-warning)
|
||||
border-radius: 0.5rem
|
||||
padding: 1rem
|
||||
margin: 1rem 0
|
||||
text-align: center
|
||||
font-weight: 500
|
||||
|
||||
p
|
||||
margin: 0 0 0.5rem 0
|
||||
|
||||
button
|
||||
transition: all 0.2s ease
|
||||
|
||||
&:hover
|
||||
background: var(--primary-hover) !important
|
||||
translate: 0 -1px
|
||||
|
||||
|
||||
.mermaid-zoom-wrapper
|
||||
transform-origin: 0 0;
|
||||
transition: transform 120ms ease-out;
|
||||
will-change: transform;
|
||||
cursor: grab;
|
||||
background: transparent;
|
||||
|
||||
.mermaid-zoom-wrapper:active
|
||||
cursor: grabbing;
|
||||
|
||||
.mermaid-zoom-controls
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
z-index: 30;
|
||||
user-select: none;
|
||||
|
||||
|
||||
.mermaid-diagram-container
|
||||
margin: 1rem 0
|
||||
border-radius: 0.75rem
|
||||
overflow: hidden
|
||||
background: var(--card-bg)
|
||||
transition: all 0.3s ease
|
||||
|
||||
&:hover
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1)
|
||||
|
||||
.dark .mermaid-diagram-container
|
||||
background: var(--card-bg)
|
||||
|
||||
svg
|
||||
filter: brightness(0.9) contrast(1.1)
|
||||
|
||||
|
||||
@keyframes pulsate
|
||||
0%
|
||||
opacity: 0.15
|
||||
50%
|
||||
opacity: 0.25
|
||||
100%
|
||||
opacity: 0.15
|
||||
|
||||
|
||||
@keyframes spin
|
||||
0%
|
||||
rotate: 0deg
|
||||
100%
|
||||
rotate: 360deg
|
||||
168
src/styles/markdown.css
Normal file
168
src/styles/markdown.css
Normal file
@@ -0,0 +1,168 @@
|
||||
@reference "tailwindcss";
|
||||
|
||||
.custom-md {
|
||||
h1 {
|
||||
@apply text-3xl;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
.anchor {
|
||||
@apply transition! -m-0.5! ml-[0.2ch]! p-0.5! select-none! opacity-0! no-underline!;
|
||||
|
||||
.anchor-icon {
|
||||
@apply mx-[0.45ch]!;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.anchor {
|
||||
@apply opacity-100!;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a:not(.no-styling) {
|
||||
@apply relative bg-none font-medium text-(--primary)
|
||||
underline decoration-(--link-underline) decoration-1 decoration-dashed underline-offset-4;
|
||||
box-decoration-break: clone;
|
||||
-webkit-box-decoration-break: clone;
|
||||
&:hover, &:active {
|
||||
@apply decoration-transparent;
|
||||
background: var(--btn-plain-bg-hover);
|
||||
border-bottom: 1px dashed var(--link-hover);
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
@apply bg-(--inline-code-bg) text-(--inline-code-color) px-1 py-0.5 rounded-md overflow-hidden;
|
||||
|
||||
font-family: 'JetBrains Mono Variable', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
|
||||
&:before {
|
||||
content:none;
|
||||
}
|
||||
&:after {
|
||||
content:none;
|
||||
}
|
||||
|
||||
counter-reset: line;
|
||||
span.line {
|
||||
&:before {
|
||||
@apply text-black/25 dark:text-white/25 mr-4 w-4 inline-block;
|
||||
content: counter(line);
|
||||
counter-increment: line;
|
||||
direction: rtl;
|
||||
}
|
||||
&:last-child:empty, &:last-child:has(> span:empty:only-child) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.collapse-btn {
|
||||
all: initial;
|
||||
@apply opacity-0 absolute active:scale-90 h-6 w-6 top-2 right-10 text-xs rounded transition-all ease-in-out z-20 cursor-pointer bg-(--btn-regular-bg) hover:bg-(--btn-regular-bg-hover) text-(--btn-content);
|
||||
}
|
||||
.expressive-code:hover .collapse-btn {
|
||||
opacity: 1;
|
||||
}
|
||||
.collapse-btn-icon {
|
||||
@apply absolute top-1/2 left-1/2 transition -translate-x-1/2 -translate-y-1/2 w-3 h-3 fill-current pointer-events-none;
|
||||
}
|
||||
.expressive-code.collapsed .collapse-icon {
|
||||
@apply -rotate-90;
|
||||
}
|
||||
.expressive-code.collapsed pre {
|
||||
@apply max-h-[5.5rem] overflow-hidden;
|
||||
}
|
||||
.expressive-code.collapsed .frame {
|
||||
@apply relative;
|
||||
}
|
||||
.expressive-code.collapsed .frame::before {
|
||||
content: "";
|
||||
@apply absolute bottom-0 left-0 right-0 h-12 bg-linear-to-t from-(--codeblock-bg) to-transparent pointer-events-none z-10;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
all: initial;
|
||||
@apply opacity-0 absolute active:scale-90 h-6 w-6 top-2 right-2 text-xs rounded transition-all ease-in-out z-20 cursor-pointer bg-(--btn-regular-bg) hover:bg-(--btn-regular-bg-hover) text-(--btn-content);
|
||||
}
|
||||
.expressive-code:hover .copy-btn {
|
||||
opacity: 1;
|
||||
}
|
||||
.copy-btn-icon {
|
||||
@apply absolute top-1/2 left-1/2 transition -translate-x-1/2 -translate-y-1/2 w-3 h-3 fill-current pointer-events-none;
|
||||
}
|
||||
.copy-btn .copy-icon {
|
||||
@apply opacity-100;
|
||||
}
|
||||
.copy-btn.success .copy-icon {
|
||||
@apply opacity-0;
|
||||
}
|
||||
.copy-btn .success-icon {
|
||||
@apply opacity-0;
|
||||
}
|
||||
.copy-btn.success .success-icon {
|
||||
@apply opacity-100;
|
||||
}
|
||||
|
||||
.expressive-code {
|
||||
@apply my-4;
|
||||
::selection {
|
||||
@apply bg-(--codeblock-selection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ul, ol {
|
||||
li::marker {
|
||||
@apply text-(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
blockquote {
|
||||
@apply not-italic border-transparent relative;
|
||||
font-weight: inherit;
|
||||
|
||||
&:before {
|
||||
@apply content-[''] absolute -left-1 block transition bg-(--btn-regular-bg) h-full w-1 rounded-full;
|
||||
}
|
||||
|
||||
/* Remove the double quotes from default styles */
|
||||
p:before, p:after {
|
||||
@apply content-none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.katex-display {
|
||||
@apply my-4;
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(0,0,0,0.3) transparent;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
height: 6px;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(0,0,0,0.3);
|
||||
border-radius: 3px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(0,0,0,0.5);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* 修复代码块内列表项标记颜色问题 */
|
||||
.custom-md .expressive-code ul li::marker,
|
||||
.custom-md .expressive-code ol li::marker {
|
||||
@apply text-inherit;
|
||||
}
|
||||
173
src/styles/musicplayer.css
Normal file
173
src/styles/musicplayer.css
Normal file
@@ -0,0 +1,173 @@
|
||||
@reference "tailwindcss";
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
.animate-pulse {
|
||||
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
}
|
||||
|
||||
@keyframes slide-up {
|
||||
from {
|
||||
translate: 0 100%;
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
translate: 0 0;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.animate-slide-up {
|
||||
animation: slide-up 0.3s ease-out;
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
from { rotate: 0deg; }
|
||||
to { rotate: 360deg; }
|
||||
}
|
||||
|
||||
@keyframes musicWave {
|
||||
0%, 100% { scale: 1 0.5; }
|
||||
50% { scale: 1 1; }
|
||||
}
|
||||
|
||||
@keyframes spin-continuous {
|
||||
from {
|
||||
rotate: 0deg;
|
||||
}
|
||||
to {
|
||||
rotate: 360deg;
|
||||
}
|
||||
}
|
||||
.cover-container img {
|
||||
animation: spin-continuous 3s linear infinite;
|
||||
animation-play-state: paused;
|
||||
}
|
||||
.cover-container img.spinning {
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
button.bg-\(--primary\) {
|
||||
box-shadow: 0 0 0 2px var(--primary);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.orb-player {
|
||||
position: relative;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
.orb-player::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: -2px;
|
||||
background: linear-gradient(45deg, var(--primary), transparent, var(--primary));
|
||||
border-radius: 50%;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
.orb-player:hover::before {
|
||||
opacity: 0.3;
|
||||
animation: rotate 2s linear infinite;
|
||||
}
|
||||
.orb-player .animate-pulse {
|
||||
animation: musicWave 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.music-player {
|
||||
max-width: 320px;
|
||||
user-select: none;
|
||||
}
|
||||
.expanded-player {
|
||||
width: 320px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
.music-player.expanded .expanded-player {
|
||||
position: relative;
|
||||
}
|
||||
.music-player.expanded .orb-player {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
.progress-section div:hover,
|
||||
.bottom-controls > div:hover {
|
||||
scale: 1 1.2;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
/* Playlist Scrollbar Styles */
|
||||
.playlist-content {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: transparent transparent;
|
||||
transition: scrollbar-color 0.3s ease;
|
||||
}
|
||||
.playlist-content:hover {
|
||||
scrollbar-color: rgba(155, 155, 155, 0.5) transparent;
|
||||
}
|
||||
.playlist-content::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
.playlist-content::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
.playlist-content::-webkit-scrollbar-thumb {
|
||||
background-color: transparent;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.playlist-content:hover::-webkit-scrollbar-thumb {
|
||||
background-color: rgba(155, 155, 155, 0.5);
|
||||
}
|
||||
|
||||
@media (hover: none) and (pointer: coarse) {
|
||||
.music-player button,
|
||||
.playlist-item {
|
||||
min-height: 44px;
|
||||
}
|
||||
.progress-section > div,
|
||||
.bottom-controls > div:nth-child(2) {
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.music-player {
|
||||
max-width: 280px;
|
||||
/*left: 8px !important;*/
|
||||
bottom: 8px !important;
|
||||
right: 8px !important;
|
||||
}
|
||||
.music-player.expanded {
|
||||
width: calc(100vw - 16px);
|
||||
max-width: 320px;
|
||||
/*left: 8px !important;*/
|
||||
right: 8px !important;
|
||||
}
|
||||
.expanded-player {
|
||||
width: min(calc(100vw - 16px), 320px) !important;
|
||||
}
|
||||
.playlist-panel {
|
||||
width: min(calc(100vw - 16px), 320px) !important;
|
||||
/*left: 8px !important;*/
|
||||
/*right: 8px !important;*/
|
||||
max-width: none;
|
||||
}
|
||||
.controls {
|
||||
gap: 8px;
|
||||
}
|
||||
.controls button {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.controls button:nth-child(3) {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
}
|
||||
269
src/styles/navbar.css
Normal file
269
src/styles/navbar.css
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* 导航栏半透明效果样式
|
||||
* Navbar Translucent Effects Styles
|
||||
* 只有当页面启用banner时才应用半透明效果
|
||||
*/
|
||||
|
||||
|
||||
/* 导航区域基础布局样式(避免 flex 子项溢出) */
|
||||
.navbar-nav-links {
|
||||
min-width: 0;
|
||||
flex-shrink: 1;
|
||||
transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s, gap 0.3s ease;
|
||||
}
|
||||
|
||||
/* 导航链接样式 */
|
||||
.nav-link-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 小屏幕时只显示图标 */
|
||||
@media (max-width: 1279px) {
|
||||
.nav-link-item {
|
||||
width: 2.75rem; /* 11 * 0.25rem */
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.nav-link-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-link-icon {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 大屏幕时显示图标+文字 */
|
||||
@media (min-width: 1280px) {
|
||||
.nav-link-item {
|
||||
padding-left: 0.75rem; /* 3 * 0.25rem */
|
||||
padding-right: 0.75rem;
|
||||
}
|
||||
|
||||
.nav-link-text {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
/* 按钮区域基础布局样式(避免 flex 子项溢出) */
|
||||
.navbar-buttons {
|
||||
min-width: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 无banner时使用原始card-base样式,不添加额外的透明效果 */
|
||||
/* 确保导航栏在没有banner时有基本的背景色和圆角(低优先级,不覆盖card-base) */
|
||||
#navbar > div {
|
||||
background: var(--card-bg);
|
||||
border-radius: var(--radius-large);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
|
||||
/* 半透明模式 - 在有banner时启用 */
|
||||
:is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #navbar[data-transparent-mode="semi"] > div {
|
||||
backdrop-filter: blur(20px) !important;
|
||||
background: rgba(255, 255, 255, 0.55) !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.55) !important;
|
||||
border-radius: 0.75rem !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1) !important;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
||||
}
|
||||
/* 半透明模式 - 在有banner时启用 - 暗色主题 */
|
||||
:root.dark :is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #navbar[data-transparent-mode="semi"] > div {
|
||||
background: rgba(0, 0, 0, 0.55) !important;
|
||||
border: 1px solid rgba(0, 0, 0, 0.55) !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2) !important;
|
||||
}
|
||||
|
||||
/* 完全透明模式 - 在有banner时启用 */
|
||||
:is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #navbar[data-transparent-mode="full"] > div {
|
||||
backdrop-filter: none !important;
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: none !important;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
||||
}
|
||||
/* 完全透明模式 - 在有banner时启用 - 暗色主题 */
|
||||
:root.dark :is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #navbar[data-transparent-mode="full"] > div {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
/* 半完全透明模式 - 在有banner时启用 - 默认状态:页面顶部时完全透明 */
|
||||
:is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #navbar[data-transparent-mode="semifull"] > div {
|
||||
backdrop-filter: none !important;
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: none !important;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
||||
}
|
||||
/* 半完全透明模式 - 在有banner时启用 - 默认状态:页面顶部时完全透明 - 暗色主题 */
|
||||
:root.dark :is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #navbar[data-transparent-mode="semifull"] > div {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
/* 半完全透明模式 - 在有banner时启用 - 滚动状态:下滑后变为半透明圆角 */
|
||||
:is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #navbar[data-transparent-mode="semifull"].scrolled > div {
|
||||
backdrop-filter: blur(20px) !important;
|
||||
background: rgba(255, 255, 255, 0.55) !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.55) !important;
|
||||
border-radius: 0.75rem !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1) !important;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
||||
}
|
||||
/* 半完全透明模式 - 在有banner时启用 - 滚动状态:下滑后变为半透明圆角 - 暗色主题 */
|
||||
:root.dark :is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #navbar[data-transparent-mode="semifull"].scrolled > div {
|
||||
background: rgba(0, 0, 0, 0.55) !important;
|
||||
border: 1px solid rgba(0, 0, 0, 0.55) !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2) !important;
|
||||
}
|
||||
|
||||
/* 二级菜单、主题色、夜间模式菜单、手机端导航在有banner时启用半透明效果 */
|
||||
:is(#banner-wrapper ~ *, body:has(#banner-wrapper)) .dropdown-content,
|
||||
:is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #display-setting,
|
||||
:is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #nav-menu-panel,
|
||||
:is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #translate-panel,
|
||||
:is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #search-panel {
|
||||
backdrop-filter: blur(20px) !important;
|
||||
background: rgba(255, 255, 255, 0.55) !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.55) !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1) !important;
|
||||
}
|
||||
/* 二级菜单、主题色、夜间模式菜单、手机端导航在有banner时启用半透明效果 - 暗色主题 */
|
||||
:root.dark :is(#banner-wrapper ~ *, body:has(#banner-wrapper)) .dropdown-content,
|
||||
:root.dark :is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #display-setting,
|
||||
:root.dark :is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #nav-menu-panel,
|
||||
:root.dark :is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #translate-panel,
|
||||
:root.dark :is(#banner-wrapper ~ *, body:has(#banner-wrapper)) #search-panel {
|
||||
background: rgba(0, 0, 0, 0.55) !important;
|
||||
border: 1px solid rgba(0, 0, 0, 0.55) !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2) !important;
|
||||
}
|
||||
|
||||
/* 响应式优化 */
|
||||
|
||||
/* 桌面端&平板端布局 */
|
||||
@media (min-width: 768px) {
|
||||
/* 使用 Grid 布局确保中间区域在有空间时居中 */
|
||||
#navbar > div {
|
||||
display: grid !important;
|
||||
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
/* 确保左侧 Home 按钮不拉伸并靠左 */
|
||||
#navbar > div > a:first-child {
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
#navbar .navbar-nav-links {
|
||||
position: static;
|
||||
left: unset;
|
||||
translate: none;
|
||||
justify-self: center;
|
||||
gap: clamp(0.12rem, 1vw, 0.36rem);
|
||||
}
|
||||
|
||||
#navbar .navbar-buttons {
|
||||
justify-self: end;
|
||||
gap: clamp(0.12rem, 1vw, 0.36rem);
|
||||
}
|
||||
}
|
||||
|
||||
/* 非大屏桌面端&平板端优化 */
|
||||
@media (min-width: 768px) and (max-width: 1279px) {
|
||||
#navbar .navbar-nav-links {
|
||||
gap: 0.2rem;
|
||||
}
|
||||
|
||||
#navbar .navbar-buttons {
|
||||
gap: 0.2rem;
|
||||
}
|
||||
|
||||
/* 搜索状态下的避让逻辑以防重叠 */
|
||||
#navbar.is-searching .navbar-nav-links {
|
||||
opacity: 0;
|
||||
scale: 0.9;
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/* 手机端导航栏 */
|
||||
@media (max-width: 768px) {
|
||||
#navbar > div {
|
||||
max-width: none !important;
|
||||
width: 100% !important;
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
/* 手机端导航栏 - 小屏 */
|
||||
@media (max-width: 512px) {
|
||||
#navbar > div {
|
||||
border-radius: 0.3rem !important;
|
||||
margin: 0 !important;
|
||||
padding-left: 0.6rem !important;
|
||||
padding-right: 0.6rem !important;
|
||||
max-width: none !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
#navbar-buttons {
|
||||
gap: 0.123rem !important;
|
||||
}
|
||||
/* Only size the trigger buttons; do not affect nested buttons inside panels */
|
||||
#navbar-buttons button:not(.float-panel *) {
|
||||
width: 2.4rem !important;
|
||||
height: 2.4rem !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* home button */
|
||||
#navbar > div > a:first-child {
|
||||
width: 7.2rem !important;
|
||||
height: 2.4rem !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 手机端导航栏 - 更小屏 */
|
||||
@media (min-width: 333px) and (max-width: 444px) {
|
||||
#navbar-buttons {
|
||||
gap: 0.111rem !important;
|
||||
}
|
||||
/* Only size the trigger buttons; do not affect nested buttons inside panels */
|
||||
#navbar-buttons button:not(.float-panel *) {
|
||||
width: 2.1rem !important;
|
||||
height: 2.1rem !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* home button */
|
||||
#navbar > div > a:first-child {
|
||||
width: 6.3rem !important;
|
||||
height: 2.1rem !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 手机端导航栏按钮 -超小屏 */
|
||||
@media (max-width: 333px) {
|
||||
#navbar-buttons {
|
||||
gap: 0 !important;
|
||||
justify-content: flex-end !important;
|
||||
}
|
||||
|
||||
/* Hide home button text (keep icon) */
|
||||
#navbar > div > a:first-child > div {
|
||||
font-size: 0 !important;
|
||||
}
|
||||
}
|
||||
190
src/styles/transition.css
Normal file
190
src/styles/transition.css
Normal file
@@ -0,0 +1,190 @@
|
||||
/* Page transition animations with Swup - Enhanced version inspired by yukina */
|
||||
|
||||
/* 主要内容区域的过渡动画 - 参考yukina的侧滑效果 */
|
||||
.transition-main {
|
||||
transition:
|
||||
opacity 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
|
||||
translate 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
}
|
||||
|
||||
/* 离开动画 - 内容向右上滑出并淡出 */
|
||||
.transition-leaving {
|
||||
transition:
|
||||
translate 300ms cubic-bezier(0.55, 0.055, 0.675, 0.19),
|
||||
opacity 300ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
|
||||
}
|
||||
|
||||
html.is-changing .transition-main {
|
||||
transition:
|
||||
opacity 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
|
||||
translate 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
}
|
||||
|
||||
html.is-leaving .transition-main {
|
||||
transition:
|
||||
opacity 300ms cubic-bezier(0.55, 0.055, 0.675, 0.19),
|
||||
translate 300ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
|
||||
}
|
||||
|
||||
/* 进入动画 - 从右下角轻微滑入,模仿yukina效果 */
|
||||
html.is-animating .transition-main {
|
||||
opacity: 0;
|
||||
translate: 0.5rem 1.5rem;
|
||||
}
|
||||
|
||||
/* 离开动画 - 向左上角滑出 */
|
||||
html.is-animating.is-leaving .transition-leaving {
|
||||
translate: -0.5rem -1rem;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* Swup fade 动画 - 保持兼容性 */
|
||||
html.is-changing .transition-swup-fade {
|
||||
transition: all 300ms ease-out;
|
||||
}
|
||||
|
||||
html.is-animating .transition-swup-fade {
|
||||
opacity: 0;
|
||||
translate: 0 1.5rem;
|
||||
}
|
||||
|
||||
/* Loading 状态下禁止滚动 */
|
||||
html.is-loading {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 淡入动画 */
|
||||
@keyframes fade-in-up {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: 0 1.5rem;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-in-down {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: 0 -1.5rem;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
/* 淡出动画 */
|
||||
@keyframes fade-out-down {
|
||||
from {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
translate: 0 -1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* 隐藏页面加载动画 */
|
||||
.onload-animation-up, .onload-animation-down {
|
||||
opacity: 0;
|
||||
}
|
||||
/* 动画结束后或在非加载/非初始动画状态下保持可见 */
|
||||
html:not(.is-loading):not(.show-initial-animation) :is(.onload-animation-up, .onload-animation-down) {
|
||||
opacity: 1;
|
||||
}
|
||||
/* 初始加载动画,仅在 .show-initial-animation 存在时触发以避免与 Swup 自身的过渡动画冲突 */
|
||||
.show-initial-animation .onload-animation-up {
|
||||
animation: fade-in-up 600ms ease-out forwards;
|
||||
}
|
||||
.show-initial-animation .onload-animation-down {
|
||||
animation: fade-in-down 600ms ease-out forwards;
|
||||
}
|
||||
/* 渐进式动画延迟 - 仅在初始加载时应用 */
|
||||
.show-initial-animation :is(.onload-animation-up, .onload-animation-down):nth-child(1) { animation-delay: 0ms; }
|
||||
.show-initial-animation :is(.onload-animation-up, .onload-animation-down):nth-child(2) { animation-delay: 150ms; }
|
||||
.show-initial-animation :is(.onload-animation-up, .onload-animation-down):nth-child(3) { animation-delay: 300ms; }
|
||||
.show-initial-animation :is(.onload-animation-up, .onload-animation-down):nth-child(4) { animation-delay: 450ms; }
|
||||
.show-initial-animation :is(.onload-animation-up, .onload-animation-down):nth-child(5) { animation-delay: 600ms; }
|
||||
|
||||
/* 特殊元素的动画 */
|
||||
.transition-slide-in {
|
||||
opacity: 0;
|
||||
translate: 8px 20px;
|
||||
transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
}
|
||||
.transition-slide-in.active {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
|
||||
/* 卡片动画 */
|
||||
.card-animation {
|
||||
opacity: 0;
|
||||
translate: 10px 30px;
|
||||
scale: 0.98;
|
||||
transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
}
|
||||
.card-animation.visible {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
scale: 1;
|
||||
}
|
||||
|
||||
/* 导航动画 */
|
||||
.nav-animation {
|
||||
opacity: 0;
|
||||
translate: -20px 0;
|
||||
transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
}
|
||||
.nav-animation.loaded {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
|
||||
/* 性能优化 */
|
||||
.transition-main,
|
||||
.transition-leaving,
|
||||
.onload-animation-up,
|
||||
.onload-animation-down,
|
||||
.transition-slide-in,
|
||||
.card-animation {
|
||||
backface-visibility: hidden;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 768px) {
|
||||
html.is-animating .transition-main {
|
||||
translate: 0.3rem 1rem;
|
||||
}
|
||||
|
||||
html.is-animating.is-leaving .transition-leaving {
|
||||
translate: -0.3rem -0.8rem;
|
||||
}
|
||||
|
||||
.transition-slide-in {
|
||||
translate: 5px 15px;
|
||||
}
|
||||
|
||||
.card-animation {
|
||||
translate: 6px 20px;
|
||||
scale: 0.99;
|
||||
}
|
||||
}
|
||||
|
||||
/* 减少动画的用户偏好设置 */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.transition-main,
|
||||
.transition-leaving,
|
||||
.onload-animation-up,
|
||||
.onload-animation-down,
|
||||
.transition-slide-in,
|
||||
.card-animation,
|
||||
.nav-animation {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
192
src/styles/twikoo.css
Normal file
192
src/styles/twikoo.css
Normal file
@@ -0,0 +1,192 @@
|
||||
@reference "tailwindcss";
|
||||
|
||||
:root {
|
||||
--tk-text: black;
|
||||
--code-block-text: #333; /* 调整为深色但在浅色背景下仍然舒适的值 */
|
||||
}
|
||||
|
||||
html.dark {
|
||||
--tk-text: #d1d5db;
|
||||
--code-block-text: #d1d5db; /* 在深色模式下使用更亮的颜色 */
|
||||
}
|
||||
|
||||
.tk-comments {
|
||||
@apply text-(--tk-text);
|
||||
}
|
||||
|
||||
.tk-submit {
|
||||
.tk-avatar {
|
||||
@apply hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/* Text Area */
|
||||
.tk-row {
|
||||
.tk-col {
|
||||
@apply flex-col-reverse;
|
||||
.tk-input {
|
||||
textarea {
|
||||
@apply rounded-(--radius-large) py-4 px-6 min-h-[150px]! focus:border-(--primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Meta */
|
||||
.tk-meta-input {
|
||||
@apply relative mt-3;
|
||||
div {
|
||||
@apply min-h-10;
|
||||
.el-input-group__prepend {
|
||||
@apply bg-inherit! rounded-l-lg;
|
||||
min-height: inherit;
|
||||
}
|
||||
input {
|
||||
@apply px-4 rounded-r-lg focus:border-(--primary)!;
|
||||
min-height: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Button */
|
||||
.tk-row.actions {
|
||||
@apply w-full ml-0! mt-0!;
|
||||
.__markdown {
|
||||
@apply hidden!;
|
||||
}
|
||||
.tk-preview,
|
||||
.tk-send,
|
||||
.tk-cancel {
|
||||
@apply border-none rounded-lg px-3 py-0 h-8
|
||||
bg-(--btn-regular-bg-active)! disabled:bg-(--btn-regular-bg)!
|
||||
text-(--btn-content)! disabled:text-[#ffffffa1]!;
|
||||
}
|
||||
}
|
||||
|
||||
/* Comment title */
|
||||
.tk-comments-title {
|
||||
.__comments svg {
|
||||
@apply fill-(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
.tk-comment {
|
||||
@apply border border-[rgba(144,147,153,0.31)] p-4 rounded-2xl hover:shadow-md transition-all;
|
||||
.tk-action-icon svg {
|
||||
@apply fill-(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
.tk-action {
|
||||
.tk-action-count {
|
||||
@apply text-(--btn-content);
|
||||
}
|
||||
}
|
||||
|
||||
.tk-meta {
|
||||
.tk-tag {
|
||||
@apply border-none rounded-lg text-(--btn-content);
|
||||
}
|
||||
|
||||
.tk-tag-green {
|
||||
@apply bg-(--btn-regular-bg) dark:bg-(--primary) dark:text-(--deep-text);
|
||||
}
|
||||
}
|
||||
|
||||
/* Content & Preview */
|
||||
.tk-content,
|
||||
.tk-preview-container {
|
||||
/* by @microsic
|
||||
Make the picture type emoticons display without wrapping
|
||||
*/
|
||||
img {
|
||||
@apply inline align-bottom!;
|
||||
}
|
||||
|
||||
a {
|
||||
@apply underline text-(--primary) font-medium;
|
||||
}
|
||||
|
||||
.tk-ruser {
|
||||
@apply no-underline;
|
||||
}
|
||||
|
||||
:not(pre) > code {
|
||||
@apply bg-(--inline-code-bg) rounded-md text-[--inline-code-color] px-1 py-0.5 font-semibold;
|
||||
}
|
||||
|
||||
li {
|
||||
@apply before:content-["•"] before:text-(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
/* Replies */
|
||||
.tk-replies {
|
||||
.tk-comment {
|
||||
@apply bg-(--page-bg);
|
||||
.tk-content {
|
||||
> span:first-of-type {
|
||||
@apply text-xs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.twikoo .code-block {
|
||||
pre {
|
||||
@apply rounded-xl!;
|
||||
}
|
||||
|
||||
/* Code block fall back */
|
||||
pre:not([class]) {
|
||||
@apply bg-(--codeblock-bg) overflow-auto p-2 text-(--code-block-text);
|
||||
}
|
||||
|
||||
.copy-btn-icon {
|
||||
width: inherit !important;
|
||||
height: inherit !important;
|
||||
}
|
||||
}
|
||||
|
||||
.tk-expand-wrap .tk-expand,
|
||||
.tk-collapse-wrap .tk-expand {
|
||||
@apply hover:rounded-lg mt-1 hover:bg-(--btn-plain-bg-hover);
|
||||
}
|
||||
|
||||
/* by @SirTamago
|
||||
Make the emoji component display correctly when there are too many emoji packs
|
||||
*/
|
||||
.card-base {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* 防止 Twikoo 操作时的意外滚动 */
|
||||
.tk-action-icon,
|
||||
.tk-owo,
|
||||
.tk-submit,
|
||||
.tk-cancel,
|
||||
.tk-preview,
|
||||
.tk-admin,
|
||||
.tk-delete,
|
||||
.tk-edit {
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
/* 确保点击区域足够大 */
|
||||
.tk-action {
|
||||
min-height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 防止表单提交时的意外跳转 */
|
||||
.tk-submit-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 管理面板样式优化 */
|
||||
.tk-admin-panel {
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
}
|
||||
99
src/styles/variables.styl
Normal file
99
src/styles/variables.styl
Normal file
@@ -0,0 +1,99 @@
|
||||
/* utils */
|
||||
white(a)
|
||||
rgba(255, 255, 255, a)
|
||||
|
||||
black(a)
|
||||
rgba(0, 0, 0, a)
|
||||
|
||||
rainbow-light = linear-gradient(to right, oklch(0.80 0.10 0), oklch(0.80 0.10 30), oklch(0.80 0.10 60), oklch(0.80 0.10 90), oklch(0.80 0.10 120), oklch(0.80 0.10 150), oklch(0.80 0.10 180), oklch(0.80 0.10 210), oklch(0.80 0.10 240), oklch(0.80 0.10 270), oklch(0.80 0.10 300), oklch(0.80 0.10 330), oklch(0.80 0.10 360))
|
||||
rainbow-dark = linear-gradient(to right, oklch(0.70 0.10 0), oklch(0.70 0.10 30), oklch(0.70 0.10 60), oklch(0.70 0.10 90), oklch(0.70 0.10 120), oklch(0.70 0.10 150), oklch(0.70 0.10 180), oklch(0.70 0.10 210), oklch(0.70 0.10 240), oklch(0.70 0.10 270), oklch(0.70 0.10 300), oklch(0.70 0.10 330), oklch(0.70 0.10 360))
|
||||
|
||||
:root
|
||||
--radius-large 1rem
|
||||
|
||||
/* An util to define variables that vary with light and dark mode */
|
||||
define(vars)
|
||||
:root
|
||||
for key, value in vars
|
||||
{key}: value[0]
|
||||
:root.dark
|
||||
for key, value in vars
|
||||
if length(value) > 1
|
||||
{key}: value[1]
|
||||
|
||||
define({
|
||||
--primary: oklch(0.70 0.14 var(--hue)) oklch(0.75 0.14 var(--hue))
|
||||
--page-bg: oklch(0.95 0.01 var(--hue)) oklch(0.16 0.014 var(--hue))
|
||||
--card-bg: white oklch(0.23 0.015 var(--hue))
|
||||
--card-bg-transparent: rgba(255, 255, 255, 0.8) rgba(23, 23, 23, 0.8)
|
||||
|
||||
--btn-content: oklch(0.55 0.12 var(--hue)) oklch(0.75 0.1 var(--hue))
|
||||
|
||||
--btn-regular-bg: oklch(0.95 0.025 var(--hue)) oklch(0.33 0.035 var(--hue))
|
||||
--btn-regular-bg-hover: oklch(0.9 0.05 var(--hue)) oklch(0.38 0.04 var(--hue))
|
||||
--btn-regular-bg-active: oklch(0.85 0.08 var(--hue)) oklch(0.43 0.045 var(--hue))
|
||||
|
||||
--btn-plain-bg-hover: oklch(0.95 0.025 var(--hue)) oklch(0.30 0.035 var(--hue))
|
||||
--btn-plain-bg-active: oklch(0.98 0.01 var(--hue)) oklch(0.27 0.025 var(--hue))
|
||||
|
||||
--btn-card-bg-hover: oklch(0.98 0.005 var(--hue)) oklch(0.3 0.03 var(--hue))
|
||||
--btn-card-bg-active: oklch(0.9 0.03 var(--hue)) oklch(0.35 0.035 var(--hue))
|
||||
|
||||
--enter-btn-bg: var(--btn-regular-bg)
|
||||
--enter-btn-bg-hover: var(--btn-regular-bg-hover)
|
||||
--enter-btn-bg-active: var(--btn-regular-bg-active)
|
||||
|
||||
--deep-text: oklch(0.25 0.02 var(--hue))
|
||||
|
||||
--title-active: oklch(0.6 0.1 var(--hue))
|
||||
|
||||
--line-divider: black(0.08) white(0.08)
|
||||
|
||||
--line-color: black(0.1) white(0.1)
|
||||
--meta-divider: black(0.2) white(0.2)
|
||||
--content-meta: black(0.6) white(0.6)
|
||||
|
||||
--inline-code-bg: var(--btn-regular-bg)
|
||||
--inline-code-color: var(--btn-content)
|
||||
--selection-bg: oklch(0.90 0.05 var(--hue)) oklch(0.40 0.08 var(--hue))
|
||||
--codeblock-selection: oklch(0.90 0.06 var(--hue)) oklch(0.45 0.06 var(--hue))
|
||||
--codeblock-bg: oklch(0.96 0.015 var(--hue)) oklch(0.18 0.015 var(--hue))
|
||||
--codeblock-topbar-bg: oklch(0.93 0.03 var(--hue)) oklch(0.12 0.015 var(--hue))
|
||||
|
||||
--license-block-bg: black(0.03) var(--codeblock-bg)
|
||||
|
||||
--link-underline: oklch(0.93 0.04 var(--hue)) oklch(0.40 0.08 var(--hue))
|
||||
--link-hover: oklch(0.95 0.025 var(--hue)) oklch(0.40 0.08 var(--hue))
|
||||
--link-active: oklch(0.90 0.05 var(--hue)) oklch(0.35 0.07 var(--hue))
|
||||
|
||||
--float-panel-bg: white oklch(0.19 0.015 var(--hue))
|
||||
|
||||
--scrollbar-bg-light: black(0.4)
|
||||
--scrollbar-bg-hover-light: black(0.5)
|
||||
--scrollbar-bg-active-light: black(0.6)
|
||||
|
||||
--scrollbar-bg-dark: white(0.4)
|
||||
--scrollbar-bg-hover-dark: white(0.5)
|
||||
--scrollbar-bg-active-dark: white(0.6)
|
||||
|
||||
--scrollbar-bg: var(--scrollbar-bg-light) var(--scrollbar-bg-dark)
|
||||
--scrollbar-bg-hover: var(--scrollbar-bg-hover-light) var(--scrollbar-bg-hover-dark)
|
||||
--scrollbar-bg-active: var(--scrollbar-bg-active-light) var(--scrollbar-bg-active-dark)
|
||||
|
||||
--color-selection-bar: rainbow-light rainbow-dark
|
||||
|
||||
--display-light-icon: 1 0
|
||||
--display-dark-icon: 0 1
|
||||
|
||||
--admonitions-color-tip: oklch(0.7 0.14 180) oklch(0.75 0.14 180)
|
||||
--admonitions-color-note: oklch(0.7 0.14 250) oklch(0.75 0.14 250)
|
||||
--admonitions-color-important: oklch(0.7 0.14 310) oklch(0.75 0.14 310)
|
||||
--admonitions-color-warning: oklch(0.7 0.14 60) oklch(0.75 0.14 60)
|
||||
--admonitions-color-caution: oklch(0.6 0.2 25) oklch(0.65 0.2 25)
|
||||
|
||||
--toc-badge-bg: oklch(0.9 0.045 var(--hue)) var(--btn-regular-bg)
|
||||
--toc-btn-hover: oklch(0.92 0.015 var(--hue)) oklch(0.22 0.02 var(--hue))
|
||||
--toc-btn-active: oklch(0.90 0.015 var(--hue)) oklch(0.25 0.02 var(--hue))
|
||||
--toc-width: calc((100vw - var(--page-width)) / 2 - 1rem)
|
||||
--toc-item-active: oklch(0.70 0.13 var(--hue)) oklch(0.35 0.07 var(--hue))
|
||||
})
|
||||
Reference in New Issue
Block a user