/* ==================================================================
 * styles/app.css —— 外壳布局（M01）
 * ------------------------------------------------------------------
 * 只负责：全局 reset + 六槽位布局 + 通用控件基类（按钮/输入/徽标）
 * 不包含任何业务模块的样式：模块自带样式请写在各自目录的 style.css
 * 所有颜色/尺寸一律引用 tokens.css 的变量，禁止硬编码。
 * 跨浏览器稳定：仅使用 flex/grid/var 等广泛支持的特性。
 * ================================================================== */

/* ---------------- 基础 reset ---------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body,
#app-root {
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  background: var(--bg-app);
  color: var(--fg-default);
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  overflow: hidden; /* 由各面板自行滚动 */
}

h1, h2, h3, h4 {
  margin: 0;
  font-weight: 600;
  line-height: var(--lh-title);
}
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }

p { margin: 0 0 var(--space-3); }
p:last-child { margin-bottom: 0; }

/* ---------------- 主布局：顶栏 / 主体三栏 / 状态栏 ---------------- */
.app-root {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

.app-top {
  flex: 0 0 auto;
  min-height: var(--topbar-h);
  background: var(--bg-panel);
  border-bottom: 1px solid var(--border-default);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-3);
}

.app-body {
  flex: 1 1 auto;
  display: flex;
  min-height: 0; /* 关键：允许子面板内部滚动 */
}

.app-panel {
  min-width: 0;
  min-height: 0;
  overflow: auto;
}

.app-left {
  flex: 0 0 var(--panel-left-w);
  background: var(--bg-panel);
  border-right: 1px solid var(--border-default);
}

.app-center {
  flex: 1 1 auto;
  background: var(--bg-app);
}

.app-right {
  flex: 0 0 var(--panel-right-w);
  background: var(--bg-panel);
  border-left: 1px solid var(--border-default);
}

.app-status {
  flex: 0 0 auto;
  /* ----------------------------------------------------------------
   * 状态栏必须是**一条固定的细带**，高度不能随内容变化。
   *
   * 【这里曾经失控到 344px（占屏高 38%）】原因不是某处写错，而是**21 个模块
   * 各自往状态栏挂了一块内容**，横向自然排不下 —— 而 flex 容器的默认行为是
   * **换行/压缩**：每个模块被压成很窄的一条，文字于是逐字竖排，
   * 堆成一大堆。用户看到的是"状态栏占了半个屏幕，字还变成竖的"。
   *
   * 两条规则一起才成立：
   *   ① 高度写死 + overflow-y: hidden → 内容再多也不许往上长；
   *   ② white-space: nowrap + 子项 flex: 0 0 auto → 不许压缩、不许逐字换行，
   *      放不下就横向滚动（状态栏是"随时瞄一眼"的信息条，滚动完全可接受）。
   * 只做①会导致内容被裁掉看不见，只做②高度仍会涨。 */
  height: var(--statusbar-h);
  min-height: var(--statusbar-h);
  max-height: var(--statusbar-h);
  background: var(--bg-panel);
  border-top: 1px solid var(--border-default);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 0 var(--space-3);
  font-size: var(--fs-aux);
  color: var(--fg-muted);
  white-space: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
}

/* 状态栏里每个模块的那一块：按内容取宽，既不压缩也不换行 */
.app-status > .panel-view {
  flex: 0 0 auto;
  min-width: 0;
  overflow: visible;
}
.app-status > .panel-view > * { flex: 0 0 auto; }

/* 窄滚动条，别让它自己把状态栏撑厚 */
.app-status::-webkit-scrollbar { height: 6px; }
.app-status::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 3px;
}
.app-status::-webkit-scrollbar-track { background: transparent; }

/* ---------------- 面板视图容器 ---------------- */
.panel-view {
  min-height: 0;
}

.panel-view:empty::before {
  /* 空槽位占位提示：便于开发期确认槽位存在 */
  content: "";
  display: block;
  padding: var(--space-3);
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-md);
  margin: var(--space-2);
  color: var(--fg-muted);
  font-size: var(--fs-aux);
}

.panel-error {
  margin: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--c-danger);
  border-radius: var(--radius-md);
  background: var(--bg-elevated);
  color: var(--c-danger);
  font-size: var(--fs-aux);
  font-family: var(--font-mono);
}

