/* ============================================================================
   S14.5 第一部分 · 全站唯一按钮类库（1-3-5 收敛）
   ----------------------------------------------------------------------------
   引入铁律：本文件必须放在各页内联 <style> 之后的 <link>，靠「同特异性后加载胜出」
             覆盖各页历史遗留的 button{} / button.mini / .btn-main 等旧样式。
   语义四档：.btn-primary 主操作 / .btn-secondary 次要 / .btn-danger 危险（须二次确认）/ .btn-ghost 中性
   规格三档：.btn-sm 28 / .btn-md 32（默认，可省略）/ .btn-lg 40；.btn-block 弹窗与移动端全宽
   铁律：每个视觉区域 Primary ≤ 1。
   ========================================================================== */

/* ---------- 1. 基础结构（btn 为容器，规格类负责尺寸） ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font: inherit;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  box-sizing: border-box; /* D 批（2026-09-22）：补齐——部分页（competitor/attribution 等）无 `*{box-sizing}` reset */
  border-style: solid;
  border-width: 1px;
  border-radius: 8px;
  padding: 8px 14px;
  font-size: 13px;
  transition: background-color .15s, border-color .15s, color .15s, filter .15s, opacity .15s;
}

/* ---------- 2. 规格三档（19.18.144：圆角全档归一 8px——此前 xs 6 / sm 7 / md 8 / lg 9 四个值，
   跨页同档按钮圆角不同（表格操作列 sm 档 7px vs 页内 .btn 8px）。现全站按钮圆角只留 8px，
   状态 chip/胶囊 999px，图标钮（关闭 ×）6px，例外仅此两处。行高改用 height 定高 + padding 归零） ---------- */
/* D 批（2026-09-22）：三档由 min-height 改 height——原先内容高（font-size×1.2+padding+border）大于 min-height 时高度会漂移
   （实测 .btn-md 在 13px 字号页为 33.6px，在其它页为 32px），同行控件因此对不齐。固定高度后档位恒定：22 / 28 / 32 / 40。 */
.btn.btn-xs { padding: 0 8px; font-size: 12px; border-radius: 8px; height: 22px; gap: 4px; }
.btn.btn-sm { padding: 0 10px; font-size: 12px; border-radius: 8px; height: 28px; }
.btn.btn-md { padding: 8px 14px; font-size: 13px; border-radius: 8px; height: 32px; }
.btn.btn-lg { padding: 0 18px; font-size: 15px; border-radius: 8px; height: 40px; }
.btn.btn-block { width: 100%; }

