/* ==========================================================================
   道来 DROPLET 官网 — ERP 界面示意组件（mockups.css）
   用纯 CSS / 内联 SVG 画出的「产品界面」，供首页与产品页嵌入，不引用任何真实截图。
   在 site.css 之后引入：<link rel="stylesheet" href="assets/css/mockups.css">
   可选脚本 mockups.js：注入图标雪碧、自动补「演示数据」标签、图表悬浮提示、演示用明暗切换。
   组件清单与 HTML 片段见根目录 _template_mockups.html。

   命名：全部 .mock-* 前缀，变量统一 --mk-* 前缀，不与 site.css / pages.css 重名。
   尺寸：组件根用容器查询单位定字号（--mk-fs），内部一律 em，随父容器宽度等比缩放；
         外层包一个 .mock（或 .mock-frame / .mock-stack__item）作为容器；
         视口 ≤960px 所有多列回落单列。
   数据：所有数字均为演示数据，组件右上角固定带 .mock-tag「演示数据」。
   图表配色经 CVD / 对比度校验：浅色 #1F5AA6 + #1697B8，深色 #5B79F7 + #18A7A1。
   ========================================================================== */

/* ---------- 0. 令牌（浅色默认；.mock-frame--dark / .mock--dark 覆盖为深色） ---------- */
:root {
  --mk-fs: 12px;
  --mk-bg: var(--c-bg-soft);              /* 工作区底 */
  --mk-surface: #FFFFFF;                  /* 卡片 / 表格底 */
  --mk-surface-2: #F0F4F8;                /* 表头 / 悬停行 / 侧栏二级底 */
  --mk-chrome: #EEF2F6;                   /* 窗口标题栏 */
  --mk-line: var(--c-line);
  --mk-ink: var(--c-ink);
  --mk-ink-2: var(--c-ink-2);
  --mk-muted: var(--c-muted);
  --mk-brand: var(--c-primary);
  --mk-brand-soft: var(--c-accent-soft);
  --mk-accent: var(--c-accent);
  --mk-nav-bg: #FFFFFF;
  --mk-nav-active-bg: var(--c-accent-soft);
  --mk-nav-active-ink: var(--c-primary);
  --mk-series-1: #1F5AA6;                 /* 图表系列 1（计划 / 单系列） */
  --mk-series-2: #1697B8;                 /* 图表系列 2（实际） */
  --mk-track: #D9E4F3;                    /* 进度条未填充段：系列 1 的浅一档 */
  --mk-grid: #E9EEF3;                     /* 网格线 */
  --mk-axis: #C9D2DC;                     /* 轴线 / 十字线 */
  --mk-ok-bg: #E4F5EC;    --mk-ok-ink: #1E7A4C;
  --mk-warn-bg: #FFF2DC;  --mk-warn-ink: #9A6400;
  --mk-bad-bg: #FBE5E4;   --mk-bad-ink: #A32E28;
  --mk-info-bg: #E6F0FB;  --mk-info-ink: #1F5AA6;
  --mk-run-bg: #DDF3F8;   --mk-run-ink: #0E7490;
  --mk-neutral-bg: #F1F3F6; --mk-neutral-ink: #6B7786;
  --mk-today-bg: rgba(26, 167, 201, .10);
  --mk-tip-bg: #1B2430;   --mk-tip-ink: #FFFFFF;
  --mk-shadow: var(--shadow-lg);
  --mk-radius: .7em;
}
.mock-frame--dark, .mock--dark {
  --mk-bg: #0F1B2D;
  --mk-surface: #16263D;
  --mk-surface-2: #1D3049;
  --mk-chrome: #0B1626;
  --mk-line: rgba(255, 255, 255, .10);
  --mk-ink: #EEF3F8;
  --mk-ink-2: #C3CEDB;
  --mk-muted: #8FA1B5;
  --mk-brand: #FFFFFF;
  --mk-brand-soft: rgba(26, 167, 201, .18);
  --mk-nav-bg: #0B1626;
  --mk-nav-active-bg: rgba(26, 167, 201, .18);
  --mk-nav-active-ink: #FFFFFF;
  --mk-series-1: #5B79F7;
  --mk-series-2: #18A7A1;
  --mk-track: rgba(91, 121, 247, .28);
  --mk-grid: #22354D;
  --mk-axis: #35496A;
  --mk-ok-bg: rgba(43, 163, 107, .22);   --mk-ok-ink: #8BE0B4;
  --mk-warn-bg: rgba(224, 154, 27, .22); --mk-warn-ink: #F5CC7F;
  --mk-bad-bg: rgba(217, 69, 61, .24);   --mk-bad-ink: #F6A6A1;
  --mk-info-bg: rgba(91, 121, 247, .22); --mk-info-ink: #B5C4F8;
  --mk-run-bg: rgba(26, 167, 201, .22);  --mk-run-ink: #8EDDEF;
  --mk-neutral-bg: rgba(255, 255, 255, .08); --mk-neutral-ink: #AAB8C8;
  --mk-today-bg: rgba(26, 167, 201, .12);
  --mk-tip-bg: #EEF3F8;   --mk-tip-ink: #0F1B2D;
  --mk-shadow: 0 16px 40px rgba(0, 0, 0, .45);
  color-scheme: dark;
}

