/**
 * shell.css — 外壳骨架 · §23 状态视觉 · 响应式
 *
 * 本文件**只引用 shell/tokens.css 的 var(--…)**，不写死任何色值与字号；
 * tools/verify/frontend-shell.js 会静态扫描并在出现色值时判失败。
 *
 * ═══════════════════════════════════════════════════════════════════════════
 * 响应式策略（§32：V1 不做原生 App，响应式网页是唯一的移动端方案）
 * ═══════════════════════════════════════════════════════════════════════════
 *   >= 1280  宽屏：侧栏常驻，卡片网格多栏，图表给到最大高度
 *   >  1200  桌面：侧栏常驻 + 主内容单栏（基础布局）
 *   901–1200 平板：侧栏收窄，卡片网格列数收敛
 *   <=  900  手机：侧栏变抽屉，卡片单栏，**宽表格自动降级为卡片列表**
 *
 * 断点数字与 tokens.css 的 --bp-* 以及各页面样式保持一致（见 tokens.css 说明）。
 *
 * 三条硬约束：
 *   1. 页面主体永不横滚。横向滚动只允许出现在显式标了 data-scroll-x 的容器里
 *      （目前只有宽表格与页签条），其余一律靠换行/降级解决。
 *   2. 不用固定像素宽度：栅格用 minmax(min(100%, …), 1fr)，侧栏用 clamp()，
 *      字号用 clamp()。px 只出现在发丝线、圆角与触控下限这类不该缩放的量上。
 *   3. 触控设备上所有可点元素 >= var(--tap-min)（44px）。
 */

/* ── 骨架 ─────────────────────────────────────────────────────────────────── */

#ms-root {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  /* width:100% 不能省：body 是 column 方向的 flex 容器，
     只写 margin:0 auto 会关掉交叉轴 stretch，让外壳缩成内容宽度并居中 */
  width: 100%;
  max-width: var(--content-max);
  margin: 0 auto;
  font-family: var(--font-sans);
  color: var(--ui-text);
  /* 主体永不横滚：内部真正需要横滚的容器自己开 overflow */
  overflow-x: hidden;
}

.ms-top {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-6);
  background: var(--ui-surface);
  border-bottom: var(--border-hair) solid var(--ui-line);
  flex: 0 0 auto;
}
.ms-brand { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.ms-brand-mark {
  width: var(--tap-compact); height: var(--tap-compact);
  border-radius: var(--radius-sm);
  background: linear-gradient(135deg, var(--brand), var(--sem-warn));
  display: grid; place-items: center; font-size: var(--fs-lg); flex: 0 0 auto;
}
.ms-brand h1 { font-size: var(--fs-lg); font-weight: var(--fw-bold); line-height: var(--lh-tight); }
.ms-brand span { font-size: var(--fs-xs); color: var(--ui-text-3); }
.ms-top-spacer { flex: 1 1 auto; }
.ms-top-field {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-sm); color: var(--ui-text-2); min-width: 0;
}

/* 抽屉开关：只在手机上出现 */
.ms-nav-toggle {
  display: none;
  align-items: center; justify-content: center;
  min-width: var(--tap-min); min-height: var(--tap-min);
  background: var(--ui-surface-2); color: var(--ui-text);
  border: var(--border-hair) solid var(--ui-line); border-radius: var(--radius-sm);
  font-size: var(--fs-lg); cursor: pointer;
}

.ms-body {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: var(--nav-w) minmax(0, 1fr);
  min-height: 0;
}

.ms-nav {
  background: var(--ui-surface);
  border-right: var(--border-hair) solid var(--ui-line);
  padding: var(--sp-5) var(--sp-3);
  display: flex; flex-direction: column; gap: var(--sp-6);
  overflow-y: auto;
  min-width: 0;
}
.ms-nav-group-label {
  font-size: var(--fs-xs); letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ui-text-3); padding: 0 var(--sp-3) var(--sp-1);
}
.ms-nav-item {
  display: flex; align-items: center;
  min-height: var(--tap-compact);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--radius-sm);
  color: var(--ui-text-2); font-size: var(--fs-md); text-decoration: none; cursor: pointer;
}
.ms-nav-item:hover { background: var(--ui-surface-2); color: var(--ui-text); }
.ms-nav-item.is-active {
  background: var(--ui-surface-2); color: var(--ui-text);
  box-shadow: inset 2px 0 0 var(--brand);
}

