/* ==========================================================================
   文字排版与状态基元（任务书 5.5 · 全局验收项）
   目标：文字不得溢出所属卡片、div、按钮或弹层的可见边界；
   重要信息换行完整展示，次要信息按规则截断。
   这里只提供明确的文本节点样式与状态容器样式，不对整卡片加 overflow:hidden。
   字号保持既定可读值，不用缩小字号解决布局。
   ========================================================================== */

/* ---------- 0. 盒模型复位（限定在本次新增组件内，不改全局样式） ----------
   没有这条复位时，width:100% 的输入控件会把自己撑出父容器（实测 label 溢出 18px）。 */
.ui-pane, .ui-pane *, .ui-preview, .ui-preview *,
.ip-cases, .ip-cases *, .ip-detail, .ip-detail *,
.ip-mail-pane, .ip-mail-pane *, .ip-mail-review, .ip-mail-review *,
.ip-work-list, .ip-work-list *, .ip-agent-list, .ip-agent-list *,
.ip-reconcile, .ip-reconcile *, .ip-transfer, .ip-transfer *,
.ip-supply, .ip-supply *, .ip-work-entry, .ip-work-entry *,
.ip-blocks, .ip-blocks *,
.chat-att-queue-host, .chat-att-queue-host * {
  box-sizing: border-box;
}

/* ---------- 1. Flex/Grid 文本子项防溢出（5.5 实现要求 1） ---------- */
.ui-text,
.ui-text-line1,
.ui-text-line2,
.ui-text-body,
.ui-text-paragraph,
.ip-field,
.ip-field-value {
  min-width: 0;
}

/* ---------- 2. 次要单行摘要：只加在明确的文本节点 ----------
   选择器重复一次以提高特异性：组件样式里的 `.xxx b{display:block}` 会覆盖单类名，
   导致限行失效（实测工作台待办标题因此铺成 7 行）。重复类名不动组件样式即可让工具类生效。 */
.ui-text-line1.ui-text-line1 {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* ---------- 3. 多行摘要（两行）：案件名称、官文标题、邮件主题 ----------
   同上：重复类名以保证限行不被组件的 display 覆盖。 */
.ui-text-line2.ui-text-line2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
  word-break: normal;
}

/* ---------- 4. 重要纯文本：完整换行；长英文/邮箱/URL 也能折行 ---------- */
.ui-text-body,
.ui-text-paragraph {
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: normal;
}

/* 需要保留原文段落的正文 */
.ui-text-paragraph {
  white-space: pre-wrap;
}

/* 超长内容通过容器内部滚动阅读，不永久裁掉 */
.ui-scroll-y {
  overflow-y: auto;
  max-height: 100%;
}

