/*
 * app.css — BETACONNECT后台共享主题(运营后台 opsd / 客户自助后台 ccd 共用同一份)。
 *
 * 设计目标:在 Bootstrap 5(纯 CSS)之上薄薄一层企业级后台外观——固定左侧深色侧栏 +
 * 顶栏 + 浅灰内容区 + 白色卡片,规整、专业、有"踏实感"。
 *
 * 一致性口径:本文件是【共享设计源】,opsd 与 ccd 两份的外壳类名与视觉必须一致,
 * 避免两套漂移;但**两份不要求逐字节相同** —— 各自可有只属于自己页面的作用域规则
 * (如本侧任务表的 13 列对齐)。`make theme-sync` 只同步 bootstrap.min.css 与 htmx.min.js,
 * **不碰 app.css**;改了共享部分需手工把对应改动搬到另一份。
 *
 * 客户可见面红线:本文件仅样式、绝不含藏筷子禁词;且经 <link> 外链引入,
 * 其字节不进入页面 HTML 主体,不影响输出断言闸。上游一律代号 upstream。
 */

:root {
  --app-sidebar-bg: #1f2a3d;
  --app-sidebar-fg: #c7d0de;
  --app-sidebar-fg-active: #ffffff;
  --app-sidebar-active-bg: #2d3c57;
  --app-sidebar-accent: #4c8bf5;
  --app-sidebar-width: 15rem;
  --app-topbar-h: 3.5rem;
  --app-content-bg: #f4f6f9;
  --app-border: #e3e8f0;
  --bs-link-color-rgb: 38, 99, 235;
}

body {
  background-color: var(--app-content-bg);
  color: #1f2733;
}

/* ───────────────────────── 应用外壳(登录后内部页) ───────────────────────── */

.app-shell {
  display: flex;
  min-height: 100vh;
}

.app-sidebar {
  width: var(--app-sidebar-width);
  flex: 0 0 var(--app-sidebar-width);
  background: var(--app-sidebar-bg);
  color: var(--app-sidebar-fg);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.app-brand {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 1.1rem 1.25rem;
  font-weight: 700;
  font-size: 1.05rem;
  color: #fff;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  line-height: 1.2;
}

.app-brand span {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--app-sidebar-fg);
  letter-spacing: 0.04em;
}

.app-nav {
  padding: 0.75rem 0.6rem;
  gap: 0.15rem;
}

.app-nav .nav-link {
  color: var(--app-sidebar-fg);
  border-radius: 0.4rem;
  padding: 0.55rem 0.85rem;
  font-size: 0.92rem;
  display: flex;
  align-items: center;
  transition: background-color 0.12s ease, color 0.12s ease;
}

.app-nav .nav-link:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--app-sidebar-fg-active);
}

.app-nav .nav-link.active {
  background: var(--app-sidebar-active-bg);
  color: var(--app-sidebar-fg-active);
  font-weight: 600;
  box-shadow: inset 3px 0 0 var(--app-sidebar-accent);
}

.app-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.app-topbar {
  height: var(--app-topbar-h);
  background: #fff;
  border-bottom: 1px solid var(--app-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 1.5rem;
  position: sticky;
  top: 0;
  z-index: 1020;
}

.app-topbar-title {
  font-weight: 600;
  font-size: 1rem;
  color: #2a3442;
}

.app-topbar-account {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.9rem;
  color: #5a6473;
}

/* 顶栏账号下拉(原生 <details>,无需 Bootstrap JS) */
.app-account {
  position: relative;
}

.app-account > summary {
  list-style: none;
  cursor: pointer;
  padding: 0.35rem 0.75rem;
  border-radius: 0.4rem;
  border: 1px solid var(--app-border);
  background: #fff;
  color: #2a3442;
  user-select: none;
}

.app-account > summary::-webkit-details-marker {
  display: none;
}

.app-account > summary:hover {
  background: #f4f6f9;
}

.app-account-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 0.35rem);
  min-width: 11rem;
  background: #fff;
  border: 1px solid var(--app-border);
  border-radius: 0.5rem;
  box-shadow: 0 8px 24px rgba(31, 42, 61, 0.12);
  padding: 0.4rem;
  list-style: none;
  margin: 0;
  z-index: 1030;
}

.app-account-menu li {
  list-style: none;
}

.app-account-menu a,
.app-account-menu button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.7rem;
  border-radius: 0.35rem;
  border: 0;
  background: none;
  color: #2a3442;
  font-size: 0.9rem;
  text-decoration: none;
  cursor: pointer;
}

.app-account-menu a:hover,
.app-account-menu button:hover {
  background: #f4f6f9;
}

.app-main {
  padding: 1.75rem;
  flex: 1 1 auto;
}

.app-page-head {
  margin-bottom: 1.25rem;
}