.ms-main {
  min-width: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--sp-6);
}
#ms-page { display: flex; flex-direction: column; gap: var(--sp-5); min-height: 100%; min-width: 0; }

/* 抽屉遮罩：仅手机抽屉展开时出现 */
.ms-scrim { display: none; }

/* 停车位：K 线工作台不在「行情」页签时待在这里，不占布局也不渲染 */
#ms-chart-park { display: none; }

/* ── 通用控件 ─────────────────────────────────────────────────────────────── */

.ms-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap-compact);
  background: var(--ui-surface-2);
  border: var(--border-hair) solid var(--ui-line);
  color: var(--ui-text);
  border-radius: var(--radius-sm);
  padding: var(--sp-2) var(--sp-5);
  font-size: var(--fs-sm); font-family: inherit; cursor: pointer;
}
.ms-btn:hover { border-color: var(--ui-text-3); }
.ms-btn:focus-visible { outline: 2px solid var(--sem-info); outline-offset: 1px; }
.ms-btn.is-primary { border-color: var(--brand); color: var(--brand); }
.ms-btn.is-on { border-color: var(--sem-ok); color: var(--sem-ok); }
.ms-btn[disabled] { opacity: 0.55; cursor: default; }

.ms-input, .ms-select {
  min-height: var(--tap-compact);
  max-width: 100%;
  background: var(--ui-bg);
  border: var(--border-hair) solid var(--ui-line);
  color: var(--ui-text);
  border-radius: var(--radius-sm);
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-sm); font-family: inherit;
}
.ms-input:focus, .ms-select:focus { outline: none; border-color: var(--sem-info); }

.ms-card {
  background: var(--ui-surface);
  border: var(--border-hair) solid var(--ui-line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  min-width: 0;
}
.ms-card-head {
  display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-6);
  border-bottom: var(--border-hair) solid var(--ui-line-soft);
}
.ms-card-title { font-size: var(--fs-md); font-weight: var(--fw-bold); }
.ms-card-aside {
  margin-left: auto; font-size: var(--fs-xs); color: var(--ui-text-3);
  display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap;
}
.ms-card-body { padding: var(--sp-5) var(--sp-6); min-width: 0; }

.ms-toolrow { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; min-width: 0; }
.ms-grid {
  display: grid; gap: var(--sp-5);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
}
.ms-dim { color: var(--ui-text-3); }
.ms-mono { font-family: var(--font-mono); font-size: var(--fs-xs); }
.ms-kv { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-8); font-size: var(--fs-sm); min-width: 0; }
.ms-kv > div { display: flex; gap: var(--sp-2); align-items: baseline; min-width: 0; }
.ms-kv b { font-weight: var(--fw-bold); }

/* ── 表格 ─────────────────────────────────────────────────────────────────
   桌面是表格，手机降级成卡片列表：每个 td 都带 data-label，
   小屏时 td 变成「标签 + 值」的一行，不再横滚。
   ui.table() 负责产出 data-label，两边共用同一份 DOM。 */

.ms-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; min-width: 0; }
.ms-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.ms-table th, .ms-table td {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: var(--border-hair) solid var(--ui-line-soft);
  text-align: left; white-space: nowrap;
}
.ms-table th {
  color: var(--ui-text-3); font-weight: var(--fw-medium);
  position: sticky; top: 0; background: var(--ui-surface); z-index: 1;
}
.ms-table td.ms-r, .ms-table th.ms-r { text-align: right; }
.ms-table tbody tr:hover { background: var(--ui-surface-2); }
/* 关键数字比正文重一档 */
.ms-table td.ms-key { font-weight: var(--fw-bold); color: var(--ui-text); }

.ms-tabs {
  display: flex; gap: var(--sp-1); flex-wrap: wrap;
  border-bottom: var(--border-hair) solid var(--ui-line);
  padding: 0 var(--sp-2);
}
.ms-tab {
  background: none; border: none; border-bottom: 2px solid transparent;
  color: var(--ui-text-2);
  min-height: var(--tap-compact);
  padding: var(--sp-3) var(--sp-5);
  font-size: var(--fs-md); font-family: inherit; cursor: pointer;
}
.ms-tab:hover { color: var(--ui-text); }
.ms-tab.is-active { color: var(--ui-text); border-bottom-color: var(--brand); }

