/*=============================================================================
  b36-apicfg.css —— 批次36 「API配置」页签(「配置软件」弹窗第 8 个页签)专用外观

  【为什么单独开一个文件, 而不是往 style.css 里加】
    style.css / b35-forms.css 在并行任务里正被别的子代理改。往既有文件里插规则 = 同一份文件
    被两个人同时写, 必定互相踩。新建文件 + index.html 加一行 <link> 是唯一零冲突的做法,
    这与 gen-modal.css / b35-forms.css / b34-version-page.css 的组织方式完全一致。

  【为什么类名统一 b36- 前缀, 且尽量把选择器限定在 [data-acfgpane="apicfg"] 内】
    这批样式只服务这一个面板, 外溢到别的页面会很难查。前缀 + 容器限定 = 双保险。

  【设计口径: 能不写就不写】
    面板容器 / 表单行 / 开关 / 输入框 / 下拉 / 按钮 / 提示条 / 输出块**全部复用既有构件**
    (.b21-panel .b21-panel-hd .b21-frow .b21-sw .b21-krow .inp .sel .btn .mono .notice
     .b22-dim .code .b21-out), 这里只补三样既有构件里没有的东西:
      ① 端点速查的「键 – 值」两列(.b36-kv)
      ② 使用统计表(.b36-tbl)+ 限高可滚动外框(.b36-tblwrap)
      ③ 页签底部的保存条(.b36-foot)与失败条(.b36-fail)
=============================================================================*/