/* ---------- 3. 语义四档（双类写法提高特异性，稳压历史 button.mini / .btn-main） ---------- */
.btn.btn-primary {
  background: var(--accent, #534AB7);
  border-color: var(--accent, #534AB7);
  color: #fff;
}
.btn.btn-primary:hover { filter: brightness(.92); }

.btn.btn-secondary {
  background: #fff;
  border-color: var(--accent, #534AB7);
  color: var(--accent, #534AB7);
}
.btn.btn-secondary:hover { background: var(--accent-soft, #f7f6fd); }

.btn.btn-danger {
  background: #fff;
  border-color: var(--danger, #B3261E);
  color: var(--danger, #B3261E);
}
.btn.btn-danger:hover { background: #fdeceb; }

.btn.btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--muted, #6b6880);
}
.btn.btn-ghost:hover { background: rgba(15, 18, 40, .06); color: var(--text, #2b2840); }

/* 文字链式按钮（U9：跳转=带箭头文字链） */
.btn.btn-link {
  background: none; border-color: transparent; color: var(--accent, #534AB7);
  padding-left: 4px; padding-right: 4px; text-decoration: underline; text-underline-offset: 3px;
}
.btn.btn-link:hover { filter: brightness(.9); }

/* ---------- 4. 交互状态一套 ---------- */
.btn:hover { text-decoration: none; }
.btn:disabled,
.btn.disabled {
  opacity: .4;
  cursor: not-allowed;
  filter: none;
}
.btn:focus-visible {
  outline: 2px solid var(--accent, #534AB7);
  outline-offset: 2px;
}
.btn.loading { pointer-events: none; opacity: .8; }
.btn.loading::before {
  content: "";
  width: 12px; height: 12px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: geo-btn-spin .7s linear infinite;
  flex: none;
}
@keyframes geo-btn-spin { to { transform: rotate(360deg); } }

/* 键盘可见焦点（全站此前缺失）——只对键盘用户生效，鼠标点击不显示描边 */
a.btn:focus-visible,
button.btn:focus-visible { outline: 2px solid var(--accent, #534AB7); outline-offset: 2px; }

/* ---------- 5. 同行等高（D 批 · 2026-09-22） ---------- */
/* 问题：同一 flex 行内混排时，按钮 28/32px、胶囊 20-28px、输入框 30-39px、
   文字链钮 20-38px 各走各的高度，渲染出来参差不齐（用户 0922 截图反馈）。
   口径：一行只允许一个控件高度——紧凑档 30px（--ctl-h，与 select.gsel 同档）、
        表单档 34px（--ctl-h-lg，与 select.gsel-lg 同档）。
   用法：给筛选行 / 工具行 / 操作条容器挂 .ctl-row（紧凑档）或 .ctl-row-lg（表单档），
        行内【直接子控件】自动等高；嵌套复合控件（.seg-ctl 内的 .seg-btn、
        .num-step 内的步进钮等）不被压缩，保持自身设计尺寸。
   注：.btn 系规则用 `.ctl-row > .btn.btn` 双类写法（0,2,1）——必须压过
       geo-btn.css 自身的 `.btn.btn-md`（0,2,0）min-height:32px，单类写法压不住。 */
.ctl-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ctl-row-lg { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.ctl-row > .btn.btn,
.ctl-row > button,
.ctl-row > input,
.ctl-row > select,
.ctl-row > .fclear,
.ctl-row > .oplink,
.ctl-row > .tag,
.ctl-row > .chip { box-sizing: border-box; height: var(--ctl-h, 30px); min-height: 0; }

.ctl-row-lg > .btn.btn,
.ctl-row-lg > button,
.ctl-row-lg > input,
.ctl-row-lg > select,
.ctl-row-lg > .fclear,
.ctl-row-lg > .oplink { box-sizing: border-box; height: var(--ctl-h-lg, 34px); min-height: 0; }

/* 行内除 input/select 外的控件统一走 inline-flex 居中（胶囊/文字链钮原为 inline-block，
   定高后文字会贴顶）；竖直 padding 归零，左右留白保持各自原值 */
.ctl-row > .btn.btn,
.ctl-row > button,
.ctl-row > .fclear,
.ctl-row > .oplink,
.ctl-row > .tag,
.ctl-row > .chip,
.ctl-row-lg > .btn.btn,
.ctl-row-lg > button,
.ctl-row-lg > .fclear,
.ctl-row-lg > .oplink { display: inline-flex; align-items: center; justify-content: center; padding-top: 0; padding-bottom: 0; }

.ctl-row > input,
.ctl-row > select,
.ctl-row-lg > input,
.ctl-row-lg > select { padding-top: 0; padding-bottom: 0; }

/* ---------- 6. 全站控件收敛层（19.18.142 · 全站按钮/胶囊规格统一批） ----------
   背景（本批实测根因，三类漂移）：
   ① 裸标签各页重置：8 个页面各自内联 `button{}`（content/assets/dashboard/tm-admin/
      tm-articles/paid-ad = 紫底 7px16px r8；settings = 白底 7px14px r6；login = 全宽主按钮），
      与本文件 `.btn` 的固定 height 档位两套并存 → 同一行里「带 class 的 .btn」与「裸 button」
      高矮胖瘦不一（用户截图：内容工作台纠偏专区两钮、监测中心总览工具条参差）。
   ② 遗留档位名五套：mini / sm / btn-mini / btn-s / ghost / pri / blue / btn-p / danger
      与本文件 btn-sm / btn-secondary / btn-primary 同义不同名，且各页取值不同
      （.btn.mini 三套、button.ghost 九套、.chip 四套、.fchip 两套、.seg-btn/.vtab 各两套）。
   ③ 页内另立色板：dashboard.html 内联把 .btn 语义色改成原型蓝（#1d63ed / #e02d2d /
      #5b6472），与全站紫主色不同源 → 同一产品出现两套按钮颜色（用户截图「按钮颜色不统一」）。

   本层口径（全站唯一）：
   · 语义四档 primary 实心主色 / secondary 白底主色边 / danger 白底红边 / ghost 无边透明字
   · 规格四档 22 / 28 / 32（默认） / 40；行内混排一律 30px（--ctl-h）或 34px（--ctl-h-lg）
   · 圆角只留三值：胶囊 999（状态片/筛选 chip）、6~9px（按钮，按档位）
   · 颜色只走 var(--accent) / var(--danger) / var(--muted)，页内不得另立色板
   铁律：新增按钮一律写 `.btn` + 规格类 + 语义类；遗留类名由本层兜住，不必逐页改 markup。 */

/* 6.1 裸标签兜底：未带 class 的 <button> 一律按 .btn.btn-md 渲染。
   【19.18.148 修正 · 重要】原选择器是裸 `button`，把「带 class 但页面自定义造型」的按钮也一起压成了 32px ——
   典型受害者：媒体采购的 `.tbtn`（类型大卡：主名 15px + 副名 10.5px + 数量徽标，两行内容需 ~52px），
   被压到 32px 后文字溢出裁切（用户截图「PR Newswire / Google」被切一半）。
   改为 `button:not([class])`：只兜「完全没写 class 的裸按钮」（页内 button{} 私有重置那八页的未分类按钮、
   tm-app.js 的 #favPrev/#favNext 等），带 class 的一律由自身类或 §6.2~6.7 决定高度 —— 各页自定义造型不被误伤。
   【19.18.151 修正 · 重要】148 收窄后仍漏一类：**导航型页签按钮恰好都没写 class**（页签靠父容器 .tabs/.view-tabs
   与选中态类定位，自身无需 class），于是被本兜底刷成实心主色底 —— 媒体采购四个页签**全部**变紫底白字、
   选中态完全不可辨（用户截图「正常样式应该是这样子才对 目前改错了吧」）；同源受害：dashboard 竞品作战 4 个
   data-sub 子页签、cms 9 个 data-tab/data-st 子导航、attribution 1 个、assets 1 个 data-dtab，共 18 个导航按钮。
   本兜底的语义是「操作按钮」而非「层级导航」，故按导航语义属性排除（各页页签的切换属性已统一为
   data-tab / data-sub / data-dtab / data-st / role=tab）；操作型裸按钮（cms 的「AI 生成配图」、paid-ad 的
   「生成」、tm-admin 的「保存凭据」等）仍按 .btn.btn-md 渲染，行为不变。
   特异性 (0,5,1) 仍高于页内裸 `button{}` (0,0,1)，压得住历史私有重置。 */
button:not([class]):not([data-tab]):not([data-sub]):not([data-dtab]):not([data-st]):not([role="tab"]) {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  box-sizing: border-box; height: 32px; padding: 0 14px;
  font-family: inherit; font-size: 13px; font-weight: 600; line-height: 1.2;
  white-space: nowrap; cursor: pointer;
  border: 1px solid var(--accent, #534AB7);
  background: var(--accent, #534AB7); color: #fff;
  border-radius: 8px;
  transition: background-color .15s, border-color .15s, color .15s, filter .15s, opacity .15s;
}
/* 6.1b 被排除的导航型按钮：只回收「实心底」这一件事。
   刻意**不写** border / height / padding / border-radius —— 这些由各页自己的页签规则负责
   （cms `.tabs button[data-tab]` 药丸带边框、tm `.tabs button` 下划线式无边框、dashboard `button[data-sub]` 另立规格）；
   本层特异性 (0,5,1) 高于页内规则，若在此处写死边框高度圆角会把页内形态整片抹掉（实测 cms 药丸曾被压成裸文字）。
   只设 background/color 两项兜住「不吃实心底 + 不至于无色」，其余一律放行。 */
button:not([class]):is([data-tab], [data-sub], [data-dtab], [data-st], [role="tab"]) {
  background: none; color: var(--muted, #6b6880);
  font-family: inherit; cursor: pointer;
  transition: color .15s, background-color .15s;
}
button:not([class]):is([data-tab], [data-sub], [data-dtab], [data-st], [role="tab"]):hover {
  color: var(--accent, #534AB7);
}

/* 6.2 遗留档位别名 → 本文件规格/语义档
   规格：.mini / .sm / .btn-mini / .btn-s → btn-sm 档（28px / 12px）
   语义：.ghost → secondary（白底主色边 + 主色字，全站六成页面本来的口径）
        .pri / .blue / .btn-p → primary   ·   .danger → danger
   写法用双类（0,2,0）确保压过各页内联的同名单类规则（本文件后加载）。 */
.btn.mini, button.mini, .btn.btn-mini, .btn.sm, .btn.btn-s,
.btn.ghost.mini, button.ghost.mini, .mini.ghost, .btn.mini.ghost {
  height: 28px; padding: 0 10px; font-size: 12px; border-radius: 8px; gap: 4px;
}
.btn.ghost, button.ghost, .btn.ghost:not(.btn-primary):not(.btn-danger) {
  background: #fff; border-color: var(--accent, #534AB7); color: var(--accent, #534AB7);
  font-weight: 600; height: 32px; border-radius: 8px; padding: 0 14px; font-size: 13px;
}
.btn.ghost:hover, button.ghost:hover { background: var(--accent-soft, #f7f6fd); }
.btn.pri, .btn.blue, .btn.btn-p {
  background: var(--accent, #534AB7); border-color: var(--accent, #534AB7);
  color: #fff; font-weight: 600;
}
.btn.danger, .btn.btn-danger-ghost {
  background: #fff; border-color: var(--danger, #B3261E); color: var(--danger, #B3261E);
}

/* 6.3 状态 chip 统一（content/assets/publish 三套 + tm 域自有除外——tm-mall.css 更晚加载）
   口径：高 22px 胶囊、12px、inline-flex 垂直居中（修原先 display:inline-block 造成的基线错位）。 */
.chip {
  display: inline-flex; align-items: center; gap: 4px;
  box-sizing: border-box; height: 22px; padding: 0 10px;
  border: 1px solid transparent; border-radius: 999px;
  background: #f1f0f6; color: var(--muted, #6b6880);
  font-size: 12px; line-height: 1; white-space: nowrap; vertical-align: middle;
}
.chip.line { background: transparent; border-color: var(--line, #e6e4f0); color: var(--muted, #6b6880); }

/* 6.4 分段控件（.seg-ctl 壳 + .seg-btn 钮）统一到行内紧凑档 30px。
   只作用于这一套类名；content 的 .seg（连排药丸）与 tm 域自有分段控件不受影响。 */
.seg-ctl { box-sizing: border-box; height: var(--ctl-h, 30px); padding: 2px; }
.seg-ctl .seg-btn { box-sizing: border-box; height: 100%; padding: 0 14px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; line-height: 1; border-radius: 8px;
}
/* 连排药丸分段（.seg，无定高壳）用固定紧凑档，避免 height:100% 塌陷成内容高 */
.seg .seg-btn, .seg button {
  box-sizing: border-box; height: 28px; padding: 0 14px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; line-height: 1; border-radius: 8px;
}

/* 6.5 工具/筛选行等高：同一行内按钮·胶囊·下拉·输入框·清除链钮统一 30px（= --ctl-h）。
   覆盖全站六类常用行容器，替代逐页手调 padding。只作用【直接子控件】，
   行内的复合控件（.seg-ctl 内的 .seg-btn、.num-step 步进钮）按 §5 豁免。 */
.filterbar > .btn, .filterbar > button, .filterbar > input, .filterbar > select,
.filterbar > .gsel, .filterbar > .fclear, .filterbar > .chip, .filterbar > .fchip,
.filterbar > .kn-tab, .filterbar > .oplink, .filterbar > .kn-src,
.fbar > .btn, .fbar > button, .fbar > input, .fbar > select, .fbar > .gsel,
.fbar > .fclear, .fbar > .chip, .fbar > .oplink,
.kn-tabs > button, .kn-tabs > .gsel, .kn-tabs > .fclear, .kn-tabs > input,
.opbar > .btn, .opbar > button, .opbar > .gsel, .opbar > .fclear,
.toolbar > .btn, .toolbar > button, .toolbar > .gsel, .toolbar > input,
.bulk > .btn, .bulk > button, .bulk > .gsel {
  box-sizing: border-box; height: var(--ctl-h, 30px); min-height: 0;
  display: inline-flex; align-items: center; justify-content: center;
  padding-top: 0; padding-bottom: 0;
}

/* 6.6 页签（视图切换）高度统一 36px —— 治「切页签后条高跳变」。
   实测各页私有页签七套高度：geo-ui .gui-subnav 39（继承 line-height 1.65 撑高）/ content .tabs 32 /
   assets .view-tabs .vtab 33 / publish .dtab 35 / tm-articles .atab 32 / cms [data-tab] 35 /
   tm-admin .pagetab .tab 35 / tm .tabs button 32。形态（下划线式 / 药丸式）各自保留，只统一高度与垂直居中。
   说明：页签属「层级导航」而非操作控件，故不参与 §6.5 的 30px 行内等高。 */
.tabs > button, .tabs button[data-tab], .vtab, .view-tabs .vtab, .dtab, .atab,
.pagetab .tab, .pagetab .tab, .gui-subnav > a, .gui-subnav > button {
  box-sizing: border-box; height: 36px; min-height: 0; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  padding-top: 0; padding-bottom: 0;
}
/* 药丸式页签圆角归 8（publish .dtab 9px / tm-articles .atab 8px / tm-admin .pagetab .tab 8px 此前不齐）；
   下划线式（.tabs button / .vtab）保留 8px 8px 0 0 顶部圆角形态，不在此归一。 */
.dtab, .atab, .pagetab .tab { border-radius: 8px; }

/* 6.7 第二层控件档（19.18.144）——§6.1~6.6 管的是「标准按钮与页签」，本节收四类此前完全没有
   规格约束的控件，是"同一屏控件参差"的主要残留源（实测清单见 version.php 对应条目）：
   ① 表格操作列小按钮：跨页三套形态（content/assets 用 .btn 或 span.e5-act 文字链、tm 域用 .opmini
      实心五色 11.5px），统一为 22px（btn-xs 档）圆角 6px 12px 按钮；语义色（删除=危险、启用=成功）
      以色彩表达，不再靠"有框/无框"区分。
   ② 关闭钮（×）：GeoModal .gm-x / geo-ui .gui-nextbar-x / content 自建弹层 .mh .x / tm 抽屉 .x
      此前 16~20px 无定高 → 统一 28×28 方形、图标居中（点按热区达标且同屏一致）。
      注：.gm-x 由 geo-modal.js 运行时注入（更晚加载），须在 geo-modal.js 内改，本节用 .gm-x 兜底无效。
   ③ 提示问号（ⓘ/ⓢ 圆形）：geo-tooltip button.info 与 .geo-term 16px、tm-mall .thtip 14px
      → 统一 20px 圆形（可点而不喧宾夺主；行内等高不参与，高度固定即视觉基准一致）。
   ④ 分页与图标小钮：.pgn button / .fav-pgn button / .geo-pagi .pg / JS 拼接的 span.pg
      此前 22~32px 混排 → 统一 28px；.ic-btn 24px → 28px。 */
.e5-act, .e5-act.del, .e5-act.on {
  display: inline-flex; align-items: center; justify-content: center;
  box-sizing: border-box; height: 22px; min-width: 34px; padding: 0 8px;
  border: 1px solid var(--line, #e6e4f0); border-radius: 8px; background: #fff;
  font-size: 12px; line-height: 1; color: var(--muted, #6b6880); cursor: pointer;
  white-space: nowrap; transition: border-color .15s, color .15s, background-color .15s;
}
.e5-act:hover { border-color: var(--accent, #534AB7); color: var(--accent, #534AB7); }
.e5-act.del { color: var(--danger, #B3261E); border-color: rgba(179, 38, 30, .35); }
.e5-act.del:hover { background: #fdeceb; border-color: var(--danger, #B3261E); }
.e5-act.on { color: var(--ok, #16a34a); border-color: rgba(22, 163, 74, .35); }
.e5-act.on:hover { background: #f0fdf4; border-color: var(--ok, #16a34a); }

.gui-nextbar-x, .mh .x, .sheet h3 .x {
  display: inline-flex; align-items: center; justify-content: center;
  box-sizing: border-box; width: 28px; height: 28px; min-width: 28px; padding: 0;
  border: 0; border-radius: 6px; background: none; color: var(--muted, #6b6880);
  font-size: 16px; line-height: 1; cursor: pointer;
}
.gui-nextbar-x:hover, .mh .x:hover, .sheet h3 .x:hover { background: var(--accent-soft, #f0edff); color: var(--accent, #534AB7); }

button.info, .geo-term, .thtip {
  display: inline-flex; align-items: center; justify-content: center;
  box-sizing: border-box; width: 20px; height: 20px; min-width: 20px;
  border-radius: 50%; font-size: 11px; line-height: 1;
}

.pgn button, .pgn button.on, .fav-pgn button, .geo-pagi .pg, .geo-pagi .pg.dis, span.pg {
  display: inline-flex; align-items: center; justify-content: center;
  box-sizing: border-box; min-width: 28px; height: 28px; padding: 0 6px; border-radius: 8px;
}
.ic-btn { box-sizing: border-box; height: 28px; min-height: 0; }