/* ---------------- 通用控件基类（供各模块复用）---------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  height: calc(var(--btn-h-s) * var(--btn-scale));
  padding: 0 var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--bg-elevated);
  color: var(--fg-default);
  font-family: var(--font-ui);
  font-size: var(--fs-btn);
  line-height: 1;
  cursor: pointer;
  transition: background var(--t-fast) ease, border-color var(--t-fast) ease;
  user-select: none;
  white-space: nowrap;
}
.btn:hover { background: var(--bg-hover); }
.btn:active { background: var(--bg-active); }
.btn:focus-visible {
  outline: 2px solid var(--c-primary);
  outline-offset: 1px;
}
.btn[disabled] { opacity: .5; cursor: not-allowed; }

.btn--m { height: calc(var(--btn-h-m) * var(--btn-scale)); }
.btn--l { height: calc(var(--btn-h-l) * var(--btn-scale)); }

.btn--primary {
  background: var(--c-primary);
  border-color: var(--c-primary);
  color: var(--fg-on-primary);
}
.btn--primary:hover { filter: brightness(1.08); }

.btn--ghost {
  background: transparent;
  border-color: transparent;
}
.btn--ghost:hover { background: var(--bg-hover); }

.input,
.select,
.textarea {
  width: 100%;
  padding: 0 var(--space-2);
  height: calc(var(--btn-h-s) * var(--btn-scale));
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--bg-app);
  color: var(--fg-default);
  font-family: var(--font-ui);
  font-size: var(--fs-btn);
}
.textarea { height: auto; min-height: 72px; padding: var(--space-2); resize: vertical; }

.input:focus,
.select:focus,
.textarea:focus {
  outline: 2px solid var(--c-primary);
  outline-offset: 0;
  border-color: var(--c-primary);
}

.badge {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-2);
  height: 20px;
  border-radius: 999px;
  background: var(--bg-hover);
  color: var(--fg-muted);
  font-size: 12px;
  line-height: 1;
}
.badge--ok { background: var(--c-primary-soft); color: var(--c-primary); }
.badge--warn { background: var(--bg-panel); color: var(--c-warning); }
.badge--err { background: var(--bg-panel); color: var(--c-danger); }

/* 通用状态徽标（M10 状态库与 M11 Bible 共用；放这里免得各模块各写一份） */
.badge--dirty {
  background: var(--bg-panel);
  color: var(--c-warning);
}

.badge--ai {
  background: var(--bg-panel);
  color: var(--c-accent);
}

.muted { color: var(--fg-muted); }
.mono { font-family: var(--font-mono); }
.small { font-size: var(--fs-aux); }

.card {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-elevated);
  padding: var(--space-3);
}

.row { display: flex; align-items: center; gap: var(--space-2); }
.row--between { justify-content: space-between; }
.col { display: flex; flex-direction: column; gap: var(--space-2); }
.grow { flex: 1 1 auto; min-width: 0; }

.scroll-y { overflow-y: auto; min-height: 0; }

/* ---------------- 弹窗层 ---------------- */
.app-modal {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 900;
}
.app-modal > * { pointer-events: auto; }

.app-modal:empty { display: none; }

/* ---------------- 窄屏：右侧面板收起（响应式下限保障）---------------- */
@media (max-width: 1024px) {
  :root {
    --panel-left-w: 200px;
    --panel-right-w: 260px;
  }
}
@media (max-width: 780px) {
  .app-right { flex-basis: 0; border-left: none; }
  .app-right:not(:empty) { flex-basis: var(--panel-right-w); }
}

/* ---------------- 模块显隐（M03 · C5）----------------
 * 隐藏由 app.theme 设置 hidden 属性；这里保证一定不占空间。
 */
.panel-view[hidden],
.panel-view.is-hidden {
  display: none !important;
}

/* ---------------- 通用表单/设置控件（M03 起，供所有设置类模块复用）----------------
 * 硬规则：这里的样式只允许出现 var(--xxx)，出现色值字面量即视为违规。
 */
.ui-title {
  margin: 0 0 var(--space-2);
  font-size: var(--fs-h3);
  font-weight: 600;
}

.ui-sub {
  margin: 0 0 var(--space-3);
  color: var(--fg-muted);
  font-size: var(--fs-aux);
  line-height: 1.6;
}

