:root { --accent-color: #4a9eff; --accent-soft: rgba(74, 158, 255, 0.1); --accent-medium: rgba(74, 158, 255, 0.18); --text-primary: #1a1a2e; --text-secondary: #555; --text-muted: #999; --glass-bg: rgba(255, 255, 255, 0.55); --glass-border: rgba(255, 255, 255, 0.6); --glass-shadow: 0 2px 16px rgba(0, 0, 0, 0.04); --header-bg: rgba(245, 247, 252, 0.88); --header-border: rgba(180, 195, 220, 0.35); --footer-bg: rgba(242, 244, 248, 0.88); --footer-border: rgba(180, 195, 220, 0.3); --divider-color: rgba(0, 0, 0, 0.06); --editor-bg: rgba(255, 255, 255, 0.72); --editor-font: 'Cascadia Code', 'Fira Code', 'Consolas', 'Monaco', monospace; --editor-text: #2c2c2c; --preview-bg: rgba(248, 250, 252, 0.6); --toolbar-bg: rgba(255, 255, 255, 0.65); --toolbar-shadow: 0 4px 24px rgba(0, 0, 0, 0.06); --btn-bg: rgba(255, 255, 255, 0.7); --scrollbar-thumb: rgba(0, 0, 0, 0.1); --scrollbar-thumb-hover: rgba(0, 0, 0, 0.2); --splitter-handle: rgba(0, 0, 0, 0.12); --sidebar-bg: rgba(250, 250, 253, 0.85); --transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1); --radius: 10px; } * { box-sizing: border-box; } body { margin: 0; padding: 0; display: flex; flex-direction: column; height: 100vh; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; overflow: hidden; color: var(--text-primary); background: linear-gradient(135deg, #e8f0fe 0%, #f5f7fa 30%, #fef6f0 70%, #f0f4ff 100%); background-attachment: fixed; } /* ── Header ── */ header { background: var(--header-bg); color: var(--text-primary); padding: 0 20px; display: flex; align-items: center; justify-content: space-between; height: 52px; flex-shrink: 0; box-shadow: 0 1px 8px rgba(0, 0, 0, 0.06); z-index: 100; position: relative; -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%); border-bottom: 1px solid var(--header-border); } header h1 { margin: 0; font-size: 17px; font-weight: 600; letter-spacing: 0.3px; display: flex; align-items: center; gap: 8px; color: var(--text-primary); } header h1::before { content: ''; display: inline-block; width: 20px; height: 20px; background: var(--accent-color); border-radius: 5px; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M2 4h6v2H4v10h4v2H2V4zm10 0h6v14h-6v-2h4V6h-4V4z' fill='black'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M2 4h6v2H4v10h4v2H2V4zm10 0h6v14h-6v-2h4V6h-4V4z' fill='black'/%3E%3C/svg%3E") center / contain no-repeat; } header .toolbar { display: flex; gap: 6px; } .header-left { display: flex; align-items: center; gap: 10px; } .header-right { display: flex; align-items: center; gap: 6px; } /* 移动端菜单按钮:仅移动端显示 */ #mobile-menu-btn { display: none; } .icon-btn { background-color: var(--btn-bg); color: var(--text-secondary); border: 1px solid var(--header-border); padding: 6px; border-radius: 8px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all var(--transition); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04); } .icon-btn:hover { background-color: var(--accent-soft); border-color: var(--accent-color); color: var(--accent-color); transform: translateY(-1px); } .icon-btn svg { fill: currentColor; } header .toolbar button, #mode-toggle { background-color: var(--btn-bg); color: var(--text-secondary); border: 1px solid var(--header-border); padding: 6px 16px; border-radius: 8px; cursor: pointer; font-size: 13px; font-weight: 500; transition: all var(--transition); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04); } header .toolbar button:hover, #mode-toggle:hover { background-color: var(--accent-soft); border-color: var(--accent-color); color: var(--accent-color); transform: translateY(-1px); box-shadow: 0 2px 8px rgba(74, 158, 255, 0.15); } header .toolbar button:active, #mode-toggle:active { background-color: var(--accent-medium); transform: translateY(0); } /* ── Layout ── */ #app { display: flex; flex-direction: column; height: 100%; } main { display: flex; flex: 1; overflow: hidden; min-height: 0; } /* ── Editor ── */ #editor-container { width: 40%; flex-shrink: 0; height: 100%; background: var(--editor-bg); position: relative; -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); } #editor { width: 100%; height: 100%; resize: none; padding: 16px 20px; border: none; background: transparent; font-family: var(--editor-font); font-size: 13.5px; line-height: 1.7; color: var(--editor-text); outline: none; tab-size: 2; } #editor::placeholder { color: var(--text-muted); line-height: 1.8; } #editor::-webkit-scrollbar { width: 6px; } #editor::-webkit-scrollbar-track { background: transparent; } #editor::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 3px; } #editor::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); } /* ── Sidebar ── */ #sidebar { width: 220px; flex-shrink: 0; height: 100%; background: var(--sidebar-bg); border-right: 1px solid var(--divider-color); display: flex; flex-direction: column; overflow: hidden; transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); } #sidebar.collapsed { width: 0; border-right: none; } #sidebar.no-anim { transition: none; } .sidebar-header { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid var(--divider-color); font-size: 13px; font-weight: 600; color: var(--text-secondary); flex-shrink: 0; } .sidebar-header button { background: var(--btn-bg); border: 1px solid var(--header-border); border-radius: 6px; cursor: pointer; font-size: 16px; color: var(--text-secondary); width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; transition: all 0.2s; line-height: 1; } .sidebar-header button:hover { background: var(--accent-soft); color: var(--accent-color); border-color: var(--accent-color); } .sidebar-docs { flex: 1; overflow-y: auto; padding: 6px; } .sidebar-docs::-webkit-scrollbar { width: 4px; } .sidebar-docs::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 2px; } .sidebar-empty { text-align: center; color: var(--text-muted); font-size: 12px; padding: 20px 10px; } .doc-item { padding: 8px 10px; border-radius: 6px; cursor: pointer; transition: background 0.2s; position: relative; margin-bottom: 2px; } .doc-item:hover { background: var(--accent-soft); } .doc-item.active { background: var(--accent-medium); } .doc-item-title { font-size: 13px; color: var(--text-primary); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 20px; } .doc-item-time { font-size: 11px; color: var(--text-muted); margin-top: 2px; } .doc-item-delete { position: absolute; top: 50%; right: 6px; transform: translateY(-50%); width: 20px; height: 20px; border: none; background: transparent; color: var(--text-muted); cursor: pointer; border-radius: 4px; display: none; align-items: center; justify-content: center; font-size: 14px; line-height: 1; } .doc-item:hover .doc-item-delete { display: flex; } .doc-item-delete:hover { background: rgba(255, 99, 71, 0.15); color: #ff6347; } /* ── Splitter ── */ #splitter { width: 5px; flex-shrink: 0; cursor: col-resize; background: var(--divider-color); position: relative; z-index: 10; transition: background 0.2s; touch-action: none; } #splitter::after { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 3px; height: 32px; border-radius: 2px; background: var(--splitter-handle); transition: background 0.2s; } #splitter:hover::after, #splitter.dragging::after { background: var(--accent-color); } #splitter:hover, #splitter.dragging { background: rgba(74, 158, 255, 0.1); } /* ── Theme Selector ── */ .theme-selector { position: relative; } .theme-dropdown { display: none; position: absolute; top: calc(100% + 6px); right: 0; background: var(--header-bg); border: 1px solid var(--header-border); border-radius: 8px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%); padding: 4px; min-width: 100px; z-index: 200; } .theme-dropdown.show { display: flex; flex-direction: column; } .theme-dropdown button { background: transparent; border: none; color: var(--text-secondary); padding: 6px 14px; border-radius: 6px; cursor: pointer; font-size: 13px; text-align: left; transition: all 0.2s; white-space: nowrap; } .theme-dropdown button:hover { background: var(--accent-soft); color: var(--accent-color); } .theme-dropdown button.active { background: var(--accent-medium); color: var(--accent-color); font-weight: 500; } /* ── 夜间模式 ── */ body.night-mode { --text-primary: #e0e0e0; --text-secondary: #aaa; --text-muted: #777; --glass-bg: rgba(30, 30, 45, 0.55); --glass-border: rgba(60, 60, 80, 0.4); --header-bg: rgba(20, 20, 35, 0.88); --header-border: rgba(60, 60, 80, 0.35); --footer-bg: rgba(20, 20, 35, 0.88); --footer-border: rgba(60, 60, 80, 0.3); --divider-color: rgba(255, 255, 255, 0.06); --editor-bg: rgba(30, 30, 45, 0.72); --editor-text: #e0e0e0; --preview-bg: rgba(25, 25, 40, 0.6); --toolbar-bg: rgba(30, 30, 45, 0.65); --btn-bg: rgba(255, 255, 255, 0.08); --scrollbar-thumb: rgba(255, 255, 255, 0.15); --scrollbar-thumb-hover: rgba(255, 255, 255, 0.25); --splitter-handle: rgba(255, 255, 255, 0.15); --sidebar-bg: rgba(20, 20, 35, 0.85); background: linear-gradient(135deg, #0d1117 0%, #161b22 30%, #1a1a2e 70%, #0d1117 100%); background-attachment: fixed; } body.night-mode .markmap-node text { fill: #e0e0e0; } body.night-mode .markmap-link { stroke: rgba(255, 255, 255, 0.15); } /* ── 思维导图节点内图片尺寸 ── */ .markmap-node img { max-width: 200px; max-height: 150px; border-radius: 4px; object-fit: contain; } /* ── Preview ── */ #markmap-container { flex: 1; height: 100%; position: relative; background: var(--preview-bg); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); } #markmap { width: 100%; height: 100%; -webkit-user-select: none; -moz-user-select: none; user-select: none; } /* ── Footer ── */ footer { background: var(--footer-bg); color: var(--text-muted); text-align: center; padding: 6px 0; font-size: 11.5px; flex-shrink: 0; letter-spacing: 0.3px; -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%); border-top: 1px solid var(--footer-border); box-shadow: 0 -1px 6px rgba(0, 0, 0, 0.04); } /* ── Floating Toolbar ── */ .markmap-toolbar { position: absolute; bottom: 16px; right: 16px; display: flex; gap: 4px; z-index: 10000; background: var(--toolbar-bg); border: 1px solid var(--glass-border); border-radius: var(--radius); padding: 6px; box-shadow: var(--toolbar-shadow); -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%); } .markmap-btn { width: 32px; height: 32px; padding: 5px; background: transparent; border: none; border-radius: 7px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all var(--transition); color: var(--text-secondary); position: relative; } .markmap-btn::after { content: attr(data-tooltip); position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%) translateY(4px); background: rgba(40, 42, 60, 0.92); color: #fff; padding: 4px 10px; border-radius: 6px; font-size: 12px; font-weight: 500; white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity 0.2s ease, transform 0.2s ease; z-index: 10001; } .markmap-btn::before { content: ''; position: absolute; bottom: calc(100% + 3px); left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: rgba(40, 42, 60, 0.92); opacity: 0; transition: opacity 0.2s ease; pointer-events: none; } .markmap-btn:hover::after { opacity: 1; transform: translateX(-50%) translateY(0); } .markmap-btn:hover::before { opacity: 1; } .markmap-btn:hover { background: var(--accent-soft); color: var(--accent-color); transform: translateY(-1px); } .markmap-btn:active { transform: translateY(0); background: var(--accent-medium); } .markmap-btn svg { width: 18px; height: 18px; fill: currentColor; } /* 自动适应窗口激活状态 */ .markmap-btn.autofit-active { background: var(--accent-soft); color: var(--accent-color); } .markmap-btn.autofit-active::after { background: var(--accent-color); } .markmap-btn.autofit-active::before { border-top-color: var(--accent-color); } /* 激活状态脉冲指示点 */ .markmap-btn.autofit-active svg { animation: autofit-pulse 2s ease-in-out infinite; } @keyframes autofit-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } /* ── PDF 方向选择弹出菜单 ── */ .pdf-orientation-menu { background: var(--toolbar-bg); -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%); border: 1px solid var(--header-border); border-radius: 10px; box-shadow: var(--toolbar-shadow); padding: 4px; z-index: 10000; display: flex; flex-direction: column; gap: 2px; min-width: 140px; animation: pdfMenuFadeIn 0.15s ease-out; } @keyframes pdfMenuFadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } } .pdf-orientation-item { background: transparent; border: none; padding: 8px 12px; border-radius: 6px; cursor: pointer; display: flex; flex-direction: column; gap: 2px; text-align: left; transition: all 0.15s; } .pdf-orientation-item:hover { background: var(--accent-soft); } .pdf-orientation-label { font-size: 13px; font-weight: 500; color: var(--text-primary); } .pdf-orientation-desc { font-size: 11px; color: var(--text-muted); } /* ── Fullscreen ── */ body.fullscreen header, body.fullscreen footer, body.fullscreen #editor-container, body.fullscreen #splitter, body.fullscreen #sidebar { display: none !important; } body.fullscreen #markmap-container { position: fixed !important; top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important; width: 100vw !important; height: 100vh !important; z-index: 9999 !important; border: none !important; } body.fullscreen .markmap-toolbar { bottom: 24px; right: 24px; } /* ── 移动端响应式布局 ── */ /* 窄屏设备:编辑区在上,渲染区在下,纵向排列 */ @media (max-width: 768px) { /* Header:紧凑高度 */ header { height: 48px; padding: 0 10px; } header h1 { font-size: 15px; } .header-left { gap: 6px; } /* 日间/夜间按钮:常驻显示,缩小尺寸 */ #mode-toggle { padding: 5px 10px; font-size: 12px; } /* 工具栏:改为下拉浮层(用 header 前缀提升特异性,覆盖桌面端 header .toolbar) */ header .toolbar { display: none; position: absolute; top: 48px; right: 8px; flex-direction: column; background: var(--header-bg); border: 1px solid var(--header-border); border-radius: 10px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12); -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%); padding: 6px; gap: 2px; z-index: 200; min-width: 140px; } header .toolbar.show { display: flex; } header .toolbar button { width: 100%; text-align: left; padding: 10px 14px; font-size: 13px; border: none; background: transparent; border-radius: 8px; justify-content: flex-start; } header .toolbar button:hover { transform: none; box-shadow: none; } /* 主题选择器:下拉内联展开 */ .theme-selector .theme-dropdown { position: static; box-shadow: none; border: none; background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; padding: 0 0 0 12px; min-width: 0; } .theme-selector .theme-dropdown.show { display: flex; flex-direction: column; } .theme-dropdown button { padding: 8px 12px; font-size: 12px; } /* 显示移动端菜单按钮 */ #mobile-menu-btn { display: flex; padding: 6px; } /* 菜单打开时按钮激活态 */ #mobile-menu-btn.menu-active { background-color: var(--accent-soft); border-color: var(--accent-color); color: var(--accent-color); } .icon-btn { padding: 6px; } /* 移动端禁用 :hover 粘连,改用 JS 控制 active 状态 */ .icon-btn:hover, header .toolbar button:hover, #mode-toggle:hover { background-color: var(--btn-bg); border-color: var(--header-border); color: var(--text-secondary); transform: none; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04); } /* main 改为纵向排列 */ main { flex-direction: column; } /* 编辑区:上方,固定比例高度 */ #editor-container { width: 100% !important; height: 40%; flex-shrink: 0; } /* iOS 防止聚焦缩放:font-size 需 >= 16px */ #editor { font-size: 16px; padding: 12px 14px; } /* 分割线:改为水平方向 */ #splitter { width: 100%; height: 5px; cursor: row-resize; } #splitter::after { width: 32px; height: 3px; } /* 渲染区:下方,自动填充剩余空间 */ #markmap-container { flex: 1; min-height: 0; } /* 侧边栏:改为浮层覆盖 */ #sidebar { position: fixed; top: 48px; left: 0; bottom: 0; width: 240px; z-index: 500; box-shadow: 4px 0 16px rgba(0, 0, 0, 0.15); } #sidebar.collapsed { width: 0; border-right: none; box-shadow: none; } /* 底部浮动工具栏调整 */ .markmap-toolbar { bottom: 12px; right: 12px; } /* footer 隐藏,节省空间 */ footer { display: none; } }