接入统一鉴权中心(Keycloak,ADR-012);活动模块 L1/L2 运营态模版(历史活动列表+检索+沙箱);数据域与工作台界面改版;个人中心 /me

This commit is contained in:
shanqin
2026-08-26 13:29:36 +08:00
parent f3397a60ef
commit f01286a89d
40 changed files with 2502 additions and 480 deletions
+101 -15
View File
@@ -476,30 +476,52 @@
.proto-root .jc-sup:focus { outline: 0; border-color: var(--brand); box-shadow: 0 0 0 3px rgba(51,112,255,.12); }
.proto-root .jc-sup:disabled { background: #f3f4f6; color: #5c626b; }
/* ===== 左侧一体化导航轨:品牌 → 四大模块 → 轨底身份(登出已挪去顶栏,见下)===== */
/* ===== 左侧一体化导航轨:品牌 → 五大模块(身份已挪去顶栏右侧,见下)===== */
.proto-root .app-nav { padding: 14px 10px 12px; }
.proto-root .jc-rail-brand { text-align: center; font-size: 10px; font-weight: 800; letter-spacing: .14em; color: var(--ink-3); margin: -4px 0 6px; }
.proto-root .app-nav button { min-height: 58px; transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast); }
.proto-root .app-nav button:active { transform: scale(.97); }
/* 轨底:全局动作(重置/通知/设置)+ 身份,margin-top:auto 吸底 */
.proto-root .jc-rail-foot { margin-top: auto; display: flex; flex-direction: column; align-items: center; gap: 8px; padding-top: 12px; border-top: 1px solid var(--line-soft); }
/* 覆盖 vendor 对 .app-nav button 的 min-height,避免轨底图标按钮被撑高 */
.proto-root .jc-rail-foot .icon-button { width: 34px; height: 34px; min-height: 34px; }
.proto-root .jc-nav-user { display: flex; flex-direction: column; align-items: center; gap: 3px; padding-top: 4px; cursor: default; }
/* 轨底身份区已撤:头像与姓名挪去顶栏右侧身份菜单(2026-08-25 用户定);
.jc-nav-ava 保留 —— 顶栏身份菜单复用这枚渐变头像 */
.proto-root .jc-nav-ava { width: 32px; height: 32px; border-radius: 999px; display: grid; place-items: center; flex: 0 0 auto; line-height: 1; color: #fff; font-size: 13px; font-weight: 800; background: linear-gradient(140deg, #2bc7d4, #0e9fd8); box-shadow: 0 2px 6px rgba(14, 159, 216, .35); }
.proto-root .jc-nav-name { font-size: 10px; font-weight: 600; color: var(--ink-3); }
/* ===== 顶栏:当前模块名 + 身份 + 退出登录 —— 与左轨互不重叠,登出只有这一处入口 ===== */
/* ===== 顶栏:44px 通栏,只放右侧身份菜单 —— 与左轨互不重叠,登出只有这一处入口 ===== */
.proto-root .app-main { min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.proto-root .app-main-body { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.proto-root .app-main-body > * { flex: 1 1 auto; min-width: 0; min-height: 0; }
.proto-root .jc-topbar { flex: 0 0 auto; height: 56px; display: flex; align-items: center; justify-content: space-between; padding: 0 20px; background: #fff; border-bottom: 1px solid var(--line); }
.proto-root .jc-topbar-title { font-size: 14px; font-weight: 700; color: var(--ink); }
.proto-root .jc-topbar-user { display: flex; align-items: center; gap: 12px; }
.proto-root .jc-topbar-user { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.proto-root .jc-topbar-name { font-size: 13px; color: var(--ink-3); }
.proto-root .jc-topbar-logout { display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px; border: 1px solid var(--line); border-radius: 8px; background: #fff; color: var(--ink-2); font-size: 13px; font-weight: 600; cursor: pointer; transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast); }
.proto-root .jc-topbar-logout:hover { background: var(--danger-soft); color: var(--danger); border-color: #f3c9c6; }
.proto-root .jc-topbar-logout:disabled { opacity: .6; cursor: default; }
/* 外壳顶栏专属:任务标题栏(共用 .jc-topbar)那条重构规则带 overflow:hidden,
会把右侧身份菜单的下拉裁得只剩顶部一小条 —— 这里放开(2026-08-25 用户报:下拉被遮挡) */
.proto-root .jc-topbar.jc-topbar-app { overflow: visible; border-radius: 0; height: 44px; padding: 0 20px; margin-bottom: 0; } /* 圆角/56px 高/大内边距/底部间距都是任务标题栏渗进来的,外壳顶栏不要(2026-08-25 用户定:44px 通栏) */
/* 顶缘蓝紫渐变条也是渗进来的(::before),外壳顶栏撤掉(2026-08-25 用户定) */
.proto-root .jc-topbar.jc-topbar-app::before { display: none; }
/* 但右上角装饰光晕定位 right:-60px,裁切一放开它就探出视口右缘 60px,整页出现横向滚动
(2026-08-25 用户报:页面能左右滑)—— 把它收回盒内,光晕照留 */
.proto-root .jc-topbar.jc-topbar-app::after { right: 0; }
/* 顶栏右侧身份菜单:头像 + 姓名,悬停出下拉(个人中心 / 退出登录)—— 纯 CSS 悬停无 JS;
登出入口从独立按钮收进下拉,仍是全站唯一入口(2026-08-25 用户定) */
.proto-root .jc-usermenu { position: relative; display: flex; align-items: center; gap: 8px; padding: 4px 8px 4px 4px; border-radius: 10px; cursor: default; color: var(--ink-4); transition: background var(--t-fast); }
.proto-root .jc-usermenu:hover { background: var(--soft); }
.proto-root .jc-usermenu .jc-nav-ava { width: 28px; height: 28px; font-size: 12px; }
/* 悬停桥:触发区与菜单之间的间隙由它补住,鼠标下移不断 hover */
.proto-root .jc-usermenu::after { content: ""; position: absolute; top: 100%; left: 0; right: 0; height: 8px; }
.proto-root .jc-usermenu-pop { position: absolute; top: calc(100% + 6px); right: 0; z-index: 60; min-width: 136px; padding: 6px; background: #fff; border: 1px solid var(--line-soft); border-radius: 12px; box-shadow: var(--shadow-2); opacity: 0; transform: translateY(-4px); pointer-events: none; transition: opacity var(--t-fast), transform var(--t-fast); }
.proto-root .jc-usermenu:hover .jc-usermenu-pop, .proto-root .jc-usermenu:focus-within .jc-usermenu-pop { opacity: 1; transform: none; pointer-events: auto; }
.proto-root .jc-usermenu-pop button, .proto-root .jc-usermenu-pop a { display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 10px; border: 0; border-radius: 8px; background: none; font-size: 13px; color: var(--ink-2); cursor: pointer; text-align: left; text-decoration: none; box-sizing: border-box; transition: background var(--t-fast), color var(--t-fast); }
.proto-root .jc-usermenu-pop button:hover, .proto-root .jc-usermenu-pop a:hover { background: var(--soft); }
.proto-root .jc-usermenu-pop button.danger:hover { background: var(--danger-soft); color: var(--danger); }
.proto-root .jc-usermenu-pop button:disabled { opacity: .6; cursor: default; }
/* 「建设中」提示弹窗:未开放模块(审批/消息/纪要/汇报)与个人中心的占位口径 —— 不跳页只弹提示 */
.proto-root .jc-wip-overlay { position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center; background: rgba(31, 35, 41, .45); }
.proto-root .jc-wip-modal { width: 360px; max-width: 92vw; padding: 24px 20px 18px; background: #fff; border-radius: 16px; box-shadow: 0 24px 60px rgba(31, 35, 41, .22); text-align: center; animation: rise var(--t-med) both; }
.proto-root .jc-wip-ico { width: 40px; height: 40px; margin: 0 auto 10px; border-radius: 12px; display: grid; place-items: center; color: var(--brand); background: var(--brand-wash); }
.proto-root .jc-wip-modal h3 { margin: 0 0 6px; font-size: 16px; color: var(--ink); }
.proto-root .jc-wip-modal p { margin: 0 0 16px; font-size: 12.5px; line-height: 1.7; color: var(--ink-3); }
.proto-root .jc-wip-ok { height: 34px; padding: 0 22px; border: 1px solid var(--brand); border-radius: 10px; background: var(--brand); color: #fff; font-size: 13px; cursor: pointer; transition: background var(--t-fast), border-color var(--t-fast); }
.proto-root .jc-wip-ok:hover { background: var(--brand-deep); border-color: var(--brand-deep); }
/* 工作清单头:渐变图标点缀 + 两级筛选 */
.proto-root .jc-wl-head { display: flex; align-items: center; justify-content: flex-start; gap: 10px; }
@@ -515,8 +537,10 @@
.proto-root .jc-wl-ico { flex: none; width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; color: #fff; background: linear-gradient(140deg, var(--brand), #7f3bf5); box-shadow: 0 3px 8px rgba(51, 112, 255, .28); }
.proto-root .jc-flt-wrap { display: flex; flex-direction: column; gap: 6px; padding: 2px 12px 12px; border-bottom: 1px solid var(--line-soft); background: #fbfdff; }
.proto-root .jc-flt { display: flex; gap: 6px; }
.proto-root .jc-flt button { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 5px; min-width: 0; border: 1px solid var(--line-soft); background: #fff; border-radius: 8px; padding: 4px 4px; font-size: 11.5px; color: var(--ink-3); cursor: pointer; transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast); }
.proto-root .jc-flt button:hover:not(.active) { background: var(--soft); }
.proto-root .jc-flt button { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 5px; min-width: 0; border: 1px solid var(--line-soft); background: #fff; border-radius: 8px; padding: 4px 4px; font-size: 11.5px; color: var(--ink-3); cursor: pointer; transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast), transform var(--t-fast); }
/* 悬停给主色洗底+描边、按下给 4% 缩放 —— 2026-08-25 用户报:hover 几乎看不出、点了不知道点没点到 */
.proto-root .jc-flt button:hover:not(.active) { background: var(--brand-wash); border-color: var(--brand-soft); color: var(--brand-deep); }
.proto-root .jc-flt button:active { transform: scale(.96); }
.proto-root .jc-flt button strong { font-family: var(--mono); font-size: 10px; font-weight: 700; color: var(--ink-4); background: var(--soft); border-radius: 999px; padding: 0 6px; }
.proto-root .jc-flt button.active { color: var(--brand-deep); border-color: var(--brand-soft); background: var(--brand-wash); font-weight: 700; }
.proto-root .jc-flt button.active strong { background: #fff; color: var(--brand-deep); }
@@ -1977,6 +2001,9 @@
/* ══ 顶部导航栏(2026-07-26 重构)══
工作流 · 任务 · 主题 · 目标 全收在这一条,常驻不滚。下面才是判据/指导书 + 报告页。 */
.proto-root .jc-topbar { position: relative; overflow: hidden; flex: 0 0 auto; margin-bottom: 12px; padding: 12px 18px 13px; background: #fff; border: 1px solid var(--line-soft); border-radius: 16px; box-shadow: var(--shadow-2); }
/* 任务标题栏(带 aria-label)必须是块级:外壳顶栏那条 56px 的 .jc-topbar 规则带 display:flex,
同优先级漏进来会把面包屑行与标题行横排挤成一行(2026-08-25 用户报:标题栏变形) */
.proto-root .jc-topbar[aria-label] { display: block; height: auto; }
/* 设计感:顶缘 AI 渐变棱线 + 右上品牌光晕;两行定高(≈88px),其余信息在「工作流」页签 */
.proto-root .jc-topbar::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px; background: var(--ai-grad); }
.proto-root .jc-topbar::after { content: ""; position: absolute; right: -60px; top: -80px; width: 210px; height: 210px; border-radius: 999px; background: radial-gradient(circle, rgba(51,112,255,.08), transparent 70%); pointer-events: none; }
@@ -3363,3 +3390,62 @@
display: block; margin-top: 3px; font-style: normal; font-size: 11px;
line-height: 1.6; color: var(--ink-3);
}
/* ══ 个人中心(/me 台面,2026-08-25)══
与工作台同皮肤:44px 通栏顶栏 + 居中内容列。
只加 .jc-me-* 作用域,共享件(.jc-kpi/.jc-nav-ava/EmptyState)本体不动。 */
.proto-root .jc-me { min-height: 100vh; display: flex; flex-direction: column; background: var(--soft); }
.proto-root .jc-me-back { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--ink-3); text-decoration: none; transition: color var(--t-fast); }
.proto-root .jc-me-back:hover { color: var(--brand-deep); }
.proto-root .jc-me-body { width: min(960px, calc(100% - 48px)); margin: 24px auto 48px; display: flex; flex-direction: column; gap: 14px; }
/* 卡片基座:白卡 1px 描边,与全站面板卡同语气 */
.proto-root .jc-me-card { background: #fff; border: 1px solid var(--line-soft); border-radius: 14px; box-shadow: var(--card-shadow, 0 1px 2px rgba(31, 35, 41, .05)); }
/* 身份卡:大头像 + 姓名岗位 + 登出入口 */
.proto-root .jc-me-hero { display: flex; align-items: flex-start; gap: 18px; padding: 22px 24px; }
.proto-root .jc-me-ava { flex: none; width: 72px; height: 72px; border-radius: 999px; display: grid; place-items: center; color: #fff; font-size: 28px; font-weight: 800; background: linear-gradient(140deg, #2bc7d4, #0e9fd8); box-shadow: 0 4px 12px rgba(14, 159, 216, .35); }
.proto-root .jc-me-id { flex: 1; min-width: 0; }
.proto-root .jc-me-id h1 { margin: 2px 0 4px; font-size: 22px; font-weight: 800; letter-spacing: -.01em; color: var(--ink); }
.proto-root .jc-me-pos { margin: 0 0 6px; font-size: 13.5px; font-weight: 700; color: var(--brand-deep); }
.proto-root .jc-me-meta { margin: 0; font-size: 12px; color: var(--ink-4); }
.proto-root .jc-me-meta em { font-style: normal; font-weight: 700; }
.proto-root .jc-me-meta em.on { color: var(--ok); }
.proto-root .jc-me-meta em.off { color: var(--danger); }
.proto-root .jc-me-note { margin: 8px 0 0; font-size: 12.5px; line-height: 1.7; color: var(--ink-3); }
.proto-root .jc-me-logout { flex: none; display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 14px; border: 1px solid var(--line); border-radius: 9px; background: #fff; color: var(--ink-2); font-size: 13px; font-weight: 600; cursor: pointer; transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast); }
.proto-root .jc-me-logout:hover { background: var(--danger-soft); color: var(--danger); border-color: #f3c9c6; }
.proto-root .jc-me-logout:disabled { opacity: .6; cursor: default; }
/* 概览四卡:复用 .jc-kpi,这里只补链接态 */
.proto-root .jc-me-kpis { margin-bottom: 0; }
.proto-root .jc-me-kpis a.jc-kpi { text-decoration: none; color: inherit; }
/* 区块卡:节头 + 内容 */
.proto-root .jc-me-sec { padding: 16px 20px 14px; }
.proto-root .jc-me-sec-h { display: flex; align-items: baseline; gap: 10px; padding-bottom: 10px; border-bottom: 1px solid var(--line-soft); margin-bottom: 10px; }
.proto-root .jc-me-sec-h h2 { margin: 0; font-size: 15px; font-weight: 800; color: var(--ink); }
.proto-root .jc-me-sec-sub { font-size: 11.5px; color: var(--ink-4); }
/* 权限分组:组名一列,客体成串,动作色章 */
.proto-root .jc-me-grant { display: grid; grid-template-columns: 92px 1fr; gap: 6px 12px; padding: 8px 0; }
.proto-root .jc-me-grant + .jc-me-grant { border-top: 1px dashed var(--line-soft); }
.proto-root .jc-me-grant > em { display: inline-flex; align-items: center; gap: 5px; font-style: normal; font-size: 12px; font-weight: 700; color: var(--ink-3); }
.proto-root .jc-me-grant > div { display: flex; flex-wrap: wrap; gap: 6px; }
.proto-root .jc-me-grant-item { display: inline-flex; align-items: center; gap: 6px; padding: 3px 4px 3px 10px; border: 1px solid var(--line-soft); border-radius: 8px; font-size: 12px; font-family: var(--mono); color: var(--ink-2); background: var(--soft); }
.proto-root .jc-me-act { font-style: normal; font-family: var(--sans); font-size: 10px; font-weight: 800; padding: 1px 7px; border-radius: 999px; }
.proto-root .jc-me-act.a-read { color: var(--brand-deep); background: var(--brand-wash); }
.proto-root .jc-me-act.a-write { color: #b25e15; background: #fdf0e6; }
.proto-root .jc-me-act.a-govern { color: #5b21cf; background: #f5f0fe; }
/* 可进的端(ADR-012):chip 即入口,点了整页导航过去 */
.proto-root .jc-me-end { text-decoration: none; font-family: var(--sans); font-weight: 600; color: var(--brand-deep); background: var(--brand-wash); border-color: transparent; padding-right: 10px; }
.proto-root .jc-me-end:hover { filter: brightness(0.96); }
/* 最近任务:一行一条,标题 + 活动 + 状态章 */
.proto-root .jc-me-task { display: flex; align-items: center; gap: 10px; padding: 8px 2px; }
.proto-root .jc-me-task + .jc-me-task { border-top: 1px dashed var(--line-soft); }
.proto-root .jc-me-task-t { flex: 1; min-width: 0; font-size: 13px; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.proto-root .jc-me-task-a { flex: none; max-width: 40%; font-size: 11.5px; color: var(--ink-4); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.proto-root .jc-me-task-st { flex: none; font-style: normal; font-size: 10.5px; font-weight: 700; padding: 2px 9px; border-radius: 999px; }
.proto-root .jc-me-task-st.run { color: var(--brand-deep); background: var(--brand-wash); }
.proto-root .jc-me-task-st.done { color: var(--ink-3); background: var(--soft); }
+275 -31
View File
@@ -125,8 +125,9 @@
/* ============ 概览页签:KPI 块 ============ */
.g-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(176px, 1fr)); gap: 12px; }
.g-kpi { position: relative; display: flex; flex-direction: column; gap: 7px; padding: 14px 16px; background: var(--card); border: 1px solid var(--cline); border-radius: 13px; box-shadow: var(--cshadow); overflow: hidden; }
.g-kpi::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--tone, #c9d2dd); }
/* 左侧 3px 色条用 inset 阴影画 —— 自动贴合圆角,**不需要** overflow 裁切;
裁切会把 .g-kpi-hint 的气泡一并剪掉(2026-08-24 用户报:气泡显示不全) */
.g-kpi { position: relative; display: flex; flex-direction: column; gap: 7px; padding: 14px 16px; background: var(--card); border: 1px solid var(--cline); border-radius: 13px; box-shadow: inset 3px 0 0 var(--tone, #c9d2dd), var(--cshadow); }
.g-kpi-l { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--ink-4); }
.g-kpi-l svg { color: var(--tone-ink, var(--ink-4)); }
.g-kpi-v { font-size: 26px; font-weight: 800; font-family: var(--mono); letter-spacing: -.03em; line-height: 1; color: var(--ink); }
@@ -135,6 +136,13 @@
.g-kpi.t-danger .g-kpi-v { color: var(--danger); } .g-kpi.t-brand .g-kpi-v { color: var(--brand-deep); }
.g-kpi-s { font-size: 11px; line-height: 1.5; color: var(--ink-4); }
/* KPI 角标说明:右上角一枚 info,悬停出气泡讲这个数的口径(纯 CSS,无 JS);
气泡深底白字 —— 全站唯一的浮层用色,描边/阴影只给浮层(§10) */
.g-kpi-hint { position: absolute; top: 10px; right: 10px; display: grid; place-items: center; width: 16px; height: 16px; border-radius: 999px; color: var(--ink-4); cursor: help; transition: color var(--t-fast), background var(--t-fast); }
.g-kpi-hint:hover { color: var(--brand-deep); background: var(--brand-wash); }
.g-kpi-hint::after { content: attr(data-tip); position: absolute; top: calc(100% + 6px); right: 0; z-index: 5; width: 208px; padding: 8px 10px; border-radius: 6px; background: var(--ink); color: #fff; font-size: 11px; font-weight: 400; line-height: 1.65; text-align: left; white-space: normal; box-shadow: var(--cshadow-2); opacity: 0; transform: translateY(-3px); pointer-events: none; transition: opacity var(--t-fast), transform var(--t-fast); }
.g-kpi-hint:hover::after { opacity: 1; transform: translateY(0); }
/* 环形(比率型指标) */
.g-dial { display: grid; place-items: center; }
.g-dial svg { transform: rotate(-90deg); }
@@ -255,50 +263,156 @@
.tb-land.on b { color: #c9372c; }
.tb-land em { display: block; margin-top: 2px; font-style: normal; font-size: 11.5px; line-height: 1.65; color: var(--g-ink-3, #646a73); }
/* ══ 数据域:按活动分组(2026-08-24 重写)══════════════════════════════
/* ══ 数据域:按活动分组(2026-08-24 重写;2026-08-24 按 docs/DESIGN-SPEC.md 改版 v2)══
一屏回答的是「我这个活动写了哪几张表、现在各有几行」——
所以行数是主角:字号最大、放行末端;性质降成一枚小徽,地址与主键退成灰字。 */
.g-actdata { display: flex; flex-direction: column; gap: 10px; padding: 14px 16px 13px;
background: #fff; border: 1px solid var(--g-line); border-radius: 12px; box-shadow: var(--g-shadow, 0 1px 2px rgba(31,35,41,.05)); }
.g-actdata + .g-actdata { margin-top: 14px; }
.g-actdata-h { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.g-actdata-h > svg { color: var(--g-brand, #3370ff); flex: none; }
.g-actdata-h b { font-size: 14.5px; font-weight: 800; color: var(--g-ink, #1f2329); }
.g-actdata-h .n { margin-left: auto; font-size: 12px; font-weight: 700; color: var(--g-ink-3, #646a73); }
.g-actdata-h .n em { font-style: normal; color: var(--g-brand, #3370ff); }
.g-actdata-h p { flex-basis: 100%; margin: 2px 0 0; font-size: 12px; line-height: 1.7; color: var(--g-ink-3, #646a73); }
行数是主角:字号最大、放行末端;性质降成一枚小徽,地址与主键退成灰字。
v2 结构改版(DOM 语义与取数不变):
· 页顶汇总带(四个合计数)给这一屏一个主角与记忆点(§1 顶层);
· 表块是**白卡**(2026-08-24 用户定:卡片形式)—— 1px 描边、行数大数字
当卡内主角、tabular-nums(§6/§11),hover 描边变深不浮起(§10);
· 卡片描边单层去阴影、圆角 8(§10/§6)。
`.g-data`/`.g-actdata`/`.g-tbl` 全站仅此页使用,不影响其他面板。 */
.g-data { display: flex; flex-direction: column; gap: 16px; }
.g-data .g-kpi { border-radius: 8px; box-shadow: inset 3px 0 0 var(--tone, #c9d2dd); border-color: #dfe3ea; }
.g-data .g-kpi-v { font-variant-numeric: tabular-nums; }
.g-actdata-tables { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 8px; }
.g-tbl { display: grid; grid-template-columns: 1fr auto; grid-template-areas: 't n' 'a n';
gap: 2px 12px; width: 100%; padding: 9px 12px; text-align: left; font: inherit; cursor: pointer;
background: var(--g-soft, #f7f8fa); border: 1px solid transparent; border-radius: 9px; transition: all .16s; }
.g-tbl:hover { background: #fff; border-color: var(--g-brand-soft, #b6d0ff); box-shadow: 0 2px 8px rgba(51,112,255,.10); }
.g-tbl-t { grid-area: t; display: flex; align-items: center; gap: 6px; min-width: 0; }
.g-tbl-t b { font-size: 13px; font-weight: 700; color: var(--g-ink, #1f2329); }
.g-tbl-k { font-style: normal; font-size: 10px; font-weight: 800; padding: 1px 6px; border-radius: 4px;
.g-actdata { display: flex; flex-direction: column; gap: 4px; padding: 16px;
background: #fff; border: 1px solid #dfe3ea; border-radius: 8px; }
.g-actdata + .g-actdata { margin-top: 16px; } /* 与 .g-data 的 16px gap 合成 32px 组间(组间松) */
.g-actdata-h { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-bottom: 8px; }
.g-actdata-i { flex: none; width: 28px; height: 28px; border-radius: 6px; display: grid; place-items: center;
color: var(--brand-deep); background: var(--brand-wash); }
.g-actdata-h b { font-size: 15px; font-weight: 700; letter-spacing: -.01em; color: var(--ink); }
.g-actdata-h .g-mono { font-size: 11px; color: var(--ink-4); }
.g-actdata-h .n { margin-left: auto; font-size: 12px; font-weight: 600; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.g-actdata-h .n em { font-style: normal; color: var(--brand); }
.g-actdata-h p { flex-basis: 100%; margin: 0; font-size: 12px; line-height: 1.75; color: var(--ink-3); }
/* 表卡片:白卡 1px 描边(§10),行数大数字是卡内主角(tabular-nums),
名称一条左线、mono 地址垫底截断;hover 描边变深不浮起(§10) */
.g-actdata-tables { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px; }
.g-tbl { display: grid; grid-template-columns: minmax(0, 1fr) auto;
grid-template-areas: 't x' 'n n' 'a a'; align-items: center; gap: 6px 12px;
width: 100%; padding: 12px 14px; text-align: left; font: inherit; cursor: pointer;
background: #fff; border: 1px solid #dfe3ea; border-radius: 8px;
transition: border-color var(--t-fast), background var(--t-fast), transform var(--t-fast); }
/* hover 三层反馈(§12 悬停是层级工具):描边变深 + 轻洗底 + 卡内主角(行数)染主色;
active 给 1% 按压感 —— 点击「被接住」。全部 0.16s ease-out,只动便宜属性(§13) */
.g-tbl:hover { border-color: #c4ccd8; background: #f6f7f9; }
.g-tbl:hover .g-tbl-n b { color: var(--brand-deep); }
.g-tbl:active { transform: scale(.99); border-color: var(--brand-soft); }
.g-tbl-t { grid-area: t; display: flex; align-items: center; gap: 8px; min-width: 0; }
.g-tbl-t b { font-size: 13.5px; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-tbl-k { flex: none; font-style: normal; font-size: 10px; font-weight: 600; padding: 1px 6px; border-radius: 4px;
background: #eef1f5; color: #5a6068; }
.g-tbl-k.t-m { background: #eaf1ff; color: #2b5fd9; }
.g-tbl-k.t-r { background: #f2f3f5; color: #5a6068; }
.g-tbl-k.t-d { background: #fdf0e6; color: #b25e15; }
.g-tbl-a { grid-area: a; font-size: 11px; color: var(--g-ink-4, #8f959e); overflow-wrap: anywhere; }
/* 地址一行截断不折行,全文在 title 里悬停看 */
.g-tbl-a { grid-area: a; font-size: 11px; color: var(--ink-4); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-tbl-a em { font-style: normal; }
/* 行数:这一屏的主角 */
.g-tbl-n { grid-area: n; align-self: center; text-align: right; font-size: 11.5px; color: var(--g-ink-3, #646a73); white-space: nowrap; }
.g-tbl-n b { font-size: 17px; font-weight: 800; color: var(--g-ink, #1f2329); margin-right: 2px; }
.g-tbl-n .none { font-style: normal; color: var(--g-ink-4, #8f959e); }
.g-tbl-n .draft { display: block; font-style: normal; font-size: 10.5px; font-weight: 700; color: var(--g-brand, #3370ff); }
/* 行数:这一屏的主角 —— 大字号 + tabular-nums,扫一列数字时个位对个位 */
.g-tbl-n { grid-area: n; font-size: 11.5px; color: var(--ink-3); white-space: nowrap; font-variant-numeric: tabular-nums; }
.g-tbl-n b { font-size: 22px; font-weight: 700; letter-spacing: -.02em; color: var(--ink); margin-right: 2px; transition: color var(--t-fast); }
.g-tbl-n .none { font-style: normal; font-weight: 400; font-size: 11px; color: var(--ink-4); }
.g-tbl-n .draft { font-style: normal; font-size: 10.5px; font-weight: 600; color: var(--brand); margin-left: 8px; }
/* 下钻箭头:平时灰,悬停整卡时染主色前移 2px —— 「这卡能点进去」不靠文字说 */
.g-tbl-x { grid-area: x; display: grid; place-items: center; color: var(--ink-4); transition: color var(--t-fast), transform var(--t-fast); }
.g-tbl:hover .g-tbl-x { color: var(--brand); transform: translateX(2px); }
.g-actdata-runs { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; padding-top: 2px; }
.g-actdata-runs > em { font-style: normal; font-size: 11px; font-weight: 700; color: var(--g-ink-4, #8f959e); }
.g-actdata-runs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-top: 10px; border-top: 1px dashed var(--line-soft); }
.g-actdata-runs > em { font-style: normal; font-size: 11px; font-weight: 600; color: var(--ink-4); }
.g-run { display: inline-flex; align-items: center; gap: 5px; padding: 2px 9px; border-radius: 999px;
font-size: 11px; font-weight: 700; background: #f2f3f5; color: #5a6068; }
.g-run i { font-style: normal; font-weight: 600; opacity: .72; }
font-size: 11px; font-weight: 600; background: #f2f3f5; color: #5a6068; }
.g-run i { font-style: normal; font-weight: 500; opacity: .72; font-variant-numeric: tabular-nums; }
.g-run.t-ok { background: #e9f7ee; color: #1f7a45; }
.g-run.t-live { background: #eaf1ff; color: #2b5fd9; }
.g-run.t-wait { background: #fdf0e6; color: #b25e15; }
.g-run.t-warn { background: #fff1f0; color: #c9372c; }
.g-actdata.t-u { background: #fbfbfc; }
/* ══ 对象详情(数据域下钻,`.g-obj` 作用域)══
上下结构(2026-08-24 用户定):记录浏览在上整宽 —— 进来的人先看的是行数据;
模式在下整宽 —— 它是辅助的结构定义(主从两栏试过一版,两栏互相挤压,撤了)。
共享件(g-dh / g-card / g-rows / g-dbtable)本体不动 —— 它们横跨十个面板;
只在本作用域内改皮:圆角收 8、去阴影留描边、模式行三列(名 / mono 键 / 类型徽)、
去斑马与卡套卡的双层描边、行高收敛到扫描型密度(§9)。 */
.g-obj { display: flex; flex-direction: column; gap: 16px; }
.g-obj .g-dh { border-radius: 8px; box-shadow: none; border-color: #dfe3ea; }
/* 页头提级(气质层):主角标题加大、图标块加内描边、kicker 加字距 */
.g-obj .g-dh-i { width: 46px; height: 46px; border-radius: 10px; box-shadow: inset 0 0 0 1px var(--brand-soft); }
.g-obj .g-dh-t h2 { font-size: 20px; }
.g-obj .g-dh-t em { letter-spacing: .06em; }
/* 主键列头的小钥匙染主色 —— 全表只有主键列有图标,有含义才有颜色 */
.g-obj .g-dbtable thead th svg { color: var(--brand); margin-right: 3px; vertical-align: -1.5px; }
.g-obj .g-dbwrap { overflow-x: auto; background: #fff; border: 1px solid #dfe3ea; border-radius: 8px; }
/* 模式表:转置矩阵 —— 行 = 参数名/字段/数据类型,列 = 字段;左列行标签吸左,列多横滚;
盒子本体在这里(标题走 Sec 在盒外,与记录浏览同构 —— 2026-08-24 用户定);
overflow-y 必须显式 hidden:只写 overflow-x:auto 时 y 向会被算成 auto,
列高亮幕(td::after 上下各伸 999px)就把纵向滚动区撑出近千米空白
(2026-08-25 用户报:3 行已全显示却还能往下滑) */
.g-obj .g-sx { overflow-x: auto; overflow-y: hidden; background: #fff; border: 1px solid #dfe3ea; border-radius: 8px; }
.g-obj .g-sx table { border-collapse: collapse; min-width: 100%; }
.g-obj .g-sx th { position: sticky; left: 0; z-index: 1; padding: 8px 12px; background: #fff; text-align: left;
font-size: 11px; font-weight: 600; color: var(--ink-4); white-space: nowrap; border-bottom: 1px solid var(--line-soft); }
/* 列高亮(2026-08-24 用户定):这表一列才是一个字段,所以悬停亮**整列** ——
悬停格画一层纵向贯穿的淡色幕,上下各伸出 999px,由 .g-sx 的 overflow 裁齐;
mix-blend-mode: multiply —— 幕在文字之上,正片叠底让深字几乎不变、只染亮底;
pointer-events 关掉,幕不抢鼠标 */
.g-obj .g-sx td { position: relative; padding: 8px 12px; white-space: nowrap; border-bottom: 1px solid var(--line-soft); }
.g-obj .g-sx td::after { content: ""; position: absolute; left: 0; right: 0; top: -999px; bottom: -999px; background: var(--brand-wash); mix-blend-mode: multiply; opacity: 0; pointer-events: none; transition: opacity var(--t-fast); }
.g-obj .g-sx td:hover::after { opacity: 1; }
.g-obj .g-sx tr:last-child th, .g-obj .g-sx tr:last-child td { border-bottom: 0; }
/* 与记录浏览同一套斑马(2026-08-24 用户定):偶数行洗底,吸左的行标签跟着换底 */
.g-obj .g-sx tbody tr:nth-child(even) { background: #f8fafc; }
.g-obj .g-sx tbody tr:nth-child(even) th { background: #f8fafc; }
.g-obj .g-sx th, .g-obj .g-sx td { border-right: 1px solid #eef1f5; }
.g-obj .g-sx tr > :last-child { border-right: 0; }
.g-obj .g-sx td.nm { font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
.g-obj .g-sx td.key { font-size: 11.5px; color: var(--ink-3); }
.g-obj .g-sx .ty { font-style: normal; font-family: var(--mono); font-size: 10px; font-weight: 600; padding: 1px 6px; border-radius: 4px; background: var(--soft); border: 1px solid var(--line-soft); color: var(--ink-4); }
/* 类型徽分色:数字蓝 / json 紫 —— 数据库工具的通用语言,语义色只进徽标(§7) */
.g-obj .g-sx .ty.k-num { background: #eaf1ff; border-color: #d5e2fb; color: #2b5fd9; }
.g-obj .g-sx .ty.k-json { background: #f5f0fe; border-color: #e4d9fa; color: #5b21cf; }
/* 记录浏览:扫描型密度(§9)—— 字号 13、单元格左右 12;长 JSON 一格一行不折行,超宽横滚 */
.g-obj .g-dbtable { font-size: 13px; }
.g-obj .g-dbtable thead th { padding: 8px 12px; }
.g-obj .g-dbtable tbody td { padding: 8px 12px; white-space: nowrap; max-width: 320px; overflow: hidden; text-overflow: ellipsis; }
/* 分隔要看得见(2026-08-24 用户报):行 = 斑马 + 加深一档的发丝线,列 = 极浅竖线;
三色都压在工作面阶内,不新增色相(§7) */
.g-obj .g-dbtable tbody tr:nth-child(even) { background: #f8fafc; }
.g-obj .g-dbtable tbody tr:hover { background: var(--brand-wash); }
.g-obj .g-dbtable tbody td { border-bottom-color: #e2e7ee; }
.g-obj .g-dbtable th + th, .g-obj .g-dbtable td + td { border-left: 1px solid #eef1f5; }
/* 空值那一格是 `-`,灰下去 —— 它是「这里没有」,不是数据 */
.g-obj .g-dbtable td.empty { color: var(--ink-4); }
/* 数字列右对齐 + 等宽(§11),列类型来自 schema,不是猜的 */
.g-obj .g-dbtable .num { text-align: right; font-variant-numeric: tabular-nums; }
/* 操作列(2026-08-25 用户定):钉在表格右缘 —— 列多横滚时「查看详情」始终够得着;
吸右格必须自带不透明底色(白/斑马/悬停三态),否则滚动的内容会透到它底下 */
.g-obj .g-dbtable th.op, .g-obj .g-dbtable td.op { position: sticky; right: 0; z-index: 1; text-align: center; white-space: nowrap; background: #fff; box-shadow: -1px 0 0 #e2e7ee; }
.g-obj .g-dbtable thead th.op { background: #f5f7fa; }
.g-obj .g-dbtable tbody tr:nth-child(even) td.op { background: #f8fafc; }
.g-obj .g-dbtable tbody tr:hover td.op { background: var(--brand-wash); }
/* 行内入口钮:主色浅底的描边小钮,悬停沉成实底 —— 可点要说得像可点(§7) */
.g-rowbtn { display: inline-flex; align-items: center; gap: 3px; padding: 3px 10px; border-radius: 6px;
border: 1px solid var(--brand-soft); background: var(--brand-wash); color: var(--brand-deep);
font: 600 12px/1.6 var(--sans); cursor: pointer; transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast); }
.g-rowbtn:hover { background: var(--brand); border-color: var(--brand); color: #fff; }
.g-rowbtn:active { transform: scale(.96); }
/* ══ 记录详情(三级页,`.g-rowpage` 作用域;套 `g-obj` 复用对象页皮)══
字段明细表:一字段一行,值整串摆全可折行 —— 浏览表管「扫」,这页管「看全」 */
.g-rowpage .g-fdt td.nm { font-weight: 600; color: var(--ink-2); white-space: nowrap; }
.g-rowpage .g-fdt td.nm svg { color: var(--brand); margin-right: 3px; vertical-align: -1.5px; }
.g-rowpage .g-fdt td.key { font-size: 11.5px; color: var(--ink-3); white-space: nowrap; }
/* 值列:撤掉浏览表那套单行截断 —— 详情页不截断,长 JSON 折行摆全 */
.g-rowpage .g-fdt td.val { white-space: pre-wrap; word-break: break-word; max-width: none; overflow: visible; text-overflow: clip; line-height: 1.7; }
/* 类型徽与模式表同款(选择器作用域不同,样式照抄三行) */
.g-rowpage .g-fdt .ty { font-style: normal; font-family: var(--mono); font-size: 10px; font-weight: 600; padding: 1px 6px; border-radius: 4px; background: var(--soft); border: 1px solid var(--line-soft); color: var(--ink-4); white-space: nowrap; }
.g-rowpage .g-fdt .ty.k-num { background: #eaf1ff; border-color: #d5e2fb; color: #2b5fd9; }
.g-rowpage .g-fdt .ty.k-json { background: #f5f0fe; border-color: #e4d9fa; color: #5b21cf; }
.g-kind { display: flex; flex-direction: column; gap: 12px; }
.g-kind + .g-kind { margin-top: 22px; }
.g-kind-h { display: grid; grid-template-columns: auto auto auto 1fr; align-items: center; gap: 8px;
@@ -391,6 +505,136 @@
.g-fcard .pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: #98a4b3; }
.g-fcard .pill.on { background: #e6f6ee; color: #0c8154; }
.g-fcard .pill.on::before { background: #18a568; }
/* ══ 运营中心 · 活动模块 L1(2026-08-25 重构模版 → 视觉增强,`.g-actv` 作用域)══
布局不动,增强只在皮:每张卡一个「业务色相」变量 --ah(报价=品牌蓝 / CRM=青 / 市场=橙 / 采购=紫),
同一枚色贯穿五处 —— 卡顶色签 / 图标块 / 输出徽章 / 实例数 / 悬停描边与色影;
色即业务,不是彩虹(全页色相 ≤4,每处都有含义)。共享件 .g-shelf/.g-fcard 本体不动 */
.g-actv .g-fcard { --ah: #3370ff; --ah-soft: #eaf1ff; }
.g-actv .g-fcard.h-teal { --ah: #0aa294; --ah-soft: #e0f5f3; }
.g-actv .g-fcard.h-amber { --ah: #d9730d; --ah-soft: #fdf0e0; }
.g-actv .g-fcard.h-violet { --ah: #7f3bf5; --ah-soft: #f1e9fe; }
/* 卡顶色签:3px 一线压顶,从左实到右渐隐 —— 第一眼把同一业务的卡归成一堆 */
.g-actv .g-fcard::before { content: ""; position: absolute; top: -1px; left: 14px; right: 14px; height: 3px; border-radius: 0 0 3px 3px; background: linear-gradient(90deg, var(--ah), color-mix(in srgb, var(--ah) 25%, transparent)); opacity: .9; }
.g-actv .g-fcard.ghost::before { display: none; }
/* 悬停:描边与投影都染业务色(彩色阴影 —— ui-ux-pro-max 企业级方向),上浮 2px */
.g-actv .g-fcard:hover { border-color: color-mix(in srgb, var(--ah) 38%, #e2e8ef); box-shadow: 0 12px 26px -14px color-mix(in srgb, var(--ah) 55%, transparent); transform: translateY(-2px); }
/* 图标块:浅底微渐变 + 内描边,色随业务;图标语义化(收件箱/计算器/靶心/趋势/眼睛/盾) */
.g-actv .g-fcard .ico { color: var(--ah); background: linear-gradient(150deg, var(--ah-soft), #fff); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ah) 18%, transparent); }
/* 标题提一档 + 全部显示不截断(2026-08-25 用户定):活动名是卡上最重要的数据,长了换行,不省略 */
.g-actv .g-fcard .ttl b { font-size: 15px; overflow: visible; white-space: normal; text-overflow: clip; }
/* 实例数染业务色 —— 底板里最该被先看到的数;底板整体字号收小一档(2026-08-25 用户定),
它是次要信息,把视觉重量让给活动名 */
.g-actv .plate > span:first-child b { color: var(--ah); }
.g-actv .plate b { font-size: 12.5px; font-weight: 400; }
/* 幽灵卡本期已注释(设计功能暂缓,2026-08-25 用户定):样式留着,恢复即能用 */
.g-actv .g-fcard.ghost[aria-disabled="true"] { cursor: default; }
.g-actv .g-fcard.ghost[aria-disabled="true"]:hover { border-color: #c0cbd8; background: #fcfdfe; color: var(--ink-4); box-shadow: none; transform: none; }
/* ══ 活动详情 L2(2026-08-25 视觉重设计,`.g-actvd` 作用域)══
业务色相从 L1 卡片接进详情页:--ah 贯穿页头/统计/页签,形成「点哪张卡,进哪色页」的连续感 */
.g-actvd { display: flex; flex-direction: column; gap: 16px; --ah: #3370ff; --ah-soft: #eaf1ff; }
.g-actvd.h-teal { --ah: #0aa294; --ah-soft: #e0f5f3; }
.g-actvd.h-amber { --ah: #d9730d; --ah-soft: #fdf0e0; }
.g-actvd.h-violet { --ah: #7f3bf5; --ah-soft: #f1e9fe; }
/* 入场:区块自下而上淡入,60ms 逐段 stagger —— 进场有来由(从下 = 深入一层);reduced-motion 全关 */
.g-actvd > * { animation: actvd-in .4s ease-out both; }
.g-actvd > *:nth-child(2) { animation-delay: 60ms; }
.g-actvd > *:nth-child(3) { animation-delay: 120ms; }
.g-actvd > *:nth-child(4) { animation-delay: 180ms; }
.g-actvd > *:nth-child(5) { animation-delay: 240ms; }
.g-actvd > *:nth-child(n+6) { animation-delay: 300ms; }
@keyframes actvd-in { from { opacity: 0; transform: translateY(10px); } }
/* —— 页头(2026-08-25 层级重排):回到默认 PageHead —— 它是导航与动作区,不是主角;
业务色相只留 42px 图标块一处(与 L1 卡片的连续感),渐变底与色签撤掉 */
.g-actvd .g-dh-i { color: var(--ah); background: var(--ah-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ah) 18%, transparent); }
/* —— 统计带(2026-08-25 层级重排):一行灰字 —— 它是清单的合计,不是主角;
状态色只进 6px 圆点(色不进文字,色盲可读:状态词在点旁边) */
.g-actvd .g-statline { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 20px; padding: 2px 2px 12px;
font-size: 12px; color: var(--ink-3); }
.g-actvd .g-statline b { margin-left: 2px; font: 600 13px/1 var(--mono); color: var(--ink); }
.g-actvd .dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; margin-right: 5px; vertical-align: 1px;
background: var(--tone, #8f959e); }
/* —— 统计带 + 检索条同一行(2026-08-26 用户定:检索放右侧)—— 左合计右检索,窄屏检索条换行落到下面 */
.g-actvd .g-ihead { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 16px;
padding: 2px 2px 12px; }
/* 统计带收进 g-ihead 后不再自己占 padding */
.g-actvd .g-ihead .g-statline { padding: 0; }
/* —— 实例检索条(2026-08-26 用户定:列表就要能搜):条件下拉 + 随条件换控件 */
.g-actvd .g-ifilter { display: flex; align-items: center; gap: 8px; color: var(--ink-4); }
.g-actvd .g-isel, .g-actvd .g-iselect-input, .g-actvd .g-ifilter-range input { height: 28px; padding: 0 8px;
font-size: 12px; color: var(--ink); background: #fff; border: 1px solid #dfe3ea; border-radius: 6px;
outline: none; transition: border-color var(--t-fast), box-shadow var(--t-fast); }
.g-actvd .g-isel:focus, .g-actvd .g-iselect-input:focus, .g-actvd .g-ifilter-range input:focus {
border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-wash); }
.g-actvd .g-isel { cursor: pointer; }
.g-actvd .g-iselect-input { width: 220px; }
.g-actvd .g-iselect-input::placeholder { color: var(--ink-4); }
.g-actvd .g-ifilter-range { display: inline-flex; align-items: center; gap: 6px; }
.g-actvd .g-ifilter-range i { font-style: normal; color: var(--ink-4); }
.g-actvd .g-ifilter-n { font-size: 11.5px; color: var(--ink-3); }
.g-actvd .g-ifilter-n b { font-family: var(--mono); color: var(--ink); }
/* 检索无结果:表体里摆一句实话 */
.g-actvd .g-irow-empty { display: flex; align-items: center; justify-content: center; gap: 6px;
padding: 22px 14px; font-size: 12px; color: var(--ink-4); }
/* —— 实例清单:列表式(2026-08-26 用户定:卡片撤了改列表)——
列齐好扫:状态 / 实例号 / 输入 / 负责人 / 开始时间 / 输出 / 操作;
状态色只进 6px 圆点(--tone 来自状态色调类);隔行极浅斑马 + 悬停亮行;行内操作悬停浮现(§11) */
.g-actvd .g-itab { background: #fff; border: 1px solid #dfe3ea; border-radius: 8px; overflow: hidden; }
/* 操作列固定宽:每行是自己的 grid 容器,若用 auto,操作钮多一枚的行会把 fr 列挤窄 —— 列就对错峰了(2026-08-26 用户报)
列序(2026-08-26 用户定):实例 / 负责人 / 输入 / 输出 / 启动时间 / 状态 / 操作 */
.g-actvd .g-itab-h, .g-actvd .g-irow { display: grid; align-items: center; gap: 12px;
grid-template-columns: 88px 72px minmax(0, 1.5fr) minmax(0, 1fr) 92px 88px 150px; padding: 0 14px; }
.g-actvd .g-itab-h { height: 34px; font-size: 11px; font-weight: 600; color: var(--ink-4); letter-spacing: .02em;
background: #f7f8fa; border-bottom: 1px solid #e6eaf0; }
.g-actvd .g-irow { min-height: 44px; padding-top: 6px; padding-bottom: 6px; position: relative;
transition: background var(--t-fast); }
.g-actvd .g-irow + .g-irow { border-top: 1px solid #eef1f5; }
.g-actvd .g-itab > .g-irow:nth-of-type(even) { background: #fafbfc; }
/* 与斑马纹同层级(都带 > .g-irow),靠声明顺序让悬停盖得住 */
.g-actvd .g-itab > .g-irow:hover { background: #f2f6fb; }
.g-actvd .g-irow .st { display: inline-flex; align-items: center; font-size: 12px; color: var(--ink-2); white-space: nowrap;
animation: actvd-pop .28s ease-out; }
.g-actvd .g-irow .st .dot { background: var(--tone, #8f959e); }
.g-actvd .g-irow .id { font-size: 11.5px; font-weight: 600; color: var(--ink-4); letter-spacing: .02em; }
.g-actvd .g-irow .in { font-size: 13px; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-actvd .g-irow .ow { font-size: 12px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-actvd .g-irow .at { font-size: 11.5px; color: var(--ink-3); }
.g-actvd .g-irow .out { font-size: 11.5px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 行内操作常驻(2026-08-26 用户报:悬停浮现看不到钮)——
「查看详情」是进 L3 的主入口,不该藏;终止活动是危险操作,更要一直看得见 */
.g-actvd .g-irow .a { display: flex; justify-content: flex-end; gap: 6px; }
@keyframes actvd-pop { from { opacity: .3; transform: scale(.86); } }
/* 停止钮:危险动作走红 —— 与「禁用活动」同色阶,危险操作永不实心(§11) */
.g-rowbtn.danger { background: #fdf2f2; border-color: #f6c6c3; color: #d83931; }
.g-rowbtn.danger:hover { background: #d83931; border-color: #d83931; color: #fff; }
.g-rowbtn:disabled { opacity: .45; cursor: default; pointer-events: none; }
/* 实例清单分页条:页数信息在左,翻页钮在右 —— 页少不上页码器 */
.g-actvd .g-pager { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.g-actvd .g-pager-n { margin-right: auto; font: 500 11.5px/1.6 var(--mono); color: var(--ink-4); }
.g-actvd .g-pager .g-rowbtn + .g-rowbtn { margin-left: 2px; }
/* —— 沙箱:仿浏览器 chrome 条(圆点 + 地址丸)+ 白盒;iframe 定高 480(postMessage 自适应待议) */
.g-actvd .g-sandbox { position: relative; background: #fff; border: 1px solid #dfe3ea; border-radius: 8px; overflow: hidden; }
.g-actvd .g-sandbox-bar { display: flex; align-items: center; gap: 12px; height: 32px; padding: 0 12px;
background: #f5f7fa; border-bottom: 1px solid #e2e7ee; }
.g-actvd .g-sandbox-bar .dots { display: flex; gap: 5px; }
.g-actvd .g-sandbox-bar .dots i { width: 8px; height: 8px; border-radius: 50%; background: #d5dae2; }
.g-actvd .g-sandbox-bar .addr { display: inline-flex; align-items: center; gap: 5px; height: 20px; padding: 0 10px;
border-radius: 10px; background: #fff; border: 1px solid #e2e7ee;
font: 500 10.5px/1 var(--mono); color: var(--ink-4); }
.g-actvd .g-sandbox-bar .addr svg { color: var(--ink-4); }
.g-actvd .g-sandbox-frame { display: block; width: 100%; height: 480px; border: 0; }
.g-actvd .g-sandbox-load { position: absolute; inset: 32px 0 0; display: flex; align-items: center; justify-content: center; gap: 6px; background: #fff; font-size: 12.5px; color: var(--ink-4); }
/* 动效开关:reduced-motion 时入场全关(§13) */
@media (prefers-reduced-motion: reduce) {
.g-actvd > * { animation: none; }
}
.g-fcard .mbtn { flex: none; width: 26px; height: 26px; display: grid; place-items: center; border: 1px solid transparent; border-radius: 7px; background: transparent; color: var(--ink-4); cursor: pointer; }
.g-fcard .mbtn:hover, .g-fcard .mbtn.on { border-color: var(--cline); background: #f3f6fa; color: var(--ink); }
.g-fcard .mbtn.bad:hover { border-color: #e6c4c4; background: #fdf2f2; color: var(--danger); }