/* 开发者平台（pages/devadmin.js，docs/specs/dev-admin.md）。归 M1 平台。类名都以 dv- 开头。
   颜色、字号、圆角都用 app.css 的变量；柱状图照 dataviz 的规矩：柱最宽 24px、顶上 4px 圆角、相邻的段和柱之间 2px 白缝、细网格线。 */

.dv-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 14px; }
.dv-head h1 { margin: 0; }

/* 分页：一排文字链接，选中的下面一道线；手机上放不下就横着滑 */
.dv-tabs { display: flex; gap: 4px; margin: 18px 0 22px; padding: 0 0 1px; overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid var(--line); }
.dv-tabs::-webkit-scrollbar { display: none; }
.dv-tabs a { flex: none; position: relative; padding: 8px 12px 10px; color: var(--muted); font-size: var(--fs-body); font-weight: var(--fw-medium);
  text-decoration: none; border-radius: var(--radius-xs) var(--radius-xs) 0 0; transition: color var(--dur-2) ease; }
.dv-tabs a:hover { color: var(--ink); text-decoration: none; }
.dv-tabs a.on { color: var(--ink); }
.dv-tabs a.on::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: -1px; height: 2px; border-radius: 2px; background: var(--ink); }
.dv-body > * + *, .dv-ov > * + *, .dv-one > * + * { margin-top: 18px; }
.dv-busy { opacity: .55; transition: opacity var(--dur-2) ease; }

/* 统计条：用 app.css 的 .cards；里面多一条用量的进度 */
.dv-cards .card .dv-meter { margin-top: 10px; }
.dv-cards .card .s { white-space: normal; }
.dv-cards .card .v.over { color: var(--red); }
.dv-hero-t { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 14px; }
.dv-hero-t h2 { margin: 0; font-size: var(--fs-2); }
.dv-hero > .small { margin-top: 4px; }   /* 这里的小字要写全（谁付的钱），放不下就换行 */
.dv-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
@media (max-width: 900px) { .dv-two { grid-template-columns: minmax(0, 1fr); } }

