Files
blog/frontend/src/index.css
T
zhaoxi 693e08d67b fix(editor): 修复草稿被默认文本覆盖的数据丢失 bug 与编辑器无法滚动
- 编辑器初始化等待文章和草稿两个查询都返回,此前草稿接口先返回
  空内容时会用默认文本初始化并被自动保存覆盖真实草稿
- CodeMirror 容器加 min-h-0(flex 子项默认 min-height:auto 会被
  内容撑开),并约束 .cm-editor 高度为 100% 使内部滚动生效
- 修复规则必须放在 @layer 外,否则被 Tailwind 当作未使用样式裁剪
2026-07-19 14:56:47 +08:00

294 lines
7.9 KiB
CSS

@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
color-scheme: light dark;
}
html {
@apply scroll-smooth;
}
body {
@apply bg-paper text-stone-900 antialiased font-serif;
font-feature-settings: 'cv11', 'ss01';
}
html.dark body {
@apply bg-space-950 text-star font-sans;
}
::selection {
@apply bg-indigo-500/30 text-indigo-900;
}
.dark ::selection {
@apply bg-nebula/40 text-star;
}
}
@layer components {
.stars {
background-image:
radial-gradient(2px 2px at 20px 30px, rgba(255,255,255,0.3), transparent),
radial-gradient(2px 2px at 40px 70px, rgba(255,255,255,0.2), transparent),
radial-gradient(1px 1px at 90px 40px, rgba(255,255,255,0.4), transparent),
radial-gradient(2px 2px at 160px 120px, rgba(255,255,255,0.2), transparent),
radial-gradient(1px 1px at 230px 80px, rgba(255,255,255,0.3), transparent),
radial-gradient(2px 2px at 300px 20px, rgba(255,255,255,0.2), transparent),
radial-gradient(1px 1px at 350px 150px, rgba(255,255,255,0.4), transparent);
background-repeat: repeat;
background-size: 400px 200px;
}
.nebula {
background-image:
radial-gradient(ellipse at 20% 30%, rgba(99,102,241,0.12), transparent 40%),
radial-gradient(ellipse at 80% 70%, rgba(139,92,246,0.08), transparent 40%),
radial-gradient(ellipse at 50% 50%, rgba(34,211,238,0.06), transparent 50%);
}
.glass {
@apply bg-white/70 backdrop-blur-md border border-white/20;
}
.dark .glass {
@apply bg-space-800/60 border-indigo-500/20;
}
.glow-text {
@apply text-transparent bg-clip-text bg-gradient-to-r from-indigo-400 via-purple-400 to-cyan-400;
}
.nav-link {
@apply relative text-stone-600 hover:text-stone-900 transition-colors;
}
.dark .nav-link {
@apply text-star-dim hover:text-star;
}
.nav-link::after {
content: '';
@apply absolute left-0 -bottom-1 w-0 h-0.5 bg-indigo-500 transition-all duration-300;
}
.nav-link:hover::after {
@apply w-full;
}
/* 卡片悬浮光晕 */
.card-glow {
@apply relative overflow-hidden rounded-lg border border-stone-200 bg-white shadow-sm transition-all duration-300;
}
.dark .card-glow {
@apply border-indigo-500/20 bg-space-800/60 shadow-none;
}
.card-glow::before {
content: '';
@apply absolute inset-0 opacity-0 transition-opacity duration-300 pointer-events-none;
background: radial-gradient(600px circle at var(--mouse-x, 50%) var(--mouse-y, 50%), rgba(99,102,241,0.08), transparent 40%);
}
.dark .card-glow::before {
background: radial-gradient(600px circle at var(--mouse-x, 50%) var(--mouse-y, 50%), rgba(129,140,248,0.12), transparent 40%);
}
.card-glow:hover::before {
@apply opacity-100;
}
/* 发光边框 */
.glow-border {
position: relative;
}
.glow-border::after {
content: '';
@apply absolute inset-0 rounded-2xl opacity-0 transition-opacity duration-300 pointer-events-none;
padding: 1px;
background: linear-gradient(135deg, rgba(99,102,241,0.4), rgba(139,92,246,0.4), rgba(34,211,238,0.4));
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
}
.glow-border:hover::after {
@apply opacity-100;
}
/* 标题动画 */
.title-reveal {
@apply inline-block overflow-hidden;
}
.title-reveal span {
@apply inline-block transform translate-y-full;
animation: titleUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes titleUp {
to {
transform: translateY(0);
}
}
/* 夜间模式正文调白(prose-invert 用的是 invert 变量,得在这里覆盖) */
.dark .prose {
--tw-prose-invert-body: #ffffff;
--tw-prose-invert-headings: #ffffff;
--tw-prose-invert-bold: #ffffff;
--tw-prose-invert-quotes: #ffffff;
--tw-prose-invert-counters: #e0e7ff;
--tw-prose-invert-bullets: #818cf8;
}
/* 代码块:浅色底框 + 顶部语言标注栏(夜间为深空蓝) */
.prose .code-block-wrapper {
@apply relative my-6 overflow-hidden rounded-lg border border-stone-200 bg-[#f6f8fa];
}
.prose .code-block-header {
@apply flex items-center justify-between border-b border-stone-200 bg-stone-100 px-4 py-1.5 text-xs font-semibold uppercase tracking-wider text-stone-500;
}
.prose pre.code-block-content {
@apply m-0 overflow-x-auto bg-transparent p-4 font-mono text-sm leading-relaxed text-stone-800;
}
/* hljs 主题自带底色和内边距,去掉以免和容器冲突 */
.prose pre.code-block-content .hljs {
background: transparent;
padding: 0;
}
/* 夜间:深空蓝底 + GitHub Dark 语法配色 */
.dark .prose .code-block-wrapper {
@apply border-indigo-500/20 bg-space-800;
}
.dark .prose .code-block-header {
@apply border-indigo-500/10 bg-space-900 text-star-dim;
}
.dark .prose pre.code-block-content {
@apply text-slate-200;
}
.dark .hljs { color: #c9d1d9; }
.dark .hljs-doctag,
.dark .hljs-keyword,
.dark .hljs-meta .hljs-keyword,
.dark .hljs-template-tag,
.dark .hljs-template-variable,
.dark .hljs-type,
.dark .hljs-variable.language_ { color: #ff7b72; }
.dark .hljs-title,
.dark .hljs-title.class_,
.dark .hljs-title.class_.inherited__,
.dark .hljs-title.function_ { color: #d2a8ff; }
.dark .hljs-attr,
.dark .hljs-attribute,
.dark .hljs-literal,
.dark .hljs-meta,
.dark .hljs-number,
.dark .hljs-operator,
.dark .hljs-variable,
.dark .hljs-selector-attr,
.dark .hljs-selector-class,
.dark .hljs-selector-id { color: #79c0ff; }
.dark .hljs-regexp,
.dark .hljs-string,
.dark .hljs-meta .hljs-string { color: #a5d6ff; }
.dark .hljs-built_in,
.dark .hljs-symbol { color: #ffa657; }
.dark .hljs-comment,
.dark .hljs-code,
.dark .hljs-formula { color: #8b949e; }
.dark .hljs-name,
.dark .hljs-quote,
.dark .hljs-selector-tag,
.dark .hljs-selector-pseudo { color: #7ee787; }
.dark .hljs-subst { color: #c9d1d9; }
.dark .hljs-section { color: #1f6feb; font-weight: bold; }
.dark .hljs-bullet { color: #f2cc60; }
.dark .hljs-emphasis { color: #c9d1d9; font-style: italic; }
.dark .hljs-strong { color: #c9d1d9; font-weight: bold; }
.dark .hljs-addition { color: #aff5b4; background-color: #033a16; }
.dark .hljs-deletion { color: #ffdcd7; background-color: #67060c; }
/* 阅读进度条 */
.progress-bar {
@apply fixed left-0 top-0 h-1 bg-gradient-to-r from-indigo-500 via-purple-500 to-cyan-500 transition-transform origin-left z-50;
}
/* TOC */
.toc-item {
@apply relative pl-4 text-sm text-stone-500 transition-colors hover:text-indigo-600 dark:text-star-dim dark:hover:text-nebula-glow;
}
.toc-item::before {
content: '';
@apply absolute left-0 top-1/2 h-0 w-0.5 -translate-y-1/2 bg-indigo-500 transition-all duration-200;
}
.toc-item.active::before {
@apply h-4;
}
.toc-item.active {
@apply text-indigo-600 font-medium dark:text-nebula-glow;
}
/* 滚动条美化 */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
@apply bg-transparent;
}
::-webkit-scrollbar-thumb {
@apply rounded-full bg-stone-300;
}
.dark ::-webkit-scrollbar-thumb {
@apply bg-space-700;
}
/* 按钮按压效果 */
.btn-press {
@apply active:scale-95 transition-transform;
}
/* 标签云 */
.tag-pill {
@apply inline-flex items-center gap-1 rounded-full px-3 py-1 text-xs font-medium transition-all duration-200;
}
/* 输入框聚焦光效 */
.input-glow {
@apply transition-all duration-200;
}
.input-glow:focus {
@apply shadow-[0_0_0_3px_rgba(99,102,241,0.15)];
}
.dark .input-glow:focus {
@apply shadow-[0_0_0_3px_rgba(129,140,248,0.2)];
}
}
/* CodeMirror 编辑器内部滚动(必须是无层级的普通 CSS,
放在 @layer 里会被 Tailwind 当作未使用样式裁剪掉) */
.cm-editor {
height: 100%;
}