diff --git a/ui/css/style.css b/ui/css/style.css index 55a41b2..6c2a8ba 100644 --- a/ui/css/style.css +++ b/ui/css/style.css @@ -150,6 +150,9 @@ body { } .btn-primary:hover { background: color-mix(in oklch, var(--accent) 86%, var(--fg)); } .btn-ghost { background: transparent; } +/* 次级按钮(原型 .btn-secondary):透明底 + 描边,hover 转 accent 边与柔和底 */ +.btn-secondary { background: transparent; color: var(--text); } +.btn-secondary:hover { border-color: color-mix(in oklch, var(--accent) 55%, var(--border)); background: var(--accent-soft); } .btn-danger { background: transparent; border-color: transparent; @@ -157,6 +160,8 @@ body { } .btn-danger:hover { background: var(--danger-soft); border-color: var(--danger); } .btn-block { width: 100%; } +/* 小尺寸按钮(原型 .btn-sm):侧边栏退出登录等紧凑位置使用 */ +.btn-sm { padding: 5px 11px; font-size: 12.5px; } .btn:disabled { opacity: .5; cursor: not-allowed; pointer-events: none; } /* 按钮按压反馈(rant 18:06:09 E::active 轻微下压;disabled 不触发) */ .btn:active:not(:disabled) { transform: scale(0.98); } @@ -334,23 +339,9 @@ select.input option { background: var(--bg-card); } gap: 14px; margin-bottom: 4px; } -.stat { - background: var(--bg-card); - border: 1px solid var(--border); - border-radius: var(--radius); - padding: 16px 18px; - transition: transform .15s ease, border-color .18s ease, box-shadow .18s ease; -} -/* 统计卡 hover 微抬升(rant 18:06:09 E) */ -.stat:hover { - transform: translateY(-2px); - border-color: var(--card-hover-border); - box-shadow: var(--card-shadow); -} -.stat .label { color: var(--text-mute); font-size: 12px; } -.stat .value { font-size: 24px; font-weight: 700; margin-top: 4px; } -.stat .sub { color: var(--text-dim); font-size: 12px; } -.stat.accent .value { color: var(--accent-text); } +/* 统计卡(rant 18:06:09 E hover 微抬升)——原型 .stat-card 为规范名, + 定义见本节末尾「通用组件层」;此处保留 .sub 副说明的历史写法 */ +.stat-card .sub { color: var(--text-dim); font-size: 12px; } /* 交易汇总条(rant 20:39:30 B:紧凑 inline 条,随 tab/筛选联动) */ .tx-summary { display: flex; flex-wrap: wrap; gap: 28px; padding: 12px 16px 10px; border-bottom: 1px solid var(--border); } @@ -438,6 +429,8 @@ select.input option { background: var(--bg-card); } .density-options .check { display: flex; align-items: center; gap: 6px; flex-direction: row; color: var(--text-dim); font-size: 13px; cursor: pointer; } .density-options input { accent-color: var(--accent); } +/* 状态徽标:规范类为原型 .pill-* / .tag(定义见「通用组件层」), + .badge 保留为兼容别名(带语义色点),外部/历史标记仍可直接使用 */ .badge { display: inline-flex; align-items: center; @@ -464,9 +457,13 @@ select.input option { background: var(--bg-card); } .toolbar .input { max-width: 240px; } .toolbar-count { align-self: center; color: var(--text-mute); font-size: 12px; margin-left: auto; } -/* 搜索增强(rant 18:06:09 D:清空 × 按钮 + 关键词高亮) */ -.search-box { position: relative; display: block; } -.search-box .input { padding-right: 30px; } +/* 搜索增强(rant 18:06:09 D:清空 × 按钮 + 关键词高亮; + rant 2026-09-11T16:23:43:类名对齐原型 .search) */ +.search { position: relative; display: block; } +.search .input { padding-right: 30px; } +/* 工具栏内搜索框按原型弹性伸缩(原型 .toolbar .search) */ +.toolbar .search { flex: 1; min-width: 180px; max-width: 320px; } +.toolbar .search .input { max-width: none; } .search-clear { position: absolute; right: 6px; @@ -619,13 +616,7 @@ mark { .mini-item.net .t { color: var(--accent-text); } .bar-list { display: flex; flex-direction: column; gap: 12px; } -.bar-row .bar-label { display: flex; justify-content: space-between; font-size: 13px; margin-bottom: 4px; } -.bar-row .bar-label .n { color: var(--text-mute); } -.bar { - height: 8px; border-radius: 999px; - background: var(--bg-hover); overflow: hidden; -} -.bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent), color-mix(in oklch, var(--accent) 55%, var(--ok))); border-radius: 999px; } +.bar-row .bar-top .n { color: var(--text-mute); } /* 空状态(rant 15:50:05 A.4:图标 + 文案 + 可选行动按钮) */ .empty-state { @@ -1029,6 +1020,144 @@ mark { } @keyframes spin { to { transform: rotate(360deg); } } +/* ============================================================ + 通用组件层(rant 2026-09-11T16:23:43 第三节) + 原型 docs/prototype/aitokenpool-console.html 的可复用类在此落成, + PR4–PR6 的视图只需组装、不再各自发明样式。 + 命名对齐原型(pill/tag/stat-card/trend/bar-track…), + 线上历史类名保留兼容别名,避免同一次改动里做 DOM 迁移。 + ============================================================ */ + +/* ---- 徽标 / 标签 ---- */ +/* 原型 .pill 系列:无描边、柔和底色、等宽字体(状态类徽标的新形态) */ +.pill { + display: inline-flex; align-items: center; gap: 5px; + padding: 2px 9px; border-radius: 999px; + font-size: 11.5px; font-weight: 600; + font-family: var(--font-mono); letter-spacing: .03em; +} +.pill-ok { background: var(--ok-soft); color: var(--ok); } +.pill-warn { background: var(--warn-soft); color: var(--warn); } +.pill-danger { background: var(--danger-soft); color: var(--danger); } +.pill-muted { background: var(--fg-soft); color: var(--muted); } +.pill-accent { background: var(--accent-soft); color: var(--accent); } + +/* 原型 .tag 系列:细描边胶囊,用于能力/属性标注(旗舰 / 推理 / 读图…) */ +.tag { + display: inline-flex; align-items: center; + padding: 2px 9px; border: 1px solid var(--border); + border-radius: 999px; font-size: 11.5px; color: var(--muted); +} +.tag-accent { border-color: color-mix(in oklch, var(--accent) 45%, var(--border)); color: var(--accent); } + +/* ---- 卡片 / 栅格 ---- */ +/* card-sub:卡片标题下的副说明(原型 .card .card-sub) */ +.card-sub { color: var(--muted); font-size: 12.5px; margin-bottom: 14px; } +/* spread:标题左 / 动作右的一行(原型 .spread) */ +.spread { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; } +/* 三等分栅格 + 主次分栏(原型 .card-grid-3 / .split) */ +.card-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 16px; } +.split { display: grid; grid-template-columns: 1.6fr 1fr; gap: 16px; align-items: start; margin-top: 16px; } +/* 栅格内卡片不再堆叠外边距(原型同名规则) */ +.split > .card + .card, .card-grid > .card + .card, .card-grid-3 > .card + .card { margin-top: 0; } + +/* stat-card:原型统计卡(等宽大数值 + 单位 + 可选 delta); + 作为 .stat 的别名提供,供 PR4–PR6 直接按原型类名书写 */ +.stat-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 16px 18px; + transition: transform .15s ease, border-color .18s ease, box-shadow .18s ease; +} +.stat-card:hover { transform: translateY(-2px); border-color: var(--card-hover-border); box-shadow: var(--card-shadow); } +.stat-card .label { font-size: 12px; color: var(--text-mute); display: flex; align-items: center; gap: 6px; } +.stat-card .value { + font-family: var(--font-mono); font-variant-numeric: tabular-nums; + font-size: 24px; font-weight: 700; line-height: 1.15; margin-top: 4px; +} +.stat-card .value .unit { font-size: 13px; color: var(--text-mute); margin-left: 4px; } +.stat-card .delta { font-size: 11.5px; font-family: var(--font-mono); } +.stat-card .delta.ok { color: var(--ok); } +.stat-card .delta.danger { color: var(--danger-text); } +.stat-card.accent .value { color: var(--accent-text); } +.stat-card.accent { + border-color: color-mix(in oklch, var(--accent) 40%, var(--border)); + background: linear-gradient(180deg, var(--accent-soft), transparent 70%), var(--bg-card); +} + +/* ---- 表格 ---- */ +/* table.dt:原型数据表——等宽大写表头 + 单位数右对齐(.table 的结构化别名) */ +table.dt { width: 100%; border-collapse: collapse; font-size: 13px; } +table.dt th, table.dt td { padding: 11px 14px; text-align: left; border-bottom: 1px solid var(--table-row-border); white-space: nowrap; } +table.dt thead th { + font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .06em; + text-transform: uppercase; color: var(--text-mute); font-weight: 500; +} +table.dt tbody tr:nth-child(even) { background: var(--table-stripe); } +table.dt tbody tr:hover { background: var(--bg-hover); } +table.dt tbody tr:last-child td { border-bottom: 0; } +table.dt td.num, table.dt th.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; } +/* 厂商/模型合并单元格(原型 .provider-cell + .model-name + .dot) */ +.provider-cell { display: flex; align-items: center; gap: 9px; } +.model-name { font-family: var(--mono); font-size: 12.5px; } +.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex: none; } +.dot.muted { background: var(--muted); } + +/* ---- 工具栏 / 搜索 ---- */ +/* .search 的原型定位规则见上方「搜索增强」(线上既有实现即原型形态) */ +.toolbar .grow { flex: 1; } + +/* ---- 表单 ---- */ +/* label.f:原型表单标签(纵向 label + 说明文字) */ +.form label.f { display: flex; flex-direction: column; gap: 6px; font-size: 12.5px; color: var(--text-dim); } +/* 文本域沿用输入框外观(原型 input.i/select.i/textarea.i) */ +textarea.input { resize: vertical; min-height: 76px; } +textarea.input:focus { border-color: var(--accent); } +/* check-line:整行复选(原型 .check-line);.checkbox-line / .checkbox 为其线上历史别名 */ +.check-line { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text); } +.check-line input { accent-color: var(--accent); width: 15px; height: 15px; } +.checkbox, .checkbox-line { flex-direction: row !important; align-items: center; gap: 8px; } +.checkbox input, .checkbox-line input { accent-color: var(--accent); width: 14px; height: 14px; } +/* 交易页自定义时间段的 datetime-local 输入:与 .input 同观感 */ +.tx-range-input { + background: var(--bg-soft); border: 1px solid var(--border); color: var(--text); + border-radius: var(--radius-sm); padding: 8px 12px; font-size: 13px; outline: none; + max-width: 210px; +} +.tx-range-input:focus { border-color: var(--accent); } +/* hint:字段级浅色提示(比 .form-hint 更轻) */ +.hint { font-size: 11.5px; color: color-mix(in oklch, var(--muted) 82%, transparent); } + +/* ---- 图表 ---- */ +/* .trend 双色柱状图(原型 .trend / .trend-col / .trend-pair / .trend-bar / .trend-x / .legend) */ +.trend { display: flex; align-items: flex-end; gap: 10px; height: 150px; padding-top: 10px; } +.trend-col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; } +.trend-pair { display: flex; align-items: flex-end; gap: 3px; height: 118px; width: 100%; justify-content: center; } +.trend-bar { width: 9px; border-radius: 3px 3px 0 0; min-height: 2px; } +.trend-bar.consume { background: var(--accent); } +.trend-bar.earn { background: color-mix(in oklch, var(--ok) 80%, var(--muted)); } +.trend-x { font-family: var(--font-mono); font-size: 10px; color: var(--muted); } +.legend { display: flex; gap: 16px; font-size: 11.5px; color: var(--muted); margin-top: 10px; } +.legend i { width: 9px; height: 9px; border-radius: 2px; display: inline-block; margin-right: 5px; } +.legend i.consume { background: var(--accent); } +.legend i.earn { background: color-mix(in oklch, var(--ok) 80%, var(--muted)); } + +/* .bar-track / .bar-fill:原型横向条(.bar > i 的结构化别名,供新视图使用) */ +.bar-track { height: 8px; border-radius: 999px; background: var(--fg-soft); overflow: hidden; } +.bar-fill { height: 100%; border-radius: 999px; background: var(--accent); } +.bar-fill.alt { background: color-mix(in oklch, var(--accent) 45%, var(--muted)); } +/* .bar-row .bar-top:原型「名称左 / 数值右」的行头(线上 .bar-label 为其别名) */ +.bar-row .bar-top { display: flex; justify-content: space-between; font-size: 12px; margin-bottom: 5px; } + +/* ---- 空态 ---- */ +/* .empty = .empty-state 的原型别名(纯文案空态,无图标) */ +.empty { text-align: center; color: var(--muted); padding: 40px 20px; font-size: 13px; } +.empty.compact { padding: 16px 8px; } + +/* ---- 面包屑 ---- */ +.crumb { font-family: var(--font-mono); font-size: 11px; color: var(--muted); margin-bottom: 6px; } + /* ---------- 响应式预留 ---------- */ @media (max-width: 900px) { @@ -1046,6 +1175,11 @@ mark { @media (max-width: 560px) { .stat-grid { grid-template-columns: 1fr 1fr; } .card-grid { grid-template-columns: 1fr; } + /* 通用组件层窄屏(原型 responsive):三等分栅格与主次分栏堆叠;趋势图收紧高度 */ + .card-grid-3 { grid-template-columns: 1fr; } + .split { grid-template-columns: 1fr; } + .trend { height: 120px; } + .trend-pair { height: 92px; } .api-key-card { margin-top: 12px; } /* 网关端点卡片窄屏:chip 与 URL 上下排(原型 responsive 规则) */ .gw-ep { grid-template-columns: 1fr; gap: 6px; } diff --git a/ui/index.html b/ui/index.html index 41ba974..263a24e 100644 --- a/ui/index.html +++ b/ui/index.html @@ -191,7 +191,7 @@

模型市场

浏览 / 搜索各家模型,按点数计价

- + @@ -430,7 +430,7 @@

接入方式

API Key

用于本地工具 / 代码接入平台的密钥。独占整行,避免表格字段挤压。

- + @@ -535,7 +535,7 @@

按部门用量

- + @@ -572,7 +572,7 @@

添加部门