InfoRadar / client /src /css /start.scss
dqy08's picture
更新主页标题和描述
7577ac0
// 单一数据源:断点定义(集中在 _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;
}
// 首页“了解更多”折叠区:将 <summary> 做成明显的 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