/*---------------------------------------------------------------------------
  ① 端点速查 / 密钥元信息: 左键右值两列。
     用 grid 而不是 table: 这里的「键」只有几个字, 值可能是一条很长的 URL,
     需要值一列能自由换行且不被撑破(第 2 列 minmax(0,1fr) 是关键, 少了它长 URL 会把弹窗顶宽)。
---------------------------------------------------------------------------*/
.b21-pane[data-acfgpane="apicfg"] .b36-kv {
  display: grid;
  gap: 6px;
  margin-bottom: 10px;
}
.b36-kv-row {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  gap: 10px;
  align-items: baseline;
}
.b36-kv-row > .k { color: #6b7280; font-size: 12.5px; }
.b36-kv-row > code { font-family: var(--mono); font-size: 12px; word-break: break-all; }

/* curl 示例: 复用既有 .code 块, 只把默认的「不换行」改成可换行 ——
   长 URL + 长密钥拼出来的命令行一定有几百像素, 不让它在块里出现横向滚动条。 */
.b36-curl {
  margin: 6px 0 0;
  white-space: pre-wrap;
  word-break: break-all;
}

/* 面板里的小标题(「读配置示例（curl）」/「按分类」/「按卡密」这类分组标签)。
   它比 .b21-panel-hd 低一级: 同一个 .b21-panel 里要分组时才用它。 */
.b36-subhd {
  font-size: 12.5px;
  font-weight: 600;
  color: #374151;
  margin: 12px 0 6px;
}
.b36-subhd:first-child { margin-top: 0; }
/* 小标题里的补充说明(「点下面表里的任意一行…」): 只跟着标题降一级颜色, 但不该跟着加粗 */
.b36-subhd .b22-dim { font-weight: 400; }

/*---------------------------------------------------------------------------
  ② 使用统计表: 可滚动外框 + 仿 .b22-doc-tbl 的观感
     为什么必须限高(max-height + overflow:auto):
       统计是「可能几十上百行」的列表, 不限高会把整块内容撑到视口外面 ——
       弹窗 body 虽然自己能滚, 但用户会一直找不到下面的「保存 API 配置」按钮。
       280px ≈ 8 行, 刚好让用户一眼看到「有没有数据」又不至于挤掉其它面板。
     表头 sticky: 滚动时列名不跟着跑掉。
---------------------------------------------------------------------------*/
.b36-tblwrap {
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: auto;
  max-height: 280px;
}
.b36-tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.b36-tbl th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: #f7f9fc;
  text-align: left;
  font-weight: 600;
  padding: 7px 9px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.b36-tbl td { padding: 6px 9px; border-bottom: 1px solid #eef1f6; vertical-align: top; line-height: 1.6; }
.b36-tbl tbody tr:last-child td { border-bottom: 0; }
.b36-tbl code { font-family: var(--mono); font-size: 12px; word-break: break-all; }
/* 计数列右对齐 + 等宽数字: 多行数字能竖直对齐, 扫一眼就能比大小 */
.b36-tbl .num { text-align: right; font-variant-numeric: tabular-nums; }

/*---------------------------------------------------------------------------
  ③ 空态 / 失败条 / 底部保存条
---------------------------------------------------------------------------*/
/* 空态与「加载中…」: 中文说明, 不用图标堆砌(与项目其余空态文案风格一致) */
.b36-empty { color: #6b7280; font-size: 12.5px; line-height: 1.85; padding: 12px 12px; }

/* 失败条: 中文原因 + 「重试」按钮。颜色沿用站点危险色的浅底版本。
   注意 [hidden] 那条规则: .b36-fail 自己声明了 display:flex, 会盖掉浏览器默认的
   [hidden]{display:none}, 所以必须显式补一条把隐藏态救回来(否则「隐藏」形同虚设)。 */
.b36-fail {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  background: #fff5f5;
  border: 1px solid #ffd4d4;
  color: #b42318;
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 12.5px;
  line-height: 1.7;
}
.b36-fail[hidden] { display: none; }
.b36-fail .why { flex: 1; min-width: 0; }

/* 底部保存条: 用一条上分隔线把它与最后一个面板切开,
   让「保存 API 配置」明显属于**整个页签**而不是某个面板的按钮。 */
.b36-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 14px 0 4px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

/*---------------------------------------------------------------------------
  ④ 「按分类」表可点行 → 下钻筛「按卡密」表
     需求原话是「这些信息支持当前分类查看、当前卡密查看」。两张平铺表只做到了
     「按分类列一遍、按卡密列一遍」; 点分类那行去看它下面的卡密, 才是"查看"。

     为什么不做成下拉筛选: 分类动辄几十个, 在下拉里找一遍, 不如直接点在眼前那一行上。

     为什么选中态写成 tr 上的 class 而不是靠 :has()/:focus:
       每次重新拉数据都是整张表 innerHTML 换掉, 选中态得由 JS 跟着状态一起写回来,
       class 是唯一能跨重渲染活下来的东西。
---------------------------------------------------------------------------*/
.b36-tbl tbody tr.b36-pickable { cursor: pointer; }
.b36-tbl tbody tr.b36-pickable:hover td { background: #f4f7fd; }
.b36-tbl tbody tr.b36-picked td { background: #eaf1ff; }
/* 左侧一条竖线, 让"我筛的是哪一行"在滚动后依然一眼可见(比只靠底色可靠) */
.b36-tbl tbody tr.b36-picked td:first-child { box-shadow: inset 3px 0 0 #4a86ff; }

/* 筛选条: 贴在「按卡密」表上方, 说明当前只看哪个分类, 并给一键取消。
   与 .b36-fail 同构(一行 flex), 但走信息色不是危险色 —— 筛选是正常状态, 不是出错。
   ⚠ 这条必须是 #apicfgByCard **外面**的独立兄弟节点: 表内容整块 innerHTML 换掉是常态,
     放里面会被 statEmpty()/statFail() 顺手抹掉。 */
.b36-pickbar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  background: #f2f7ff;
  border: 1px solid #cfe0ff;
  color: #1f4fa8;
  border-radius: 6px;
  padding: 7px 10px;
  margin-bottom: 6px;
  font-size: 12.5px;
  line-height: 1.7;
}
.b36-pickbar .why { flex: 1; min-width: 0; }
.b36-pickbar code { font-family: var(--mono); font-size: 12px; word-break: break-all; }
/* .b36-pickbar 自己声明了 display:flex, 会盖掉浏览器默认的 [hidden]{display:none},
   必须显式补一条把隐藏态救回来(与 .b36-fail[hidden] 同一个坑)。 */
.b36-pickbar[hidden] { display: none; }

/*---------------------------------------------------------------------------
  ⑤ 批次39: 「客户端读配置」的 7 项改成「统一小格子」(.b39-tiles)

  用户反馈(批次38 的三列竖排): 「看着散、高低不齐」。本批按用户口径重排:
    每个选项 = 一个**等高等宽的浅色小方块**, 格子内 **标签在左、控件在右、同一行**;
    一行 3 个, 7 项 → 3 + 3 + 1(「回读间隔（秒）」单独占最后一行的第一格)。

  为什么另起一个类名而不是改 .b36-grid3:
    批次38 的 .b36-grid3 已经在软件级 / 分类级两个弹窗里生效, 直接就地改会把「谁改了布局」
    这件事从类名上抹掉(后人看到 .b36-grid3 会以为是竖排那套)。新名 .b39-tiles 一眼可辨,
    旧的 .b36-grid3 段整段删除(它只服务这一个块, 没有别的引用)。

  为什么必须覆盖 .b21-frow 本身:
    .b21-frow 在 style.css 里是 `display:grid; grid-template-columns:172px minmax(0,1fr)`,
    标签列固定 172px —— 塞进 1/3 宽的格子里会直接把控件挤出容器。所以这里:
      · 容器 .b39-tiles = 等宽三列(用 minmax(0,1fr), 天然不横向溢出);
      · 格子 .b39-tiles > .b21-frow = flex 单行: 标签 flex:1 1 auto(吃掉剩余空间) +
        控件 **定宽 96px**(flex:0 0 96px)。控件定宽 = 标签长(总开关 / 采集：打开次数)短,
        控件左边缘都不动 → 7 个开关在格子里**纵向对齐成一条线**(本批验收指标)。
    只作用于 .b39-tiles 的直接子 .b21-frow, 用 `>` 限定; 面板里其它 .b21-frow
    (API 密钥 / 地区服务两块)与**其它页签**的 .b21-frow 一律不受影响。
    ★ acfgFrow / acfgSw 的行为一个字没改 —— 这里只加样式。

  窄屏(<760px)退化成单列: 三列时每个格子只剩 ~1/3 宽度, 标签会折成多行。
---------------------------------------------------------------------------*/
.b39-tiles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 10px;
}
/* 浅色小方块: 等高由 grid 的行拉伸保证(同一行 stretch), 行内 align-items:center 让标签与控件同一条中线。
   min-height 取 50(= 数字框 36 + 上下内边距 12 + 上下边框 2)而不是 48:
   「回读间隔」那一格比开关格高 2px, 只按 48 写会让第 3 行与上两行差 2px —— 用户要的是「等高」。 */
.b39-tiles > .b21-frow {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 0;
  box-sizing: border-box;
  min-height: 50px;
  padding: 6px 10px;
  background: #f7f8fa;
  border: 1px solid var(--border);
  border-radius: 6px;
}
/* 标签: 覆盖 style.css 的 `flex: 0 0 110px` 与右对齐, 改为占据剩余空间、左对齐、
   ? 帮助图标紧跟文字(acfgFrow 照旧把 help 放进 label 里, 选择器一字未动)。 */
.b39-tiles > .b21-frow > .lb {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
  min-height: 0;
  justify-content: flex-start;
  text-align: left;
}
/* 控件列定宽 —— 7 个格子里控件左边缘因此唯一 */
.b39-tiles > .b21-frow > .ctl {
  flex: 0 0 96px;
  width: 96px;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 6px;
}
.b39-tiles > .b21-frow > .ctl > .b21-sw { display: flex; align-items: center; }
/* 数字框: .inp 基线是 width:100%, 与右边的「秒」小字同处一个 flex 行会撑破格子,
   故改成按剩余空间伸缩(flex:1 1 0 + min-width:0)。 */
.b39-tiles > .b21-frow > .ctl > .inp {
  flex: 1 1 0;
  width: auto;
  min-width: 0;
  box-sizing: border-box;
}
/* 「秒」只是一个灰色小字 span: 不进 input 的 value、不参与任何读写(collectApiCfg 按 id 读的是 input) */
.b39-unit { flex: 0 0 auto; font-size: 12px; color: var(--fg-dim); }
@media (max-width: 760px) {
  .b39-tiles { grid-template-columns: minmax(0, 1fr); }
}