.app-page-head h2 {
  font-size: 1.4rem;
  font-weight: 700;
  margin-bottom: 0.25rem;
}

.app-page-head p {
  color: #69727f;
  margin-bottom: 0;
  font-size: 0.92rem;
}

/* ───────────────────────── 卡片 / 区块 ───────────────────────── */

.app-card {
  background: #fff;
  border: 1px solid var(--app-border);
  border-radius: 0.6rem;
  box-shadow: 0 1px 2px rgba(31, 42, 61, 0.04);
  margin-bottom: 1.25rem;
}

.app-card > .app-card-head {
  padding: 0.85rem 1.1rem;
  border-bottom: 1px solid var(--app-border);
  font-weight: 600;
  color: #2a3442;
}

.app-card > .app-card-body {
  padding: 1.1rem;
}

/* ───────────────────────── 表格 ───────────────────────── */

.app-table-wrap {
  border: 1px solid var(--app-border);
  border-radius: 0.6rem;
  background: #fff;
  overflow: auto;
  max-height: 72vh;
}

.app-table {
  margin-bottom: 0;
  font-size: 0.9rem;
}

.app-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: #f1f4f9;
  color: #46505f;
  font-weight: 600;
  white-space: nowrap;
  border-bottom: 2px solid var(--app-border);
}

.app-table td,
.app-table th {
  padding: 0.55rem 0.75rem;
  vertical-align: middle;
}

