:root { font-family: 'Noto Sans', 'Segoe UI', Helvetica, Arial, sans-serif; line-height: 1.5; font-weight: 400; font-synthesis: none; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } :root, :root[data-theme='light'] { color-scheme: light; --app-bg: #f4f6fb; --app-text: #1f2937; --panel-bg: rgba(255, 255, 255, 0.5); --panel-border: #d7deea; --panel-shadow: 0 8px 24px rgba(16, 24, 40, 0.12); --btn-bg: rgba(255, 255, 255, 0.5); --btn-fg: #5b6470; --btn-hover-bg: #4a90d9; --btn-hover-fg: #ffffff; --btn-disabled-bg: rgba(207, 213, 223, 0.5); --btn-disabled-fg: #8a92a0; --overlay-bg: rgba(15, 23, 42, 0.3); --tooltip-bg: #111827; --tooltip-fg: #f9fafb; --muted-text: #6b7280; --danger-text: #dc2626; --scrollbar-thumb: #d4dae4; --scrollbar-thumb-hover: #bbc4d2; --focus-ring: #3b82f6; --toggle-bg-start: rgba(255, 248, 221, 0.5); --toggle-bg-end: rgba(242, 244, 255, 0.5); --toggle-thumb-bg: #ffffff; --toggle-sun: #f59e0b; --toggle-moon: #475569; --ghost-text: #7d8796; --ghost-code-bg: rgba(15, 23, 42, 0.06); --code-inline-bg: rgba(15, 23, 42, 0.06); --code-block-bg: #f8fafc; --code-block-border: rgba(148, 163, 184, 0.28); --code-text: #0f172a; --mermaid-max-height: 480px; --mermaid-mobile-max-height: 320px; --mermaid-glass-bg: rgba(255, 255, 255, 0.55); --mermaid-glass-border: rgba(180, 200, 230, 0.5); --mermaid-glass-border-hover: rgba(59, 130, 246, 0.45); --mermaid-glass-shadow: 0 4px 24px rgba(15, 23, 42, 0.08), 0 1px 4px rgba(15, 23, 42, 0.05); --mermaid-glass-shadow-hover: 0 8px 32px rgba(59, 130, 246, 0.12), 0 2px 8px rgba(15, 23, 42, 0.08); --mermaid-btn-bg: rgba(255, 255, 255, 0.8); --mermaid-btn-hover-bg: rgba(239, 246, 255, 0.95); --mermaid-btn-fg: #374151; --mermaid-btn-border: rgba(180, 200, 230, 0.6); --crepe-color-background: #ffffff; --crepe-color-on-background: #000000; --crepe-color-surface: #f7f7f7; --crepe-color-surface-low: #ededed; --crepe-color-on-surface: #1c1c1c; --crepe-color-on-surface-variant: #4d4d4d; --crepe-color-outline: #a8a8a8; --crepe-color-primary: #333333; --crepe-color-secondary: #cfcfcf; --crepe-color-on-secondary: #000000; --crepe-color-inverse: #f0f0f0; --crepe-color-on-inverse: #1a1a1a; --crepe-color-inline-code: #ba1a1a; --crepe-color-error: #ba1a1a; --crepe-color-hover: #e0e0e0; --crepe-color-selected: #d5d5d5; --crepe-color-inline-area: #cacaca; } :root[data-theme='dark'] { color-scheme: dark; --app-bg: #0f1117; --app-text: #e5e7eb; --panel-bg: rgba(26, 30, 39, 0.5); --panel-border: #2f3644; --panel-shadow: 0 10px 26px rgba(0, 0, 0, 0.5); --btn-bg: rgba(34, 40, 52, 0.5); --btn-fg: #d2d8e4; --btn-hover-bg: #6ea8ff; --btn-hover-fg: #0d1117; --btn-disabled-bg: rgba(46, 52, 65, 0.5); --btn-disabled-fg: #7a8498; --overlay-bg: rgba(2, 6, 23, 0.65); --tooltip-bg: #f8fafc; --tooltip-fg: #0f172a; --muted-text: #aeb6c5; --danger-text: #f87171; --scrollbar-thumb: #40485a; --scrollbar-thumb-hover: #5f6980; --focus-ring: #60a5fa; --toggle-bg-start: rgba(45, 49, 64, 0.5); --toggle-bg-end: rgba(31, 36, 48, 0.5); --toggle-thumb-bg: #dbe3f2; --toggle-sun: #fbbf24; --toggle-moon: #e2e8f0; --ghost-text: #95a0b4; --ghost-code-bg: rgba(226, 232, 240, 0.12); --code-inline-bg: rgba(30, 41, 59, 0.92); --code-block-bg: rgba(15, 23, 42, 0.92); --code-block-border: rgba(71, 85, 105, 0.55); --code-text: #e2e8f0; --mermaid-max-height: 480px; --mermaid-mobile-max-height: 320px; --mermaid-glass-bg: rgba(20, 28, 44, 0.6); --mermaid-glass-border: rgba(60, 80, 120, 0.4); --mermaid-glass-border-hover: rgba(96, 165, 250, 0.45); --mermaid-glass-shadow: 0 4px 24px rgba(0, 0, 0, 0.3), 0 1px 4px rgba(0, 0, 0, 0.2); --mermaid-glass-shadow-hover: 0 8px 32px rgba(96, 165, 250, 0.15), 0 2px 8px rgba(0, 0, 0, 0.3); --mermaid-btn-bg: rgba(40, 52, 75, 0.85); --mermaid-btn-hover-bg: rgba(55, 70, 100, 0.95); --mermaid-btn-fg: #c9d6e8; --mermaid-btn-border: rgba(70, 95, 140, 0.55); --crepe-color-background: #1a1a1a; --crepe-color-on-background: #e6e6e6; --crepe-color-surface: #121212; --crepe-color-surface-low: #1c1c1c; --crepe-color-on-surface: #d1d1d1; --crepe-color-on-surface-variant: #a9a9a9; --crepe-color-outline: #757575; --crepe-color-primary: #b5b5b5; --crepe-color-secondary: #4d4d4d; --crepe-color-on-secondary: #d6d6d6; --crepe-color-inverse: #e5e5e5; --crepe-color-on-inverse: #2a2a2a; --crepe-color-inline-code: #ff6666; --crepe-color-error: #ff6666; --crepe-color-hover: #232323; --crepe-color-selected: #2f2f2f; --crepe-color-inline-area: #2b2b2b; } :root[data-theme='light'] .milkdown { --crepe-color-background: transparent; --crepe-color-on-background: #000000; --crepe-color-surface: rgba(247, 247, 247, 0.5); --crepe-color-surface-low: rgba(237, 237, 237, 0.5); --crepe-color-on-surface: #1c1c1c; --crepe-color-on-surface-variant: #4d4d4d; --crepe-color-outline: #a8a8a8; --crepe-color-primary: #333333; --crepe-color-secondary: #cfcfcf; --crepe-color-on-secondary: #000000; --crepe-color-inverse: #f0f0f0; --crepe-color-on-inverse: #1a1a1a; --crepe-color-inline-code: #ba1a1a; --crepe-color-error: #ba1a1a; --crepe-color-hover: #e0e0e0; --crepe-color-selected: #d5d5d5; --crepe-color-inline-area: #cacaca; } :root[data-theme='dark'] .milkdown { --crepe-color-background: transparent; --crepe-color-on-background: #e6e6e6; --crepe-color-surface: rgba(18, 18, 18, 0.5); --crepe-color-surface-low: rgba(28, 28, 28, 0.5); --crepe-color-on-surface: #d1d1d1; --crepe-color-on-surface-variant: #a9a9a9; --crepe-color-outline: #757575; --crepe-color-primary: #b5b5b5; --crepe-color-secondary: #4d4d4d; --crepe-color-on-secondary: #d6d6d6; --crepe-color-inverse: #e5e5e5; --crepe-color-on-inverse: #2a2a2a; --crepe-color-inline-code: #ff6666; --crepe-color-error: #ff6666; --crepe-color-hover: #232323; --crepe-color-selected: #2f2f2f; --crepe-color-inline-area: #2b2b2b; } html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow-x: hidden; overflow-y: auto; background: var(--app-bg); color: var(--app-text); } body { min-width: 320px; } #app { width: 100vw; height: 100vh; margin: 0; padding: 0; max-width: none; background: var(--app-bg); color: var(--app-text); } *, *::before, *::after { box-sizing: border-box; transition: background-color 220ms ease, color 220ms ease, border-color 220ms ease, box-shadow 220ms ease; } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; } } /* ── Mermaid diagram blocks ─────────────────────────────────────────── */ .mermaid-block { position: relative; display: block; width: 100%; max-width: 100%; margin: 1.25em 0; padding: 0; background: var(--mermaid-glass-bg); border: 1px solid var(--mermaid-glass-border); border-radius: 16px; box-shadow: var(--mermaid-glass-shadow); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); transition: border-color 240ms ease, box-shadow 240ms ease; overflow: hidden; } .mermaid-block:hover { border-color: var(--mermaid-glass-border-hover); box-shadow: var(--mermaid-glass-shadow-hover); } /* 悬浮控制栏:右上角,hover 时渐现 */ .mermaid-controls { position: absolute; top: 10px; right: 10px; z-index: 10; display: flex; align-items: center; gap: 6px; opacity: 0; transform: translateY(-4px); transition: opacity 200ms ease, transform 200ms ease; pointer-events: none; } .mermaid-block:hover .mermaid-controls { opacity: 1; transform: translateY(0); pointer-events: auto; } .mermaid-action-btn { appearance: none; border: 1px solid var(--mermaid-btn-border); background: var(--mermaid-btn-bg); color: var(--mermaid-btn-fg); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 5px; font-size: 12px; font-weight: 500; line-height: 1; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); box-shadow: 0 1px 4px rgba(0,0,0,0.15), inset 0 1px 0 rgba(255,255,255,0.1); transition: background 160ms ease, border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease; } .mermaid-zoom-btn { width: 30px; height: 30px; padding: 0; border-radius: 50%; } .mermaid-download-btn { height: 30px; padding: 0 12px; border-radius: 999px; } .mermaid-action-btn:hover:not([disabled]) { background: var(--mermaid-btn-hover-bg); border-color: var(--focus-ring); box-shadow: 0 0 0 3px rgba(59,130,246,0.18), 0 2px 8px rgba(0,0,0,0.2); transform: translateY(-1px); } .mermaid-action-btn:active:not([disabled]) { transform: translateY(0); box-shadow: 0 1px 4px rgba(0,0,0,0.15); } .mermaid-action-btn[disabled] { opacity: 0.35; cursor: not-allowed; pointer-events: none; } .mermaid-inner { display: block; width: 100%; max-height: var(--mermaid-max-height); overflow: auto; padding: 20px; background: transparent; } .mermaid-inner::-webkit-scrollbar { width: 6px; height: 6px; } .mermaid-inner::-webkit-scrollbar-thumb { background-color: var(--scrollbar-thumb); border-radius: 3px; } .mermaid-inner::-webkit-scrollbar-thumb:hover { background-color: var(--scrollbar-thumb-hover); } .mermaid-image { display: block; width: auto; height: auto; max-width: 100%; margin: 0 auto; border-radius: 6px; } .mermaid-inner svg { display: block; margin: 0 auto; } /* 三点弹跳加载动画 */ .mermaid-loading { display: flex; align-items: center; justify-content: center; gap: 6px; padding: 36px; } .mermaid-loading span { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--muted-text, #6b7280); animation: mermaid-bounce 1.2s ease-in-out infinite; } .mermaid-loading span:nth-child(2) { animation-delay: 0.2s; } .mermaid-loading span:nth-child(3) { animation-delay: 0.4s; } @keyframes mermaid-bounce { 0%, 80%, 100% { transform: scale(0.55); opacity: 0.35; } 40% { transform: scale(1); opacity: 1; } } .mermaid-error { margin: 12px; padding: 12px 16px; background: rgba(220, 38, 38, 0.08); border: 1px solid var(--danger-text, #dc2626); border-radius: 8px; color: var(--danger-text, #dc2626); font-size: 12px; font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Mono', monospace; white-space: pre-wrap; word-break: break-word; } :root .milkdown .katex { color: var(--crepe-color-on-background); } :root[data-theme='dark'] .milkdown .katex .mord, :root[data-theme='dark'] .milkdown .katex .mbin, :root[data-theme='dark'] .milkdown .katex .mrel, :root[data-theme='dark'] .milkdown .katex .minner { color: var(--crepe-color-on-background); } :root[data-theme='dark'] .milkdown .katex .mord.text { color: var(--crepe-color-on-background); } :root[data-theme='dark'] .milkdown .cm-editor, :root[data-theme='dark'] .milkdown .cm-scroller { background-color: var(--code-block-bg); color: var(--code-text); } :root[data-theme='dark'] .milkdown .cm-gutters { background-color: var(--code-block-bg); color: var(--crepe-color-on-surface-variant); border-right: 1px solid var(--code-block-border); } :root[data-theme='dark'] .milkdown .cm-activeLine { background-color: rgba(255, 255, 255, 0.05); } :root[data-theme='dark'] .milkdown .cm-activeLineGutter { background-color: rgba(255, 255, 255, 0.08); } :root[data-theme='dark'] .milkdown .cm-selectionBackground, :root[data-theme='dark'] .milkdown .cm-selectionBackground::selection { background-color: rgba(59, 130, 246, 0.25); } :root[data-theme='dark'] .milkdown .cm-cursor { border-left-color: var(--crepe-color-on-background); } :root .milkdown .ProseMirror pre, :root .milkdown .ProseMirror code { background: var(--code-inline-bg); color: var(--code-text); border: 1px solid var(--code-block-border); } :root .milkdown .ProseMirror pre { padding: 12px 16px; border-radius: 8px; background: var(--code-block-bg); } :root .milkdown .ProseMirror pre code { background: none; border: none; padding: 0; } :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.comment, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.prolog, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.doctype, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.cdata { color: #6b7280; } :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.punctuation { color: #9ca3af; } :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.property, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.tag, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.boolean, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.number, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.constant, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.symbol, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.deleted { color: #f472b6; } :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.selector, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.attr-name, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.string, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.char, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.builtin, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.inserted { color: #a78bfa; } :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.operator, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.entity, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.url, :root[data-theme='dark'] .milkdown .ProseMirror pre code .language-css .token.string, :root[data-theme='dark'] .milkdown .ProseMirror pre code .style .token.string { color: #60a5fa; } :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.atrule, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.attr-value, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.keyword { color: #34d399; } :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.function, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.class-name { color: #fbbf24; } :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.regex, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.important, :root[data-theme='dark'] .milkdown .ProseMirror pre code .token.variable { color: #fb923c; } @media (max-width: 768px) { .mermaid-inner { max-height: var(--mermaid-mobile-max-height); } }