/* ---------- 1. 容器与组件根 ---------- */
.mock, .mock-frame, .mock-stack__item,
.mock-dashboard, .mock-gantt, .mock-haccp, .mock-board, .mock-table, .mock-chat { container-type: inline-size; }
.mock { position: relative; width: 100%; min-width: 0; }
.mock-stack, .mock-frame, .mock-dashboard, .mock-gantt, .mock-haccp, .mock-board, .mock-table, .mock-chat {
  position: relative; width: 100%; min-width: 0;
  font-family: var(--font); font-size: var(--mk-fs); line-height: 1.45; font-weight: 400;
  color: var(--mk-ink); text-align: left; font-variant-numeric: tabular-nums;
}
@supports (font-size: 1cqw) {
  :root { --mk-fs: clamp(10px, calc(1.45cqw + 4px), 13px); }
  .mock-stack .mock-frame { --mk-fs: clamp(8px, calc(1.6cqw + 2px), 12px); }
}
.mock-frame *, .mock-dashboard *, .mock-gantt *, .mock-haccp *, .mock-board *, .mock-table *, .mock-chat * { min-width: 0; }
.mock-frame p, .mock-dashboard p, .mock-haccp p, .mock-board p, .mock-table p, .mock-chat p { margin: 0; }

/* 图标（mockups.js 注入 <symbol> 雪碧；页面写 <svg class="mk-i"><use href="#mk-grid"/></svg>） */
.mk-i { display: inline-block; width: 1em; height: 1em; flex: 0 0 auto; vertical-align: -.15em; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.mk-i--fill { fill: currentColor; stroke: none; }
.mock-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* 「演示数据」标签：每个独立展示单元右上角一枚；外框内的组件不再重复 */
.mock-tag {
  position: absolute; top: .55em; right: .7em; z-index: 5;
  display: inline-flex; align-items: center; gap: .3em; padding: .12em .6em;
  border-radius: 999px; border: 1px solid rgba(224, 154, 27, .45);
  background: var(--mk-warn-bg); color: var(--mk-warn-ink);
  font-size: .82em; font-weight: 600; line-height: 1.5; letter-spacing: .02em; white-space: nowrap;
  pointer-events: none;
}
.mock-tag--plan { background: var(--mk-info-bg); color: var(--mk-info-ink); border-color: rgba(31, 90, 166, .35); }
.mock-tags { position: absolute; top: .55em; right: .7em; z-index: 5; display: flex; gap: .4em; }
.mock-tags .mock-tag { position: static; }

/* 通用小件 */
.mock-badge {
  display: inline-flex; align-items: center; gap: .32em; padding: .08em .6em .08em .5em;
  border-radius: 999px; font-size: .85em; font-weight: 600; line-height: 1.6; white-space: nowrap;
  background: var(--mk-neutral-bg); color: var(--mk-neutral-ink);
}
.mock-badge::before { content: ""; width: .5em; height: .5em; border-radius: 50%; background: currentColor; flex: 0 0 auto; }
.mock-badge--ok { background: var(--mk-ok-bg); color: var(--mk-ok-ink); }
.mock-badge--warn { background: var(--mk-warn-bg); color: var(--mk-warn-ink); }
.mock-badge--bad { background: var(--mk-bad-bg); color: var(--mk-bad-ink); }
.mock-badge--info { background: var(--mk-info-bg); color: var(--mk-info-ink); }
.mock-badge--run { background: var(--mk-run-bg); color: var(--mk-run-ink); }
.mock-badge--pass, .mock-badge--fail, .mock-badge--pending { padding-left: .55em; }
.mock-badge--pass::before, .mock-badge--fail::before, .mock-badge--pending::before { width: auto; height: auto; border-radius: 0; background: none; font-weight: 700; line-height: 1; }
.mock-badge--pass { background: var(--mk-ok-bg); color: var(--mk-ok-ink); }
.mock-badge--pass::before { content: "✓"; }
.mock-badge--fail { background: var(--mk-bad-bg); color: var(--mk-bad-ink); }
.mock-badge--fail::before { content: "✕"; }
.mock-badge--pending { background: var(--mk-neutral-bg); color: var(--mk-neutral-ink); }
.mock-badge--pending::before { content: "○"; }

.mock-chip { display: inline-flex; align-items: center; gap: .35em; padding: .18em .75em; border-radius: 999px; border: 1px solid var(--mk-line); background: var(--mk-surface); color: var(--mk-ink-2); font-size: .85em; white-space: nowrap; }
.mock-chip--active { background: var(--mk-brand-soft); color: var(--mk-nav-active-ink); border-color: transparent; font-weight: 600; }
.mock-seg { display: inline-flex; border: 1px solid var(--mk-line); border-radius: .4em; overflow: hidden; font-size: .82em; }
.mock-seg span { padding: .2em .6em; color: var(--mk-muted); border-left: 1px solid var(--mk-line); white-space: nowrap; }
.mock-seg span:first-child { border-left: 0; }
.mock-seg .is-active { background: var(--mk-brand-soft); color: var(--mk-nav-active-ink); font-weight: 600; }

.mock-progress { position: relative; height: .5em; border-radius: 999px; background: var(--mk-track); overflow: hidden; flex: 1 1 auto; }
.mock-progress i { display: block; height: 100%; border-radius: inherit; background: var(--mk-series-1); }
.mock-progress--ok i { background: var(--c-success); }
.mock-progress--warn i { background: var(--c-warning); }
.mock-progress--bad i { background: var(--c-danger); }

.mock-card { background: var(--mk-surface); border: 1px solid var(--mk-line); border-radius: var(--mk-radius); padding: 1em; min-width: 0; }
.mock-card__head { display: flex; align-items: center; justify-content: space-between; gap: .6em; flex-wrap: wrap; margin-bottom: .6em; }
.mock-card__title { font-weight: 600; font-size: 1em; margin: 0; color: var(--mk-ink); }
.mock-card__sub { color: var(--mk-muted); font-size: .85em; }

/* 表格（仪表盘小表 / HACCP / 追溯 共用） */
.mock-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
.mock-tbl { width: 100%; border-collapse: collapse; font-size: .92em; color: var(--mk-ink); }
.mock-tbl th { text-align: left; font-weight: 600; font-size: .9em; color: var(--mk-muted); padding: .55em .75em; border-bottom: 1px solid var(--mk-line); background: var(--mk-surface-2); white-space: nowrap; }
.mock-tbl td { padding: .62em .75em; border-bottom: 1px solid var(--mk-line); vertical-align: middle; white-space: nowrap; }
.mock-tbl tbody tr:last-child td { border-bottom: 0; }
.mock-tbl tbody tr:hover td { background: var(--mk-surface-2); }
.mock-tbl .num { text-align: right; }
.mock-tbl .mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; font-size: .95em; color: var(--mk-ink-2); }
.mock-tbl .wrap { white-space: normal; min-width: 10em; }
.mock-tbl .wrap-sm small { white-space: nowrap; }
.mock-tbl small { color: var(--mk-muted); font-size: .85em; }
.mock-tbl__note td { white-space: normal; font-size: .85em; color: var(--mk-ink-2); background: var(--mk-bad-bg); border-left: 3px solid var(--c-danger); padding-top: .45em; padding-bottom: .45em; }
.mock-tbl__sub td:first-child { padding-left: 1.6em; }
.mock-tbl__sub td:first-child::before { content: "└ "; color: var(--mk-muted); }