/* ---------- 5. 可展开文本 ---------- */
.ui-text-expandable { min-width: 0; }
.ui-text-toggle { align-self: flex-start; }
.ui-text-expand { margin-left: 4px; padding: 0 4px; border: 0; background: none; color: var(--green-ink, #2f6b4f); font: inherit; cursor: pointer; text-decoration: underline; }

/* ---------- 6. 长邮箱 / URL：完整可核对可复制，只视觉断行 ---------- */
.ui-emails { display: flex; flex-wrap: wrap; gap: 4px 10px; min-width: 0; }
.ui-email { overflow-wrap: anywhere; word-break: break-word; font-variant-numeric: tabular-nums; }

/* ---------- 7. 技术详情：默认收进折叠区，展开后可断行复制 ---------- */
.ui-text-technical { margin-top: 4px; }
.ui-text-technical summary { color: var(--fg3); font-size: 12px; cursor: pointer; }
.ui-text-technical code {
  display: block;
  margin-top: 4px;
  padding: 4px 6px;
  border-radius: 4px;
  background: var(--bg-alt);
  font-size: 11.5px;
  overflow-wrap: anywhere;
  word-break: break-all;   /* 只用于哈希/路径等技术串，不用于业务正文 */
  max-height: 12rem;
  overflow-y: auto;
}

/* ---------- 8. 语义色调（由配置提供，不按中文字符串猜颜色） ---------- */
.ui-tone-muted { color: var(--fg3); }
.ui-tone-unverified { color: #8a6d1f; }
.ip-tone-muted { color: var(--fg3); }
.ip-tone-unverified { color: #8a6d1f; font-weight: 500; }
.ip-tone-success { color: #1f6f43; }
.ip-tone-warning { color: #8a5a12; }
.ip-tone-danger { color: #a12a2a; }
.ip-tone-pending { color: #20558a; }
.ip-tone-unknown { color: var(--fg3); }

/* ---------- 9. 分块状态：loading / ready / empty / error / forbidden 分开 ---------- */
.ui-pane {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg);
  font-size: 13px;
  overflow-wrap: anywhere;
}
.ui-pane b { font-size: 13px; }
.ui-pane p { margin: 0; color: var(--fg3); font-size: 12.5px; white-space: normal; overflow-wrap: anywhere; }
.ui-pane ul { margin: 0; padding-left: 18px; color: var(--fg3); font-size: 12.5px; }
.ui-pane-empty { border-style: dashed; }
.ui-pane-error { border-color: color-mix(in srgb, #a12a2a 35%, var(--line)); background: color-mix(in srgb, #a12a2a 4%, var(--bg)); }
.ui-pane-forbidden { border-color: color-mix(in srgb, #8a5a12 35%, var(--line)); background: color-mix(in srgb, #8a5a12 4%, var(--bg)); }
.ui-pane-pending { border-style: dashed; }

/* ---------- 10. 状态标签：优先短中文；空间不足整体换行 ---------- */
.ip-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 7px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-alt);
  font-size: 12px;
  line-height: 1.6;
  white-space: nowrap;
}
.ip-chip-success { border-color: color-mix(in srgb, #1f6f43 40%, var(--line)); color: #1f6f43; }
.ip-chip-warning { border-color: color-mix(in srgb, #8a5a12 40%, var(--line)); color: #8a5a12; }
.ip-chip-danger { border-color: color-mix(in srgb, #a12a2a 40%, var(--line)); color: #a12a2a; }
.ip-chip-pending { border-color: color-mix(in srgb, #20558a 40%, var(--line)); color: #20558a; }
.ip-chip-muted { color: var(--fg3); }
.ip-chip-demo { border-color: color-mix(in srgb, #6b4ea8 40%, var(--line)); color: #6b4ea8; }

/* ---------- 11. 统一附件预览器（4.3.1） ---------- */
.ui-preview { display: flex; flex-direction: column; min-height: 0; height: 100%; border: 1px solid var(--line); border-radius: 10px; background: var(--bg); overflow: hidden; }
.ui-preview-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; padding: 10px 12px; border-bottom: 1px solid var(--line); background: var(--bg-alt); }
.ui-preview-head > div:first-child { min-width: 0; }
.ui-preview-head b { display: block; font-size: 13.5px; overflow-wrap: anywhere; }
.ui-preview-meta { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 4px; color: var(--fg3); font-size: 12px; }
.ui-preview-actions { display: flex; flex-wrap: wrap; gap: 6px; flex: 0 0 auto; }
.ui-preview-switch { display: inline-flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.ui-preview-switch button { padding: 4px 10px; border: 0; background: var(--bg); color: var(--fg2); font: 12px inherit; cursor: pointer; }
.ui-preview-switch button.on { background: var(--green, #2f6b4f); color: #fff; }
.ui-preview-body { flex: 1; min-height: 18rem; overflow: auto; }
.ui-preview-frame, .ui-preview-image { width: 100%; height: 100%; min-height: 18rem; border: 0; object-fit: contain; }
.ui-preview-xml {
  margin: 0;
  padding: 12px;
  font: 12px/1.65 ui-monospace, SFMono-Regular, Menlo, monospace;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: 70vh;
}
.ui-preview-note { margin: 0; padding: 6px 12px; border-top: 1px solid var(--line); color: var(--fg3); font-size: 12px; }
.ui-preview-empty, .ui-preview-error, .ui-preview-forbidden, .ui-preview-missing, .ui-preview-unsupported { display: flex; flex-direction: column; gap: 6px; padding: 18px; font-size: 13px; }
.ui-preview.is-fullscreen { position: fixed; inset: 0; z-index: 200; border-radius: 0; }
.ui-preview-fullscreen-open { overflow: hidden; }

/* ---------- 11.1 预览页框（文件/官文/邮件/审核共用同一张“纸”） ----------
   用法：宿主（flex:1 或定高）内放 uiKit.previewPageHtml() 产出的 stage；
   纸面永远按宿主宽度铺满，不足一页时补到 A4 高度（210:297），超出则由 stage 上下滚动；
   圆角由 --ui-preview-radius 统一（默认 4px，宿主容器同值即可做到 r 角一致）。 */
.ui-preview-stage { container-type: size; flex: 1 1 auto; min-height: 0; min-width: 0; display: block; overflow: auto; overscroll-behavior: contain; }
.ui-preview-page { width: 100%; min-height: calc(297 / 210 * 100cqw); box-sizing: border-box; display: flex; flex-direction: column; background: #fff; border: 1px solid var(--line); border-radius: var(--ui-preview-radius, 4px); overflow: hidden; }
.ui-preview-page-body { flex: 0 0 auto; min-height: 0; display: flex; flex-direction: column; }
/* PDF 一页纸：浏览器阅读器需要一个确定高度的框，按 A4 比例给；页内滚动由阅读器负责。 */
.ui-preview-page.is-sheet { aspect-ratio: 210 / 297; min-height: 0; }
.ui-preview-page.is-sheet > .ui-preview-page-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
.ui-preview-page-body > .ui-preview-frame { flex: 1 1 auto; width: 100%; height: 100%; min-height: 0; border: 0; }
.ui-preview-page-body > .ui-preview-image { width: 100%; height: auto; display: block; }
.ui-preview-page-body > .ui-preview-xml { flex: none; min-height: 0; max-height: none; }
.ui-preview-page-state { margin: 0; padding: 28px 22px; color: var(--fg3); font-size: 13px; line-height: 1.8; }
/* 宿主里放了页框：宿主改成纵向排布，注脚/状态留在纸面外。 */
.ui-preview-body:has(> .ui-preview-stage) { display: flex; flex-direction: column; gap: 8px; overflow: hidden; }

/* ---------- 11.2 两列表单栅格（字段少、面板宽时一屏看完） ----------
   .ui-form-contents 让中间容器不占格（内容按外层栅格排列），可组合多层；
   data-field-span="full" 沿用项目公共字段的整行写法（与 .ip-field-group-body 同一套语义）。 */
.ui-form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 16px; align-content: start; }
.ui-form-grid [data-field-span="full"] { grid-column: 1 / -1; }
.ui-form-contents { display: contents; }
@media (max-width: 900px) {
  .ui-form-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- 12. 容器宽度与宽内容隔离（5.5 实现要求 4/5） ---------- */
.ui-scroll { max-width: 100%; overflow: auto; }
table.ui-wide { display: block; max-width: 100%; overflow-x: auto; }

/* ---------- 13. 响应式与缩放：重要信息优先，次要信息让位 ---------- */
@media (max-width: 900px) {
  .ui-emails { flex-direction: column; }
}
@media (prefers-reduced-motion: reduce) {
  .ai-target-flash { animation: none; }
}


/* 前端模块未全部加载时的提示条（app.js 的模块自检渲染）：
   复用既有的告警色，但独立于页面内容容器，切换路由不会被冲掉。 */
.app-module-failure{display:flex;flex-direction:column;gap:6px;margin:0 0 12px;padding:12px 14px;border:1px solid #f0b8b8;border-radius:8px;background:#fff7f7;color:#7a271a}
.app-module-failure b{font-size:13px}
.app-module-failure p{margin:0;font-size:12px;line-height:1.6;color:#8a4b41}
.app-module-failure [data-module-failure-reload]{align-self:flex-start;margin-top:2px}