.ui-divider {
  height: 1px;
  margin: var(--space-3) 0;
  background: var(--border-default);
  border: 0;
}

.ui-field {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

.ui-field > label,
.ui-label {
  flex: 0 0 auto;
  min-width: 84px;
  color: var(--fg-muted);
  font-size: var(--fs-aux);
}

.ui-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.ui-row--between { justify-content: space-between; }
.ui-wrap { flex-wrap: wrap; }

.ui-seg {
  display: inline-flex;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  overflow: hidden;
  /* 分段控件（中央区工作面切换 / 外观模式切换）在窄容器里会被 flex 压窄，
   * 一旦压到比文字还窄，文字就**逐字换行竖排**——这是本类控件最典型的坏相。
   * 所以：自己不压缩、按内容取宽，装不下时整体横向滚动。
   * 用法上应当少而短（超过 ~8 段就该换成下拉或分组），但界面不该因为段多就崩相。 */
  flex: 0 0 auto;
  max-width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
}

.ui-seg > button {
  /* 收紧内边距：19 个工作面要挤进一条工具栏，原来 12px 的左右内边距
   * 光空隙就吃掉 450px（19×24），是"装不下 → 换行 → 竖排"的直接原因。 */
  padding: 0 var(--space-2);
  height: calc(var(--btn-h-s) * var(--btn-scale));
  border: 0;
  border-right: 1px solid var(--border-default);
  background: var(--bg-elevated);
  color: var(--fg-default);
  font-family: var(--font-ui);
  font-size: var(--fs-btn);
  cursor: pointer;
  /* 【关键】按钮文字永不换行、永不压缩 */
  white-space: nowrap;
  flex: 0 0 auto;
}
.ui-seg > button:last-child { border-right: 0; }
.ui-seg > button:hover { background: var(--bg-hover); }
.ui-seg > button.is-active {
  background: var(--c-primary);
  color: var(--fg-on-primary);
}

/* ----------------------------------------------------------------
 * 中央区工作面切换条：**段特别多**（每个中央区模块一段，现已有 19 段），
 * 所以单独收紧一档，让它尽量在一条工具栏里显示完整。
 * 全局的 .ui-seg 不能跟着一起缩 —— 顶栏那几个（日间/夜间/护眼）本来就很宽松。
 * 即使这样仍然放不下时，外层 overflow-x 会让它横向滚动，不会换行竖排。
 * ---------------------------------------------------------------- */
.ui-seg--center > button {
  /* 3px = space-1 的 75%：19 段要先挤进 ~880px 的工具栏，
   * 实测 4px 内边距时总宽 922px、容器 919px，就差几像素。
   * 仍然走 token 体系（C5），不写死像素值。 */
  padding: 0 calc(var(--space-1) * 0.75);
  font-size: calc(var(--fs-btn) * 0.88);
}
/* 【刻意不给 .is-active 加粗】粗体会让"当前面板"那一段变宽，
 * 于是每切换一次面板，整条切换条的宽度就跳一下、后面的按钮跟着位移。
 * 选中态的区分交给背景色（--c-primary）就够了。 */
/* 中央切换条自己再留一条细滚动条（段数继续增长时用得上） */
.ui-seg--center::-webkit-scrollbar { height: 5px; }
.ui-seg--center::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 3px;
}

.ui-slider {
  flex: 1 1 auto;
  min-width: 0;
  accent-color: var(--c-primary);
}

.ui-num {
  flex: 0 0 auto;
  min-width: 48px;
  text-align: right;
  color: var(--fg-muted);
  font-family: var(--font-mono);
  font-size: var(--fs-aux);
}

.ui-swatch {
  width: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-app);
  cursor: pointer;
}

.ui-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.ui-list > li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--bg-elevated);
}

.ui-list > li > .grow {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ui-hint {
  color: var(--fg-muted);
  font-size: var(--fs-aux);
  line-height: 1.6;
}

.ui-hint--warn { color: var(--c-warning); }
.ui-hint--err { color: var(--c-danger); }
.ui-hint--ok { color: var(--c-success); }

/* ---------------- 打印/导出辅助（M21 会用到）---------------- */
@media print {
  .app-top, .app-left, .app-right, .app-status { display: none !important; }
}
