/* DevFlow 设置统一组件库(UX 重构阶段1) 各 Panel scoped 副本抽取到全局,消除 panel/setting 系列/toggle/btn 5/5+3/5 重复。 来源基准:GeneralPanel/KnowledgePanel scoped(已确认 CSS 一致)。 各 Panel scoped 仅保留特有样式:provider-card/dir-row/connection-card 等。 */ /* ===== 面板容器(5/5 Panel 重复) ===== */ .panel { background: var(--df-bg-card); border: 0.5px solid var(--df-border); border-radius: var(--df-radius-lg); padding: var(--df-pad-panel); } .panel-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--df-gap-head); } .panel-header h2 { font-size: 15px; font-weight: 500; } /* ===== 设置行容器(表单型 Panel 共用) ===== */ .general-settings { display: flex; flex-direction: column; } /* 窄列(设置抽屉/面板窄态)三防线:gap 隔开 info 与 control;info min-width:0 允许收缩、 label/desc 文本按常规断行(多词换行,不逐字竖排);control 不被压缩挤扁 */ .setting-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 14px 0; border-bottom: 0.5px solid var(--df-border); } .setting-row:last-child { border-bottom: none; } .setting-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; } .setting-label { font-size: 14px; font-weight: 500; color: var(--df-text); } .setting-desc { font-size: 12px; color: var(--df-text-dim); } .setting-control { display: flex; align-items: center; flex-shrink: 0; } /* ===== 控件(5/5 Panel 重复) ===== */ /* 控件统一基准(padding/border/radius/font 对齐),各 type 仅差异化必要属性 */ .setting-select { padding: 6px 12px; background: var(--df-bg); border: 0.5px solid var(--df-border); border-radius: var(--df-radius-sm); color: var(--df-text); font-size: 13px; outline: none; cursor: pointer; min-width: 160px; } .setting-select:focus { border-color: var(--df-accent); } /* number input:窄,无 spinner 累赘外观,继承基准样式 */ .setting-number { padding: 6px 12px; background: var(--df-bg); border: 0.5px solid var(--df-border); border-radius: var(--df-radius-sm); color: var(--df-text); font-size: 13px; font-family: inherit; outline: none; cursor: pointer; min-width: 80px; } .setting-number:focus { border-color: var(--df-accent); } /* 隐藏原生数字加减箭头(与文本框视觉统一;注释声明无 spinner 但此前漏了实现) */ .setting-number::-webkit-outer-spin-button, .setting-number::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } .setting-number { -moz-appearance: textfield; appearance: textfield; } /* text input:通用单行文本(目录/模型名/脚本名单) */ .setting-input { padding: 6px 12px; background: var(--df-bg); border: 0.5px solid var(--df-border); border-radius: var(--df-radius-sm); color: var(--df-text); font-size: 13px; font-family: inherit; outline: none; min-width: 160px; } .setting-input:focus { border-color: var(--df-accent); } .setting-input::placeholder { color: var(--df-text-dim); } /* textarea:多行(自定义提示词等),垂直拉伸 */ .setting-textarea { width: 100%; padding: 8px 12px; background: var(--df-bg); border: 0.5px solid var(--df-border); border-radius: var(--df-radius-sm); color: var(--df-text); font-size: 13px; font-family: inherit; line-height: 1.5; outline: none; resize: vertical; min-height: 80px; box-sizing: border-box; } .setting-textarea:focus { border-color: var(--df-accent); } .setting-textarea::placeholder { color: var(--df-text-dim); } /* Toggle(3/5 Panel 重复) */ .toggle { position: relative; display: inline-block; width: 40px; height: 22px; cursor: pointer; } .toggle input { opacity: 0; width: 0; height: 0; } /* 键盘聚焦可见环:原生 checkbox 被 opacity:0+零尺寸隐藏,global.css 的 :focus-visible 兜底 画在零尺寸 input 上不可见;把聚焦态转移到可见的 slider。用 :focus-visible(非 :focus-within) 保证鼠标点击不显环、仅 Tab 键盘导航出现;.toggle--sm 变体同匹配(.toggle 前缀)。 :focus{border-color} 仅覆盖 setting-select/input 等可见输入,覆盖不到这种视觉隐藏 checkbox。 */ .toggle input:focus-visible + .toggle-slider { outline: 2px solid var(--df-accent); outline-offset: 2px; } .toggle-slider { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: var(--df-border); border-radius: var(--df-radius-lg); transition: background 0.2s; } .toggle-slider::before { content: ''; position: absolute; width: 16px; height: 16px; left: 3px; bottom: 3px; background: var(--df-text-dim); border-radius: 50%; transition: transform 0.2s, background 0.2s; } .toggle input:checked + .toggle-slider { background: var(--df-accent); } .toggle input:checked + .toggle-slider::before { transform: translateX(18px); background: #fff; } /* ===== 按钮(原 Settings.vue,列表型 Panel 共用) ===== */ .btn { padding: 8px 16px; border: none; border-radius: var(--df-radius-sm); font-size: 13px; cursor: pointer; transition: background 0.15s, color 0.15s; } .btn-primary { background: var(--df-accent); color: #fff; } .btn-primary:hover { background: var(--df-accent-hover); } .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; } .btn-ghost { background: transparent; color: var(--df-text-secondary); border: 0.5px solid var(--df-border); } .btn-ghost:hover { background: var(--df-bg-card); color: var(--df-text); } .btn-ghost:disabled { opacity: 0.5; cursor: not-allowed; } .btn-sm { padding: 4px 12px; font-size: 12px; } /* ===== 空提示(列表型 Panel 共用) ===== */ .empty-hint { color: var(--df-text-dim); font-size: 13px; padding: 16px 0; text-align: center; }