/*
 * WebUI 全局契约类（02 §3.2；三件套之一）
 * 壳与插件直接使用；插件只能使用不能重定义（02 §5.5 样式沙箱，
 * 门禁扫描：业务 CSS 出现契约类选择器即构建失败）。
 * 页面骨架一律 page-shell（header：标题/副标题/动作区 → body：卡片与表格）。
 */

/* ── 页面骨架 ── */

.page-shell {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-height: 100%;
  /* 容器查询锚点（39 §2 基建）：壳管理面页根建立容器上下文，
   * 页内契约类可按三档断点 @container 自适应（零视觉增量） */
  container-type: inline-size;
}

.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.page-title {
  margin: 0;
  font-size: var(--text-xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--leading-tight);
}

.page-subtitle {
  margin: var(--space-1) 0 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

/* 动作区：主操作居左，保存类居右下（由 FormSaveBar 承载），危险操作红色靠后 */
.page-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.page-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-height: 0;
  flex: 1;
}

/* ── 工具行（卡片内：搜索/过滤/轻动作）── */

.toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* ── 卡片 ── */

.card {
  background: var(--bg-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  padding: var(--space-4);
}

/* ── 区块小标题 ── */

.section-heading {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
}

/* ── 数据表格（Q-1 行节奏：行高于控件，按钮在行内悬浮居中，不允许控件把行顶满）── */

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-base);
}

.data-table th {
  text-align: left;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--text-secondary);
  /* 表头行脱离控件死高：控件高 + 单侧留白（令牌推导，非魔法数） */
  height: calc(var(--control-sm) + var(--space-2));
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border-strong);
  white-space: nowrap;
}

.data-table td {
  /* 数据行底线 = 控件 28 + 上下各 8 = 44px：内容/按钮在 hairline 行间悬浮居中，
     而不是与行等高顶满（极简的呼吸感来自留白，不来自更粗的线或更高的控件）。
     table-cell 的 height 为最小高，展开行/多行文本可自然增高。 */
  height: calc(var(--control-sm) + var(--space-2) * 2);
  padding: var(--space-2) var(--space-3);
  vertical-align: middle;
  border-bottom: 1px solid var(--border-subtle);
  color: var(--text-primary);
  /* 默认不换行：短标签（操作者/状态/ID/时间）不应在半截折行；只有 col-grow
     文本主列显式允许换行。这样短列永远贴合内容、空间由 grow 列自适应吸收。 */
  white-space: nowrap;
}

.data-table tbody tr:hover {
  background: var(--bg-sunken);
}

/* 数值列：统一左对齐（极简一致：所有列同一条起始线），仅保留等宽数字字形——
   tabular-nums 让等宽数字纵向不跳动；不再用右对齐制造列向差异。
   width:1% 收缩贴合最长数字（同 col-shrink），避免宽屏下数字列被灌入大片空白。 */