/* ---------- 2. 窗口外框 .mock-frame ---------- */
.mock-frame {
  display: flex; flex-direction: column;
  background: var(--mk-bg); border: 1px solid var(--mk-line); border-radius: .85em;
  box-shadow: var(--mk-shadow); overflow: hidden;
}
.mock-frame__bar { display: flex; align-items: center; gap: .9em; height: 2.6em; padding: 0 1em; background: var(--mk-chrome); border-bottom: 1px solid var(--mk-line); flex: 0 0 auto; }
.mock-frame__dots { display: flex; gap: .45em; flex: 0 0 auto; }
.mock-frame__dots i { width: .75em; height: .75em; border-radius: 50%; background: #E0655E; }
.mock-frame__dots i:nth-child(2) { background: #E8B04A; }
.mock-frame__dots i:nth-child(3) { background: #4FBF86; }
.mock-frame__url {
  flex: 0 1 46%; margin: 0 auto; height: 1.75em; padding: 0 .85em;
  display: flex; align-items: center; gap: .4em;
  border-radius: 999px; background: var(--mk-surface); border: 1px solid var(--mk-line);
  color: var(--mk-muted); font-size: .88em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mock-frame__url .mk-i { width: .9em; height: .9em; }
.mock-frame__body { display: flex; flex: 1 1 auto; min-height: 0; }
.mock-frame__nav { flex: 0 0 11.5em; display: flex; flex-direction: column; gap: .15em; padding: .9em .6em; background: var(--mk-nav-bg); border-right: 1px solid var(--mk-line); }
.mock-frame__brand { display: flex; align-items: center; gap: .5em; padding: .3em .6em 1em; font-size: 1.05em; font-weight: 700; color: var(--mk-brand); white-space: nowrap; }
.mock-frame__brand .mk-i { width: 1.4em; height: 1.4em; color: var(--mk-accent); }
.mock-frame__item { display: flex; align-items: center; gap: .6em; padding: .45em .7em; border-radius: .45em; color: var(--mk-ink-2); white-space: nowrap; }
.mock-frame__item .mk-i { width: 1.1em; height: 1.1em; }
.mock-frame__item.is-active { background: var(--mk-nav-active-bg); color: var(--mk-nav-active-ink); font-weight: 600; }
.mock-frame__main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.mock-frame__top { display: flex; align-items: center; gap: .8em; padding: .65em 1.2em; background: var(--mk-surface); border-bottom: 1px solid var(--mk-line); }
.mock-frame__title { font-weight: 700; font-size: 1.1em; color: var(--mk-ink); line-height: 1.3; white-space: nowrap; }
.mock-frame__crumb { color: var(--mk-muted); font-size: .82em; white-space: nowrap; }
.mock-frame__search { margin-left: auto; display: flex; align-items: center; gap: .4em; height: 2em; padding: 0 .9em; border-radius: 999px; border: 1px solid var(--mk-line); background: var(--mk-bg); color: var(--mk-muted); font-size: .88em; white-space: nowrap; flex: 0 1 16em; overflow: hidden; }
.mock-frame__bell { width: 2em; height: 2em; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: var(--mk-ink-2); background: var(--mk-bg); border: 1px solid var(--mk-line); flex: 0 0 auto; position: relative; }
.mock-frame__bell::after { content: ""; position: absolute; top: .35em; right: .4em; width: .45em; height: .45em; border-radius: 50%; background: var(--c-danger); border: 1px solid var(--mk-surface); }
.mock-frame__avatar { width: 2em; height: 2em; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex: 0 0 auto; background: linear-gradient(135deg, var(--c-accent), var(--c-primary)); color: #fff; font-size: .9em; font-weight: 700; }
.mock-frame__content { flex: 1 1 auto; min-width: 0; padding: 1.2em; }
.mock-frame--bare .mock-frame__nav, .mock-frame--bare .mock-frame__top { display: none; }  /* 只要窗口壳 */
@container (max-width: 600px) {
  .mock-frame__nav { flex-basis: 3.5em; padding: .9em .5em; }
  /* 只隐藏文字子节点：.mock-frame__item 本身是 span，不能用后代选择器整项隐藏 */
  .mock-frame__item > span, .mock-frame__brand > span { display: none; }
  .mock-frame__brand { justify-content: center; padding-left: 0; padding-right: 0; }
  .mock-frame__item { justify-content: center; padding: .5em; }
  .mock-frame__search { flex-basis: 2em; padding: 0 .55em; }
  .mock-frame__search span { display: none; }
  .mock-frame__crumb { display: none; }
}
@container (max-width: 360px) {
  .mock-frame__nav { display: none; }
  .mock-frame__content { padding: .8em; }
}

/* ---------- 3. 仪表盘 .mock-dashboard ---------- */
.mock-dashboard { display: grid; gap: 1em; }
.mock-dashboard__kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1em; }
.mock-kpi { background: var(--mk-surface); border: 1px solid var(--mk-line); border-radius: var(--mk-radius); padding: .9em 1em; display: flex; flex-direction: column; gap: .2em; }
.mock-kpi__label { font-size: .88em; color: var(--mk-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mock-kpi__value { font-size: 1.9em; font-weight: 700; line-height: 1.15; color: var(--mk-ink); font-variant-numeric: normal; letter-spacing: -.01em; white-space: nowrap; }
.mock-kpi__value small { font-size: .5em; font-weight: 500; color: var(--mk-muted); margin-left: .25em; letter-spacing: 0; }
.mock-kpi__delta { display: flex; align-items: center; gap: .3em; font-size: .85em; color: var(--mk-ok-ink); white-space: nowrap; }
.mock-kpi__delta .mk-i { width: .9em; height: .9em; stroke-width: 2.4; }
.mock-kpi__delta--down { color: var(--mk-bad-ink); }
.mock-kpi__delta--flat { color: var(--mk-muted); }
.mock-kpi__delta small { color: var(--mk-muted); font-weight: 400; }
.mock-dashboard__charts { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 1em; }
.mock-legend { display: flex; flex-wrap: wrap; gap: .3em 1em; font-size: .85em; color: var(--mk-ink-2); }
.mock-legend span { display: inline-flex; align-items: center; gap: .4em; white-space: nowrap; }
.mock-legend i { display: inline-block; width: 1.2em; height: 2px; border-radius: 1px; background: var(--mk-series-1); }
.mock-legend i.s2 { background: var(--mk-series-2); }
.mock-legend i.sq { width: .75em; height: .75em; border-radius: 2px; }

/* 图表：inline SVG，viewBox 等比缩放；细线、细网格、少量直接标注 */
.mock-chart { position: relative; }
.mock-chart svg { display: block; width: 100%; height: auto; overflow: visible; font-family: inherit; }
.mock-chart text { fill: var(--mk-muted); font-size: 11px; }
.mock-chart__grid line { stroke: var(--mk-grid); stroke-width: 1; }
.mock-chart__axis { stroke: var(--mk-axis); stroke-width: 1; }
.mock-chart__line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.mock-chart__line--1 { stroke: var(--mk-series-1); }
.mock-chart__line--2 { stroke: var(--mk-series-2); }
.mock-chart__area { opacity: .1; }
.mock-chart__area--1 { fill: var(--mk-series-1); }
.mock-chart__area--2 { fill: var(--mk-series-2); }
.mock-chart__dots circle { stroke: var(--mk-surface); stroke-width: 2; }
.mock-chart__dots--1 circle { fill: var(--mk-series-1); }
.mock-chart__dots--2 circle { fill: var(--mk-series-2); }
.mock-chart__lbl { fill: var(--mk-ink-2); font-weight: 600; }
.mock-chart__bar { fill: var(--mk-series-1); transition: opacity .15s; }
.mock-chart__hit { fill: transparent; outline: none; }
.mock-chart__cross { stroke: var(--mk-axis); stroke-width: 1; opacity: 0; transition: opacity .15s; pointer-events: none; }
.mock-chart__col:hover .mock-chart__cross, .mock-chart__col:focus-within .mock-chart__cross { opacity: 1; }
.mock-chart__col:hover .mock-chart__bar, .mock-chart__col:focus-within .mock-chart__bar { opacity: .72; }
.mock-tip {
  position: absolute; z-index: 6; left: 0; top: 0; pointer-events: none;
  padding: .4em .65em; border-radius: .4em; background: var(--mk-tip-bg); color: var(--mk-tip-ink);
  font-size: .85em; line-height: 1.4; white-space: nowrap; box-shadow: var(--shadow-md);
  opacity: 0; transform: translate(-50%, 0); transition: opacity .15s;
}
.mock-tip.is-on { opacity: 1; }

/* ---------- 4. 排程甘特 .mock-gantt ---------- */
.mock-gantt { --gantt-label: 9.5em; --gantt-today: 2; background: var(--mk-surface); border: 1px solid var(--mk-line); border-radius: var(--mk-radius); padding: 1em; }
.mock-gantt__head { display: flex; align-items: center; gap: .6em; flex-wrap: wrap; margin-bottom: .8em; padding-right: 6em; }
.mock-gantt__title { font-weight: 600; white-space: nowrap; }
.mock-gantt__tools { margin-left: auto; display: flex; align-items: center; gap: .45em; flex-wrap: wrap; }
.mock-gantt__grid { position: relative; border: 1px solid var(--mk-line); border-radius: .5em; overflow: hidden; }
.mock-gantt__row { display: grid; grid-template-columns: var(--gantt-label) minmax(0, 1fr); border-bottom: 1px solid var(--mk-line); }
.mock-gantt__row:last-child { border-bottom: 0; }
.mock-gantt__corner, .mock-gantt__label { padding: .5em .75em; border-right: 1px solid var(--mk-line); background: var(--mk-surface-2); font-size: .9em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mock-gantt__corner { color: var(--mk-muted); }
.mock-gantt__label { display: flex; flex-direction: column; justify-content: center; line-height: 1.3; font-weight: 600; }
.mock-gantt__label small { color: var(--mk-muted); font-weight: 400; font-size: .85em; }
.mock-gantt__days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); background: var(--mk-surface-2); }
.mock-gantt__days span { padding: .5em 0; text-align: center; font-size: .82em; color: var(--mk-muted); border-left: 1px solid var(--mk-line); white-space: nowrap; overflow: hidden; }
.mock-gantt__days span:first-child { border-left: 0; }
.mock-gantt__days .is-today { color: var(--mk-nav-active-ink); font-weight: 700; background: var(--mk-today-bg); }
.mock-gantt__days .is-today::after { content: "今天"; margin-left: .4em; padding: 0 .35em; border-radius: .3em; font-size: .85em; font-weight: 700; background: var(--c-accent); color: #fff; }
.mock-gantt__lane {
  position: relative; display: grid; grid-template-columns: repeat(14, minmax(0, 1fr)); grid-auto-rows: auto; row-gap: .3em; align-items: center;
  min-height: 3em; padding: .45em 0;
  background-image: repeating-linear-gradient(to right, transparent 0, transparent calc(100% / 7 - 1px), var(--mk-line) calc(100% / 7 - 1px), var(--mk-line) calc(100% / 7));
}
.mock-gantt__lane::before { content: ""; position: absolute; top: 0; bottom: 0; left: calc(100% / 7 * var(--gantt-today)); width: calc(100% / 7); background: var(--mk-today-bg); pointer-events: none; }
.mock-gantt__bar {
  position: relative; grid-row: 1; height: 2em; margin: 0 2px; padding: 0 .6em;
  display: flex; align-items: center; gap: .35em; overflow: hidden;
  border-radius: .35em; border: 1px solid rgba(31, 90, 166, .3);
  background: var(--mk-info-bg); color: var(--mk-info-ink);
  font-size: .85em; font-weight: 600; white-space: nowrap;
}
.mock-gantt__bar > span { overflow: hidden; text-overflow: ellipsis; position: relative; z-index: 1; }
.mock-gantt__bar > i { position: absolute; left: 0; bottom: 0; height: 3px; width: var(--p, 0%); background: var(--mk-series-1); }
.mock-gantt__bar--run { background: var(--mk-run-bg); color: var(--mk-run-ink); border-color: rgba(26, 167, 201, .45); }
.mock-gantt__bar--run > i { background: var(--c-accent); }
.mock-gantt__bar--done { background: var(--mk-ok-bg); color: var(--mk-ok-ink); border-color: rgba(43, 163, 107, .4); }
.mock-gantt__bar--done > i { background: var(--c-success); }
.mock-gantt__bar--hold { border-style: dashed; background: var(--mk-neutral-bg); color: var(--mk-neutral-ink); border-color: var(--mk-muted); }
.mock-gantt__bar--conflict { background: var(--mk-bad-bg); color: var(--mk-bad-ink); border: 1.5px solid var(--c-danger); box-shadow: 0 0 0 2px rgba(217, 69, 61, .18); }
.mock-gantt__bar--conflict::before { content: "!"; flex: 0 0 auto; width: 1.2em; height: 1.2em; border-radius: 50%; background: var(--c-danger); color: #fff; font-size: .85em; line-height: 1.2em; text-align: center; font-weight: 800; }
.mock-gantt__today { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--c-accent); z-index: 2; pointer-events: none; left: calc(var(--gantt-label) + (100% - var(--gantt-label)) / 7 * (var(--gantt-today) + .5)); }
.mock-gantt__hint { position: absolute; z-index: 3; padding: .4em .7em; border-radius: .4em; background: var(--mk-tip-bg); color: var(--mk-tip-ink); font-size: .8em; font-weight: 600; white-space: nowrap; box-shadow: var(--shadow-md); pointer-events: none; }
.mock-gantt__hint::after { content: ""; position: absolute; left: 1em; bottom: -.4em; border: .4em solid transparent; border-top-color: var(--mk-tip-bg); border-bottom: 0; }
.mock-gantt__legend { display: flex; flex-wrap: wrap; gap: .4em 1.2em; margin-top: .8em; font-size: .85em; color: var(--mk-ink-2); }
.mock-gantt__legend span { display: inline-flex; align-items: center; gap: .4em; white-space: nowrap; }
.mock-gantt__legend i { width: .95em; height: .95em; border-radius: .25em; border: 1px solid rgba(31, 90, 166, .3); background: var(--mk-info-bg); }
.mock-gantt__legend i.run { background: var(--mk-run-bg); border-color: rgba(26, 167, 201, .45); }
.mock-gantt__legend i.done { background: var(--mk-ok-bg); border-color: rgba(43, 163, 107, .4); }
.mock-gantt__legend i.hold { background: var(--mk-neutral-bg); border-style: dashed; border-color: var(--mk-muted); }
.mock-gantt__legend i.conflict { background: var(--mk-bad-bg); border-color: var(--c-danger); }
@container (max-width: 560px) {
  .mock-gantt { --gantt-label: 6em; }
  .mock-gantt__label small { display: none; }
  .mock-gantt__hint, .mock-gantt__tools .mock-seg { display: none; }
  .mock-gantt__days .is-today::after { display: none; }
}

/* ---------- 5. HACCP 检查表 .mock-haccp ---------- */
.mock-haccp { background: var(--mk-surface); border: 1px solid var(--mk-line); border-radius: var(--mk-radius); padding: 1em; }
.mock-haccp__head { display: flex; align-items: center; gap: .5em 1.2em; flex-wrap: wrap; margin-bottom: .8em; padding-right: 6em; }
.mock-haccp__title { font-weight: 600; white-space: nowrap; }
.mock-haccp__meta { display: flex; flex-wrap: wrap; gap: .3em 1em; color: var(--mk-muted); font-size: .88em; }
.mock-haccp__meta b { color: var(--mk-ink-2); font-weight: 600; }
.mock-haccp__summary { margin-left: auto; display: flex; gap: .4em; flex-wrap: wrap; }
.mock-haccp__foot { margin-top: .7em; font-size: .82em; color: var(--mk-muted); }

/* ---------- 6. 在手订单看板 .mock-board ---------- */
.mock-board { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1em; }
.mock-board__bar { grid-column: 1 / -1; display: flex; align-items: center; gap: .5em; flex-wrap: wrap; padding-right: 10em; }
.mock-board__title { font-weight: 600; white-space: nowrap; }
.mock-board__col { background: var(--mk-bg); border: 1px solid var(--mk-line); border-radius: var(--mk-radius); padding: .8em; display: flex; flex-direction: column; gap: .7em; }
.mock-board__colhead { display: flex; align-items: center; gap: .5em; font-weight: 600; white-space: nowrap; }
.mock-board__colhead::before { content: ""; width: .3em; height: 1.1em; border-radius: 2px; background: var(--mk-accent); }
.mock-board__colhead small { color: var(--mk-muted); font-weight: 400; font-size: .85em; overflow: hidden; text-overflow: ellipsis; }
.mock-board__count { margin-left: auto; }
.mock-order { background: var(--mk-surface); border: 1px solid var(--mk-line); border-radius: .6em; padding: .8em; display: flex; flex-direction: column; gap: .45em; }
.mock-order__top { display: flex; align-items: center; justify-content: space-between; gap: .5em; }
.mock-order__no { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .85em; color: var(--mk-ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mock-order__name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mock-order__meta { display: flex; justify-content: space-between; gap: .6em; color: var(--mk-muted); font-size: .85em; white-space: nowrap; }
.mock-order__meta b { color: var(--mk-ink-2); font-weight: 600; }
.mock-order__bar { display: flex; align-items: center; gap: .6em; font-size: .85em; color: var(--mk-ink-2); font-weight: 600; }
.mock-order__nums { font-size: .82em; color: var(--mk-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---------- 7. 批次追溯表 .mock-table ---------- */
.mock-table { background: var(--mk-surface); border: 1px solid var(--mk-line); border-radius: var(--mk-radius); padding: 1em; }
.mock-table__head { display: flex; align-items: center; gap: .5em .8em; flex-wrap: wrap; margin-bottom: .8em; padding-right: 6em; }
.mock-table__title { font-weight: 600; white-space: nowrap; }
.mock-table__filters { display: flex; gap: .4em; flex-wrap: wrap; }
.mock-table__foot { margin-top: .7em; font-size: .82em; color: var(--mk-muted); }
.mock-chain { display: inline-flex; align-items: center; flex-wrap: nowrap; gap: .2em; }
.mock-chain__step { padding: .1em .55em; border-radius: .3em; font-size: .8em; font-weight: 600; background: var(--mk-ok-bg); color: var(--mk-ok-ink); white-space: nowrap; }
.mock-chain__step--now { background: var(--mk-run-bg); color: var(--mk-run-ink); }
.mock-chain__step--todo { background: transparent; color: var(--mk-muted); border: 1px dashed var(--mk-line); font-weight: 500; }
.mock-chain__arrow { color: var(--mk-muted); font-size: .8em; line-height: 1; }

/* ---------- 8. AI 助手对话 .mock-chat ---------- */
.mock-chat { display: flex; flex-direction: column; background: var(--mk-surface); border: 1px solid var(--mk-line); border-radius: .9em; overflow: hidden; }
.mock-chat__head { display: flex; align-items: center; gap: .65em; padding: .8em 1em; padding-right: 7em; background: var(--mk-surface-2); border-bottom: 1px solid var(--mk-line); }
.mock-chat__avatar, .mock-msg__avatar { flex: 0 0 auto; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #fff; background: linear-gradient(135deg, var(--c-accent), var(--c-primary)); }
.mock-chat__avatar { width: 2.2em; height: 2.2em; }
.mock-chat__avatar .mk-i { width: 1.2em; height: 1.2em; }
.mock-chat__name { font-weight: 600; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mock-chat__status { display: flex; align-items: center; gap: .35em; font-size: .8em; color: var(--mk-muted); }
.mock-chat__status::before { content: ""; width: .5em; height: .5em; border-radius: 50%; background: var(--c-success); }
.mock-chat__body { display: flex; flex-direction: column; gap: .75em; padding: 1em; background: var(--mk-bg); }
.mock-msg { display: flex; align-items: flex-end; gap: .5em; max-width: 88%; }
.mock-msg--ai { align-self: flex-start; }
.mock-msg--user { align-self: flex-end; flex-direction: row-reverse; }
.mock-msg__avatar { width: 1.6em; height: 1.6em; font-size: .85em; font-weight: 700; }
.mock-msg--user .mock-msg__avatar { background: var(--mk-neutral-bg); color: var(--mk-ink-2); }
.mock-msg__bubble { padding: .6em .9em; border-radius: .9em; background: var(--mk-surface); border: 1px solid var(--mk-line); line-height: 1.55; font-size: .95em; }
.mock-msg--ai .mock-msg__bubble { border-bottom-left-radius: .25em; }
.mock-msg--user .mock-msg__bubble { background: var(--c-primary); color: #fff; border-color: var(--c-primary); border-bottom-right-radius: .25em; }
.mock-msg__bubble p { margin: 0; }
.mock-msg__bubble p + p { margin-top: .4em; }
.mock-msg__bubble ul, .mock-msg__bubble ol { margin: .35em 0 .35em 1.2em; padding: 0; list-style: disc; }
.mock-msg__bubble ol { list-style: decimal; }
.mock-msg__bubble li { margin: .15em 0; }
.mock-msg__bubble li + li { margin-top: .15em; }
.mock-msg__meta { font-size: .75em; color: var(--mk-muted); margin-top: .25em; }
.mock-msg__table { margin: .4em 0; font-size: .9em; }
.mock-chat__typing { display: inline-flex; gap: .3em; padding: .75em .9em; }
.mock-chat__typing i { width: .45em; height: .45em; border-radius: 50%; background: var(--mk-muted); animation: mkBlink 1.2s infinite ease-in-out; }
.mock-chat__typing i:nth-child(2) { animation-delay: .2s; }
.mock-chat__typing i:nth-child(3) { animation-delay: .4s; }
@keyframes mkBlink { 0%, 80%, 100% { opacity: .3; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-.15em); } }
.mock-chat__chips { display: flex; flex-wrap: wrap; gap: .4em; padding: 0 1em .9em; background: var(--mk-bg); }
.mock-chat__input { display: flex; align-items: center; gap: .6em; padding: .7em 1em; background: var(--mk-surface); border-top: 1px solid var(--mk-line); }
.mock-chat__field { flex: 1 1 auto; height: 2.3em; padding: 0 1em; display: flex; align-items: center; border: 1px solid var(--mk-line); border-radius: 999px; background: var(--mk-bg); color: var(--mk-muted); font-size: .9em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mock-chat__send { width: 2.3em; height: 2.3em; border-radius: 50%; flex: 0 0 auto; display: flex; align-items: center; justify-content: center; background: var(--c-primary); color: #fff; }
.mock-chat__send .mk-i { width: 1.05em; height: 1.05em; }

/* ---------- 9. 三层叠放 .mock-stack（hero 用） ----------
   三个 .mock-stack__item 必须是 <div>（按 nth-of-type 定位，后→前），标签用 <span class="mock-tag"> 不占序号 */
.mock-stack { position: relative; width: 100%; aspect-ratio: 16 / 11; perspective: 1800px; perspective-origin: 60% 40%; }
.mock-stack__item {
  position: absolute; width: 74%; aspect-ratio: 16 / 10; overflow: hidden;
  border-radius: .85em; box-shadow: var(--mk-shadow); background: var(--mk-bg);
  transform-style: preserve-3d; transition: transform .6s var(--ease);
}
.mock-stack__item > .mock-frame { height: 100%; border-radius: inherit; box-shadow: none; }
.mock-stack__item:nth-of-type(1) { left: 0; top: 0; z-index: 1; transform: rotateY(-12deg) rotateX(5deg) translateZ(-140px); }
.mock-stack__item:nth-of-type(2) { left: 13%; top: 14%; z-index: 2; transform: rotateY(-12deg) rotateX(5deg) translateZ(-70px); }
.mock-stack__item:nth-of-type(3) { left: 26%; top: 28%; z-index: 3; transform: rotateY(-12deg) rotateX(5deg); }
.mock-stack:hover .mock-stack__item:nth-of-type(3) { transform: rotateY(-8deg) rotateX(3deg) translateY(-.4em); }
.mock-stack > .mock-tag { top: auto; bottom: .4em; right: .4em; z-index: 6; }
/* 后层界面的「规划中」标签：≤960 只显示最前一层时，由 mockups.js 复制到容器层（.mock-stack__plan），桌面端隐藏 */
.mock-stack > .mock-stack__plan { display: none; }
/* 叠放里强制桌面布局（缩略展示，不按容器断点折叠） */
.mock-stack .mock-dashboard__kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.mock-stack .mock-dashboard__charts { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
.mock-stack .mock-frame__content { padding: .9em; }

/* ---------- 10. 容器断点（组件本身较窄时） ---------- */
@container (max-width: 560px) {
  .mock-dashboard__kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mock-dashboard__charts { grid-template-columns: minmax(0, 1fr); }
  .mock-board { grid-template-columns: minmax(0, 1fr); }
  .mock-hide-sm { display: none !important; }
  .mock-tbl .wrap-sm { white-space: normal; min-width: 7em; }
  .mock-tbl .wrap-sm small { display: block; }
  .mock-chart--line text { font-size: 17px; }
  .mock-gantt__head, .mock-haccp__head, .mock-table__head { padding-right: 0; padding-top: 1.6em; }
  .mock-board__bar { padding-right: 0; padding-top: 1.6em; }
  .mock-chat__head { padding-right: 6em; }
}

/* ---------- 11. 视口断点：≤960 全部单列；减少动效 ---------- */
@media (max-width: 960px) {
  .mock-dashboard__kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mock-dashboard__charts { grid-template-columns: minmax(0, 1fr); }
  .mock-board { grid-template-columns: minmax(0, 1fr); }
  .mock-stack { aspect-ratio: auto; perspective: none; }
  .mock-stack__item, .mock-stack__item:nth-of-type(1), .mock-stack__item:nth-of-type(2), .mock-stack__item:nth-of-type(3) { position: relative; width: 100%; aspect-ratio: auto; transform: none !important; left: 0; top: 0; }
  .mock-stack__item:nth-of-type(1), .mock-stack__item:nth-of-type(2) { display: none; }
  .mock-stack__item > .mock-frame { height: auto; }
  .mock-stack .mock-dashboard__kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mock-stack .mock-dashboard__charts { grid-template-columns: minmax(0, 1fr); }
  .mock-stack > .mock-tag { top: .55em; bottom: auto; right: .7em; }
  .mock-stack > .mock-stack__plan { display: inline-flex; top: .55em; bottom: auto; right: auto; left: .7em; }
  .mock-gantt__hint { display: none; }
  /* 10 手机上不再缩字：外框内基准字号固定 12px（最小派生字号 ≈ 10px），内容区放不下时在框内横向滚动 */
  .mock-frame, .mock-stack .mock-frame { --mk-fs: 12px; }
  .mock-tag, .mock-stack > .mock-tag { font-size: max(10px, .82em); }
  .mock-frame__content { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
  .mock-frame__content > .mock-gantt { min-width: 36em; }
  .mock-frame__content > .mock-table, .mock-frame__content > .mock-board, .mock-frame__content > .mock-haccp { min-width: 30em; }
  /* 示意内的次级小字统一不低于 10px（桌面端不变） */
  :is(.mock-frame, .mock-dashboard, .mock-gantt, .mock-haccp, .mock-board, .mock-table, .mock-chat) :is(small, .mock-kpi__label, .mock-kpi__delta, .mock-chip, .mock-badge, .mock-seg, .mock-tbl, .mock-tbl th, .mock-tbl__note td, .mock-card__sub, .mock-legend, .mock-gantt__days span, .mock-gantt__corner, .mock-gantt__label, .mock-gantt__bar, .mock-gantt__legend, .mock-frame__url, .mock-frame__crumb, .mock-frame__search, .mock-msg__meta, .mock-msg__bubble, .mock-chat__status, .mock-chat__field, .mock-order__no, .mock-order__meta, .mock-order__bar, .mock-order__nums, .mock-chain__step, .mock-chain__arrow, .mock-haccp__meta, .mock-haccp__foot, .mock-table__foot, .mock-tag) { font-size: max(10px, .85em); }
  .mock-kpi__value small { font-size: max(10px, .5em); }
}
@media (max-width: 600px) {
  .mock-hide-sm { display: none !important; }
  .mock-tbl .wrap-sm { white-space: normal; min-width: 7em; }
  .mock-tbl .wrap-sm small { display: block; }
  .mock-chart--line text { font-size: 17px; }
  .mock-gantt { --gantt-label: 6em; }
  .mock-gantt__label small { display: none; }
  .mock-gantt__tools .mock-seg { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .mock-stack__item, .mock-chart__bar, .mock-chart__cross, .mock-tip { transition: none; }
  .mock-chat__typing i { animation: none; opacity: .6; }
}

/* ---------- 12. 真实截图（mockups.js 探测到 assets/img/screens/<name>.png 后给容器挂 .has-shot） ----------
   截图不存在时下面的规则一条都不命中，页面与纯 CSS 示意完全一致。
   --mk-shot-ratio 由脚本按截图宽高写在容器上（最小 4:3），内容区据此定高，懒加载前后高度不变。 */
.mock-shot { display: block; width: 100%; height: auto; max-width: none; margin: 0; object-fit: cover; object-position: top left; background: var(--mk-surface); border-radius: 0; }
/* 窗口外框：保留 .mock-frame__bar（三圆点 / 地址栏），.mock-frame__body 整块换成截图（含示意侧栏与顶栏） */
.mock-frame.has-shot > .mock-frame__body { position: relative; overflow: hidden; aspect-ratio: var(--mk-shot-ratio, 16 / 10); }
.mock-frame.has-shot > .mock-frame__body > :not(.mock-shot) { display: none !important; }
.mock-frame.has-shot > .mock-frame__body > .mock-shot { position: absolute; inset: 0; width: 100%; height: 100%; }
.mock-frame.has-shot .mock-frame__content { overflow: hidden; }
/* 页面自绘的 .mock（.mock__bar + 内容 + .mock__foot）与组件根（.mock-dashboard / .mock-chat …）：
   保留标题条、脚注与「演示数据」标签，其余子节点隐藏，截图按比例铺满 */
.has-shot:not(.mock-frame) > :not(.mock-shot):not(.mock__bar):not(.mock__foot):not(.mock-tag):not(.mock-tags):not(.mock-stack__plan) { display: none !important; }
.has-shot:not(.mock-frame) > .mock-shot { aspect-ratio: var(--mk-shot-ratio, 16 / 10); }
.mock-dashboard.has-shot, .mock-gantt.has-shot, .mock-haccp.has-shot, .mock-board.has-shot, .mock-table.has-shot { display: block; padding: 0; overflow: hidden; border-radius: var(--mk-radius); }
.mock-chat.has-shot { display: block; }
@media (max-width: 960px) {
  /* 手机：内容区不再横向滚动，截图同样等比铺满 */
  .mock-frame.has-shot > .mock-frame__body { overflow: hidden; }
  .mock-frame.has-shot .mock-frame__content { overflow: hidden; }
}