/* 一行「名字　值」，宽屏两三列 */
.dv-kvs { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px 24px; }
.dv-kv { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dv-kv > span { font-size: var(--fs-xs); color: var(--muted); }
.dv-kv > b { font-weight: var(--fw-medium); color: var(--ink); overflow-wrap: anywhere; }
.dv-n { font-variant-numeric: tabular-nums; }

/* 状态：一个圆点加一句话（颜色不单独表意） */
.dv-st { display: inline-flex; align-items: center; gap: 7px; min-width: 0; }
.dv-table .dv-st { white-space: nowrap; }
.dv-st > .dot { width: 8px; height: 8px; }

/* 每天上限用了多少：浅色的槽、深一点的填充；到八成用黄、到上限用红 */
.dv-meter { display: block; width: 100%; min-width: 60px; height: 6px; border-radius: 3px; overflow: hidden; background: var(--tint-soft); }
.dv-meter > i { display: block; height: 100%; border-radius: 3px; background: var(--tint); }
.dv-meter.near { background: var(--yellow-soft); }
.dv-meter.near > i { background: var(--yellow); }
.dv-meter.over { background: var(--red-soft); }
.dv-meter.over > i { background: var(--red); }

/* 微信、邮件、教学网三个小标记 */
.dv-chs { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.dv-ch { display: inline-flex; align-items: center; height: 20px; padding: 0 7px; border-radius: var(--radius-pill); font-size: 11.5px; white-space: nowrap;
  color: var(--muted); background: var(--soft); }
.dv-ch.ok { color: var(--green); background: var(--green-soft); }
.dv-ch.warn { color: var(--yellow-ink); background: var(--yellow-soft); }
.dv-ch.wait { color: var(--tint); background: var(--tint-soft); }   /* 在等同学说话：不是故障 */
.dv-ch.error { color: var(--red); background: var(--red-soft); }

.dv-uid { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
a.dv-uid { color: var(--link); }
.dv-num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.dv-back { display: inline-block; margin-bottom: 10px; color: var(--muted); text-decoration: none; }
.dv-back:hover { color: var(--ink); text-decoration: none; }

/* 搜索和排序一行（别叫 dv-bar：那是柱状图的柱子） */
.dv-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.dv-q { flex: 1 1 260px; max-width: 360px; }
.dv-tools .seg { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.dv-tools .seg button { flex: none; white-space: nowrap; }
@media (max-width: 760px) { .dv-q { max-width: none; } .dv-tools .seg button { padding: 4px 10px; } }
.dv-count { margin: 0 0 8px; }

/* 表格：细线隔行，数靠右对齐；放不下就在框里横着滑 */
.dv-scroll { overflow-x: auto; margin: 0 -4px; padding: 0 4px; }
.dv-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.dv-table th { padding: 8px 10px; text-align: left; font-size: var(--fs-xs); font-weight: var(--fw-medium); color: var(--muted); white-space: nowrap;
  border-bottom: 1px solid var(--line-2); }
.dv-table td { padding: 10px; vertical-align: top; border-bottom: 1px solid var(--line); font-variant-numeric: tabular-nums; white-space: nowrap; }
.dv-table :is(.dv-wrap, .dv-acct) { display: block; min-width: 140px; max-width: 360px; white-space: normal; }   /* 长的字（提醒标题、出错原因、账户）才换行 */
.dv-table tbody tr:last-child td { border-bottom: 0; }
.dv-acc tbody tr { cursor: pointer; transition: background-color var(--dur-1) ease; }
.dv-acc tbody tr:hover { background: var(--soft); }
.dv-acc td { vertical-align: middle; }
.dv-table .dv-acct { display: flex; flex-direction: column; gap: 1px; min-width: 150px; max-width: 230px; }
.dv-acct > a { font-weight: var(--fw-head); color: var(--ink); }
.dv-today { display: flex; flex-direction: column; gap: 5px; min-width: 120px; }
.dv-stack { display: flex; flex-direction: column; gap: 1px; }
.box > .dv-acc, .box > .dv-scroll { margin-top: 10px; }
.box h4 { margin: 22px 0 6px; font-size: var(--fs-sm); font-weight: var(--fw-head); }

/* 调每天上限：调过的一行说明（带「恢复默认」），改的那块收在一个 details 里 */
.dv-adj-now { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-top: 12px; }
.dv-adj { margin-top: 12px; }
.dv-adj > summary { cursor: pointer; font-size: var(--fs-sm); color: var(--link); }
.dv-adj-f { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 10px 0 4px; }
.dv-adj-in { width: 110px; }

/* 手机上：账户表一行变成一张卡片，每格前面写表头 */
@media (max-width: 760px) {
  .dv-acc thead { display: none; }
  .dv-acc, .dv-acc tbody, .dv-acc tr, .dv-acc td { display: block; width: 100%; }
  .dv-acc tr { padding: 12px 2px; border-bottom: 1px solid var(--line); }
  .dv-acc td { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 4px 0; border: 0; }
  .dv-acc td::before { content: attr(data-l); flex: none; font-size: var(--fs-xs); color: var(--muted); }
  .dv-acc td:first-child { padding-bottom: 6px; }
  .dv-acc td:first-child::before { content: none; }
  .dv-today, .dv-stack { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 4px 10px; min-width: 0; }
  .dv-today .dv-meter { width: 80px; }
}

/* ---------------------------------------------------------------- 柱状图 */
.dv-chart { margin: 14px 0 0; }
.dv-legend { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-bottom: 12px; font-size: var(--fs-xs); color: var(--text); }
.dv-legend > span { display: inline-flex; align-items: center; gap: 6px; }
.dv-legend i { width: 10px; height: 10px; border-radius: 2px; }
.dv-plot { position: relative; height: 168px; margin-left: 46px; }
.dv-gl { position: absolute; left: 0; right: 0; height: 0; border-top: 1px solid var(--line); }
.dv-gl:first-child { border-top-color: var(--line-2); }
.dv-gl > span { position: absolute; right: calc(100% + 8px); top: -8px; font-size: 11px; line-height: 16px; color: var(--muted); white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.dv-cols { position: absolute; inset: 0; display: flex; align-items: flex-end; gap: 2px; }
.dv-col { flex: 1 1 0; min-width: 0; height: 100%; display: flex; align-items: flex-end; justify-content: center; padding: 0; border: 0; border-radius: 0;
  background: none; box-shadow: none; cursor: default; }
.dv-col:hover, .dv-col:active { background: none; }
.dv-col:hover .dv-bar, .dv-col:focus-visible .dv-bar { filter: brightness(1.12); }
.dv-col:focus-visible { outline: 2px solid var(--tint); outline-offset: 1px; border-radius: 4px; }
.dv-bar { display: flex; flex-direction: column-reverse; align-items: stretch; gap: 2px; width: min(24px, 100%); min-height: 0;
  border-radius: 4px 4px 0 0; overflow: hidden; }   /* 每一段撑满柱宽；顶上的圆角靠 overflow 裁出来 */
.dv-seg { display: block; width: 100%; flex-basis: 0; min-height: 1px; }
.dv-x { display: flex; gap: 2px; margin: 6px 0 0 46px; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.dv-x > span { flex: 1 1 0; min-width: 0; display: flex; justify-content: center; white-space: nowrap; }
.dv-tip { position: absolute; bottom: calc(100% + 6px); z-index: 2; min-width: 120px; padding: 8px 10px; border-radius: var(--radius-sm); pointer-events: none;
  background: var(--panel); box-shadow: var(--shadow); border: 1px solid var(--line); font-size: var(--fs-xs); color: var(--text); white-space: nowrap; }
.dv-tip[hidden] { display: none; }
.dv-tip-d { margin-bottom: 4px; color: var(--muted); }
.dv-tip-r { display: flex; align-items: center; gap: 6px; }
.dv-tip-r > i { width: 10px; height: 2px; border-radius: 1px; }
.dv-tip-r > b { font-weight: var(--fw-head); color: var(--ink); font-variant-numeric: tabular-nums; }
.dv-tip-r > span { color: var(--muted); }
.dv-tip-sum { margin-top: 2px; padding-left: 16px; }
.dv-tip-x { margin-top: 2px; color: var(--muted); }
.dv-tbl { margin-top: 10px; }
.dv-tbl > summary { cursor: pointer; font-size: var(--fs-xs); color: var(--muted); }
.dv-tbl .dv-scroll { max-height: 280px; overflow-y: auto; margin-top: 6px; }
@media (max-width: 640px) { .dv-plot { height: 140px; margin-left: 38px; } .dv-x { margin-left: 38px; } }

/* ---------------------------------------------------------------- 一个账户：最近在用它做什么（一件一件，新的在上）
   同学说的话照原样换行；从哪来的小圆点和对话里一样（微信绿、网页蓝）。 */
.dv-case-sum > p { margin: 4px 0 0; }
.dv-case-sum > p:first-child { margin-top: 0; }
.dv-cases { display: flex; flex-direction: column; margin-top: 12px; }
.dv-case { min-width: 0; padding: 12px 0; border-top: 1px solid var(--line); }
.dv-case-h { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; font-size: var(--fs-xs); color: var(--muted); }
.dv-src { display: inline-flex; align-items: center; gap: 6px; font-weight: var(--fw-medium); color: var(--text); }
.dv-src::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--faint); }
.dv-src.is-wechat::before { background: var(--green); }
.dv-src.is-web::before { background: var(--tint); }
.dv-said { margin-top: 6px; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }
.dv-quote { margin-bottom: 4px; padding-left: 8px; border-left: 2px solid var(--line-2); font-size: var(--fs-xs); color: var(--muted); white-space: pre-wrap; }
.dv-did { margin-top: 6px; font-size: var(--fs-sm); color: var(--text); overflow-wrap: anywhere; }
.dv-did-l { display: inline-block; margin-right: 8px; padding: 0 7px; border-radius: var(--radius-pill); font-size: 11.5px; line-height: 18px;
  color: var(--green); background: var(--green-soft); }
.dv-said-x { margin-top: 4px; overflow-wrap: anywhere; }
.dv-reply { margin-top: 6px; }
.dv-reply > summary { cursor: pointer; font-size: var(--fs-xs); color: var(--muted); }
.dv-reply-t { margin-top: 6px; padding: 8px 10px; border-radius: var(--radius-sm); background: var(--soft); font-size: var(--fs-sm); color: var(--text);
  white-space: pre-wrap; overflow-wrap: anywhere; }
.dv-more { align-self: flex-start; margin-top: 10px; }
/* 班次明细：收在使用历史最下面 */
.dv-shifts { margin-top: 22px; }
.dv-shifts > summary { font-size: var(--fs-sm); font-weight: var(--fw-head); color: var(--ink); }
.dv-shifts .dv-scroll { max-height: none; }

/* ---------------------------------------------------------------- 积木笔记窗口（#admin-jimu） */
.dv-jm-hint { margin: 0 0 4px; }
/* 课名、同学名点了只看那一门、那一位：看着像链接的按钮 */
.dv-jm-pick { padding: 0; border: 0; background: none; box-shadow: none; color: var(--link); font: inherit; text-align: left; cursor: pointer; }
.dv-jm-pick:hover:not(:disabled), .dv-jm-pick:active:not(:disabled) { background: none; text-decoration: underline; }
.dv-acct > .dv-jm-pick { font-weight: var(--fw-head); color: var(--ink); }
.dv-ct td:first-child { white-space: normal; min-width: 120px; }
.dv-ct tr.on { background: var(--tint-soft); }

/* 手机上：一行变成一张卡片，每格前面写表头（和账户表一样） */
@media (max-width: 760px) {
  .dv-ct thead { display: none; }
  .dv-ct, .dv-ct tbody, .dv-ct tr, .dv-ct td { display: block; width: 100%; }
  .dv-ct tr { padding: 10px 2px; border-bottom: 1px solid var(--line); }
  .dv-ct td { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 3px 0; border: 0; white-space: normal; text-align: right; }
  .dv-ct td::before { content: attr(data-l); flex: none; font-size: var(--fs-xs); color: var(--muted); text-align: left; }
  .dv-ct td:first-child { justify-content: flex-start; text-align: left; font-weight: var(--fw-medium); }
  .dv-ct td:first-child::before { content: none; }
  .dv-ct .dv-wrap { min-width: 0; max-width: none; }
  .dv-ct .dv-acct { min-width: 0; max-width: none; }
}

/* ---------------------------------------------------------------- 核心数据的表格（pages/devcore.js）：类名 dv-u- 开头，原来是「功能使用」的，那一页 10-20 删了 */
.dv-u-dev { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm); color: var(--text); cursor: pointer; }
.dv-u-d { font-size: var(--fs-xs); color: var(--muted); }
.dv-u-d.up { color: var(--green); }
.dv-u-d.down { color: var(--red); }
.dv-u-tbl th:nth-child(n+2), .dv-u-tbl td:nth-child(n+2) { text-align: right; }
.dv-u-tbl td:first-child { width: 50%; }
/* 手机上：用量表一行变一张卡片：名字一行，几个人、几次、比前一段排一行，趋势在后面 */
@media (max-width: 760px) {
  .dv-u-tbl thead { display: none; }
  .dv-u-tbl, .dv-u-tbl tbody { display: block; width: 100%; }
  .dv-u-tbl tr { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; padding: 10px 2px; border-bottom: 1px solid var(--line); }
  .dv-u-tbl td, .dv-u-tbl td:nth-child(n+2) { display: inline-flex; align-items: center; gap: 6px; width: auto; padding: 0; border: 0; text-align: left; }
  .dv-u-tbl td::before { content: attr(data-l); font-size: var(--fs-xs); color: var(--muted); }
  .dv-u-tbl td:first-child { width: 100%; font-weight: var(--fw-medium); }
  .dv-u-tbl td:first-child::before, .dv-u-tbl td:last-child::before { content: none; }
  .dv-u-tbl td:last-child { margin-left: auto; }
  .dv-u-ret .dv-u-tbl td:last-child::before { content: attr(data-l); }   /* 留存表最后一列是数，要列名 */
}

/* 反馈（pages/devfeedback.js） */
.box .dv-fb-list > .dv-fb { padding: 12px 0; }
.dv-fb .dv-fb-who { display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 0 4px; }
.dv-fb-text { margin-top: 8px !important; font-size: 15px; line-height: 1.65; }
.dv-fb-sum { padding: 6px 10px; border-radius: var(--radius-xs); background: var(--soft); }
.dv-fb-reply { margin-top: 8px !important; padding: 6px 10px; border-left: 2px solid var(--tint); background: var(--soft); border-radius: 0 var(--radius-xs) var(--radius-xs) 0; }
.dv-fb-rp textarea { display: block; width: 100%; margin: 6px 0; resize: vertical; }

/* 核心数据（pages/devcore.js，#admin-core，docs/specs/core-metrics.md）：类名 dv-c- 开头，表格用上面的 dv-u-tbl */
.dv-col-mk .dv-bar { opacity: .55; }   /* 柱状图里标出来的日子：淡一点 */
.dv-c-how { margin: 6px 0 0; padding-left: 18px; color: var(--text); line-height: 1.7; }
.dv-c-demographics { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; align-items: start; }
.dv-c-demographics h4 { margin-bottom: 4px; }
.dv-c-dist { margin: 16px 0; }
.dv-c-dist-head { display: flex; justify-content: space-between; gap: 12px; font-size: var(--fs-sm); }
.dv-c-dist-head > span { overflow-wrap: anywhere; }
.dv-c-dist-head > b { white-space: nowrap; font-weight: var(--fw-medium); }
.dv-c-dist-bar { display: flex; height: 6px; margin-top: 6px; background: var(--soft); border-radius: 4px; overflow: hidden; }
.dv-c-dist-bar > .direct { background: #2a78d6; }
.dv-c-dist-bar > .inferred { background: #eb9b34; }
.dv-c-dist-bar > .unknown { background: var(--muted); }
.dv-c-dist > p { margin: 4px 0 0; }
@media (max-width: 850px) { .dv-c-demographics { grid-template-columns: 1fr; gap: 8px; } }

/* 总览四个数下面收起的几块（模型花费对账、北大资讯初筛试验） */
.dv-fold { margin-top: 14px; }
.dv-fold > summary { cursor: pointer; font-size: var(--fs-sm); color: var(--muted); }

/* ---------------------------------------------------------------- 一个账户：微信聊天记录（旧的在上，同学的在右、助手和提醒在左，和手机微信一样） */
.dv-wx { display: flex; flex-direction: column; gap: 10px; max-height: 70vh; overflow-y: auto; margin-top: 10px; padding: 12px;
  border-radius: var(--radius-sm); background: var(--soft); }
.dv-wx-more { align-self: center; }
.dv-wx-day { align-self: center; margin-top: 6px; font-size: var(--fs-xs); color: var(--muted); }
.dv-wx-row { display: flex; flex-direction: column; align-items: flex-start; max-width: 78%; min-width: 0; }
.dv-wx-row.is-me { align-self: flex-end; align-items: flex-end; }
.dv-wx-meta { margin-bottom: 2px; font-size: var(--fs-xs); color: var(--muted); }
.dv-wx-bub { padding: 8px 11px; border-radius: var(--radius-sm); background: var(--panel); border: 1px solid var(--line); font-size: var(--fs-sm);
  color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; max-width: 100%; }
.dv-wx-row.is-me .dv-wx-bub { background: var(--green-soft); border-color: transparent; }
.dv-wx-row.is-push .dv-wx-bub { border-style: dashed; color: var(--text); }
.dv-wx-atts { display: flex; flex-direction: column; gap: 7px; margin-top: 7px; white-space: normal; }
.dv-wx-bub > .dv-wx-atts:first-child { margin-top: 0; }
.dv-wx-att { padding: 8px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel); min-width: 0; }
.dv-wx-att.is-failed { border-color: var(--red); }
.dv-wx-att-name { overflow-wrap: anywhere; }
.dv-wx-att-link { display: block; color: var(--blue); }
.dv-wx-att-meta { margin-top: 3px; font-size: var(--fs-xs); color: var(--muted); }
.dv-wx-att.is-failed .dv-wx-att-meta { color: var(--red); }
.dv-wx-att-preview { display: block; width: fit-content; margin-bottom: 6px; }
.dv-wx-att-preview img { display: block; max-width: min(220px, 100%); max-height: 180px; object-fit: contain; border-radius: 4px; }
.dv-wx-shift { align-self: center; max-width: 90%; font-size: var(--fs-xs); color: var(--muted); text-align: center; overflow-wrap: anywhere; }
@media (max-width: 640px) { .dv-wx-row { max-width: 92%; } }

/* 问卷（pages/devsurvey.js）：发起一轮那一行、编辑、每份答卷 */
.dv-sv-label { display: inline-flex; align-items: center; gap: 6px; }
.dv-sv-num { width: 64px; }
.dv-sv-check { display: inline-flex; align-items: center; gap: 6px; }
.dv-sv-gap { flex: 1; }
.dv-sv-field { display: flex; flex-direction: column; gap: 4px; margin: 0 0 12px; }
.dv-sv-in { box-sizing: border-box; width: 100%; font: inherit; }
.dv-sv-q > .dv-sv-in { margin: 10px 0; }
.dv-sv-opts { display: flex; flex-direction: column; gap: 6px; margin: 0 0 10px; }
.dv-sv-opt { display: flex; align-items: center; gap: 8px; }
.dv-sv-opt .dv-sv-in { flex: 1; min-width: 0; }
.dv-sv-x { flex: none; width: 32px; }
.dv-sv-add { align-self: flex-start; }
.dv-sv-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin-top: 8px; }
.dv-sv-cond { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; width: 100%; }
.dv-sv-bad { color: var(--red); }
.dv-sv-one p { margin: 6px 0 0; }
.dv-sv-one .row { flex-wrap: wrap; gap: 4px 10px; }

/* #962：原始反馈下的关联事项；沿用开发者平台的按钮和类型控件。 */
.dv-fb-matters { margin: 12px 0; }
.dv-fb-matter { padding: 10px 0; border-top: 1px solid var(--line, #e7e7e7); }
.dv-fb-matter input { max-width: 180px; }
.dv-fb-matter select { width: auto; }