/* ID / 任务号等用等宽字体,便于对齐核对 */
.app-mono,
.app-table .app-mono {
  font-family: var(--bs-font-monospace, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 0.86rem;
}

/* 数值列右对齐 */
.app-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/*
 * 任务查询表固定 13 列；表头须保持无属性（输出断言闸按 <th>…</th> 抽取列名），
 * 故第 6–10 列数值/金额表头经作用域选择器右对齐，不在 <th> 上加 class。
 */
.app-table-tasks th:nth-child(6),
.app-table-tasks th:nth-child(7),
.app-table-tasks th:nth-child(8),
.app-table-tasks th:nth-child(9),
.app-table-tasks th:nth-child(10) {
  text-align: right;
}

/* ───────────────────────── 登录 / 改密(公开页) ───────────────────────── */

.app-auth {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(160deg, #1f2a3d 0%, #2d3c57 55%, #34507c 100%);
  padding: 1.5rem;
}

.app-auth-card {
  width: 100%;
  max-width: 23rem;
  background: #fff;
  border-radius: 0.8rem;
  box-shadow: 0 18px 48px rgba(15, 23, 42, 0.28);
  padding: 2rem 1.9rem;
}

.app-auth-brand {
  text-align: center;
  margin-bottom: 1.4rem;
}

.app-auth-brand .app-auth-logo {
  font-weight: 700;
  font-size: 1.25rem;
  color: #1f2a3d;
}

.app-auth-brand .app-auth-sub {
  display: block;
  font-size: 0.85rem;
  color: #6b7686;
  margin-top: 0.2rem;
}

/* ⚠️ 改 .app-auth-card 的 max-width 或左右 padding 之前先算一遍，下面两档都要算到。
   登录页上的验证码挂件宽度下限是厂商定死的 **300px 绝对像素**（紧凑档之外改不了），
   挂件放不下时不是"挤一挤"，是横向溢出卡片、右半边可能点不到。

   宽屏档：卡片内容区 = max-width − 左右 padding = 23 − 2×1.9 = 19.2rem，
   浏览器默认 16px 字号下 307px —— **只比挂件下限宽 7px**。把卡片改窄或把 padding 加大就溢出。
   内容区按 rem 算、挂件下限按 px 算，故用户把浏览器字号调小同样会溢出（14px 下只剩 269px）。

   窄屏档（下面那个 media query）：卡片宽度由视口决定，内容区 = 视口 − 2×外边距 − 2×卡片内边距。
   按原来的 1.5rem / 1.9rem 算，375px 视口下只剩 266px，放不下 —— 故窄屏收紧到 0.75rem / 1rem，
   内容区变成 视口 − 56px：360px 视口下 304px、375px 下 319px，够。 */

/* 窄屏（≤26rem，即手机竖屏）收紧登录卡内外边距，给验证码挂件让出 300px。
   断点取 26rem 不是随手定的：416px 视口下按原边距刚好剩 307px（与宽屏档等宽），
   再窄一点就不够 —— 这个断点就是"原边距开始放不下"的那条线。
   ⬜ 320px 这档极窄屏仍差一点（264px）。没为它换又窄又高的紧凑档挂件 ——
   那会连带改掉所有屏幕上的观感，代价不成比例。 */
@media (max-width: 26rem) {
  .app-auth {
    padding: 0.75rem;
  }

  .app-auth-card {
    padding: 1.5rem 1rem;
  }
}

/* ───────────────────────── 提示条 / 一次性密钥框 ───────────────────────── */

.app-flash {
  border-radius: 0.5rem;
  padding: 0.65rem 0.9rem;
  margin-bottom: 1rem;
  font-size: 0.9rem;
  border: 1px solid transparent;
}

.app-flash-ok {
  background: #e7f6ec;
  border-color: #bfe6cd;
  color: #1f7a44;
}

.app-flash-error {
  background: #fdecea;
  border-color: #f5c2bd;
  color: #b3261e;
}

.app-secret {
  font-family: var(--bs-font-monospace, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 1.05rem;
  background: #f4f6f9;
  border: 1px dashed #b9c2d0;
  border-radius: 0.4rem;
  padding: 0.6rem 0.8rem;
  user-select: all;
  word-break: break-all;
}

/* ───────────────────────── 响应式:窄屏侧栏转顶部 ───────────────────────── */

@media (max-width: 768px) {
  .app-shell {
    flex-direction: column;
  }
  .app-sidebar {
    width: 100%;
    flex-basis: auto;
    height: auto;
    position: static;
  }
  .app-nav {
    flex-direction: row;
    flex-wrap: wrap;
  }
  .app-main {
    padding: 1.1rem;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * 语义适配层(semantic adapter)
 *
 * 目的:让仍用语义化标签/旧类名(article / figure>table / hgroup / .grid / .secondary /
 * .ops-flash / .cc-flash …)书写的内页,无需逐个改模板即可获得与样张完全一致的企业级外观。
 *
 * 一致性手法:所有"裸元素"规则统一包在 :where() 里(特异度为 0),因此一旦元素带上
 * Bootstrap/本主题的显式类名(.form-control / .btn / .app-card / .table …),显式类必胜出 ——
 * 已改造页面走显式类、未改造页面走本适配层,二者外观对齐、互不打架。
 * 旧业务类名(.ops-flash/.secondary/.grid 等)用正常特异度规则,稳定覆盖。
 * ═══════════════════════════════════════════════════════════════════════════ */

/* 标题组 */
:where(.app-main) hgroup {
  margin-bottom: 1.25rem;
}
:where(.app-main) hgroup h1,
:where(.app-main) hgroup h2 {
  font-size: 1.4rem;
  font-weight: 700;
  margin-bottom: 0.25rem;
}
:where(.app-main) hgroup p {
  color: #69727f;
  margin-bottom: 0;
  font-size: 0.92rem;
}

:where(.app-main) section {
  margin-bottom: 1.5rem;
}
:where(.app-main) section > h3 {
  font-size: 1.1rem;
  font-weight: 700;
  margin-bottom: 0.85rem;
}
:where(.app-main) section > h4 {
  font-size: 0.98rem;
  font-weight: 600;
  margin: 1rem 0 0.6rem;
}
:where(.app-main) small {
  color: #69727f;
}

/* 区块卡片(裸 <article> → 卡片;含 <header> → 卡头) */
:where(.app-main) article {
  background: #fff;
  border: 1px solid var(--app-border);
  border-radius: 0.6rem;
  box-shadow: 0 1px 2px rgba(31, 42, 61, 0.04);
  margin-bottom: 1.25rem;
  padding: 1.1rem;
}
:where(.app-main) article > header {
  margin: -1.1rem -1.1rem 1rem;
  padding: 0.85rem 1.1rem;
  border-bottom: 1px solid var(--app-border);
  font-weight: 600;
  color: #2a3442;
  border-radius: 0.6rem 0.6rem 0 0;
}

/* 表格(裸 <figure><table>) */
:where(.app-main) figure {
  margin: 0 0 1.25rem;
  border: 1px solid var(--app-border);
  border-radius: 0.6rem;
  background: #fff;
  overflow-x: auto;
}
:where(.app-main) figure table {
  width: 100%;
  margin: 0;
  border-collapse: collapse;
  font-size: 0.9rem;
}
:where(.app-main) figure th,
:where(.app-main) figure td {
  padding: 0.55rem 0.75rem;
  border-bottom: 1px solid var(--app-border);
  text-align: left;
  vertical-align: middle;
}
:where(.app-main) figure thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: #f1f4f9;
  color: #46505f;
  font-weight: 600;
  white-space: nowrap;
  border-bottom: 2px solid var(--app-border);
}
:where(.app-main) figure tbody tr:nth-child(odd) {
  background: #fbfcfe;
}
:where(.app-main) figure tbody tr:hover {
  background: #eef3fb;
}
:where(.app-main) figure tfoot th,
:where(.app-main) figure tfoot td {
  font-weight: 700;
  background: #f1f4f9;
  border-top: 2px solid var(--app-border);
}
:where(.app-main) figure code {
  font-size: 0.84rem;
}

/* 表单控件(裸 input/select/textarea) */
:where(.app-main) form label {
  display: block;
  margin-bottom: 0.85rem;
  font-weight: 500;
  font-size: 0.92rem;
  color: #3a4452;
}
:where(.app-main) :where(input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]), select, textarea) {
  display: block;
  width: 100%;
  padding: 0.4rem 0.7rem;
  margin-top: 0.25rem;
  font-size: 0.92rem;
  line-height: 1.5;
  color: #1f2733;
  background: #fff;
  border: 1px solid #ced4da;
  border-radius: 0.4rem;
}
:where(.app-main) :where(input, select, textarea):focus {
  outline: 0;
  border-color: #86b7fe;
  box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.18);
}
:where(.app-main) input[type="checkbox"],
:where(.app-main) input[type="radio"] {
  margin-right: 0.4rem;
}

/* 两列/多列栅格(旧 Pico .grid) */
.app-main .grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  margin-bottom: 0.5rem;
}
.app-main .grid > label {
  margin-bottom: 0;
}