/* ── §23 状态 ─────────────────────────────────────────────────────────────
   四种最容易混淆的状态：边框形态 + 底纹 + 颜色三重区分，
   色觉障碍下不靠颜色也能分辨。 */

.ms-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-2); text-align: center;
  padding: var(--sp-8) var(--sp-6);
  border-radius: var(--radius-md);
  min-height: clamp(6rem, 18vh, 9rem);
}
.ms-state-icon { font-size: var(--fs-xl); line-height: 1; }
.ms-state-title { font-size: var(--fs-lg); font-weight: var(--fw-bold); }
.ms-state-desc { font-size: var(--fs-sm); color: var(--ui-text-2); max-width: 34rem; }
.ms-state-extra { font-size: var(--fs-sm); color: var(--ui-text); }
.ms-state-note { font-size: var(--fs-xs); color: var(--ui-text-3); max-width: 34rem; }
.ms-state-actions { margin-top: var(--sp-3); display: flex; gap: var(--sp-3); flex-wrap: wrap; justify-content: center; }
.ms-state-missing { margin-top: var(--sp-2); text-align: left; max-width: 34rem; width: 100%; }
.ms-state-missing-title { font-size: var(--fs-xs); color: var(--ui-text-2); margin-bottom: var(--sp-1); }
.ms-state-missing-list { list-style: none; display: flex; flex-direction: column; gap: var(--sp-1); }
.ms-state-missing-list li {
  font-size: var(--fs-sm); padding: var(--sp-1) var(--sp-3);
  background: var(--c-amber-a08); border-radius: var(--radius-sm);
}

/* 加载中：中性灰，不用任何颜色暗示结论 */
.ms-state[data-visual='pulse-bar'] {
  border: var(--border-hair) solid var(--state-loading-line);
  background: var(--state-loading-bg);
}
.ms-state[data-visual='pulse-bar'] .ms-state-title { color: var(--state-loading-fg); }

/* 空数据：灰色虚线框 + 透明底 */
.ms-state[data-visual='dashed-gray-box'] {
  border: var(--border-hair) dashed var(--state-empty-line);
  background: var(--state-empty-bg);
}
.ms-state[data-visual='dashed-gray-box'] .ms-state-title { color: var(--state-empty-fg); }

/* 数据不足：黄色实线框 + 浅黄底 */
.ms-state[data-visual='solid-yellow-box'] {
  border: var(--border-hair) solid var(--state-insufficient-line);
  background: var(--state-insufficient-bg);
}
.ms-state[data-visual='solid-yellow-box'] .ms-state-title { color: var(--state-insufficient-fg); }

/* 参数未配置：黄色点线框，与「数据不足」在形态上再拉开一层 */
.ms-state[data-visual='dotted-yellow-box'] {
  border: 2px dotted var(--state-unconfigured-line);
  background: var(--state-unconfigured-bg);
}
.ms-state[data-visual='dotted-yellow-box'] .ms-state-title { color: var(--state-unconfigured-fg); }

/* 服务异常：红色实线框 + 斜纹底 */
.ms-state[data-visual='striped-red-box'] {
  border: var(--border-hair) solid var(--state-fault-line);
  background-color: var(--state-fault-bg);
  background-image: repeating-linear-gradient(
    45deg,
    var(--state-fault-stripe) 0, var(--state-fault-stripe) 6px,
    transparent 6px, transparent 12px
  );
}
.ms-state[data-visual='striped-red-box'] .ms-state-title { color: var(--state-fault-fg); }

/* 权限不足 */
.ms-state[data-visual='solid-purple-box'] {
  border: var(--border-hair) solid var(--state-locked-line);
  background: var(--state-locked-bg);
}
.ms-state[data-visual='solid-purple-box'] .ms-state-title { color: var(--state-locked-fg); }

/* 订阅受限 */
.ms-state[data-visual='solid-gold-box'] {
  border: var(--border-hair) solid var(--state-gated-line);
  background: var(--state-gated-bg);
}
.ms-state[data-visual='solid-gold-box'] .ms-state-title { color: var(--state-gated-fg); }