.col-num {
  width: 1%;
  text-align: left;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* 操作列：统一左对齐（与各列同一起始线），配合 RowActions（02 §4.3 语义映射）。
   同 width:1% 收缩贴合按钮组（RowActions nowrap），不再吞掉主信息列的剩余宽度；
   窄屏表格在 .data-grid-scroll 内有界横滚（02 §3.3 宽表唯一横向出口）。 */
.col-action {
  width: 1%;
  text-align: left;
  white-space: nowrap;
}

/* 自适应列宽角色（Q-1 全局列模型）：
   col-shrink = 贴合内容、绝不换行（时间/状态/用户/IP/ID 等短列）；
   col-grow   = 吃剩余宽度、唯一允许换行的文本主列（标题/详情/路径）。
   选择器带 .data-table td/th 前缀提升特异性到 (0,2,1)，压过默认 td 的 nowrap；
   min-width 护栏避免窄屏下被压到逐字折行（超长先在此列换行，仍不够再走有界横滚）。 */
.data-table .col-shrink {
  width: 1%;
  white-space: nowrap;
}

.data-table td.col-grow {
  min-width: 9rem;
  white-space: normal;
  overflow-wrap: anywhere;
}

.data-table th.col-grow {
  min-width: 9rem;
  white-space: normal;
}

/* 表头与数据同列同对齐（全部左对齐）；表头保持非等宽（中文表头不应用 mono）。
   显式声明避免后续给 th 单独改对齐时出现「表头左、数据右」的分叉。 */
.data-table th.col-num,
.data-table th.col-action {
  text-align: left;
  font-family: inherit;
}

/* ── 宽表唯一横向出口（02 §3.3：页面滚动区永不横滚）── */

.data-grid-scroll {
  overflow: auto;
}

.data-grid-scroll .data-table {
  min-width: 100%;
}

/* ── 表格内编辑（cell-edit 场景紧凑输入）── */

.cell-input {
  height: var(--control-xs);
  padding: 0 var(--space-2);
  background: var(--bg-sunken);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  font-family: var(--font-mono);
  color: var(--text-primary);
  outline: none;
  transition: border-color var(--duration-fast) var(--ease-smooth);
}

.cell-input:hover:not(:disabled) {
  border-color: var(--border-strong);
}

.cell-input:focus-visible {
  border-color: var(--accent);
}

.cell-input:disabled {
  opacity: 0.6;
}

/* ── 长文阅读栏（68 §3.5：公开站文章/知识库；≤68ch 居中，出版物排版节奏）──
   仅承载长文的页面/控件使用；营销宽幅区块（Hero/网格）不套此契约。 */

.prose-column {
  max-width: var(--prose-w);
  margin-inline: auto;
  font-size: var(--text-prose);
  line-height: var(--leading-prose);
}

/* ── 弹窗表单（Modal 内容布局，W5 Modal 组件使用）── */

.modal-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* ── 设置/部件/凭据类表单（唯一布局，74 表单布局收口）──────────────────────
   纪律：
   - 业务页面禁止私写 repeat(auto-fit/auto-fill, minmax()) 万能网格（R17 门禁）；
     双列设置表单一律 .form-grid，长字段/组合字段/分组/错误条用 .form-span-2 占整行。
   - 字段统一「label 在上 → 控件居中 → hint 在下」三段同构：顶对齐 + 固定列轨道，
     同行字段的 label/控件/hint 三条基线自动齐（根治开关与输入框混排、尾随按钮错位）。
   - 响应式走容器查询（39 §2，page-shell 建容器上下文）：compact 单列、regular 起双列；
     Modal 内最近祖先无容器上下文时安全退化为单列。
   - 显式多列的特化组合（如「色样 32px + 输入」的颜色行、3 列对比度表）不套本类，
     属有意的字段级排布，仍由页面 scoped 样式表达。 */

.form-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  align-items: start;
}

.form-grid > * {
  min-width: 0;
}

@container (min-width: 768px) {
  .form-grid {
    grid-template-columns: 1fr 1fr;
    column-gap: var(--space-5);
  }
}

/* 占满整行：长文本/带尾随动作的组合字段/开关设置行/分组小标题/错误条 */
.form-span-2 {
  grid-column: 1 / -1;
}

/* 开关设置行：左标题+说明、右开关（配 Switch labelPosition="end"）。
   逐行 hairline 分组；首行无上分隔线。 */
.settings-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-5);
  padding: var(--space-3) 0;
  border-top: 1px solid var(--border-subtle);
}

.settings-row:first-child {
  border-top: 0;
  padding-top: 0;
}

.settings-row:last-child {
  padding-bottom: 0;
}

/* ── 卡片/媒体画廊网格（展示型等宽卡片唯一布局，74）──
   容器断点只用冻结档 {480,768}（39 §2 / R14）：<480 单列；≥480 起 auto-fill，
   列数由最小卡宽随容器自然折行（禁页面私写 auto-fit/fill 万能网格）。
   最小卡宽用自定义属性参数化（语义默认值，消费方仅覆盖该变量、不重写网格模板）：
     .card-grid  默认 260px（信息卡）；--card-min 可在页面 scoped 内放宽/收窄。
     .media-grid 默认 120px（缩略图选择器）。 */

.card-grid {
  --card-min: 260px;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@container (min-width: 480px) {
  .card-grid {
    /* min(var,100%) 防窄容器单卡溢出（布局纪律：永不横滚）；同行 stretch 等高 */
    grid-template-columns: repeat(auto-fill, minmax(min(var(--card-min), 100%), 1fr));
    align-items: stretch;
  }
}

/* 媒体缩略图画廊：≥480 起按最小卡宽 auto-fill（缩略图本就小，单列过稀）；
   <480 退单列。--card-min 默认 120，媒体库大卡可在 scoped 内调到 200。 */
.media-grid {
  --card-min: 120px;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
}

@container (min-width: 480px) {
  .media-grid {
    grid-template-columns: repeat(auto-fill, minmax(min(var(--card-min), 100%), 1fr));
  }
}