/* 输入行组(role=group) */
:where(.app-main) fieldset[role="group"] {
  display: flex;
  gap: 0.5rem;
  align-items: start;
  border: 0;
  padding: 0;
  margin: 0;
}
:where(.app-main) fieldset[role="group"] > * {
  margin-top: 0;
}

/* 按钮(裸 button / a[role=button] / summary[role=button] / input[submit]) */
:where(.app-main) :where(button, a[role="button"], summary[role="button"], input[type="submit"]) {
  display: inline-block;
  font-weight: 500;
  line-height: 1.5;
  text-align: center;
  text-decoration: none;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
  padding: 0.45rem 0.9rem;
  font-size: 0.92rem;
  border-radius: 0.4rem;
  border: 1px solid #0d6efd;
  background: #0d6efd;
  color: #fff;
  transition: filter 0.12s ease;
}
:where(.app-main) :where(button, a[role="button"], summary[role="button"]):hover {
  filter: brightness(0.93);
  color: #fff;
}
/* 链接按钮(a[role=button])去下划线:基样的 text-decoration:none 在 :where() 零特异度里，
   会被 Bootstrap 对 <a> 的默认下划线盖掉，故在此以正常特异度显式清除。 */
.app-main a[role="button"] {
  text-decoration: none;
}

:where(.app-main) summary {
  cursor: pointer;
}
:where(.app-main) details {
  margin-bottom: 1rem;
}

/* 按钮变体(旧 Pico .secondary / .outline);正常特异度,稳定覆盖上面的裸按钮基样 */
.app-main .secondary {
  background: #5c677d;
  border-color: #5c677d;
  color: #fff;
}
.app-main .secondary:hover {
  color: #fff;
}
.app-main .outline {
  background: transparent;
  border-color: currentColor;
  color: #0d6efd;
}
.app-main .secondary.outline {
  background: transparent;
  color: #5c677d;
}
.app-main .contrast {
  background: #212529;
  border-color: #212529;
  color: #fff;
}

/* 提示条(旧 .ops-flash / .cc-flash 及其错误/成功变体) */
.app-main .ops-flash,
.app-main .cc-flash {
  background: #e8f1fe;
  border: 1px solid #b9d4fb;
  color: #0b4ea2;
  border-radius: 0.5rem;
  padding: 0.65rem 0.9rem;
  margin-bottom: 1rem;
  font-size: 0.9rem;
}
.app-main .ops-flash-ok {
  background: #e7f6ec;
  border-color: #bfe6cd;
  color: #1f7a44;
}
.app-main .ops-flash-error,
.app-main .cc-error {
  background: #fdecea;
  border-color: #f5c2bd;
  color: #b3261e;
}
:where(.app-main) p[role="alert"] {
  color: #b3261e;
}

/* 一次性密钥框(旧 .ops-secret / .cc-secret) */
.app-main .ops-secret,
.app-main .cc-secret {
  display: block;
  font-family: var(--bs-font-monospace, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 1.05rem;
  background: #f4f6f9;
  border: 1px dashed #b9c2d0;
  border-radius: 0.4rem;
  padding: 0.6rem 0.8rem;
  user-select: all;
  word-break: break-all;
}

/* 行内代码 / 代码块 */
:where(.app-main) :not(pre) > code {
  background: #eef1f6;
  padding: 0.1rem 0.35rem;
  border-radius: 0.3rem;
  font-size: 0.85em;
  color: #b8367f;
}
:where(.app-main) pre {
  background: #0f172a;
  color: #e2e8f0;
  padding: 0.9rem 1rem;
  border-radius: 0.5rem;
  overflow: auto;
  font-size: 0.85rem;
}
:where(.app-main) pre code {
  background: none;
  color: inherit;
  padding: 0;
}