/* 数据延迟：K 线照画，用蓝色提示而不是红色，免得被当成故障 */
.ms-state[data-visual='solid-blue-box'] {
  border: var(--border-hair) solid var(--state-stale-line);
  background: var(--state-stale-bg);
}
.ms-state[data-visual='solid-blue-box'] .ms-state-title { color: var(--state-stale-fg); }

/* 表格里的小尺寸状态标记，与大块同一套配色与形态 */
.ms-chip {
  display: inline-block; font-size: var(--fs-xs);
  padding: 0 var(--sp-3); border-radius: var(--radius-pill);
  white-space: nowrap; cursor: help;
}
.ms-chip[data-visual='dashed-gray-box'] { border: var(--border-hair) dashed var(--state-empty-line); color: var(--state-empty-fg); }
.ms-chip[data-visual='solid-yellow-box'] {
  border: var(--border-hair) solid var(--state-insufficient-line);
  background: var(--state-insufficient-bg); color: var(--state-insufficient-fg);
}
.ms-chip[data-visual='dotted-yellow-box'] { border: 2px dotted var(--state-unconfigured-line); color: var(--state-unconfigured-fg); }
.ms-chip[data-visual='striped-red-box'] {
  border: var(--border-hair) solid var(--state-fault-line); color: var(--state-fault-fg);
  background-image: repeating-linear-gradient(
    45deg, var(--c-red-a20) 0, var(--c-red-a20) 4px, transparent 4px, transparent 8px
  );
}
.ms-chip[data-visual='solid-purple-box'] { border: var(--border-hair) solid var(--state-locked-line); color: var(--state-locked-fg); }
.ms-chip[data-visual='solid-gold-box'] { border: var(--border-hair) solid var(--state-gated-line); color: var(--state-gated-fg); }
.ms-chip[data-visual='solid-blue-box'] { border: var(--border-hair) solid var(--state-stale-line); color: var(--state-stale-fg); }
.ms-chip[data-visual='pulse-bar'] { border: var(--border-hair) solid var(--state-loading-line); color: var(--state-loading-fg); }

/* ── 页面局部 ─────────────────────────────────────────────────────────────── */

.ms-page-head { display: flex; align-items: baseline; gap: var(--sp-5); flex-wrap: wrap; min-width: 0; }
.ms-page-head h2 { font-size: var(--fs-xl); font-weight: var(--fw-bold); }
.ms-page-head p { font-size: var(--fs-sm); color: var(--ui-text-3); }

/* 代币页固定头：链 / 合约 / 交易所·交易对 / 更新时间，任何页签下都不消失 */
.ms-token-head { display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-7); align-items: center; min-width: 0; }
.ms-token-symbol { font-size: var(--fs-xl); font-weight: var(--fw-bold); }

/* 代币页「行情」页签：K 线工作台被搬进这里 */
.ms-chart-slot { min-height: var(--chart-min-h); display: flex; min-width: 0; }
.ms-chart-slot > #cw-container { flex: 1 1 auto; min-width: 0; }

/* 大盘：十个模块的卡片网格 */
.ms-overview-grid {
  display: grid; gap: var(--sp-5);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr));
}
.ms-metric { display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; }
.ms-metric-value { font-size: var(--fs-metric); font-weight: var(--fw-bold); line-height: var(--lh-tight); }
.ms-metric-unit { font-size: var(--fs-sm); color: var(--ui-text-3); }
.ms-bar { height: var(--sp-2); border-radius: var(--radius-pill); background: var(--ui-surface-2); overflow: hidden; }
.ms-bar > i { display: block; height: 100%; background: var(--sem-info); }

.ms-timeline { list-style: none; display: flex; flex-direction: column; gap: var(--sp-3); }
.ms-timeline li { display: flex; gap: var(--sp-4); font-size: var(--fs-sm); flex-wrap: wrap; }
.ms-timeline time { color: var(--ui-text-3); white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ── 断点 ─────────────────────────────────────────────────────────────────
   数值与 tokens.css 的 --bp-* 保持一致（媒体查询不能用变量）。 */

/* >= 1280 宽屏：内容区更松，卡片可以更多栏 */
@media (min-width: 1280px) {
  .ms-main { padding: var(--sp-7) var(--sp-8); }
  .ms-overview-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 23rem), 1fr)); }
}

