// 单一数据源:断点定义(集中在 _breakpoints.scss 中维护) @use "breakpoints" as *; // 样式模块(Sass 新模块系统) @use "violin"; @use "buttons"; @use "responsive"; @use "dialog"; @use "demo-list"; // CSS变量定义 - 日间模式(默认) :root { // 响应式断点变量(从单一数据源自动生成) --breakpoint-mobile: #{$breakpoint-mobile}; --breakpoint-tablet: #{$breakpoint-tablet}; // 基准字号(移动端在 _responsive.scss 中覆盖为 9pt) --font-size-base: 10pt; --bg-color: rgb(255, 255, 255); --text-color: #333; --text-muted: #777; --panel-bg: #fafafa; --border-color: #ddd; --button-bg: #f8f8f8; --button-hover-bg: #f0f0f0; --button-active-bg: #e8e8e8; --button-border: #d0d0d0; --button-text: #333; --input-bg: #fff; --input-border: #d0d0d0; --tooltip-bg: #dddddd; --resizer-bg: #f0f0f0; --resizer-hover: #999; --loading-overlay-bg: rgba(250, 250, 250, 0.5); --loading-spinner-border: #f3f3f3; --loading-spinner-top: #555; --text-action-btn-hover: rgba(0, 0, 0, 0.05); --refresh-btn-hover: #f5f5f5; --refresh-btn-color: #999; --hover-bg-color: #f0f0f0; // 菜单项悬浮背景色(日间模式) --bg-hover: #f5f5f5; // 弹窗内信息块/列表项背景(日间) --bg-hover-light: #f8f8f8; // 弹窗内列表项 hover(日间) --primary-color: #2196F3; // 主题色(链接、当前模型标题等) --text-disabled: #999; // 禁用态文本 --text-area-bg: #fff; // 文本显示区域背景色 --minimap-width: 8px; // minimap 宽度 --tooltip-text-normal: #333; // tooltip普通文本颜色 --tooltip-text-selected: #933; // tooltip选中文本颜色 --tooltip-text-detail: #666666; // tooltip详情文本颜色 --tooltip-text-value: #333; // tooltip数值文本颜色 --token-hover-shadow: rgba(42, 158, 255, 0.6); // token悬浮阴影颜色(日间模式) --token-hover-outline: #1e6fff; // token悬浮边框颜色 --bin-highlight-outline: #1e6fff; // bin高亮边框(保持与悬浮一致) --bin-highlight-shadow: rgba(30, 111, 255, 0.65); // bin高亮阴影 --avg-line-color: #8c8c8c; // 平均值参考线颜色(日间模式) --text-color-light: #c3c3c3; // 浅色文本颜色(主要用于夜间模式) } // 全局禁用横向滚动(通用样式) html { margin: 0; // 移除默认margin,消除底部空白 padding: 0; // 移除默认padding overflow-x: hidden; // 禁止横向滚动 width: 100%; max-width: 100vw; // 确保html不超过视口宽度 // 移动端:限制触摸滑动只能垂直方向 touch-action: pan-y; // 只允许垂直方向的触摸滑动 } // 基础主题:日间模式(默认) :root { color-scheme: light; } // 夜间模式变量 :root[data-theme="dark"] { color-scheme: dark; --bg-color: #191919; --text-color: var(--text-color-light); --text-muted: #888; --panel-bg: #2d2d2d; --border-color: #444; --button-bg: #353535; --button-hover-bg: #454545; --button-active-bg: #505050; --button-border: #555; --button-text: var(--text-color-light); --input-bg: #282828; --input-border: #555; --tooltip-bg: #3a3a3a; --resizer-bg: #2d2d2d; --resizer-hover: #666; --loading-overlay-bg: rgba(25, 25, 25, 0.7); --loading-spinner-border: #3a3a3a; --loading-spinner-top: #888; --text-action-btn-hover: rgba(255, 255, 255, 0.1); --refresh-btn-hover: #3a3a3a; --refresh-btn-color: #888; --hover-bg-color: #3a3a3a; // 菜单项悬浮背景色(夜间模式,更暗) --bg-hover: #2d2d2d; // 弹窗内信息块/列表项背景(夜间) --bg-hover-light: #353535; // 弹窗内列表项 hover(夜间) --primary-color: #5c8dff; // 主题色(夜间模式略亮) --text-disabled: #666; // 禁用态文本(夜间) --text-area-bg: #191919; // 夜间模式:文本显示区域背景色与主背景一致 --tooltip-text-normal: #ccc; // tooltip普通文本颜色(夜间模式) --tooltip-text-selected: #ff6666; // tooltip选中文本颜色(夜间模式,更亮的红色) --tooltip-text-detail: #888; // tooltip详情文本颜色(夜间模式) --tooltip-text-value: var(--text-color-light); // tooltip数值文本颜色(夜间模式) --token-hover-shadow: rgba(66, 165, 255, 0.8); // token悬浮阴影颜色(夜间模式,更亮更明显) --token-hover-outline: #5c8dff; // token悬浮边框颜色(夜间模式) --bin-highlight-outline: #5c8dff; // 夜间模式 bin 高亮边框 --bin-highlight-shadow: rgba(92, 141, 255, 0.8); // 夜间模式 bin 高亮阴影 --avg-line-color: #b0b0b0; // 平均值参考线颜色(夜间模式) // 夜间模式:LMF 区域使用 Light 字重(300) .LMF { font-weight: 300; // 使用 Light 字重,更细的字体 } } // Body 通用样式(所有屏幕尺寸共享) body { margin: 0; // 移除默认margin,消除底部空白 padding: 0; // 移除默认padding background-color: var(--bg-color); color: var(--text-color); // 使用系统字体栈:优先使用各平台最佳中英文字体 // macOS: PingFang SC, Windows: Microsoft YaHei, Linux: Noto Sans CJK SC font-family: -apple-system, // macOS/iOS 系统字体 "PingFang SC", // macOS 中文字体 "Hiragino Sans GB", // macOS 中文字体(旧版) "Microsoft YaHei", // Windows 中文字体 "WenQuanYi Micro Hei", // Linux 中文字体 "Noto Sans CJK SC", // Linux/通用中文字体 "Source Han Sans SC", // Adobe 思源黑体 sans-serif; // 通用无衬线字体 font-weight: 400; font-size: var(--font-size-base); transition: background-color 0.3s ease, color 0.3s ease; overflow-x: hidden; // 全局禁止横向滚动 width: 100%; max-width: 100vw; // 确保body不超过视口宽度 // 注意:height 和 min-height 已移至响应式媒体查询中 } a { color: inherit; } textarea{ font-family: inherit; width: 100%; height: 50px; // 可以保留默认高度 min-height: 50px; // 设置最小高度 max-height: 300px; // 设置最大高度限制,避免占用过多空间 box-sizing: border-box; resize: vertical; // 改为只允许垂直调整大小 background-color: var(--input-bg); color: var(--text-color); border: 1px solid var(--input-border); transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease; } .textarea-wrapper { width: 100%; box-sizing: border-box; // 确保宽度计算包含padding和border position: relative; textarea { width: 100%; box-sizing: border-box; // 确保textarea宽度计算正确 resize: vertical; // 修改这里:改为只允许垂直调整大小 } .textarea-counter { font-size: 8pt; color: var(--text-muted); white-space: nowrap; } .button-group { display: flex; justify-content: space-between; // Analyze在左,Save在右 align-items: center; width: 100%; margin-top: 5px; gap: 10px; box-sizing: border-box; // 确保宽度计算正确 flex-wrap: wrap; // 允许换行 .button-left { display: flex; align-items: center; gap: 10px; flex-shrink: 0; // 防止左侧按钮被压缩 position: relative; // 为绝对定位的进度消息提供定位上下文 } .button-right { display: flex; align-items: center; gap: 10px; flex-shrink: 0; // 防止右侧按钮被压缩 } .text-metrics { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 2px; font-size: 8pt; color: var(--text-muted); min-width: 150px; // 设置最小宽度,空间不够时会换行 min-height: 32px; transition: opacity 0.2s ease; } .text-metrics-primary { display: flex; align-items: center; justify-content: center; gap: 6px; flex-wrap: wrap; // 允许换行 text-align: center; max-width: 100%; // 确保不超过容器宽度 } .text-metrics-secondary { font-size: 8pt; color: var(--text-muted); text-align: center; } .text-metrics.is-hidden { visibility: hidden; opacity: 0; } .text-metrics-secondary.is-hidden { visibility: hidden; opacity: 0; } .text-metrics-divider { color: var(--text-muted); } } } // Clear 和 Paste 按钮容器 - 在文本框上方,右侧对齐 .text-action-buttons-top { display: flex; gap: 4px; // 按钮之间间距 align-items: center; .textarea-counter { font-size: 8pt; // 与text-metrics保持一致 color: var(--text-muted); // 与text-metrics保持一致 white-space: nowrap; margin-right: 8px; // 字数信息与Clear按钮之间的间距 } } // 按钮样式已移至 _buttons.scss #header { display: table; width: 100%; background-color: lightgray; height: 30px; } #headertext { display: table-cell; vertical-align: middle; text-align: center; font-size: 18px; font-family: 'Source Sans Pro', sans-serif; } svg { vertical-align: top; } select { font-size: 9pt; font-weight: 600; background-color: var(--input-bg); color: var(--text-color); padding: 8px 6px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; border-radius: 4px; border: 1px solid var(--input-border); outline: 0; transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease; } .slider { -webkit-appearance: none; width: 100px; height: 10px; border-radius: 5px; background: #d3d3d3; outline: none; opacity: 0.7; -webkit-transition: .2s; transition: opacity .2s; } .slider:hover { opacity: 1; } .slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 15px; height: 15px; border-radius: 50%; background: #666666; cursor: pointer; } #clear_highlight_btn { margin-top: 10px; padding: 4px 12px; font-size: 9pt; cursor: pointer; } .navbar { position: absolute; top: 0; left: 0; width: 100%; height: 50px; background-color: antiquewhite; } .navbarContent { margin: 10px 20px; span { padding-left: 10px; } button { margin-left: 10px; } } .navbarTitle { font-size: 12pt; font-weight: bold; } // 修改原有的floating_content样式 .floating_content { padding: 0; // 移除内边距,因为已经在left_panel中设置 margin: 0; width: 100%; // 使用100%宽度,自适应父容器 max-width: 100%; // 确保不超过父容器宽度 box-sizing: border-box; // 确保宽度计算包含padding和border } // 介绍区域样式 .intro-section { margin-bottom: 15px; p { margin: 8px 0; } } .intro-brief { font-size: 11pt; // 比 body 的 10pt 大一号 } .intro-brief .intro-token { background-color: rgba(var(--intro-rgb), var(--a, 0)); border-radius: 6px; } // 首页“了解更多”折叠区:将 做成明显的 CTA(避免像普通链接/原文样式) .intro-more { margin-top: 10px; } // 未展开:更小更窄、弱提示,贴右侧 .intro-section .intro-more:not([open]) { display: block; width: fit-content; } // 展开:恢复为完整信息块容器,占整行 .intro-more[open] { display: block; margin-left: 0; border: 1px solid var(--border-color); border-radius: 10px; background: var(--panel-bg); overflow: hidden; } .intro-more > summary { list-style: none; cursor: pointer; user-select: none; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 12px; font-weight: 500; border-radius: 10px; background: transparent; color: var(--text-muted); transition: background-color 0.15s ease, color 0.15s ease; &::-webkit-details-marker { display: none; } &::marker { content: ""; } &::after { content: "›"; font-size: 18px; line-height: 1; opacity: 0.45; transition: transform 0.15s ease, opacity 0.15s ease; } &:hover { background-color: var(--hover-bg-color); color: var(--text-color); } } .intro-more:not([open]) > summary { display: inline-flex; width: fit-content; padding: 4px 10px; gap: 6px; font-size: 9pt; border: 1px solid var(--border-color); border-radius: 10px; &::after { font-size: 16px; } } .intro-more[open] > summary { border-bottom-left-radius: 0; border-bottom-right-radius: 0; background: var(--button-bg); color: var(--text-color); &::after { transform: rotate(90deg); opacity: 0.85; } } // 首页“了解更多”折叠按钮文案:展开状态与折叠状态切换 .intro-more > summary .intro-summary-when-open { display: none; } .intro-more[open] > summary .intro-summary-when-closed { display: none; } .intro-more[open] > summary .intro-summary-when-open { display: inline; font-size: 90%; font-weight: 400; color: var(--text-muted); } .intro-more .intro-block { padding: 10px 12px; h4 { margin: 0 0 6px 0; font-size: 11pt; } pre { white-space: pre-wrap; // 保留空白,但允许换行 word-wrap: break-word; // 长单词换行 overflow-wrap: break-word; // 溢出时换行 overflow-x: auto; // 如果仍然溢出,显示横向滚动条 max-width: 100%; // 不超过容器宽度 margin: 8px 0; // 适当的上下间距 } } .intro-more .intro-block + .intro-block { border-top: 1px dashed var(--border-color); } // Demo 区域样式 .demo-section { margin-bottom: 15px; } // 输入区域样式 .input-section { margin-bottom: 15px; } // 结果区域样式 .results-section { margin-top: 20px; } .container { margin-right: auto; margin-left: auto; padding: 10pt; } #input { margin-right: 5px; float: left; width: calc(50% - 225px); height: 100%; } // ----- My own ----- // GLTR 文本容器样式,确保文本节点能正确显示和选中 // 基础样式(所有屏幕尺寸通用) .LMF { position: relative; // 相对定位,让内容自然扩展 user-select: text; -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; // 使用 pre-wrap 保留所有空格和换行符,确保输入文本和显示文本完全一致 white-space: pre-wrap; word-wrap: break-word; // 单独增大文本渲染区的字体大小 font-size: 12pt; // 比body的10pt大,使文本更易读 line-height: 1.5; // 白天模式使用默认字重(400),夜间模式使用 Light 字重(300) background-color: var(--text-area-bg); // 使用CSS变量控制背景色 color: var(--text-color); // 使用CSS变量控制文字颜色 transition: background-color 0.3s ease, color 0.3s ease; // 平滑过渡 // 确保至少350px高度以容纳tooltip(内容不足时生效) min-height: 350px; // 不设置固定padding-bottom,让内容自然决定高度 &.loading { // 添加轻微的脉冲动画效果 animation: textPulse 2s ease-in-out infinite; } } .token { display: inline; font-size: inherit; // 继承容器的字体大小 font-weight: 500; cursor: pointer; user-select: text; // 确保可以选中文本 // 使用 inline 而不是 inline-block,这样文本节点之间的空格和换行能正确显示 // line-height 和 vertical-align 使用默认值,确保所有字符对齐一致 border-radius: 6px; transition: box-shadow 0.15s ease, outline 0.15s ease; &:hover { // 增强的悬浮效果:不改变背景色(背景色是关键信息),使用边框和外发光 // 注意:不设置background-color,保持token原有的背景色(用于表示可预测性) box-shadow: 0 0 5px var(--token-hover-shadow), 0 0 9px var(--token-hover-shadow); // 外发光效果,增强可见性但更收敛 outline: 2px solid var(--token-hover-outline); // 更粗的边框,更明显 outline-offset: -2px; // 让outline紧贴元素边缘 position: relative; // 确保z-index生效 z-index: 2; // 确保悬浮元素在背景色之上 } // bin高亮样式 - 使用outline和box-shadow,确保显示在背景色之上 &.bin-highlighted { border-radius: 6px; // 使用实线勾勒无外发光 outline: 1.5px solid var(--bin-highlight-outline); outline-offset: -2px; box-shadow: none; position: relative; z-index: 1; } } // SVG覆盖层方案使用的样式 .svg-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; // 在文本下方 pointer-events: none; // 默认不拦截鼠标事件 // token group:当group hover时,其内部所有rect一起发光 g.token-group { pointer-events: auto; // group区域可交互 cursor: pointer; // 当group hover时,为所有rect添加蓝色描边(无发光) &:hover rect { // 发光效果已关闭(历史代码备份) // filter: // drop-shadow(0 0 2px rgba(30, 111, 255, 1)) // drop-shadow(0 0 5px rgba(30, 111, 255, 0.85)) // drop-shadow(0 0 10px rgba(30, 111, 255, 0.7)); stroke: rgba(30, 111, 255, 0.9); stroke-width: 2.5px; } // 如果group内的rect同时有bin-highlighted类,hover时也仅保留蓝色描边 &:hover rect.bin-highlighted { // 发光效果已关闭(历史代码备份) // filter: // drop-shadow(0 0 2px rgba(30, 111, 255, 1)) // drop-shadow(0 0 5px rgba(30, 111, 255, 0.85)) // drop-shadow(0 0 10px rgba(30, 111, 255, 0.7)); stroke: rgba(30, 111, 255, 0.9); stroke-width: 2.5px; } } rect { rx: 6px; ry: 6px; pointer-events: auto; // rect区域可交互 cursor: pointer; transition: fill-opacity 0.1s ease, stroke-opacity 0.15s ease, filter 0.15s ease, stroke 0.15s ease, stroke-width 0.15s ease; // Hover效果:保留蓝色描边,不使用发光 &.token-hovered { // 发光效果已关闭(历史代码备份) // 桌面端:叠加多层更强的霓虹效果,突出与蓝框一致的发光 // filter: // drop-shadow(0 0 2px rgba(30, 111, 255, 1)) // drop-shadow(0 0 5px rgba(30, 111, 255, 0.85)) // drop-shadow(0 0 10px rgba(30, 111, 255, 0.7)); // 移动端备用方案:使用 stroke 作为发光效果(iOS Safari filter 支持不佳) // 使用 2.5px 区分于 bin-highlighted 的 1.5px stroke: rgba(30, 111, 255, 0.9); stroke-width: 2.5px; } // 高亮效果 &.bin-highlighted { // 保持默认滤镜,避免与悬浮发光冲突 filter: none; // 注意:stroke 由 JavaScript 设置为 1.5px,这里不覆盖 } // 同时悬浮与高亮时:使用更粗的蓝色描边区分 &.token-hovered.bin-highlighted { // 发光效果已关闭(历史代码备份) // filter: // drop-shadow(0 0 2px rgba(30, 111, 255, 1)) // drop-shadow(0 0 5px rgba(30, 111, 255, 0.85)) // drop-shadow(0 0 10px rgba(30, 111, 255, 0.7)); // 覆盖 bin-highlighted 的 stroke,使用更粗的 stroke 表示同时悬浮 stroke: rgba(30, 111, 255, 0.9); stroke-width: 2.5px; } } } // 确保文本层在SVG上方 // 文本层样式 .text-layer { position: relative; z-index: 2; // 确保文本在SVG上方 pointer-events: none; // 允许事件穿透到SVG层,文本仍可选择 } // 文本区域加载遮罩层 .text-loading-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; min-height: 100%; // 确保至少覆盖整个容器高度 background: var(--loading-overlay-bg); display: flex; align-items: center; justify-content: center; z-index: 100; // 确保在文本内容之上 pointer-events: none; // 不阻止用户交互(虽然文本已显示) opacity: 0; transition: opacity 0.3s ease-in-out, background-color 0.3s ease; &.visible { opacity: 1; } .loading-content { display: flex; flex-direction: column; align-items: center; gap: 10px; color: var(--text-color); font-size: 12pt; .loading-spinner { width: 60px; // 从24px增大到60px height: 60px; border: 4px solid var(--loading-spinner-border); border-top: 4px solid var(--loading-spinner-top); border-radius: 50%; animation: spin 1s linear infinite; } } } // 文本脉冲动画 @keyframes textPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.85; } } .tooltip { font-size: 9pt; font-weight: 500; border-radius: 5px; padding: 5px; background: var(--tooltip-bg); color: var(--text-color); transition-property: opacity, background-color, color; transition-duration: .2s; position: absolute; // 相对于 #results 容器定位,与文本区域使用相同的坐标系统 z-index: 101; // Tooltip 层级,在模态框之上 pointer-events: auto; // 允许接收点击事件 cursor: pointer; // 添加指针样式,提示可点击 } // 当前token显示区域,使用等宽字体以便分辨连续的␣ // 借鉴系统等宽字体栈,优先使用各平台最佳等宽字体 .currentToken { font-family: "SF Mono", // macOS 系统等宽字体(最佳) "Menlo", // macOS 等宽字体(旧版) "Monaco", // macOS 等宽字体(经典) "Consolas", // Windows 等宽字体(最佳) "Liberation Mono", // Linux 等宽字体 "DejaVu Sans Mono", // Linux 等宽字体(备选) "Courier New", // 通用等宽字体(备选) monospace; // 通用等宽字体回退 font-size: 9pt; // 与 tooltip 保持一致 margin-bottom: 4px; // 与下方内容保持间距 line-height: 1.4; // 适当的行高 } // 候选列表也使用等宽字体,与当前token保持一致,以便分辨连续的␣ .predictions { .row { font-family: "SF Mono", // macOS 系统等宽字体(最佳) "Menlo", // macOS 等宽字体(旧版) "Monaco", // macOS 等宽字体(经典) "Consolas", // Windows 等宽字体(最佳) "Liberation Mono", // Linux 等宽字体 "DejaVu Sans Mono", // Linux 等宽字体(备选) "Courier New", // 通用等宽字体(备选) monospace; // 通用等宽字体回退 } } // 首页demo列表特有样式 - 公共样式已移至 _demo-list.scss .demos { height: 150px; // 首页固定高度 } // 多选模式相关样式 - 紧凑型设计 // 路径导航器包装器,支持换行 .demo-path-nav-wrapper { flex-wrap: wrap; // 允许换行 row-gap: 4px; // 行之间的间距 min-height: 28px; // 与 refresh-btn 高度保持一致(无按钮时也占满高度) align-items: center; // 确保文字在这 28px 内垂直居中 } // 路径导航文字区域:提高行高,使其与按钮高度一致 .demo-path-navigator { line-height: 28px; // 与 .refresh-btn 的 height 对齐 } // 多选控制栏(在多选切换按钮的左边) .demo-multiselect-bar-center { display: flex; align-items: center; gap: 4px; // 减少30%:6px → 4px flex-wrap: nowrap; background-color: var(--panel-bg, transparent); padding: 1px 6px; // 减少30%:2px 8px → 1px 6px border-radius: 4px; margin-right: 4px; // 与多选切换按钮之间的间距 width: fit-content; // 只占据内容宽度,不占满 flex-shrink: 0; // 防止被压缩 .multiselect-count { font-size: 9pt; color: var(--text-muted); white-space: nowrap; } // 控制栏中的按钮使用refresh-btn样式,但可以调整文字大小 .refresh-btn { font-size: 9pt; padding: 1px 6px; // 减少30%:2px 8px → 1px 6px min-width: auto; height: auto; white-space: nowrap; &.inactive { opacity: 0.5; cursor: not-allowed; pointer-events: none; } // 可用状态时颜色加深 &:not(.inactive) { color: var(--text-color, #333); font-weight: 500; &:hover { color: var(--primary-color, #3b82f6); } } } } // 内联复选框(在demo名左侧,不影响行距) .demo-checkbox-inline { cursor: pointer; margin-right: 1px; // 减小间距,让复选框更贴近demo项 width: 14px; height: 14px; // 使用middle对齐,让复选框垂直居中 vertical-align: middle; // 确保复选框不会影响行距 display: inline-block; // 微调位置,确保完全居中 margin-top: 0; margin-bottom: 0; // 确保复选框在demo-item的最左边 flex-shrink: 0; order: -1; // 确保复选框在最左边 } // 日间模式和夜间模式下的复选框样式 .demo-checkbox-inline { // 移除默认样式,使用自定义样式 appearance: none; -webkit-appearance: none; -moz-appearance: none; // 设置复选框背景为透明,露出底下的颜色 background-color: transparent; border: 1px solid var(--text-muted, #888); border-radius: 2px; // 选中状态下的样式 &:checked { background-color: var(--primary-color, #3b82f6); // 选中时使用主题色背景 border-color: var(--primary-color, #3b82f6); // 添加选中标记(对勾) background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M2 6l3 3 5-5'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: center; background-size: 10px 10px; } // 悬停状态 &:hover:not(:disabled) { border-color: var(--text-color, #333); } // 聚焦状态 &:focus:not(:disabled) { outline: 1px solid var(--primary-color, #3b82f6); outline-offset: 1px; } // disabled状态:与不可选的demo项颜色一致,无hover效果 &:disabled { opacity: 0.3; cursor: not-allowed; pointer-events: none; // 禁用所有鼠标交互,包括hover } } // 夜间模式下的复选框样式调整 :root[data-theme="dark"] { .demo-checkbox-inline { // 悬停状态(夜间模式) &:hover:not(:disabled) { border-color: var(--text-color, var(--text-color-light)); } } } .demo-delete-btn { background: transparent !important; border: none !important; color: var(--text-color); cursor: pointer; font-size: 16px; line-height: 1; padding: 0 4px; opacity: 0.6; transition: opacity 0.2s; flex-shrink: 0; // 防止按钮被压缩 &:hover { opacity: 1; color: var(--error-color, #e74c3c); // 如果定义了错误颜色变量则使用,否则使用默认红色 } } .loadersmall { display: inline-block; border: 3px solid var(--loading-spinner-border); -webkit-animation: spin 1s linear infinite; animation: spin 1s linear infinite; border-top: 3px solid var(--loading-spinner-top); border-radius: 50%; width: 10px; height: 10px; transition: border-color 0.3s ease; flex-shrink: 0; // 防止在flex布局中被压缩 } // 分析进度显示样式 .analyze-progress { display: none; // 默认隐藏 font-size: 9pt; color: var(--text-muted, #666); white-space: nowrap; line-height: 1.2; position: absolute; // 绝对定位,不占用正常布局空间 left: 100%; // 定位在button-left的右侧 margin-left: 30px; // loader宽度(10px) + loader的margin(10px) + 额外间距(10px) z-index: 10; // 确保在上层显示 // 夜间模式下的颜色 :root[data-theme="dark"] & { color: var(--text-muted, #999); } } // 加载器容器样式 #loader { top: 0px; opacity: 1; transition-property: opacity; transition-duration: 0.5s; } // 主框架样式 .main_frame { opacity: 1; transition-property: opacity; transition-duration: 1s; } // 首页顶部工具栏(类似比较页的外观) .dark-mode-toggle-wrapper { padding: 10px 20px; margin: 0 -20px 10px -20px; // 负margin抵消left_panel的padding,让toolbar占满宽度,顶部保留避免被遮挡 // 添加安全区域支持(iOS刘海屏等),适用于所有设备 padding-top: max(10px, env(safe-area-inset-top)); border-bottom: 1px solid var(--border-color); display: flex; align-items: center; gap: 10px; background-color: var(--bg-color); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); box-sizing: border-box; flex-wrap: wrap; row-gap: 6px; transition: background-color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease; } .home-toolbar-title { margin: 0; font-size: 20px; // 比原 18px 大一号 font-weight: 600; line-height: 1.2; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; white-space: normal; overflow: visible; flex: 1 1 320px; .title-main-line { white-space: nowrap; } .title-tagline { font-size: 18px; font-weight: 400; margin-left: 1em; } .title-formula { font-size: 10px; font-weight: 400; color: var(--text-muted); opacity: 0.75; font-style: italic; } } .home-toolbar-actions { display: flex; align-items: center; justify-content: flex-end; gap: 10px; flex: 0 0 auto; margin-left: auto; // 始终靠右,包括换行到新行时 } // 语言切换按钮样式 .language-toggle-btn { padding: 4px 10px; border: 1px solid var(--button-border); background: var(--button-bg); color: var(--button-text); border-radius: 4px; cursor: pointer; font-size: 13px; transition: background-color 0.2s, border-color 0.2s; &:hover { background-color: var(--button-hover-bg); } &:active { background-color: var(--button-active-bg); } } // 设置菜单样式 .settings-menu-wrapper { position: relative; display: inline-block; } .settings-btn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; border: 1px solid var(--border-color); border-radius: 4px; background: var(--button-bg); color: var(--text-color); cursor: pointer; font-size: 14px; line-height: 1; transition: background-color 0.2s ease, border-color 0.2s ease; .settings-icon { font-size: 16px; line-height: 1; } &:hover { background-color: var(--button-hover-bg); } &:active { background-color: var(--button-active-bg); } } .settings-menu { position: absolute; top: 100%; right: 0; margin-top: 4px; background: var(--button-bg); border: 1px solid var(--border-color); border-radius: 4px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); z-index: 1000; width: max-content; min-width: 180px; } .settings-menu-item { padding: 8px 12px; box-sizing: border-box; } .settings-menu-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; } .settings-menu-label { white-space: nowrap; flex-shrink: 0; } .settings-menu-control { flex-shrink: 0; } .settings-menu-checkbox input[type="checkbox"] { cursor: pointer; margin: 0; } .settings-menu-btn { padding: 4px 8px; border: 1px solid var(--border-color); border-radius: 4px; background: var(--button-bg); color: var(--text-color); cursor: pointer; font-size: inherit; white-space: nowrap; transition: background-color 0.2s ease; &:hover { background-color: var(--button-hover-bg); } &:active { background-color: var(--button-active-bg); } } .settings-menu-divider { height: 1px; background-color: var(--border-color); margin: 4px 0; } // 设置下拉菜单共用样式(Theme/Language/Token render style 等,通过 settings-dropdown-* 共享) #dark_mode_toggle, .settings-dropdown-in-menu { padding: 0; border: none; background: transparent; cursor: pointer; .settings-dropdown { position: relative; display: inline-block; .settings-dropdown-btn { display: flex; align-items: center; gap: 6px; padding: 4px 8px; border: 1px solid var(--border-color); border-radius: 4px; background: var(--button-bg); color: var(--text-color); cursor: pointer; font-size: inherit; font-family: inherit; transition: background-color 0.2s ease, border-color 0.2s ease; white-space: nowrap; &:hover { background-color: var(--button-hover-bg); } &.active { background-color: var(--button-hover-bg); border-color: var(--button-border); } &:active { background-color: var(--button-active-bg); } } .settings-dropdown-menu { position: absolute; top: 100%; left: 0; margin-top: 4px; min-width: 100%; width: max-content; box-sizing: border-box; background: var(--panel-bg); border: 1px solid var(--border-color); border-radius: 4px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); z-index: 1001; opacity: 0; visibility: hidden; transform: translateY(-10px); transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease; pointer-events: none; overflow: hidden; &.open { opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto; } .settings-dropdown-option { display: flex; align-items: center; gap: 6px; width: 100%; padding: 8px 12px; border: none; background: transparent; color: var(--text-color); cursor: pointer; font-size: inherit; font-family: inherit; text-align: left; transition: background-color 0.2s ease; white-space: nowrap; &:hover { background-color: var(--hover-bg-color); } &.active { background-color: var(--hover-bg-color); font-weight: 500; cursor: not-allowed; pointer-events: none; opacity: 0.5; } &:first-child { border-radius: 4px 4px 0 0; } &:last-child { border-radius: 0 0 4px 4px; } &:only-child { border-radius: 4px; } } } } } // 设置菜单内下拉按钮更紧凑 .settings-menu .settings-dropdown-btn { padding: 2px 6px; font-size: inherit; } :root[data-theme="dark"] { #dark_mode_toggle .settings-dropdown-menu, .settings-dropdown-in-menu .settings-dropdown-menu { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); } } // Demo 标题区域 .demo-header { font-weight: bold; display: flex; align-items: center; gap: 5px; } // 文件输入组件样式(模拟原生文件输入框) .file-input-wrapper { display: inline-flex; align-items: stretch; border: 1px solid var(--input-border); border-radius: 4px; background-color: var(--input-bg); overflow: visible; // 允许内容换行时显示 font-size: 9pt; // 移除 min-height,让高度由内部按钮的 padding 决定,与其他按钮保持一致 .file-input-button { // 继承通用按钮样式,仅收紧 padding 和结构 padding: 3px 8px; border-radius: 0; border-right: 1px solid var(--input-border); white-space: nowrap; display: inline-flex; align-items: center; } // 夜间模式下的按钮样式 :root[data-theme="dark"] & { .file-input-button { background-color: #3a3a3a; color: var(--text-color); &:hover { background-color: #4a4a4a; } &:active { background-color: #505050; } } } .file-input-filename { padding: 3px 2px; color: var(--text-muted); overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; max-width: 200px; // 限制文件名显示的最大宽度 min-width: 100px; // 最小宽度 font-size: clamp(7pt, 2vw, 9pt); // 响应式字体大小,空间不足时自动缩小 display: flex; align-items: center; justify-content: center; // 水平居中文本 text-align: center; // 多行时仍保持居中 flex: 1; // 允许文件名区域占据剩余空间 line-height: 1.3; // 设置行高以支持多行显示 } } // Demo 加载提示 .demos-loading { display: none; color: #666; font-size: 9pt; margin-left: 5px; } // 输入文本标题区域 .input-header { padding-top: 10px; display: flex; align-items: center; justify-content: space-between; gap: 5px; } // 加载器小图标容器 .loader-small-container { position: absolute; // 绝对定位,不占用正常布局空间 left: 100%; // 定位在button-left的右侧 margin-left: 10px; // 与左侧元素保持间距 z-index: 10; // 确保在上层显示 } // 统计图容器 .stats-container { text-align: center; } // 直方图项目 .histogram-item { display: block; text-align: center; margin-bottom: 20px; } // Tooltip 基础样式 #major_tooltip { position: absolute; pointer-events: none; opacity: 0; } // 窄屏下 tooltip 使用 fixed 定位,空间不足时可叠加在 left_panel 上 @media (max-width: $breakpoint-mobile) { #major_tooltip { position: fixed; } } // 预测表格样式 .predictions-table { display: table; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } #all_result{ display: flex; flex-flow: column; width: 100%; // 确保宽度为100%,自适应父容器 max-width: 100%; // 确保不超过父容器宽度 box-sizing: border-box; // 确保宽度计算正确 opacity: 0; transition-duration: 0.5s; margin-top: 20px; } // 统计图容器样式(桌面端和移动端通用) #stats { width: 100%; // 确保宽度为100%,自适应父容器 max-width: 100%; // 确保不超过父容器宽度 box-sizing: border-box; // 确保宽度计算正确 padding: 0; // 移除默认padding,由内部元素控制间距 svg { max-width: 100%; // SVG最大宽度不超过容器 box-sizing: border-box; // 确保宽度计算正确 } } // Toast通知样式 .toast { position: fixed; top: 20px; right: 20px; background-color: var(--panel-bg); color: var(--text-color); padding: 12px 20px; border-radius: 4px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); z-index: 102; // Toast 通知层级,最高层 opacity: 0; transform: translateY(-20px); transition: opacity 0.3s ease, transform 0.3s ease; pointer-events: none; max-width: 300px; word-wrap: break-word; border: 1px solid var(--border-color); &.show { opacity: 1; transform: translateY(0); } &.success { border-left: 4px solid #4caf50; } &.error { border-left: 4px solid #f44336; } } // 响应式样式已移至 _responsive.scss // 对比页面样式已移至 compare.scss