Render mermaid code blocks as SVG diagrams instead of syntax-highlighted source code. Includes a full pan/zoom viewer with drag, scroll wheel zoom, pinch-to-zoom, fit-to-view, and fullscreen support. Theme-aware (dark/light). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2079 lines
40 KiB
CSS
2079 lines
40 KiB
CSS
@import "tailwindcss";
|
|
@plugin "@tailwindcss/typography";
|
|
|
|
/* Class-based dark mode for next-themes */
|
|
@custom-variant dark (&:where(.dark, .dark *));
|
|
|
|
/* Auto-detect content in the submodule */
|
|
@source "../content";
|
|
|
|
/* Tailwind v4 CSS-first theme configuration */
|
|
@theme {
|
|
/* Custom colors (CSS variable references) */
|
|
--color-accent: var(--color-accent);
|
|
--color-accent-soft: var(--color-accent-soft);
|
|
--color-accent-textLight: var(--color-accent-text-light);
|
|
--color-accent-textDark: var(--color-accent-text-dark);
|
|
|
|
/* Custom font families */
|
|
--font-serif-eng: var(--font-serif-eng), serif;
|
|
--font-serif-cn: var(--font-serif-cn), "Songti SC", "Noto Serif TC", "SimSun", serif;
|
|
|
|
/* Custom transition timing */
|
|
--ease-snappy: cubic-bezier(0.32, 0.72, 0, 1);
|
|
|
|
/* Custom transition durations */
|
|
--duration-180: 180ms;
|
|
--duration-260: 260ms;
|
|
|
|
/* Custom box shadows */
|
|
--shadow-lifted: 0 12px 30px -14px rgba(15, 23, 42, 0.25);
|
|
--shadow-outline: 0 0 0 1px rgba(59, 130, 246, 0.25);
|
|
|
|
/* Custom keyframes */
|
|
--animate-fade-in-up: fade-in-up 0.6s ease-out both;
|
|
--animate-float-soft: float-soft 12s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes fade-in-up {
|
|
0% { opacity: 0; transform: translateY(8px) scale(0.98); }
|
|
100% { opacity: 1; transform: translateY(0) scale(1); }
|
|
}
|
|
|
|
.repo-card-enter {
|
|
animation: fade-in-up 0.6s ease-out both;
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.repo-card-enter {
|
|
animation: none;
|
|
}
|
|
}
|
|
|
|
@keyframes float-soft {
|
|
0% { transform: translate3d(0,0,0) scale(1); }
|
|
50% { transform: translate3d(4px,-6px,0) scale(1.03); }
|
|
100% { transform: translate3d(0,0,0) scale(1); }
|
|
}
|
|
|
|
/* Dev env device hero - Mac mini + 螢幕 3D mockup */
|
|
@keyframes device-float {
|
|
0% { transform: perspective(800px) rotateY(-4deg) rotateX(2deg) translate3d(0, 0, 0); }
|
|
50% { transform: perspective(800px) rotateY(-4deg) rotateX(2deg) translate3d(0, -8px, 0); }
|
|
100% { transform: perspective(800px) rotateY(-4deg) rotateX(2deg) translate3d(0, 0, 0); }
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.dev-env-device-hero .dev-env-device-scene {
|
|
animation: none;
|
|
}
|
|
}
|
|
|
|
.dev-env-device-hero {
|
|
min-height: 320px;
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.dev-env-device-hero {
|
|
min-height: 400px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.dev-env-device-hero {
|
|
min-height: 460px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1536px) {
|
|
.dev-env-device-hero {
|
|
min-height: 520px;
|
|
}
|
|
}
|
|
|
|
.dev-env-device-scene {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
perspective: 800px;
|
|
transform-style: preserve-3d;
|
|
animation: device-float 8s ease-in-out infinite;
|
|
}
|
|
|
|
.dev-env-monitor {
|
|
position: relative;
|
|
width: min(340px, 88vw);
|
|
padding-bottom: 75%; /* 4:3 較高,讓 terminal 內容完整顯示 */
|
|
transform-style: preserve-3d;
|
|
}
|
|
|
|
.dev-env-monitor + .dev-env-desk {
|
|
margin-top: 40px;
|
|
}
|
|
|
|
/* Large screen: scale up proportionally to fill space */
|
|
@media (min-width: 1024px) {
|
|
.dev-env-monitor {
|
|
width: min(520px, 42vw);
|
|
}
|
|
.dev-env-monitor + .dev-env-desk {
|
|
margin-top: 48px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.dev-env-monitor {
|
|
width: min(600px, 40vw);
|
|
}
|
|
.dev-env-monitor + .dev-env-desk {
|
|
margin-top: 56px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1536px) {
|
|
.dev-env-monitor {
|
|
width: min(700px, 42vw);
|
|
}
|
|
.dev-env-monitor + .dev-env-desk {
|
|
margin-top: 64px;
|
|
}
|
|
}
|
|
|
|
.dev-env-bezel {
|
|
position: absolute;
|
|
inset: 0;
|
|
background: linear-gradient(145deg, #2d2d2d 0%, #1a1a1a 100%);
|
|
border-radius: 12px;
|
|
padding: 8px;
|
|
box-shadow:
|
|
0 25px 50px -12px rgba(0, 0, 0, 0.4),
|
|
0 0 0 1px rgba(255, 255, 255, 0.05) inset,
|
|
-2px -2px 8px rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.dev-env-bezel {
|
|
border-radius: 14px;
|
|
padding: 10px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.dev-env-bezel {
|
|
border-radius: 16px;
|
|
padding: 12px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1536px) {
|
|
.dev-env-bezel {
|
|
border-radius: 18px;
|
|
padding: 14px;
|
|
}
|
|
}
|
|
|
|
.dark .dev-env-bezel {
|
|
background: linear-gradient(145deg, #1a1a1a 0%, #0d0d0d 100%);
|
|
}
|
|
|
|
.dev-env-screen {
|
|
position: absolute;
|
|
inset: 8px;
|
|
border-radius: 6px;
|
|
overflow: hidden;
|
|
background: linear-gradient(165deg, #e8ecf0 0%, #dde2e8 50%, #e2e6ec 100%);
|
|
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4) inset;
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.dev-env-screen {
|
|
inset: 10px;
|
|
border-radius: 8px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.dev-env-screen {
|
|
inset: 12px;
|
|
border-radius: 9px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1536px) {
|
|
.dev-env-screen {
|
|
inset: 14px;
|
|
border-radius: 10px;
|
|
}
|
|
}
|
|
|
|
.dark .dev-env-screen {
|
|
background: linear-gradient(165deg, #1a1d21 0%, #15181c 50%, #1c1f24 100%);
|
|
}
|
|
|
|
/* macOS desktop mockup */
|
|
.dev-env-desktop {
|
|
position: absolute;
|
|
inset: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
/* macOS Menu bar - 毛玻璃效果 */
|
|
.dev-env-menubar {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
height: 26px;
|
|
padding: 0 14px;
|
|
background: rgba(255, 255, 255, 0.72);
|
|
backdrop-filter: blur(20px) saturate(180%);
|
|
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
|
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
|
font-size: 13px;
|
|
font-weight: 500;
|
|
color: rgba(0, 0, 0, 0.88);
|
|
}
|
|
|
|
.dark .dev-env-menubar {
|
|
background: rgba(50, 50, 50, 0.72);
|
|
border-bottom-color: rgba(255, 255, 255, 0.06);
|
|
color: rgba(255, 255, 255, 0.9);
|
|
}
|
|
|
|
.dev-env-apple {
|
|
font-size: 17px;
|
|
font-weight: 400;
|
|
margin-right: 6px;
|
|
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", sans-serif;
|
|
}
|
|
|
|
.dev-env-app-name {
|
|
opacity: 0.95;
|
|
}
|
|
|
|
.dev-env-spacer {
|
|
flex: 1;
|
|
}
|
|
|
|
.dev-env-menubar-right {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 14px;
|
|
}
|
|
|
|
.dev-env-menubar-icon {
|
|
width: 16px;
|
|
height: 16px;
|
|
border-radius: 50%;
|
|
background: rgba(0, 0, 0, 0.25);
|
|
}
|
|
|
|
.dark .dev-env-menubar-icon {
|
|
background: rgba(255, 255, 255, 0.2);
|
|
}
|
|
|
|
.dev-env-time {
|
|
font-size: 12px;
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.dev-env-window {
|
|
flex: 1;
|
|
min-height: 80px;
|
|
margin: 12px 16px;
|
|
background: rgba(255, 255, 255, 0.98);
|
|
border-radius: 10px;
|
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
|
|
overflow: hidden;
|
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.dev-env-window {
|
|
margin: 14px 20px;
|
|
min-height: 90px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.dev-env-window {
|
|
margin: 16px 24px;
|
|
min-height: 100px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1536px) {
|
|
.dev-env-window {
|
|
margin: 18px 28px;
|
|
min-height: 110px;
|
|
}
|
|
}
|
|
|
|
.dark .dev-env-window {
|
|
background: rgba(30, 30, 30, 0.98);
|
|
border-color: rgba(255, 255, 255, 0.06);
|
|
}
|
|
|
|
/* macOS 紅黃綠三色按鈕 */
|
|
.dev-env-window-titlebar {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
height: 32px;
|
|
padding: 0 12px;
|
|
background: rgba(0, 0, 0, 0.04);
|
|
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
|
|
}
|
|
|
|
.dark .dev-env-window-titlebar {
|
|
background: rgba(255, 255, 255, 0.03);
|
|
border-bottom-color: rgba(255, 255, 255, 0.06);
|
|
}
|
|
|
|
.dev-env-traffic-light {
|
|
width: 12px;
|
|
height: 12px;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.dev-env-traffic-red {
|
|
background: #ff5f57;
|
|
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.dev-env-traffic-yellow {
|
|
background: #febc2e;
|
|
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.dev-env-traffic-green {
|
|
background: #28c840;
|
|
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.dev-env-window-content {
|
|
padding: 10px 14px;
|
|
font-family: ui-monospace, "SF Mono", "Monaco", "Consolas", monospace;
|
|
font-size: 9px;
|
|
line-height: 1.2;
|
|
overflow: visible;
|
|
flex: 1;
|
|
min-height: 52px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.dev-env-window-content {
|
|
padding: 12px 18px;
|
|
font-size: 10px;
|
|
min-height: 58px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.dev-env-window-content {
|
|
padding: 14px 20px;
|
|
font-size: 11px;
|
|
min-height: 64px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1536px) {
|
|
.dev-env-window-content {
|
|
padding: 16px 24px;
|
|
font-size: 12px;
|
|
min-height: 72px;
|
|
}
|
|
}
|
|
|
|
.dev-env-terminal-prompt {
|
|
margin-bottom: 8px;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.dev-env-terminal-logos {
|
|
display: flex;
|
|
gap: 12px;
|
|
justify-content: center;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
flex: 1 0 auto;
|
|
min-height: 36px;
|
|
padding: 4px 0;
|
|
}
|
|
|
|
.dev-env-logo-svg {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.dev-env-logo-svg svg {
|
|
width: 36px;
|
|
height: 36px;
|
|
flex-shrink: 0;
|
|
display: block;
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.dev-env-logo-svg svg {
|
|
width: 42px;
|
|
height: 42px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.dev-env-logo-svg svg {
|
|
width: 48px;
|
|
height: 48px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1536px) {
|
|
.dev-env-logo-svg svg {
|
|
width: 54px;
|
|
height: 54px;
|
|
}
|
|
}
|
|
|
|
.dev-env-svg-arch {
|
|
color: #1793d1;
|
|
}
|
|
|
|
.dark .dev-env-svg-arch {
|
|
color: #38bdf8;
|
|
}
|
|
|
|
.dev-env-svg-ubuntu {
|
|
color: #e95420;
|
|
}
|
|
|
|
.dark .dev-env-svg-ubuntu {
|
|
color: #f97316;
|
|
}
|
|
|
|
.dev-env-svg-tux {
|
|
color: #334155;
|
|
}
|
|
|
|
.dark .dev-env-svg-tux {
|
|
color: #cbd5e1;
|
|
}
|
|
|
|
.dev-env-terminal-line {
|
|
height: 8px;
|
|
margin-bottom: 6px;
|
|
background: rgba(0, 0, 0, 0.08);
|
|
border-radius: 2px;
|
|
}
|
|
|
|
.dev-env-terminal-line.short {
|
|
width: 60%;
|
|
}
|
|
|
|
.dark .dev-env-terminal-line {
|
|
background: rgba(255, 255, 255, 0.05);
|
|
}
|
|
|
|
.dev-env-prompt {
|
|
color: #22c55e;
|
|
}
|
|
|
|
.dark .dev-env-prompt {
|
|
color: #4ade80;
|
|
}
|
|
|
|
.dev-env-stand {
|
|
position: absolute;
|
|
bottom: -12px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
width: 60px;
|
|
height: 24px;
|
|
background: linear-gradient(180deg, #8a8a8a 0%, #6e6e6e 100%);
|
|
border-radius: 12px 12px 0 0;
|
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.dev-env-stand {
|
|
width: 72px;
|
|
height: 28px;
|
|
bottom: -14px;
|
|
border-radius: 14px 14px 0 0;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.dev-env-stand {
|
|
width: 84px;
|
|
height: 32px;
|
|
bottom: -16px;
|
|
border-radius: 16px 16px 0 0;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1536px) {
|
|
.dev-env-stand {
|
|
width: 96px;
|
|
height: 36px;
|
|
bottom: -18px;
|
|
border-radius: 18px 18px 0 0;
|
|
}
|
|
}
|
|
|
|
.dark .dev-env-stand {
|
|
background: linear-gradient(180deg, #2d2d2d 0%, #1a1a1a 100%);
|
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
.dev-env-desk {
|
|
position: relative;
|
|
width: min(380px, 92vw);
|
|
height: 56px;
|
|
margin: 0 auto;
|
|
padding: 0 12px;
|
|
display: flex;
|
|
align-items: flex-end;
|
|
justify-content: space-evenly;
|
|
gap: 12px;
|
|
background: linear-gradient(180deg, #b8b8b8 0%, #9a9a9a 50%, #888888 100%);
|
|
border-radius: 4px;
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.dev-env-desk {
|
|
width: min(560px, 45vw);
|
|
height: 66px;
|
|
padding: 0 16px;
|
|
gap: 16px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.dev-env-desk {
|
|
width: min(640px, 43vw);
|
|
height: 76px;
|
|
padding: 0 20px;
|
|
gap: 20px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1536px) {
|
|
.dev-env-desk {
|
|
width: min(760px, 46vw);
|
|
height: 86px;
|
|
padding: 0 24px;
|
|
gap: 24px;
|
|
}
|
|
}
|
|
|
|
.dark .dev-env-desk {
|
|
background: linear-gradient(180deg, #3d3d3d 0%, #2a2a2a 100%);
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
}
|
|
|
|
/* 鍵盤 - Magic Keyboard 風格,鍵帽網格 */
|
|
.dev-env-keyboard {
|
|
width: 110px;
|
|
height: 36px;
|
|
display: flex;
|
|
align-items: flex-end;
|
|
justify-content: center;
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.dev-env-keyboard {
|
|
width: 130px;
|
|
height: 42px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.dev-env-keyboard {
|
|
width: 150px;
|
|
height: 48px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1536px) {
|
|
.dev-env-keyboard {
|
|
width: 170px;
|
|
height: 54px;
|
|
}
|
|
}
|
|
|
|
.dev-env-keyboard-body {
|
|
width: 100%;
|
|
padding: 4px 6px;
|
|
background: linear-gradient(
|
|
180deg,
|
|
#e8e8ed 0%,
|
|
#d1d1d6 25%,
|
|
#c8c8cd 60%,
|
|
#b8b8bd 100%
|
|
);
|
|
border-radius: 6px;
|
|
box-shadow:
|
|
0 2px 8px rgba(0, 0, 0, 0.2),
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.6);
|
|
}
|
|
|
|
.dark .dev-env-keyboard-body {
|
|
background: linear-gradient(
|
|
180deg,
|
|
#4a4a4f 0%,
|
|
#3d3d42 40%,
|
|
#2d2d32 100%
|
|
);
|
|
box-shadow:
|
|
0 2px 8px rgba(0, 0, 0, 0.4),
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.06);
|
|
}
|
|
|
|
.dev-env-keyboard-keys {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
}
|
|
|
|
.dev-env-keyboard-row {
|
|
display: flex;
|
|
justify-content: center;
|
|
gap: 1px;
|
|
}
|
|
|
|
.dev-env-keyboard-row:nth-child(2) { padding-left: 4px; }
|
|
.dev-env-keyboard-row:nth-child(3) { padding-left: 8px; }
|
|
.dev-env-keyboard-row:nth-child(4) { padding-left: 12px; }
|
|
.dev-env-keyboard-row:nth-child(5) { padding-left: 20px; }
|
|
|
|
.dev-env-keyboard-row-space {
|
|
padding-left: 24px !important;
|
|
}
|
|
|
|
.dev-env-key-space {
|
|
width: 36px;
|
|
}
|
|
|
|
.dev-env-key {
|
|
width: 5px;
|
|
height: 4px;
|
|
background: linear-gradient(
|
|
180deg,
|
|
rgba(255, 255, 255, 0.9) 0%,
|
|
rgba(0, 0, 0, 0.08) 100%
|
|
);
|
|
border-radius: 1px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.dark .dev-env-key {
|
|
background: linear-gradient(
|
|
180deg,
|
|
rgba(255, 255, 255, 0.08) 0%,
|
|
rgba(0, 0, 0, 0.4) 100%
|
|
);
|
|
}
|
|
|
|
/* Mac mini - 頂視,無 3D 旋轉,避免偽影 */
|
|
.dev-env-macmini {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
justify-content: center;
|
|
height: 44px;
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.dev-env-macmini {
|
|
height: 52px;
|
|
}
|
|
.dev-env-macmini-top {
|
|
width: 76px;
|
|
height: 76px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.dev-env-macmini {
|
|
height: 60px;
|
|
}
|
|
.dev-env-macmini-top {
|
|
width: 88px;
|
|
height: 88px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1536px) {
|
|
.dev-env-macmini {
|
|
height: 68px;
|
|
}
|
|
.dev-env-macmini-top {
|
|
width: 100px;
|
|
height: 100px;
|
|
}
|
|
}
|
|
|
|
.dev-env-macmini-top {
|
|
width: 64px;
|
|
height: 64px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: linear-gradient(
|
|
145deg,
|
|
#eaeaf0 0%,
|
|
#d4d4d9 25%,
|
|
#c4c4c9 55%,
|
|
#b4b4b9 85%,
|
|
#a8a8ad 100%
|
|
);
|
|
border-radius: 14px;
|
|
box-shadow:
|
|
0 4px 12px rgba(0, 0, 0, 0.15),
|
|
inset 0 2px 4px rgba(255, 255, 255, 0.6),
|
|
inset 0 -1px 2px rgba(0, 0, 0, 0.06);
|
|
}
|
|
|
|
.dark .dev-env-macmini-top {
|
|
background: linear-gradient(
|
|
145deg,
|
|
#7a7a7f 0%,
|
|
#5e5e63 25%,
|
|
#4e4e53 55%,
|
|
#3e3e43 85%,
|
|
#323237 100%
|
|
);
|
|
box-shadow:
|
|
0 4px 12px rgba(0, 0, 0, 0.35),
|
|
inset 0 2px 4px rgba(255, 255, 255, 0.08),
|
|
inset 0 -1px 2px rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
.dev-env-macmini-apple {
|
|
font-size: 24px;
|
|
font-weight: 400;
|
|
color: rgba(0, 0, 0, 0.5);
|
|
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", sans-serif;
|
|
}
|
|
|
|
.dark .dev-env-macmini-apple {
|
|
color: rgba(255, 255, 255, 0.4);
|
|
}
|
|
|
|
/* HomeLab device hero - Switch, NAS (TrueNAS), Router (VyOS) */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.homelab-device-hero .homelab-device-scene {
|
|
animation: none;
|
|
}
|
|
}
|
|
|
|
.homelab-device-hero {
|
|
min-height: 280px;
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.homelab-device-hero {
|
|
min-height: 340px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.homelab-device-hero {
|
|
min-height: 380px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1536px) {
|
|
.homelab-device-hero {
|
|
min-height: 420px;
|
|
}
|
|
}
|
|
|
|
.homelab-device-scene {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
perspective: 800px;
|
|
transform-style: preserve-3d;
|
|
animation: device-float 8s ease-in-out infinite;
|
|
}
|
|
|
|
.homelab-rack {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-wrap: nowrap;
|
|
gap: 12px;
|
|
width: 100%;
|
|
min-width: 320px;
|
|
max-width: 420px;
|
|
margin: 0 auto;
|
|
padding: 16px 20px;
|
|
background: linear-gradient(180deg, #b8b8b8 0%, #9a9a9a 50%, #888888 100%);
|
|
border-radius: 8px;
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
|
|
}
|
|
|
|
@media (min-width: 640px) {
|
|
.homelab-rack {
|
|
max-width: 520px;
|
|
gap: 16px;
|
|
padding: 20px 24px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.homelab-rack {
|
|
max-width: 800px;
|
|
padding: 24px 32px;
|
|
gap: 24px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.homelab-rack {
|
|
max-width: 900px;
|
|
padding: 28px 40px;
|
|
gap: 28px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1536px) {
|
|
.homelab-rack {
|
|
max-width: 1000px;
|
|
padding: 32px 48px;
|
|
gap: 32px;
|
|
}
|
|
}
|
|
|
|
.dark .homelab-rack {
|
|
background: linear-gradient(180deg, #4a4a4a 0%, #3d3d3d 50%, #2a2a2a 100%);
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
|
|
}
|
|
|
|
/* Cable / 線路 - 虛線連接,垂直置中對齊設備 */
|
|
.homelab-cable {
|
|
display: flex;
|
|
align-items: center;
|
|
align-self: center;
|
|
flex-shrink: 0;
|
|
min-width: 20px;
|
|
width: 20px;
|
|
}
|
|
|
|
.homelab-cable-line {
|
|
display: block;
|
|
width: 100%;
|
|
height: 0;
|
|
border-top: 2px dashed #64748b;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
@media (min-width: 640px) {
|
|
.homelab-cable {
|
|
min-width: 24px;
|
|
width: 24px;
|
|
}
|
|
.homelab-cable-line {
|
|
border-top-width: 2px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.homelab-cable {
|
|
min-width: 48px;
|
|
width: 48px;
|
|
}
|
|
.homelab-cable-line {
|
|
border-top-width: 2px;
|
|
}
|
|
}
|
|
|
|
.dark .homelab-cable-line {
|
|
border-top-color: #94a3b8;
|
|
}
|
|
|
|
/* Router */
|
|
.homelab-router {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.homelab-router-body {
|
|
width: 64px;
|
|
height: 40px;
|
|
padding: 4px 6px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 2px;
|
|
background: linear-gradient(145deg, #3d3d3d 0%, #2a2a2a 100%);
|
|
border-radius: 6px;
|
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
box-shadow:
|
|
0 4px 12px rgba(0, 0, 0, 0.25),
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
}
|
|
|
|
@media (min-width: 640px) {
|
|
.homelab-router-body {
|
|
width: 80px;
|
|
height: 48px;
|
|
padding: 6px 8px;
|
|
gap: 4px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.homelab-router-body {
|
|
width: 104px;
|
|
height: 64px;
|
|
padding: 8px 10px;
|
|
gap: 6px;
|
|
border-radius: 8px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.homelab-router-body {
|
|
width: 116px;
|
|
height: 72px;
|
|
padding: 10px 12px;
|
|
gap: 8px;
|
|
}
|
|
}
|
|
|
|
.dark .homelab-router-body {
|
|
background: linear-gradient(145deg, #2a2a2a 0%, #1a1a1a 100%);
|
|
border-color: rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
.homelab-router-leds {
|
|
display: flex;
|
|
gap: 4px;
|
|
}
|
|
|
|
.homelab-led {
|
|
width: 4px;
|
|
height: 4px;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.homelab-led {
|
|
width: 5px;
|
|
height: 5px;
|
|
}
|
|
}
|
|
|
|
.homelab-led-power {
|
|
background: #22c55e;
|
|
box-shadow: 0 0 4px #22c55e;
|
|
}
|
|
|
|
.homelab-led-wan {
|
|
background: #3b82f6;
|
|
box-shadow: 0 0 4px #3b82f6;
|
|
}
|
|
|
|
.homelab-led-lan {
|
|
background: #eab308;
|
|
box-shadow: 0 0 4px #eab308;
|
|
}
|
|
|
|
.homelab-router-logos {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 6px;
|
|
flex: 1;
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.homelab-router-logos {
|
|
gap: 8px;
|
|
}
|
|
}
|
|
|
|
.homelab-proxmox-logo {
|
|
color: #e57008;
|
|
width: 16px;
|
|
height: 16px;
|
|
}
|
|
|
|
@media (min-width: 640px) {
|
|
.homelab-proxmox-logo {
|
|
width: 20px;
|
|
height: 20px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.homelab-proxmox-logo {
|
|
width: 24px;
|
|
height: 24px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.homelab-proxmox-logo {
|
|
width: 28px;
|
|
height: 28px;
|
|
}
|
|
}
|
|
|
|
.dark .homelab-proxmox-logo {
|
|
color: #f59e0b;
|
|
}
|
|
|
|
.homelab-router-logos .homelab-logo-svg {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.homelab-router-icon {
|
|
width: 16px;
|
|
height: 16px;
|
|
color: #64748b;
|
|
}
|
|
|
|
@media (min-width: 640px) {
|
|
.homelab-router-icon {
|
|
width: 20px;
|
|
height: 20px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.homelab-router-icon {
|
|
width: 24px;
|
|
height: 24px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.homelab-router-icon {
|
|
width: 28px;
|
|
height: 28px;
|
|
}
|
|
}
|
|
|
|
.dark .homelab-router-icon {
|
|
color: #94a3b8;
|
|
}
|
|
|
|
/* Switch */
|
|
.homelab-switch {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.homelab-switch-body {
|
|
width: 120px;
|
|
height: 48px;
|
|
padding: 6px 10px;
|
|
background: linear-gradient(145deg, #3d3d3d 0%, #2a2a2a 100%);
|
|
border-radius: 6px;
|
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
box-shadow:
|
|
0 4px 12px rgba(0, 0, 0, 0.25),
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
}
|
|
|
|
@media (min-width: 640px) {
|
|
.homelab-switch-body {
|
|
width: 160px;
|
|
height: 60px;
|
|
padding: 8px 12px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.homelab-switch-body {
|
|
width: 220px;
|
|
height: 76px;
|
|
padding: 10px 14px;
|
|
border-radius: 8px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.homelab-switch-body {
|
|
width: 260px;
|
|
height: 86px;
|
|
padding: 12px 16px;
|
|
}
|
|
}
|
|
|
|
.dark .homelab-switch-body {
|
|
background: linear-gradient(145deg, #2a2a2a 0%, #1a1a1a 100%);
|
|
border-color: rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
.homelab-switch-ports {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
height: 100%;
|
|
justify-content: center;
|
|
}
|
|
|
|
.homelab-port-row {
|
|
display: flex;
|
|
gap: 4px;
|
|
justify-content: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.homelab-port {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 1px;
|
|
}
|
|
|
|
.homelab-port-led {
|
|
width: 3px;
|
|
height: 3px;
|
|
border-radius: 50%;
|
|
background: #444;
|
|
}
|
|
|
|
@media (min-width: 640px) {
|
|
.homelab-port-led {
|
|
width: 4px;
|
|
height: 4px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.homelab-port-led {
|
|
width: 5px;
|
|
height: 5px;
|
|
}
|
|
}
|
|
|
|
.homelab-port-led-active {
|
|
background: #22c55e;
|
|
box-shadow: 0 0 3px #22c55e;
|
|
}
|
|
|
|
.dark .homelab-port-led {
|
|
background: #555;
|
|
}
|
|
|
|
.dark .homelab-port-led-active {
|
|
background: #4ade80;
|
|
box-shadow: 0 0 3px #4ade80;
|
|
}
|
|
|
|
/* NAS */
|
|
.homelab-nas {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.homelab-nas-body {
|
|
width: 60px;
|
|
height: 48px;
|
|
padding: 4px 6px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 2px;
|
|
background: linear-gradient(145deg, #3d3d3d 0%, #2a2a2a 100%);
|
|
border-radius: 6px;
|
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
box-shadow:
|
|
0 4px 12px rgba(0, 0, 0, 0.25),
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
}
|
|
|
|
@media (min-width: 640px) {
|
|
.homelab-nas-body {
|
|
width: 88px;
|
|
height: 64px;
|
|
padding: 6px 8px;
|
|
gap: 4px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.homelab-nas-body {
|
|
width: 108px;
|
|
height: 76px;
|
|
padding: 8px 10px;
|
|
gap: 6px;
|
|
border-radius: 8px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1280px) {
|
|
.homelab-nas-body {
|
|
width: 120px;
|
|
height: 86px;
|
|
padding: 10px 12px;
|
|
gap: 8px;
|
|
}
|
|
}
|
|
|
|
.dark .homelab-nas-body {
|
|
background: linear-gradient(145deg, #2a2a2a 0%, #1a1a1a 100%);
|
|
border-color: rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
.homelab-nas-drives {
|
|
display: flex;
|
|
gap: 3px;
|
|
}
|
|
|
|
.homelab-drive-slot {
|
|
width: 12px;
|
|
height: 4px;
|
|
background: rgba(255, 255, 255, 0.12);
|
|
border-radius: 1px;
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.homelab-drive-slot {
|
|
width: 14px;
|
|
height: 5px;
|
|
}
|
|
}
|
|
|
|
.dark .homelab-drive-slot {
|
|
background: rgba(255, 255, 255, 0.08);
|
|
}
|
|
|
|
.homelab-nas-logo {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex: 1;
|
|
}
|
|
|
|
.homelab-truenas-logo {
|
|
color: #0095d5;
|
|
}
|
|
|
|
.dark .homelab-truenas-logo {
|
|
color: #38bdf8;
|
|
}
|
|
|
|
|
|
@keyframes mastodon-shimmer {
|
|
0% { background-position: -200% 0; }
|
|
100% { background-position: 200% 0; }
|
|
}
|
|
|
|
.mastodon-skeleton-shimmer {
|
|
background: linear-gradient(
|
|
110deg,
|
|
#e2e8f0 0%,
|
|
#e2e8f0 35%,
|
|
rgba(255, 255, 255, 0.6) 50%,
|
|
#e2e8f0 65%,
|
|
#e2e8f0 100%
|
|
);
|
|
background-size: 200% 100%;
|
|
background-position: -200% 0;
|
|
animation: mastodon-shimmer 2.2s ease-in-out infinite;
|
|
}
|
|
|
|
.dark .mastodon-skeleton-shimmer {
|
|
background: linear-gradient(
|
|
110deg,
|
|
#1e293b 0%,
|
|
#1e293b 35%,
|
|
rgba(167, 139, 250, 0.3) 50%,
|
|
#1e293b 65%,
|
|
#1e293b 100%
|
|
);
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.mastodon-skeleton-shimmer {
|
|
animation: none;
|
|
background-position: 0 0;
|
|
background: #e2e8f0;
|
|
}
|
|
.dark .mastodon-skeleton-shimmer {
|
|
background: #1e293b;
|
|
}
|
|
}
|
|
|
|
/* Reading progress bar - Scroll-Driven Animations API (Chrome 115+, Safari 26+, Edge 115+) */
|
|
@keyframes reading-progress-grow {
|
|
from { transform: scaleX(0); }
|
|
to { transform: scaleX(1); }
|
|
}
|
|
|
|
.reading-progress-bar-scroll-driven {
|
|
animation: reading-progress-grow auto linear forwards;
|
|
animation-timeline: scroll(block root);
|
|
}
|
|
|
|
:root {
|
|
--motion-duration-short: 180ms;
|
|
--motion-duration-medium: 260ms;
|
|
--motion-ease-snappy: cubic-bezier(0.32, 0.72, 0, 1);
|
|
--card-translate-y: -6px;
|
|
--line-height-body: clamp(1.5, 0.15vw + 1.45, 1.65);
|
|
--font-weight-regular: 400;
|
|
--font-weight-medium: 500;
|
|
--font-weight-semibold: 600;
|
|
--font-system-sans: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'SF Pro Display', 'PingFang TC', 'PingFang SC', 'Hiragino Sans', 'Hiragino Kaku Gothic ProN', 'Segoe UI Variable Text', 'Segoe UI', 'Microsoft JhengHei', 'Microsoft YaHei', 'Noto Sans TC', 'Noto Sans SC', 'Noto Sans CJK TC', 'Noto Sans CJK SC', 'Source Han Sans TC', 'Source Han Sans SC', 'Roboto', 'Ubuntu', 'Cantarell', 'Inter', 'Helvetica Neue', Arial, sans-serif;
|
|
|
|
/* Ink + accent palette */
|
|
--color-ink-strong: #0f172a;
|
|
--color-ink-body: #1f2937;
|
|
--color-ink-muted: #475569;
|
|
--color-accent: #7c3aed;
|
|
--color-accent-soft: #f4f0ff;
|
|
|
|
font-size: clamp(15px, 0.65vw + 11px, 19px);
|
|
}
|
|
|
|
.dark {
|
|
--color-ink-strong: #e2e8f0;
|
|
--color-ink-body: #cbd5e1;
|
|
--color-ink-muted: #94a3b8;
|
|
--color-accent: #a78bfa;
|
|
--color-accent-soft: #1f1a3d;
|
|
}
|
|
|
|
@media (min-width: 2560px) {
|
|
:root {
|
|
font-size: 20px;
|
|
}
|
|
}
|
|
|
|
body {
|
|
@apply bg-white text-gray-900 transition-colors duration-200 ease-snappy dark:bg-gray-950 dark:text-gray-100;
|
|
font-size: 1rem;
|
|
line-height: var(--line-height-body);
|
|
font-family: var(--font-system-sans);
|
|
color: var(--color-ink-body);
|
|
}
|
|
|
|
@keyframes timeline-scroll {
|
|
0% {
|
|
transform: translate(-50%, -10%);
|
|
opacity: 0;
|
|
}
|
|
|
|
15% {
|
|
opacity: 1;
|
|
}
|
|
|
|
85% {
|
|
opacity: 1;
|
|
}
|
|
|
|
100% {
|
|
transform: translate(-50%, 110%);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes pageEnter {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(16px) scale(0.99);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0) scale(1);
|
|
}
|
|
}
|
|
|
|
.page-transition {
|
|
opacity: 0;
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.page-transition {
|
|
opacity: 1;
|
|
transform: none;
|
|
}
|
|
}
|
|
|
|
/* Scroll reveal animations - CSS only */
|
|
.scroll-reveal {
|
|
opacity: 0;
|
|
transform: translateY(12px);
|
|
transition: opacity 0.5s cubic-bezier(0.32, 0.72, 0, 1),
|
|
transform 0.5s cubic-bezier(0.32, 0.72, 0, 1);
|
|
}
|
|
|
|
.scroll-reveal.is-visible {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
|
|
/* Respect user's motion preferences */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.scroll-reveal {
|
|
opacity: 1;
|
|
transform: none;
|
|
transition: none;
|
|
}
|
|
}
|
|
|
|
|
|
.toc-target-highlight {
|
|
@apply bg-yellow-50/60 dark:bg-yellow-900/40 transition-colors duration-500;
|
|
}
|
|
|
|
/* Subtle hover for article elements */
|
|
.prose blockquote {
|
|
@apply transition-transform transition-shadow duration-180 ease-snappy;
|
|
border-left: 4px solid var(--color-accent, #2563eb);
|
|
background: linear-gradient(135deg, rgba(124, 58, 237, 0.06), rgba(124, 58, 237, 0.1));
|
|
padding: 1.2rem 1.5rem;
|
|
font-style: italic;
|
|
color: rgba(15, 23, 42, 0.78);
|
|
position: relative;
|
|
}
|
|
|
|
.dark .prose blockquote {
|
|
background: linear-gradient(135deg, rgba(167, 139, 250, 0.12), rgba(124, 58, 237, 0.08));
|
|
color: rgba(226, 232, 240, 0.85);
|
|
border-left-color: rgba(167, 139, 250, 0.9);
|
|
}
|
|
|
|
.prose blockquote:hover {
|
|
@apply -translate-y-0.5 shadow-sm;
|
|
}
|
|
|
|
.prose blockquote::before {
|
|
content: '\201C';
|
|
position: absolute;
|
|
top: 0.5rem;
|
|
left: 0.8rem;
|
|
font-size: 3rem;
|
|
font-family: 'Times New Roman', 'Noto Serif TC', serif;
|
|
color: rgba(37, 99, 235, 0.25);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.prose pre {
|
|
@apply transition-transform transition-shadow duration-180 ease-snappy;
|
|
}
|
|
|
|
.prose pre:hover {
|
|
@apply -translate-y-0.5 shadow-md;
|
|
}
|
|
|
|
/* Typography plugin prose overrides */
|
|
.prose {
|
|
font-size: clamp(1rem, 0.2vw + 0.9rem, 1.2rem);
|
|
line-height: var(--line-height-body);
|
|
color: var(--color-ink-body);
|
|
}
|
|
|
|
.prose a {
|
|
color: var(--color-accent-text-light);
|
|
}
|
|
|
|
.prose a:hover {
|
|
color: var(--color-accent);
|
|
}
|
|
|
|
.dark .prose a {
|
|
color: var(--color-accent-text-dark);
|
|
}
|
|
|
|
.dark .prose a:hover {
|
|
color: var(--color-accent);
|
|
}
|
|
|
|
.prose h1 {
|
|
font-size: clamp(2.2rem, 1.4rem + 2.2vw, 3.4rem);
|
|
line-height: 1.25;
|
|
color: var(--color-ink-strong);
|
|
font-weight: 700;
|
|
letter-spacing: 0.01em; /* 手写风格字体需要稍微增加字间距 */
|
|
font-family: var(--font-serif-cn), var(--font-serif-eng), "Songti SC", serif;
|
|
}
|
|
|
|
.prose h2 {
|
|
font-size: clamp(1.8rem, 1.1rem + 1.6vw, 2.8rem);
|
|
line-height: 1.3;
|
|
color: var(--color-ink-strong);
|
|
font-weight: 600;
|
|
letter-spacing: 0.015em; /* 手写风格字体需要稍微增加字间距 */
|
|
font-family: var(--font-serif-cn), var(--font-serif-eng), "Songti SC", serif;
|
|
}
|
|
|
|
.prose h3 {
|
|
font-size: clamp(1.4rem, 0.9rem + 1vw, 2rem);
|
|
line-height: 1.35;
|
|
color: var(--color-ink-strong);
|
|
}
|
|
|
|
.prose p,
|
|
.prose li {
|
|
font-size: clamp(1rem, 0.2vw + 0.9rem, 1.15rem);
|
|
line-height: var(--line-height-body);
|
|
color: var(--color-ink-body);
|
|
}
|
|
|
|
.prose small,
|
|
.prose figcaption {
|
|
font-size: clamp(0.85rem, 0.2vw + 0.8rem, 0.95rem);
|
|
}
|
|
|
|
/* Dark mode prose overrides (replaces prose-dark) */
|
|
.dark .prose {
|
|
color: var(--color-ink-body);
|
|
}
|
|
|
|
.dark .prose strong,
|
|
.dark .prose b {
|
|
color: #f8fafc;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.dark .prose em {
|
|
color: #f1f5f9;
|
|
}
|
|
|
|
.dark .prose h1,
|
|
.dark .prose h2 {
|
|
color: #f8fafc;
|
|
}
|
|
|
|
.prose h1>a,
|
|
.prose h2>a,
|
|
.prose h3>a,
|
|
.prose h4>a,
|
|
.prose h5>a,
|
|
.prose h6>a {
|
|
text-decoration: none !important;
|
|
color: inherit !important;
|
|
}
|
|
|
|
.hero-title {
|
|
position: relative;
|
|
display: inline-flex;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.hero-title__sweep {
|
|
position: absolute;
|
|
inset: 0;
|
|
background: linear-gradient(120deg, transparent 10%, rgba(59, 130, 246, 0.35) 45%, transparent 90%);
|
|
transform: translateX(-120%);
|
|
animation: hero-sweep 4s var(--motion-ease-snappy) infinite;
|
|
pointer-events: none;
|
|
}
|
|
|
|
|
|
@keyframes hero-sweep {
|
|
0% {
|
|
transform: translateX(-120%);
|
|
opacity: 0;
|
|
}
|
|
|
|
30% {
|
|
opacity: 0.4;
|
|
}
|
|
|
|
60% {
|
|
transform: translateX(120%);
|
|
opacity: 0;
|
|
}
|
|
|
|
100% {
|
|
transform: translateX(120%);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
.tag-chip {
|
|
position: relative;
|
|
overflow: hidden;
|
|
transition: color var(--motion-duration-short) var(--motion-ease-snappy), background-color var(--motion-duration-short) var(--motion-ease-snappy);
|
|
}
|
|
|
|
.tag-chip::after {
|
|
content: '';
|
|
position: absolute;
|
|
left: 50%;
|
|
bottom: 4px;
|
|
width: 0;
|
|
height: 2px;
|
|
background: currentColor;
|
|
opacity: 0.5;
|
|
transition: width var(--motion-duration-short) var(--motion-ease-snappy), left var(--motion-duration-short) var(--motion-ease-snappy);
|
|
}
|
|
|
|
.tag-chip:hover::after,
|
|
.tag-chip:focus-visible::after {
|
|
width: 100%;
|
|
left: 0;
|
|
}
|
|
|
|
/* TOC transitions - replaces Framer Motion */
|
|
.toc-sidebar {
|
|
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
|
|
will-change: opacity, transform;
|
|
}
|
|
|
|
.toc-sidebar-enter {
|
|
opacity: 0;
|
|
transform: translateX(20px);
|
|
}
|
|
|
|
.toc-sidebar-enter-active {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
|
|
.toc-sidebar-exit {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
|
|
.toc-sidebar-exit-active {
|
|
opacity: 0;
|
|
transform: translateX(20px);
|
|
}
|
|
|
|
.toc-mobile {
|
|
transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out;
|
|
will-change: opacity, transform;
|
|
}
|
|
|
|
.toc-mobile-enter {
|
|
opacity: 0;
|
|
transform: translateY(20px);
|
|
}
|
|
|
|
.toc-mobile-enter-active {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
|
|
.toc-mobile-exit {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
|
|
.toc-mobile-exit-active {
|
|
opacity: 0;
|
|
transform: translateY(20px);
|
|
}
|
|
|
|
.toc-button {
|
|
transition: all 0.2s ease-in-out;
|
|
}
|
|
|
|
.toc-button:active {
|
|
transform: scale(0.95);
|
|
}
|
|
|
|
.toc-button:hover {
|
|
transform: scale(1.05);
|
|
}
|
|
|
|
@layer components {
|
|
.type-display {
|
|
font-size: clamp(2.2rem, 1.6rem + 2.4vw, 3.5rem);
|
|
line-height: 1.2;
|
|
font-weight: var(--font-weight-semibold);
|
|
font-family: var(--font-serif-cn), var(--font-serif-eng), "Songti SC", serif;
|
|
letter-spacing: 0.01em; /* 手写风格字体需要稍微增加字间距 */
|
|
}
|
|
|
|
.type-title {
|
|
font-size: clamp(1.6rem, 1.1rem + 1.4vw, 2.6rem);
|
|
line-height: 1.3;
|
|
font-weight: var(--font-weight-semibold);
|
|
font-family: var(--font-serif-cn), var(--font-serif-eng), "Songti SC", serif;
|
|
letter-spacing: 0.025em; /* 手写风格字体需要稍微增加字间距 */
|
|
}
|
|
|
|
.type-subtitle {
|
|
font-size: clamp(1.25rem, 0.9rem + 1vw, 1.9rem);
|
|
line-height: 1.35;
|
|
font-weight: var(--font-weight-medium);
|
|
font-family: var(--font-serif-cn), var(--font-serif-eng), "Songti SC", serif;
|
|
letter-spacing: 0.02em; /* 保持原有字间距 */
|
|
}
|
|
|
|
.type-body {
|
|
font-size: clamp(1rem, 0.2vw + 0.9rem, 1.15rem);
|
|
line-height: var(--line-height-body);
|
|
font-weight: var(--font-weight-regular);
|
|
}
|
|
|
|
.type-small {
|
|
font-size: clamp(0.85rem, 0.2vw + 0.8rem, 0.95rem);
|
|
line-height: 1.4;
|
|
font-weight: var(--font-weight-regular);
|
|
}
|
|
|
|
h1 {
|
|
font-weight: 700;
|
|
letter-spacing: 0.01em; /* 手写风格字体需要稍微增加字间距 */
|
|
font-family: var(--font-serif-cn), var(--font-serif-eng), "Songti SC", serif;
|
|
}
|
|
|
|
h2 {
|
|
font-weight: 600;
|
|
letter-spacing: 0.015em; /* 手写风格字体需要稍微增加字间距 */
|
|
font-family: var(--font-serif-cn), var(--font-serif-eng), "Songti SC", serif;
|
|
}
|
|
|
|
.type-nav {
|
|
font-size: clamp(0.95rem, 0.2vw + 0.85rem, 1.05rem);
|
|
font-weight: var(--font-weight-medium);
|
|
letter-spacing: 0.04em;
|
|
}
|
|
|
|
.motion-card {
|
|
transition: transform var(--motion-duration-medium) var(--motion-ease-snappy),
|
|
box-shadow var(--motion-duration-medium) var(--motion-ease-snappy),
|
|
background-color var(--motion-duration-medium) var(--motion-ease-snappy),
|
|
border-color var(--motion-duration-medium) var(--motion-ease-snappy);
|
|
}
|
|
|
|
.motion-card:hover {
|
|
transform: translateY(var(--card-translate-y));
|
|
}
|
|
|
|
.motion-link {
|
|
transition: color var(--motion-duration-short) var(--motion-ease-snappy),
|
|
transform var(--motion-duration-short) var(--motion-ease-snappy);
|
|
}
|
|
}
|
|
|
|
/* Search modal overlay (cmdk / Radix Dialog) */
|
|
[data-radix-dialog-overlay] {
|
|
@apply bg-black/50 backdrop-blur-sm;
|
|
}
|
|
|
|
/* Code Syntax Highlighting Styles (rehype-pretty-code) */
|
|
.prose pre {
|
|
@apply overflow-x-auto rounded-lg border border-slate-200 dark:border-slate-700;
|
|
padding: 1rem 1.2rem;
|
|
margin: 1.5rem 0;
|
|
background-color: #f8fafc;
|
|
}
|
|
|
|
.dark .prose pre {
|
|
background-color: #0f172a;
|
|
}
|
|
|
|
.prose pre > code {
|
|
@apply grid;
|
|
counter-reset: line;
|
|
font-size: 0.9em;
|
|
line-height: 1.7;
|
|
}
|
|
|
|
.prose pre > code > [data-line] {
|
|
padding: 0 1rem;
|
|
border-left: 2px solid transparent;
|
|
}
|
|
|
|
.prose pre > code > [data-line]::before {
|
|
counter-increment: line;
|
|
content: counter(line);
|
|
display: inline-block;
|
|
width: 1.5rem;
|
|
margin-right: 1.5rem;
|
|
text-align: right;
|
|
color: #94a3b8;
|
|
user-select: none;
|
|
}
|
|
|
|
.dark .prose pre > code > [data-line]::before {
|
|
color: #475569;
|
|
}
|
|
|
|
/* Highlighted lines */
|
|
.prose pre > code > [data-highlighted-line] {
|
|
background-color: rgba(59, 130, 246, 0.1);
|
|
border-left-color: rgb(59, 130, 246);
|
|
}
|
|
|
|
.dark .prose pre > code > [data-highlighted-line] {
|
|
background-color: rgba(96, 165, 250, 0.15);
|
|
border-left-color: rgb(96, 165, 250);
|
|
}
|
|
|
|
/* Inline code */
|
|
.prose :not(pre) > code {
|
|
@apply rounded bg-slate-100 px-1.5 py-0.5 text-sm font-semibold text-slate-800 dark:bg-slate-800 dark:text-slate-200;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* Code title (if specified in markdown: ```js title="example.js") */
|
|
.prose [data-rehype-pretty-code-title] {
|
|
@apply rounded-t-lg border border-b-0 border-slate-200 bg-slate-100 px-4 py-2 text-sm font-semibold text-slate-700 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-300;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.prose [data-rehype-pretty-code-title] + pre {
|
|
@apply mt-0 rounded-t-none;
|
|
}
|
|
|
|
/* GitHub-style Callouts/Alerts */
|
|
.prose .callout {
|
|
@apply my-6 rounded-lg border-l-4 p-4 shadow-sm;
|
|
background: linear-gradient(135deg, var(--callout-bg-start), var(--callout-bg-end));
|
|
}
|
|
|
|
.prose .callout-header {
|
|
@apply mb-3 flex items-center gap-2;
|
|
}
|
|
|
|
.prose .callout-icon {
|
|
@apply text-2xl;
|
|
line-height: 1;
|
|
}
|
|
|
|
.prose .callout-title {
|
|
@apply text-sm font-bold uppercase tracking-wider;
|
|
color: var(--callout-title-color);
|
|
letter-spacing: 0.05em;
|
|
}
|
|
|
|
.prose .callout-content {
|
|
@apply text-sm leading-relaxed;
|
|
}
|
|
|
|
.prose .callout-content > *:first-child {
|
|
@apply mt-0;
|
|
}
|
|
|
|
.prose .callout-content > *:last-child {
|
|
@apply mb-0;
|
|
}
|
|
|
|
/* NOTE - Blue */
|
|
.prose .callout-note {
|
|
--callout-bg-start: rgba(59, 130, 246, 0.08);
|
|
--callout-bg-end: rgba(59, 130, 246, 0.04);
|
|
--callout-title-color: #2563eb;
|
|
@apply border-blue-500;
|
|
}
|
|
|
|
.dark .prose .callout-note {
|
|
--callout-bg-start: rgba(96, 165, 250, 0.12);
|
|
--callout-bg-end: rgba(96, 165, 250, 0.06);
|
|
--callout-title-color: #93c5fd;
|
|
@apply border-blue-400;
|
|
}
|
|
|
|
/* TIP - Green */
|
|
.prose .callout-tip {
|
|
--callout-bg-start: rgba(34, 197, 94, 0.08);
|
|
--callout-bg-end: rgba(34, 197, 94, 0.04);
|
|
--callout-title-color: #16a34a;
|
|
@apply border-green-500;
|
|
}
|
|
|
|
.dark .prose .callout-tip {
|
|
--callout-bg-start: rgba(74, 222, 128, 0.12);
|
|
--callout-bg-end: rgba(74, 222, 128, 0.06);
|
|
--callout-title-color: #86efac;
|
|
@apply border-green-400;
|
|
}
|
|
|
|
/* IMPORTANT - Purple */
|
|
.prose .callout-important {
|
|
--callout-bg-start: rgba(168, 85, 247, 0.08);
|
|
--callout-bg-end: rgba(168, 85, 247, 0.04);
|
|
--callout-title-color: #9333ea;
|
|
@apply border-purple-500;
|
|
}
|
|
|
|
.dark .prose .callout-important {
|
|
--callout-bg-start: rgba(192, 132, 252, 0.12);
|
|
--callout-bg-end: rgba(192, 132, 252, 0.06);
|
|
--callout-title-color: #c084fc;
|
|
@apply border-purple-400;
|
|
}
|
|
|
|
/* WARNING - Orange/Yellow */
|
|
.prose .callout-warning {
|
|
--callout-bg-start: rgba(251, 191, 36, 0.08);
|
|
--callout-bg-end: rgba(251, 191, 36, 0.04);
|
|
--callout-title-color: #d97706;
|
|
@apply border-yellow-500;
|
|
}
|
|
|
|
.dark .prose .callout-warning {
|
|
--callout-bg-start: rgba(253, 224, 71, 0.12);
|
|
--callout-bg-end: rgba(253, 224, 71, 0.06);
|
|
--callout-title-color: #fde047;
|
|
@apply border-yellow-400;
|
|
}
|
|
|
|
/* CAUTION - Red */
|
|
.prose .callout-caution {
|
|
--callout-bg-start: rgba(239, 68, 68, 0.08);
|
|
--callout-bg-end: rgba(239, 68, 68, 0.04);
|
|
--callout-title-color: #dc2626;
|
|
@apply border-red-500;
|
|
}
|
|
|
|
.dark .prose .callout-caution {
|
|
--callout-bg-start: rgba(248, 113, 113, 0.12);
|
|
--callout-bg-end: rgba(248, 113, 113, 0.06);
|
|
--callout-title-color: #fca5a5;
|
|
@apply border-red-400;
|
|
}
|
|
|
|
/* Mermaid diagram viewer */
|
|
.mermaid-diagram {
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
margin: 1.5rem 0;
|
|
border: 1px solid #e2e8f0;
|
|
border-radius: 0.75rem;
|
|
background: #fafbfc;
|
|
opacity: 0;
|
|
transition: opacity 0.3s ease-in;
|
|
}
|
|
|
|
.dark .mermaid-diagram {
|
|
border-color: #334155;
|
|
background: #0f172a;
|
|
}
|
|
|
|
.mermaid-diagram.mermaid-rendered {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* Fullscreen overrides */
|
|
.mermaid-diagram:fullscreen {
|
|
border-radius: 0;
|
|
border: none;
|
|
}
|
|
|
|
.mermaid-diagram:fullscreen .mermaid-canvas {
|
|
height: calc(100vh - 40px);
|
|
}
|
|
|
|
/* Canvas — the pannable/zoomable area */
|
|
.mermaid-canvas {
|
|
position: relative;
|
|
z-index: 0;
|
|
overflow: hidden;
|
|
width: 100%;
|
|
height: 360px;
|
|
cursor: grab;
|
|
touch-action: none;
|
|
}
|
|
|
|
@media (min-width: 768px) {
|
|
.mermaid-canvas {
|
|
height: 420px;
|
|
}
|
|
}
|
|
|
|
.mermaid-grabbing .mermaid-canvas {
|
|
cursor: grabbing;
|
|
}
|
|
|
|
.mermaid-viewport {
|
|
display: inline-flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
min-width: 100%;
|
|
min-height: 100%;
|
|
transform-origin: 0 0;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* Toolbar */
|
|
.mermaid-zoom-bar {
|
|
position: relative;
|
|
z-index: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 2px;
|
|
padding: 4px 8px;
|
|
border-top: 1px solid #e2e8f0;
|
|
background: #f1f5f9;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.dark .mermaid-zoom-bar {
|
|
border-top-color: #334155;
|
|
background: #1e293b;
|
|
}
|
|
|
|
.mermaid-zoom-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 32px;
|
|
height: 28px;
|
|
padding: 0 8px;
|
|
border: none;
|
|
border-radius: 6px;
|
|
background: transparent;
|
|
color: #475569;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: background 0.15s, color 0.15s;
|
|
user-select: none;
|
|
}
|
|
|
|
.mermaid-zoom-btn:hover {
|
|
background: #e2e8f0;
|
|
color: #0f172a;
|
|
}
|
|
|
|
.mermaid-zoom-btn:active {
|
|
background: #cbd5e1;
|
|
}
|
|
|
|
.dark .mermaid-zoom-btn {
|
|
color: #94a3b8;
|
|
}
|
|
|
|
.dark .mermaid-zoom-btn:hover {
|
|
background: #334155;
|
|
color: #e2e8f0;
|
|
}
|
|
|
|
.dark .mermaid-zoom-btn:active {
|
|
background: #475569;
|
|
}
|
|
|
|
.mermaid-zoom-level {
|
|
font-size: 12px;
|
|
font-variant-numeric: tabular-nums;
|
|
min-width: 48px;
|
|
}
|
|
|
|
.mermaid-sep {
|
|
width: 1px;
|
|
height: 16px;
|
|
margin: 0 4px;
|
|
background: #cbd5e1;
|
|
}
|
|
|
|
.dark .mermaid-sep {
|
|
background: #475569;
|
|
}
|