/* 901–1200 平板：侧栏收窄，卡片列数收敛 */
@media (min-width: 901px) and (max-width: 1200px) {
  .ms-body { grid-template-columns: clamp(8rem, 20vw, 11rem) minmax(0, 1fr); }
  .ms-overview-grid, .ms-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); }
}

/* <= 900 手机：抽屉导航 + 单栏 + 表格降级为卡片 */
@media (max-width: 900px) {
  .ms-top { padding: var(--sp-3) var(--sp-4); gap: var(--sp-3); }
  .ms-brand span { display: none; }
  .ms-nav-toggle { display: inline-flex; order: -1; }

  /* 顶栏在手机上只占两行：品牌一行、三个偏好挤成一行。
     标签文字隐去（可访问名由 aria-label 承担），下拉框等分剩余宽度。 */
  .ms-top-field > span { display: none; }
  .ms-top-field { flex: 1 1 0; min-width: 0; }
  .ms-top-field .ms-select { width: 100%; min-width: 0; }
  .ms-top-spacer { flex-basis: 100%; height: 0; }

  .ms-body { grid-template-columns: minmax(0, 1fr); }

  /* 导航变成从左侧滑入的抽屉；收起时移出视口而不是 display:none，
     这样切换有过渡、也不会在展开瞬间重排整棵树 */
  .ms-nav {
    position: fixed; inset: 0 auto 0 0;
    width: min(78vw, 17rem);
    z-index: var(--z-drawer);
    transform: translateX(-100%);
    transition: transform 0.18s ease-out;
    border-right: var(--border-hair) solid var(--ui-line);
  }
  #ms-root[data-drawer='open'] .ms-nav { transform: translateX(0); }
  #ms-root[data-drawer='open'] .ms-scrim {
    display: block; position: fixed; inset: 0;
    background: var(--ui-overlay); z-index: var(--z-scrim);
  }
  /* 抽屉里的导航项是主要触控目标 */
  .ms-nav-item { min-height: var(--tap-min); font-size: var(--fs-md); }

  .ms-main { padding: var(--sp-4); }
  .ms-grid, .ms-overview-grid { grid-template-columns: minmax(0, 1fr); }
  .ms-card-body { padding: var(--sp-4); }
  .ms-kv { gap: var(--sp-2) var(--sp-6); }

  /* 触控设备的点击目标下限 */
  .ms-btn, .ms-tab, .ms-input, .ms-select, .ms-nav-toggle { min-height: var(--tap-min); }
  .ms-btn { padding-inline: var(--sp-5); }

  /* 页签条允许横滚（显式标记），但不会带着页面一起滚 */
  .ms-tabs { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .ms-tab { flex: 0 0 auto; }

  /* ── 宽表格 → 卡片列表 ──────────────────────────────────────────────
     13 列的榜单在手机上横滚是不可用的。这里让每行变成一张卡片，
     每个单元格显示成「列名 + 值」一行，横向滚动彻底消失。 */
  .ms-table-wrap { overflow-x: visible; }
  .ms-table, .ms-table tbody, .ms-table tr, .ms-table td { display: block; width: 100%; }
  .ms-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .ms-table tr {
    border: var(--border-hair) solid var(--ui-line);
    border-radius: var(--radius-md);
    margin-bottom: var(--sp-4);
    padding: var(--sp-2) var(--sp-4);
    background: var(--ui-surface);
  }
  .ms-table td {
    display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
    border-bottom: var(--border-hair) solid var(--ui-line-soft);
    padding: var(--sp-2) 0;
    white-space: normal; text-align: right;
  }
  .ms-table td:last-child { border-bottom: none; }
  .ms-table td::before {
    content: attr(data-label);
    color: var(--ui-text-3); font-size: var(--fs-xs);
    text-align: left; flex: 0 0 auto; white-space: nowrap;
  }
  .ms-table td.ms-r { text-align: right; }
}

/* 触控设备（含平板）统一放大点击目标，不只看宽度 */
@media (pointer: coarse) {
  .ms-btn, .ms-tab, .ms-input, .ms-select, .ms-nav-item { min-height: var(--tap-min); }
}

/* 尊重系统的减少动效偏好 */
@media (prefers-reduced-motion: reduce) {
  .ms-nav { transition: none; }
}
