/* ============================================================
   船厂裁切车间管理系统 · 视觉系统 v3
   设计语言：SoybeanAdmin（Naive UI 风格后台框架）
   - 浅色侧栏 + 顶栏面包屑 + 多标签页 + 浅灰内容区 + 白卡片
   - 主色默认 SoybeanAdmin 绿 #18A058，可切蓝 / 青 / 橙 / 暗夜
   - html[data-theme] 切换调色板，html[data-sider="off"] 折叠侧栏
   ============================================================ */

/* ==================== 0. 设计变量 ==================== */
:root,
html[data-theme="green"] {
    --brand: #18a058;
    --brand-hover: #36ad6a;
    --brand-pressed: #0c7a43;
    --brand-50: rgba(24, 160, 88, .08);
    --brand-100: rgba(24, 160, 88, .16);
    --brand-fade: rgba(24, 160, 88, .06);
    --brand-ring: rgba(24, 160, 88, .22);
}

html[data-theme="blue"] {
    --brand: #1890ff;
    --brand-hover: #40a9ff;
    --brand-pressed: #096dd9;
    --brand-50: rgba(24, 144, 255, .08);
    --brand-100: rgba(24, 144, 255, .16);
    --brand-fade: rgba(24, 144, 255, .06);
    --brand-ring: rgba(24, 144, 255, .22);
}

html[data-theme="cyan"] {
    --brand: #13a8a8;
    --brand-hover: #2dbdbd;
    --brand-pressed: #0b8787;
    --brand-50: rgba(19, 168, 168, .08);
    --brand-100: rgba(19, 168, 168, .16);
    --brand-fade: rgba(19, 168, 168, .06);
    --brand-ring: rgba(19, 168, 168, .22);
}

html[data-theme="orange"] {
    --brand: #fa8c16;
    --brand-hover: #ffa940;
    --brand-pressed: #d46b08;
    --brand-50: rgba(250, 140, 22, .09);
    --brand-100: rgba(250, 140, 22, .18);
    --brand-fade: rgba(250, 140, 22, .07);
    --brand-ring: rgba(250, 140, 22, .24);
}

/* ---------- 浅色中性色（所有浅色主题共用） ---------- */
:root {
    --bg: #f4f6f8;
    --panel: #ffffff;
    --panel-2: #f7f8fa;
    --panel-3: #f0f2f5;
    --track: #e7eaee;
    --line: #e8ebef;
    --line-soft: #f0f2f5;
    --thead-bg: #fafbfc;
    --row-hover: rgba(24, 160, 88, .045);
    --input-bg: #ffffff;

    --ink: #1f2225;
    --ink-2: #4b5563;
    --ink-3: #98a2b3;
    --muted: #8c939d;

    --ok: #18a058;    --ok-bg: #eaf8f0;   --ok-line: #b7e4c8;
    --warn: #d98b12;  --warn-bg: #fdf6e7; --warn-line: #f2dfae;
    --err: #d03050;   --err-bg: #fdeef1;  --err-line: #f5c3cf;
    --core: #6157d9;  --core-bg: #efedfd;
    --info: #1890ff;  --info-bg: #eaf4fe; --info-line: #bcdcfb;

    /* 项目状态三色：刻意不跟 --brand / --ok / --warn 走。
       主题有绿 / 蓝 / 青 / 橙 四套，品牌色一变，「建设中」若还用品牌绿，
       切到绿主题就和整体 UI 糊成一片。所以固定成三档无彩→棕→墨绿：
         未开工 #5f6b7a 白字对比 5.4
         建设中 #92400e 白字对比 7.1
         完成   #134e4a 白字对比 9.5
       取色时对 4 套品牌色 + ok/warn/err/core/info 全部算过 CIE76 ΔE，
       最小 37（原来跟 --brand/--ok 走时最小只有 20，切青主题就分不出）。
       三色两两 ΔE ≥ 25，且都是深色实底 + 白字。
       -t 结尾的是浅底标签/文字用的同色相深色（暗色主题下另给提亮值）。 */
    --st-idle: #5f6b7a;  --st-idle-t: #57626f;
    --st-build: #92400e; --st-build-t: #7c360b;
    --st-done: #134e4a;  --st-done-t: #10413e;

    --sh-card: 0 1px 2px rgba(16, 24, 40, .03);
    --sh-pop: 0 8px 24px rgba(16, 24, 40, .10), 0 1px 3px rgba(16, 24, 40, .05);
    --sh-btn: 0 1px 2px rgba(24, 160, 88, .18);

    --radius: 8px;
    --radius-sm: 6px;
    --sb-w: 232px;
    --header-h: 56px;
    --tabbar-h: 42px;
}

/* ---------- 暗夜（深色模式） ---------- */
html[data-theme="dark"] {
    --brand: #18a058;
    --brand-hover: #36ad6a;
    --brand-pressed: #0c7a43;
    --brand-50: rgba(24, 160, 88, .14);
    --brand-100: rgba(24, 160, 88, .26);
    --brand-fade: rgba(24, 160, 88, .10);
    --brand-ring: rgba(24, 160, 88, .3);

    --bg: #101014;
    --panel: #18181c;
    --panel-2: #1f1f26;
    --panel-3: #26262e;
    --track: #23232b;
    --line: #2b2b34;
    --line-soft: #23232a;
    --thead-bg: #1d1d24;
    --row-hover: rgba(24, 160, 88, .1);
    --input-bg: #1b1b21;

    --ink: #e8eaf0;
    --ink-2: #b8bfcb;
    --ink-3: #7c8494;
    --muted: #868e9c;

    --ok: #36ad6a;    --ok-bg: #172c22;   --ok-line: #24523a;
    --warn: #e0a53c;  --warn-bg: #2e2515; --warn-line: #57431d;
    --err: #e86b86;   --err-bg: #2f1a20;  --err-line: #5a2b36;
    --core: #9b93f0;  --core-bg: #232038;
    --info: #4ca6f5;  --info-bg: #14263a; --info-line: #24486b;

    /* 暗色下胶囊仍是实色（白字够读），只有浅底标签的文字要提亮 */
    --st-idle: #5f6b7a;  --st-idle-t: #a3b0c0;
    --st-build: #92400e; --st-build-t: #e5a253;
    --st-done: #134e4a;  --st-done-t: #4fbfb4;

    --sh-card: 0 1px 2px rgba(0, 0, 0, .4);
    --sh-pop: 0 10px 30px rgba(0, 0, 0, .55);
    --sh-btn: 0 1px 2px rgba(0, 0, 0, .5);
}

/* ==================== 1. 基础 ==================== */
* { box-sizing: border-box; }

body {
    margin: 0;
    min-height: 100vh;
    font: 14px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
          "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
    background: var(--bg);
    color: var(--ink);
    -webkit-text-size-adjust: 100%;
    -webkit-font-smoothing: antialiased;
}

a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-hover); text-decoration: none; }
::selection { background: var(--brand-100); }

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-thumb { background: rgba(140, 147, 157, .35); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: rgba(140, 147, 157, .55); }
::-webkit-scrollbar-track { background: transparent; }

@keyframes fadeUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes cardIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ---------- 图标兜底 ----------
   任何没有显式宽度/高度的内联 SVG 默认按 1em 渲染，
   避免模板里新增图标类而样式缺失时撑满整块容器。
   已被 .icon-btn svg / .menu-head .ic svg / .logo svg 等类规则覆盖。 */
svg { width: 1em; height: 1em; flex: none; vertical-align: -.125em; }

@media (prefers-reduced-motion: reduce) {
    * { animation: none !important; transition: none !important; }
}

/* ==================== 2. 侧栏 ==================== */
.sider {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: var(--sb-w);
    display: flex;
    flex-direction: column;
    background: var(--panel);
    border-right: 1px solid var(--line);
    z-index: 30;
    transition: transform .24s ease;
}
html[data-sider="off"] .sider { transform: translateX(-100%); }

.sider-brand {
    flex: none;
    height: var(--header-h);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 14px;
    border-bottom: 1px solid var(--line);
}
.sider-brand .logo {
    flex: none;
    width: 30px; height: 30px;
    display: grid; place-items: center;
    border-radius: 7px;
    background: var(--brand);
    color: #fff;
    box-shadow: 0 1px 3px var(--brand-ring);
}
.sider-brand .logo svg { width: 18px; height: 18px; }
.sider-brand b {
    font-size: 14.5px;
    font-weight: 600;
    letter-spacing: .3px;
    color: var(--ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sider-brand span {
    margin-left: auto;
    flex: none;
    font-size: 11px;
    color: var(--ink-3);
    background: var(--panel-2);
    border: 1px solid var(--line);
    padding: 0 6px;
    line-height: 17px;
    border-radius: 4px;
}

.menu {
    flex: 1;
    overflow-y: auto;
    padding: 8px;
}
.menu::-webkit-scrollbar { width: 5px; }

.menu-group { margin-bottom: 1px; }
/* 首页「总览」是最上面的一级单页入口，和下面的分组留一点呼吸感 */
.menu-group:first-child { margin-bottom: 8px; }

.menu-head {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 8px 10px;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    font: inherit;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--ink-2);
    text-align: left;
    cursor: pointer;
    transition: background .16s, color .16s;
}
.menu-head:hover { background: var(--panel-2); color: var(--ink); }
.menu-head .ic {
    flex: none;
    width: 17px; height: 17px;
    color: var(--ink-3);
    transition: color .16s;
}
.menu-head .ic svg { width: 100%; height: 100%; display: block; }
.menu-head:hover .ic { color: var(--ink-2); }
/* 单页一级菜单（如「总览」）激活态 */
.menu-head.on {
    background: var(--brand);
    color: #fff;
    box-shadow: 0 1px 3px var(--brand-ring);
}
.menu-head.on:hover { background: var(--brand-hover); color: #fff; }
.menu-head.on .ic,
.menu-head.on:hover .ic { color: #fff; }
.menu-head .tx { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.menu-head .chev {
    flex: none;
    width: 12px; height: 12px;
    color: var(--ink-3);
    transition: transform .2s ease;
}
.menu-group.open > .menu-head { color: var(--brand); }
.menu-group.open > .menu-head .ic { color: var(--brand); }
.menu-group.open > .menu-head .chev { transform: rotate(90deg); }

.menu-sub { display: none; padding: 2px 0 6px; }
.menu-group.open > .menu-sub { display: block; }

.menu-link {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 1px 0 1px 20px;
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    font-size: 13.5px;
    color: var(--ink-2);
    transition: background .16s, color .16s;
}
.menu-link:hover { background: var(--brand-50); color: var(--brand); }
.menu-link.on {
    background: var(--brand);
    color: #fff;
    font-weight: 500;
    box-shadow: 0 1px 3px var(--brand-ring);
}
.menu-link.soon { color: var(--ink-3); cursor: not-allowed; }
.menu-link.soon:hover { background: none; color: var(--ink-3); }

.menu-badge {
    margin-left: auto;
    flex: none;
    padding: 0 5px;
    font-size: 10.5px;
    line-height: 16px;
    font-weight: 500;
    border-radius: 3px;
    background: var(--brand-50);
    color: var(--brand);
}
.menu-link.on .menu-badge { background: rgba(255, 255, 255, .22); color: #fff; }

.sider-foot {
    flex: none;
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 10px 14px;
    border-top: 1px solid var(--line);
    font-size: 11.5px;
    color: var(--ink-3);
    white-space: nowrap;
    overflow: hidden;
}
.sider-foot .live {
    flex: none;
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--ok);
    box-shadow: 0 0 0 3px rgba(24, 160, 88, .16);
}

/* ==================== 3. 顶栏 ==================== */
.main {
    margin-left: var(--sb-w);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    transition: margin-left .24s ease;
}
html[data-sider="off"] .main { margin-left: 0; }

.header {
    position: sticky;
    top: 0;
    z-index: 20;
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
    height: var(--header-h);
    padding: 0 16px;
    background: var(--panel);
    border-bottom: 1px solid var(--line);
}

.icon-btn {
    flex: none;
    width: 32px; height: 32px;
    display: grid; place-items: center;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--ink-2);
    cursor: pointer;
    transition: background .16s, color .16s;
}
.icon-btn:hover { background: var(--panel-2); color: var(--brand); }
.icon-btn svg { width: 18px; height: 18px; }

.crumb {
    display: flex;
    align-items: center;
    gap: 5px;
    min-width: 0;
    font-size: 13px;
    color: var(--ink-3);
    white-space: nowrap;
    overflow: hidden;
}
.crumb .sep { color: var(--ink-3); opacity: .6; }
.crumb a { color: var(--ink-3); }
.crumb a:hover { color: var(--brand); }
.crumb .cur { color: var(--ink); font-weight: 500; font-size: 14px; }

.header-right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 4px;
}

/* 用户区下拉 */
.user-wrap, .theme-switch { position: relative; }
.user {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 3px 8px 3px 3px;
    border: 0;
    border-radius: 20px;
    background: none;
    font: inherit;
    cursor: pointer;
    transition: background .16s;
}
.user:hover { background: var(--panel-2); }
.avatar {
    flex: none;
    width: 28px; height: 28px;
    display: grid; place-items: center;
    border-radius: 50%;
    background: var(--brand);
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    overflow: hidden;
}
.avatar img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
.user .nm { font-size: 13.5px; color: var(--ink); max-width: 108px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user svg { width: 13px; height: 13px; color: var(--ink-3); }

/* 下拉菜单（主题 / 用户） */
.dropdown {
    position: absolute;
    right: 0;
    top: calc(100% + 8px);
    min-width: 186px;
    padding: 6px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--sh-pop);
    z-index: 60;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition: opacity .16s, transform .16s, visibility .16s;
}
.dropdown.open { opacity: 1; visibility: visible; transform: none; }
.dropdown .tt {
    padding: 5px 9px 7px;
    font-size: 11.5px;
    letter-spacing: .4px;
    color: var(--ink-3);
}
.dropdown .sep-line { height: 1px; margin: 5px 4px; background: var(--line-soft); }

.dd-item {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 7px 9px;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    font: inherit;
    font-size: 13.5px;
    color: var(--ink-2);
    text-align: left;
    cursor: pointer;
    transition: background .14s, color .14s;
}
.dd-item:hover { background: var(--panel-2); color: var(--ink); }
.dd-item svg { flex: none; width: 15px; height: 15px; color: var(--ink-3); }
.dd-item.danger:hover { background: var(--err-bg); color: var(--err); }
.dd-item.danger:hover svg { color: var(--err); }

.theme-item i {
    flex: none;
    width: 15px; height: 15px;
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .1);
}
.theme-item .tick { margin-left: auto; color: var(--brand); font-weight: 700; opacity: 0; font-size: 13px; }
.theme-item.on { background: var(--brand-50); color: var(--brand); }
.theme-item.on .tick { opacity: 1; }

/* ==================== 4. 多标签页 ==================== */
.tabbar {
    position: sticky;
    top: var(--header-h);
    z-index: 19;
    flex: none;
    display: flex;
    align-items: center;
    gap: 6px;
    height: var(--tabbar-h);
    padding: 0 12px;
    background: var(--panel);
    border-bottom: 1px solid var(--line);
    overflow-x: auto;
    overflow-y: hidden;
}
.tabbar::-webkit-scrollbar { height: 0; }

.tab-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: none;
    height: 26px;
    padding: 0 7px 0 9px;
    border: 1px solid var(--line);
    border-radius: 4px;
    background: var(--panel);
    font-size: 12.5px;
    color: var(--ink-2);
    white-space: nowrap;
    cursor: pointer;
    transition: color .14s, border-color .14s, background .14s;
}
.tab-chip:hover { color: var(--brand); border-color: var(--brand-100); }
.tab-chip > span {
    display: inline-block;
    max-width: 168px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.tab-chip.on {
    background: var(--brand-50);
    border-color: var(--brand-100);
    color: var(--brand);
    font-weight: 500;
}
.tab-chip.on::before {
    content: '';
    flex: none;
    width: 5px; height: 5px;
    border-radius: 50%;
    background: var(--brand);
}
.tab-chip .x {
    display: grid;
    place-items: center;
    width: 14px; height: 14px;
    border-radius: 3px;
    font-size: 13px;
    line-height: 1;
    color: inherit;
    opacity: .45;
}
.tab-chip .x:hover { background: rgba(0, 0, 0, .07); opacity: 1; }
html[data-theme="dark"] .tab-chip .x:hover { background: rgba(255, 255, 255, .1); }

.tabbar-tool { margin-left: auto; display: flex; align-items: center; gap: 2px; flex: none; }
.tabbar-tool .icon-btn { width: 26px; height: 26px; }
.tabbar-tool .icon-btn svg { width: 15px; height: 15px; }

/* ==================== 5. 内容区 / 卡片 ==================== */
.content { flex: 1; padding: 16px; }

.card {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 16px 18px;
    margin-bottom: 16px;
    box-shadow: var(--sh-card);
    animation: cardIn .26s ease backwards;
}
.card > h2 {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 14px;
    padding: 0 0 12px;
    font-size: 15px;
    font-weight: 600;
    color: var(--ink);
    border-bottom: 1px solid var(--line-soft);
}
.card > h2 .right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 400;
    font-size: 12.5px;
    color: var(--ink-3);
}
.card > h3 { color: var(--ink); font-weight: 600; }

.hint { color: var(--muted); font-size: 12.5px; margin: 8px 0 0; }
.empty { text-align: center; color: var(--ink-3); padding: 30px 10px; font-size: 13.5px; }

/* ==================== 6. 表格 ==================== */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table { width: 100%; border-collapse: collapse; font-size: 13.5px; }

th, td {
    padding: 10px 12px;
    text-align: left;
    border-bottom: 1px solid var(--line-soft);
    white-space: nowrap;
}
th {
    background: var(--thead-bg);
    color: var(--ink-2);
    font-weight: 500;
    font-size: 13px;
    border-bottom: 1px solid var(--line);
}
tbody tr { transition: background .12s; }
tbody tr:hover { background: var(--row-hover); }
tbody tr:last-child td { border-bottom: none; }
td.wrap { white-space: normal; min-width: 160px; }
table.tight th, table.tight td { padding: 7px 10px; }
th.num, td.num { text-align: right; font-variant-numeric: tabular-nums; }
.stock-low { color: var(--err); font-weight: 600; }

/* ==================== 7. 表单 ==================== */
.form-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.field { display: flex; flex-direction: column; gap: 6px; min-width: 148px; }
.field.grow { flex: 1; }
.field label { font-size: 12.5px; color: var(--ink-2); font-weight: 500; }
.field .req { color: var(--err); }

input[type=text], input[type=password], input[type=number], input[type=date],
input[type=datetime-local], input[type=search], select, textarea {
    width: 100%;
    padding: 0 11px;
    height: 34px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    font: inherit;
    font-size: 13.5px;
    background: var(--input-bg);
    color: var(--ink);
    transition: border-color .16s, box-shadow .16s;
}
textarea { height: auto; min-height: 76px; padding: 8px 11px; resize: vertical; line-height: 1.6; }
input::placeholder, textarea::placeholder { color: var(--ink-3); }
input:hover, select:hover, textarea:hover { border-color: var(--brand-100); }
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 2px var(--brand-ring);
}
input[readonly] { background: var(--panel-2); color: var(--muted); cursor: default; }
input[type=checkbox], input[type=radio] { accent-color: var(--brand); width: 15px; height: 15px; }
input[type=file] { font-size: 13px; }

.check { display: flex; align-items: center; gap: 7px; font-size: 13.5px; color: var(--ink-2); cursor: pointer; }
.check input { width: 15px; height: 15px; }

/* ==================== 8. 按钮 ==================== */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 34px;
    padding: 0 15px;
    border: 1px solid var(--brand);
    border-radius: var(--radius-sm);
    background: var(--brand);
    color: #fff;
    font: inherit;
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1;
    cursor: pointer;
    white-space: nowrap;
    transition: background .16s, border-color .16s, color .16s, transform .16s cubic-bezier(.23, 1, .32, 1);
}
.btn:hover { background: var(--brand-hover); border-color: var(--brand-hover); color: #fff; text-decoration: none; }
.btn:active { background: var(--brand-pressed); border-color: var(--brand-pressed); transform: scale(.97); }

.btn.ghost {
    background: var(--panel);
    border-color: var(--line);
    color: var(--ink-2);
}
.btn.ghost:hover { border-color: var(--brand-100); color: var(--brand); background: var(--brand-50); }
.btn.ghost:active { background: var(--brand-50); }

.btn.danger { background: var(--err); border-color: var(--err); box-shadow: none; }
.btn.danger:hover { background: #e04a68; border-color: #e04a68; }

.btn.sm { height: 28px; padding: 0 10px; font-size: 12.5px; border-radius: 5px; }
.btn.block { width: 100%; display: flex; height: 38px; }

/* 按钮组（分段筛选） */
.btn-group { display: inline-flex; gap: 6px; flex-wrap: wrap; }

/* ==================== 9. 提示 / 标签 ==================== */
.alert {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 9px 13px;
    border-radius: var(--radius-sm);
    margin-bottom: 14px;
    font-size: 13.5px;
    border: 1px solid transparent;
    animation: fadeUp .24s ease backwards;
}
.alert.ok    { background: var(--ok-bg);   border-color: var(--ok-line);   color: var(--ok); }
.alert.error { background: var(--err-bg);  border-color: var(--err-line);  color: var(--err); }
.alert.warn  { background: var(--warn-bg); border-color: var(--warn-line); color: var(--warn); }
.alert.info  { background: var(--info-bg); border-color: var(--info-line); color: var(--info); }

.tag {
    display: inline-flex;
    align-items: center;
    padding: 0 7px;
    line-height: 20px;
    border-radius: 4px;
    font-size: 12px;
    background: var(--panel-3);
    border: 1px solid transparent;
    color: var(--ink-2);
    vertical-align: middle;
}
.tag.core { background: var(--core-bg); color: var(--core); }
.tag.ok   { background: var(--ok-bg);   color: var(--ok); }
.tag.warn { background: var(--warn-bg); color: var(--warn); }
.tag.err  { background: var(--err-bg);  color: var(--err); }

/* ==================== 10. 页内分段导航 ==================== */
.page-tabs {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 2px;
    padding: 3px;
    margin-bottom: 14px;
    background: var(--track);
    border-radius: var(--radius-sm);
}
.page-tabs .tab {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 6px 14px;
    border-radius: 5px;
    color: var(--ink-2);
    font-size: 13.5px;
    font-weight: 400;
    white-space: nowrap;
    transition: background .14s, color .14s, box-shadow .14s;
}
.page-tabs .tab:hover { color: var(--brand); }
.page-tabs .tab.on {
    background: var(--panel);
    color: var(--brand);
    font-weight: 600;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .08);
}
.page-tabs .tab svg { width: 15px; height: 15px; }

/* 二级标签（如「系统设置 › 基础字典」下的四个字典页）：更轻，避免和上一级抢视觉 */
.page-tabs.sub {
    display: flex;
    padding: 0;
    margin: -4px 0 14px;
    background: transparent;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    gap: 0;
}
.page-tabs.sub .tab {
    padding: 7px 14px;
    border-radius: 0;
    font-size: 13px;
    color: var(--ink-3);
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}
.page-tabs.sub .tab:hover { color: var(--brand); background: transparent; }
.page-tabs.sub .tab.on {
    background: transparent;
    color: var(--brand);
    font-weight: 500;
    box-shadow: none;
    border-bottom-color: var(--brand);
}

/* ==================== 11. KPI / 条形图 / 柱状图 ==================== */
.kpis {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(142px, 1fr));
    gap: 12px;
}
.kpi {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 14px 14px 13px;
    transition: border-color .16s, box-shadow .16s;
}
.kpi:hover { border-color: var(--brand-100); box-shadow: 0 2px 10px rgba(16, 24, 40, .05); }
/* 卡片内的 KPI 用浅底，避免白上白只剩边框 */
.card .kpi { background: var(--panel-2); }
.card .kpi:hover { background: var(--panel); }
.kpi b {
    display: block;
    font-size: 22px;
    line-height: 1.25;
    font-weight: 600;
    color: var(--ink);
    letter-spacing: -.3px;
    font-variant-numeric: tabular-nums;
}
.kpi span { display: block; margin-top: 2px; font-size: 12.5px; color: var(--ink-3); }

/* 层次管理（船号/工程 → 图纸号 → 分段） */
.hier { display: grid; grid-template-columns: 288px minmax(0, 1fr); gap: 16px; align-items: start; }
.hier-main { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.hier-tree .tree { margin-top: 4px; }

.tree { display: flex; flex-direction: column; gap: 2px; }
.tnode { border-radius: var(--radius-sm); padding: 1px; }
.tnode.on { background: var(--brand-50); }
.tlabel {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    font-weight: 600;
    color: var(--ink);
}
.tlabel:hover { background: var(--panel-2); color: var(--brand); text-decoration: none; }
.tnode.on .tlabel { color: var(--brand); }
.tlabel .tno { font-size: 13.5px; letter-spacing: .2px; }
.tlabel em { font-style: normal; font-weight: 400; font-size: 11.5px; color: var(--ink-3); }

.tchildren {
    display: flex;
    flex-direction: column;
    gap: 1px;
    margin: 0 0 6px 12px;
    padding-left: 10px;
    border-left: 1px solid var(--line);
}
.tgroup { padding: 6px 8px 3px; font-size: 11.5px; color: var(--ink-3); }
.tleaf {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 6px 9px;
    border-radius: 5px;
    font-size: 13px;
    color: var(--ink-2);
}
.tleaf:hover { background: var(--panel-2); color: var(--brand); text-decoration: none; }
.tleaf.on { background: var(--brand-50); color: var(--brand); font-weight: 600; }
.tleaf em { font-style: normal; font-size: 11.5px; color: var(--ink-3); }
.tempty { padding: 5px 9px; font-size: 12.5px; color: var(--ink-3); }

/* 条形图（库龄 / 排行） */
.bars { display: flex; flex-direction: column; gap: 10px; }
.bar-row { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.bar-label { flex: 0 0 96px; color: var(--ink-2); text-align: right; }
.bar-track { flex: 1; height: 14px; background: var(--track); border-radius: 4px; overflow: hidden; }
.bar-fill {
    display: block;
    height: 100%;
    border-radius: 4px;
    min-width: 2px;
    background: var(--brand);
    transition: width .4s ease;
}
.bar-val { flex: 0 0 66px; color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }

/* 柱状图（看板趋势） */
.chart {
    display: flex;
    align-items: flex-end;
    gap: 6px;
    height: 172px;
    overflow-x: auto;
    padding: 4px 2px 0;
    border-bottom: 1px solid var(--line);
}
.chart-col {
    flex: 0 0 32px;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
}
.chart-val { font-size: 11px; color: var(--ink-3); margin-bottom: 3px; font-variant-numeric: tabular-nums; }
.chart-bar {
    width: 62%;
    min-height: 2px;
    display: flex;
    flex-direction: column;
    border-radius: 3px 3px 0 0;
    overflow: hidden;
    background: var(--brand);
}
.chart-bar .seg-ng { background: var(--err); }
.chart-bar .seg-ok { flex: 1; }
.chart-x { font-size: 11px; color: var(--ink-3); margin-top: 5px; white-space: nowrap; }
.legend { display: flex; flex-wrap: wrap; gap: 16px; font-size: 12.5px; color: var(--muted); margin-top: 10px; }
.legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 5px; }

/* ==================== 12. 分页 ==================== */
.pager { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 14px; font-size: 13px; }
.pager a, .pager span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 28px;
    height: 28px;
    padding: 0 8px;
    border-radius: 5px;
    border: 1px solid var(--line);
    background: var(--panel);
    color: var(--ink-2);
    font-variant-numeric: tabular-nums;
}
.pager a:hover { border-color: var(--brand-100); color: var(--brand); }
.pager .cur { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 500; }

/* 切割任务分页：整行靠右，左边显示总条数/页码；到头了的按钮置灰 */
.pager.is-end { justify-content: flex-end; }
.pager .pager-sum {
    margin-right: auto;
    padding: 0;
    border: 0;
    background: transparent;
    height: auto;
    min-width: 0;
    color: var(--ink-3);
    font-size: 12.5px;
}
.pager .pager-sum b { color: var(--ink-2); font-weight: 600; font-variant-numeric: tabular-nums; }
.pager .btn.is-off { opacity: .42; pointer-events: none; }

/* ==================== 13. 登录页 ==================== */
.plain-wrap.plain-login { padding: 0; display: block; max-width: none; }

.login-page {
    display: flex;
    min-height: 100vh;
    background: var(--panel);
}

/* 左：品牌宣传区 */
.login-aside {
    position: relative;
    flex: 1.1;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    color: #fff;
    background:
        radial-gradient(760px 460px at 14% -10%, rgba(255, 255, 255, .16), transparent 62%),
        radial-gradient(680px 480px at 98% 104%, rgba(255, 255, 255, .12), transparent 60%),
        linear-gradient(160deg, var(--brand-hover) 0%, var(--brand) 52%, var(--brand-pressed) 100%);
}
.login-aside::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, transparent 46%, rgba(0, 0, 0, .16));
    pointer-events: none;
    z-index: 1;
}
.shipyard {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: .22;
    mask-image: linear-gradient(90deg, rgba(0, 0, 0, .8) 0%, rgba(0, 0, 0, .4) 58%, transparent 100%);
    -webkit-mask-image: linear-gradient(90deg, rgba(0, 0, 0, .8) 0%, rgba(0, 0, 0, .4) 58%, transparent 100%);
}

.login-orb {
    position: absolute;
    z-index: 1;
    border-radius: 50%;
    filter: blur(2px);
    opacity: .42;
    pointer-events: none;
    animation: orbFloat 9s ease-in-out infinite;
}
.login-orb.o1 {
    width: 180px; height: 180px;
    top: 10%; right: 12%;
    background: radial-gradient(circle at 32% 30%, rgba(255, 255, 255, .42), rgba(255, 255, 255, .03) 70%);
}
.login-orb.o2 {
    width: 104px; height: 104px;
    bottom: 20%; left: 14%;
    background: radial-gradient(circle at 34% 30%, rgba(255, 255, 255, .3), rgba(255, 255, 255, .04) 72%);
    animation-delay: -3s;
    animation-duration: 11s;
}
.login-orb.o3 {
    width: 56px; height: 56px;
    top: 58%; right: 30%;
    background: radial-gradient(circle at 36% 32%, rgba(255, 255, 255, .34), transparent 72%);
    animation-delay: -6s;
    animation-duration: 8s;
}
@keyframes orbFloat {
    0%, 100% { transform: translate(0, 0); }
    33%      { transform: translate(10px, -22px); }
    66%      { transform: translate(-14px, 12px); }
}

.aside-inner {
    position: relative;
    z-index: 2;
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 56px 64px 56px clamp(56px, 8vw, 132px);
    max-width: 660px;
}
.aside-brand { display: flex; align-items: center; gap: 10px; margin-bottom: 22px; }
.aside-brand .logo {
    width: 38px; height: 38px;
    display: grid; place-items: center;
    border-radius: 9px;
    background: rgba(255, 255, 255, .18);
    border: 1px solid rgba(255, 255, 255, .26);
}
.aside-brand .logo svg { width: 22px; height: 22px; }
.aside-brand b { font-size: 17px; font-weight: 600; letter-spacing: .8px; }
.aside-title {
    margin: 0 0 12px;
    font-size: 31px;
    line-height: 1.32;
    font-weight: 700;
    letter-spacing: 1px;
}
.aside-desc { margin: 0 0 28px; font-size: 14px; line-height: 1.85; color: rgba(255, 255, 255, .86); }
.aside-feats { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.aside-feats .feat { display: flex; align-items: center; gap: 11px; padding: 6px 0; font-size: 13px; color: rgba(255, 255, 255, .9); }
.aside-feats .feat b {
    flex: none;
    width: 24px; height: 24px;
    display: grid; place-items: center;
    border-radius: 6px;
    font-size: 12px;
    font-weight: 600;
    background: rgba(255, 255, 255, .16);
    border: 1px solid rgba(255, 255, 255, .2);
}
.aside-foot {
    position: relative;
    z-index: 2;
    padding: 0 clamp(56px, 8vw, 132px) 20px;
    font-size: 12px;
    color: rgba(255, 255, 255, .62);
}

/* 右：登录表单区 */
.login-main {
    position: relative;
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 48px 40px 56px;
    background: var(--panel);
}
.login-box { position: relative; z-index: 1; width: 366px; max-width: 100%; animation: fadeUp .34s ease backwards; }
.login-box h1 { margin: 0 0 6px; font-size: 23px; font-weight: 600; letter-spacing: .3px; color: var(--ink); }
.login-sub { margin: 0 0 24px; font-size: 13px; color: var(--ink-3); }
.login-form { display: flex; flex-direction: column; gap: 15px; }
.login-form .field label { font-size: 13px; }
.login-form input { height: 40px; font-size: 14px; }
.login-form .btn { height: 40px; font-size: 14.5px; letter-spacing: 4px; margin-top: 2px; }
.login-foot {
    margin-top: 20px;
    padding-top: 14px;
    border-top: 1px solid var(--line-soft);
    text-align: center;
    font-size: 12px;
    color: var(--ink-3);
}
.login-row { display: flex; align-items: center; justify-content: space-between; font-size: 13px; color: var(--ink-3); }
.login-tip {
    margin-top: 20px;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    background: var(--panel-2);
    border: 1px solid var(--line);
    font-size: 12.5px;
    line-height: 1.75;
    color: var(--muted);
}
.login-tip b { color: var(--ink-2); }
.login-switch-theme { margin-top: 14px; display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink-3); flex-wrap: wrap; }

.theme-dot {
    width: 18px; height: 18px;
    padding: 0;
    border: 2px solid var(--panel);
    border-radius: 50%;
    box-shadow: 0 0 0 1px var(--line);
    cursor: pointer;
    transition: transform .16s, box-shadow .16s;
}
.theme-dot:hover { transform: scale(1.12); }
.theme-dot.on { box-shadow: 0 0 0 2px var(--brand); }

/* ==================== 14. 打印 / 纯页面 ==================== */
.plain-wrap { padding: 20px; max-width: 1100px; margin: 0 auto; }
@media print {
    body { background: #fff; }
    .no-print, .sider, .header, .tabbar { display: none !important; }
    .main { margin-left: 0 !important; }
    .content { padding: 0; }
    .plain-wrap { padding: 0; max-width: none; }
}

/* ==================== 15. 移动端 / 抽屉遮罩 ==================== */
.overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(16, 24, 40, .45);
    z-index: 25;
}
.overlay.show { display: block; }

@media (max-width: 1080px) {
    .aside-inner { padding: 44px 36px 44px clamp(36px, 5vw, 76px); }
    .aside-title { font-size: 26px; }
    .aside-foot { padding: 0 clamp(36px, 5vw, 76px) 18px; }
    .login-box { width: 340px; }
}

@media (max-width: 980px) {
    .sider {
        transform: translateX(-100%);
        box-shadow: 0 0 32px rgba(16, 24, 40, .18);
    }
    .sider.open { transform: none; }
    html[data-sider="off"] .sider { transform: translateX(-100%); }
    .main { margin-left: 0; }
    html[data-sider="off"] .main { margin-left: 0; }
    .content { padding: 12px; }
    .card { padding: 14px; }
    .header { padding: 0 12px; gap: 4px; }
    .crumb .grp, .crumb .sep:first-of-type { display: none; }
    .user .nm { display: none; }
    .field { min-width: 118px; flex: 1 1 118px; }
    .kpis { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 8px; }
    .kpi { padding: 11px 10px; }
    .kpi b { font-size: 19px; }
    .hier { grid-template-columns: 1fr; gap: 12px; }
    .tabbar { padding: 0 8px; }
}

/* 窄屏：品牌区改顶部横幅，表单区在下 */
@media (max-width: 860px) {
    .login-page { flex-direction: column; }
    .login-aside {
        flex: none;
        padding: 28px 24px 24px;
        text-align: center;
        align-items: center;
    }
    .login-aside::after { display: none; }
    .shipyard { opacity: .18; }
    .login-orb.o2, .login-orb.o3 { display: none; }
    .login-orb.o1 { width: 120px; height: 120px; top: -40%; right: -8%; }
    .aside-inner { padding: 0; max-width: 440px; align-items: center; justify-content: flex-start; }
    .aside-brand { justify-content: center; margin-bottom: 10px; }
    .aside-brand .logo { width: 32px; height: 32px; }
    .aside-brand b { font-size: 15px; letter-spacing: .6px; }
    .aside-title { font-size: 19px; margin-bottom: 6px; letter-spacing: .4px; }
    .aside-desc { font-size: 12.5px; margin-bottom: 0; line-height: 1.7; }
    .aside-feats, .aside-foot { display: none; }
    .login-main { flex: none; min-height: auto; padding: 26px 20px 32px; }
    .login-box { width: 100%; max-width: 420px; }
}

/* ══════════════════════════════════════════════════════════
   弹窗（用户管理编辑 / 通用）
   ══════════════════════════════════════════════════════════ */
.modal-mask {
    position: fixed;
    inset: 0;
    z-index: 900;
    background: rgba(16, 24, 40, .45);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 60px 16px 40px;
    overflow: auto;
    animation: fadeIn .16s ease;
}
.modal-box {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: 0 18px 48px rgba(16, 24, 40, .18);
    padding: 20px 22px 22px;
    width: 100%;
    max-width: 760px;
    animation: cardIn .18s ease;
}
.modal-box > h3 {
    margin: 0 0 16px;
    font-size: 15px;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* ══════════════════════════════════════════════════════════
   用户中心
   ══════════════════════════════════════════════════════════ */
.uc-head {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 18px 20px;
}
.uc-avatar {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    flex: none;
    overflow: hidden;
    background: var(--brand-50);
    color: var(--brand);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
    font-weight: 600;
    border: 1px solid var(--brand-100);
}
.uc-avatar img { width: 100%; height: 100%; object-fit: cover; }

/* 头像可点击更换：悬浮遮罩 */
.uc-avatar-wrap {
    position: relative;
    width: 64px;
    height: 64px;
    flex: none;
    cursor: pointer;
    border-radius: 50%;
}
.uc-avatar-wrap .uc-avatar { width: 100%; height: 100%; transition: transform .18s; }
.uc-avatar-wrap:hover .uc-avatar { transform: scale(1.03); }
.uc-avatar-mask {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: rgba(16, 24, 40, .52);
    color: #fff;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    font-size: 10.5px;
    line-height: 1;
    opacity: 0;
    transition: opacity .18s;
    pointer-events: none;
}
.uc-avatar-mask svg { width: 16px; height: 16px; }
.uc-avatar-wrap:hover .uc-avatar-mask { opacity: 1; }
.uc-avatar-wrap:focus-visible { outline: 2px solid var(--brand-ring); outline-offset: 2px; }
.uc-ava-from { display: flex; align-items: center; gap: 4px; margin-top: 6px; font-size: 12px; color: var(--ink-3); }
@media (max-width: 640px) {
    .uc-avatar-wrap { width: 52px; height: 52px; }
    .uc-avatar-mask { display: none; }
}
.uc-meta { flex: 1; min-width: 180px; }
.uc-meta b { font-size: 16px; display: block; margin-bottom: 4px; }
.uc-meta span { font-size: 12.5px; color: var(--ink-3); }
.uc-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 16px;
    margin-top: 16px;
}
.uc-list { display: flex; flex-direction: column; gap: 10px; margin-top: 4px; }
.uc-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px dashed var(--line);
    font-size: 13px;
}
.uc-row:last-child { border-bottom: none; }
.uc-row span:first-child { color: var(--ink-3); flex: none; min-width: 76px; }
.uc-row b { font-weight: 500; word-break: break-all; }

@media (max-width: 640px) {
    .modal-mask { padding: 24px 10px; }
    .modal-box { padding: 16px; }
    .uc-head { padding: 14px; gap: 12px; }
    .uc-avatar { width: 52px; height: 52px; font-size: 20px; }
    .uc-grid { grid-template-columns: 1fr; }
}

/* ══════════════════════════════════════════════════════════
   系统设置（短信 / 邮件 / 微信 / 通知）
   结构：页头卡（标题 + 渠道状态 + 标签）→ 左右两栏（左配置 / 右测试与说明）
   ══════════════════════════════════════════════════════════ */
.sys-head { padding: 0; margin-bottom: 16px; overflow: hidden; }
.sys-head-body { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; padding: 16px 18px 0; }
.sys-head-tt { min-width: 0; }
.sys-head-tt h1 { margin: 0; font-size: 17px; font-weight: 600; letter-spacing: -.2px; color: var(--ink); }
.sys-head-tt p { margin: 4px 0 0; font-size: 12.5px; color: var(--ink-3); }
.sys-head-chips { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; padding-top: 2px; }

.ch-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 26px;
    padding: 0 11px;
    border-radius: 999px;
    font-size: 12.5px;
    line-height: 1;
    background: var(--panel-2);
    border: 1px solid var(--line);
    color: var(--ink-3);
}
.ch-chip i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .55; flex: none; }
.ch-chip.on { background: var(--ok-bg); border-color: var(--ok-line); color: var(--ok); }
.ch-chip.on i { opacity: 1; }

.sys-head .page-tabs { margin: 14px 18px 16px; }

/* 左右两栏 */
.set-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.set-cols > .card, .set-col > .card { margin-bottom: 0; }
.set-col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

/* 卡片标题前的小图标 + 标题右侧徽标 */
.card > h2 .ic {
    width: 22px; height: 22px;
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 6px;
    background: var(--brand-50);
    color: var(--brand);
}
.card > h2 .ic svg { width: 14px; height: 14px; }
.card > h2 .badges { display: inline-flex; align-items: center; gap: 6px; margin-left: 2px; flex-wrap: wrap; }

/* 表单两列栅格 */
.fgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.fgrid .field { min-width: 0; }
.fgrid .full { grid-column: 1 / -1; }

/* 开关（替代裸 checkbox） */
.switch { display: inline-flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--ink-2); cursor: pointer; user-select: none; }
.switch input { position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; }
.switch .track {
    position: relative;
    width: 38px; height: 21px;
    flex: none;
    border-radius: 999px;
    background: var(--track);
    transition: background .18s;
}
.switch .track::after {
    content: '';
    position: absolute;
    top: 2px; left: 2px;
    width: 17px; height: 17px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .22);
    transition: transform .18s;
}
.switch input:checked + .track { background: var(--brand); }
.switch input:checked + .track::after { transform: translateX(17px); }
.switch input:focus-visible + .track { box-shadow: 0 0 0 3px var(--brand-ring); }
.switch:hover { color: var(--ink); }

/* 已保存配置（灰底摘要，读取自数据库） */
.kv-box {
    margin-top: 16px;
    padding: 12px 14px;
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
}
.kv-box > b { display: block; margin-bottom: 8px; font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
.kv-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 18px; font-size: 12.5px; color: var(--ink-2); }
.kv-grid em { font-style: normal; color: var(--ink-3); margin-right: 6px; }
.kv-note { margin: 9px 0 0; font-size: 12px; line-height: 1.7; color: var(--ink-3); }

/* ── AI 使用记录（系统设置 › AI 识别） ───────────────────── */
.ai-stat {
    margin-top: 4px;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
}
.ai-stat > div {
    padding: 10px 12px;
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    min-width: 0;
}
.ai-stat span { display: block; font-size: 12px; color: var(--ink-3); }
.ai-stat b { display: block; margin: 3px 0 2px; font-size: 19px; line-height: 1.2; color: var(--ink); }
.ai-stat i { display: block; font-style: normal; font-size: 11.5px; color: var(--ink-3); }

.ai-log td { font-size: 12.5px; }
.ai-log .ai-when { color: var(--ink-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ai-log .ai-cmd { color: var(--ink); font-weight: 500; text-decoration: none; word-break: break-all; }
.ai-log a.ai-cmd:hover { color: var(--brand); text-decoration: underline; }
.ai-log .ai-pg {
    margin-left: 5px;
    padding: 0 5px;
    border-radius: 4px;
    background: var(--brand-50);
    color: var(--brand);
    font-size: 11px;
}
.ai-log .ai-model { color: var(--ink-2); font-size: 12px; word-break: break-all; }
.ai-log .ai-tk { font-variant-numeric: tabular-nums; color: var(--ink-2); white-space: nowrap; }
.ai-log .ai-tk strong { color: var(--ink); }
.ai-log .ai-u { margin-left: 1px; color: var(--ink-3); }
.ai-pager { margin-top: 12px; display: flex; align-items: center; gap: 10px; font-size: 12.5px; color: var(--ink-3); }

@media (max-width: 980px) {
    .ai-stat { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* 配置说明：编号步骤 */
.steps {
    margin: 0; padding: 0;
    list-style: none;
    counter-reset: st;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 12.5px;
    line-height: 1.75;
    color: var(--ink-2);
}
.steps li { position: relative; padding-left: 25px; }
.steps li::before {
    counter-increment: st;
    content: counter(st);
    position: absolute;
    left: 0;
    top: 3px;
    width: 17px; height: 17px;
    border-radius: 50%;
    background: var(--brand-50);
    color: var(--brand);
    font-size: 11px;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
}
.doc-sec + .doc-sec { margin-top: 16px; padding-top: 14px; border-top: 1px dashed var(--line); }
.doc-sec > b { display: block; margin-bottom: 8px; font-size: 13px; color: var(--ink); }

/* 通知设置：渠道胶囊标签 */
.ch-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.ch-tabs .ct {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 34px;
    padding: 0 14px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--line);
    background: var(--panel);
    color: var(--ink-2);
    font-size: 13px;
    transition: border-color .16s, color .16s, background .16s;
}
.ch-tabs .ct svg { width: 15px; height: 15px; }
.ch-tabs .ct:hover { border-color: var(--brand-100); color: var(--brand); }
.ch-tabs .ct.on { background: var(--brand-50); border-color: var(--brand-100); color: var(--brand); font-weight: 500; }

/* 通知设置：渠道配置条 */
.cfg-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 13px 16px; margin-bottom: 12px; }
.cfg-bar .t { font-size: 14px; font-weight: 600; }
.cfg-bar .sub { font-size: 12.5px; color: var(--ink-3); }
.cfg-bar .r { margin-left: auto; display: flex; align-items: center; gap: 8px; }

/* 通知设置：模板列表 */
.ntable td { vertical-align: top; white-space: normal; padding: 12px; }
.ntable th { white-space: nowrap; }
.ntable .sn { font-weight: 600; color: var(--ink); }
.ntable .sd { margin-top: 4px; font-size: 12px; color: var(--ink-3); line-height: 1.65; }
.ntable .badges { display: flex; gap: 6px; flex-wrap: wrap; }
.ntable .ops { display: flex; gap: 6px; flex-wrap: wrap; }
.ntable tr.grp td { background: var(--panel-2); padding: 9px 12px; font-size: 12.5px; color: var(--ink-2); }
.ntable tr.grp b { font-weight: 600; }
.ntable tr.grp span { color: var(--ink-3); margin-left: 8px; }

@media (max-width: 1120px) {
    .set-cols { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 720px) {
    .fgrid, .kv-grid { grid-template-columns: minmax(0, 1fr); }
    .sys-head-body { padding: 14px 14px 0; }
    .sys-head .page-tabs { margin: 12px 14px 14px; }
    .sys-head-chips { margin-left: 0; }
    .cfg-bar { padding: 12px; }
}

/* 卡片内小节标题（微信设置：公众号 / 开放平台两段） */
.sec-h {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin: 18px 0 12px;
    padding-top: 16px;
    border-top: 1px solid var(--line);
}
.sec-h b { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.ntable .nprev { margin-top: 6px; color: var(--ink-3); }

/* 行内代码（配置说明 / 提示里的 CODE、变量名） */
code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Courier New", monospace;
    font-size: 12px;
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--panel-3);
    color: var(--ink-2);
    white-space: nowrap;
}

/* ══════════════════════════════════════════════════════════
   侧栏深色皮肤（参考梦百合：深色底 + 浅色字 + 高亮激活块）
   底色随主题变化：绿→墨绿 / 蓝→深蓝 / 青→深青 / 橙→深棕 / 暗夜→近黑
   只覆盖侧栏内部配色，不影响内容区
   ══════════════════════════════════════════════════════════ */
:root,
html[data-theme="green"] {
    --sider-bg-1: #0d3a24;
    --sider-bg-2: #06231a;
    --sider-top: #114a2f;
    --sider-accent: #4bd486;
    --sider-accent-soft: rgba(75, 212, 134, .30);
}
html[data-theme="blue"] {
    --sider-bg-1: #0f2a5e;
    --sider-bg-2: #0a1d44;
    --sider-top: #123469;
    --sider-accent: #58b4ff;
    --sider-accent-soft: rgba(88, 180, 255, .28);
}
html[data-theme="cyan"] {
    --sider-bg-1: #0a3a40;
    --sider-bg-2: #05232a;
    --sider-top: #0d4950;
    --sider-accent: #45d6d6;
    --sider-accent-soft: rgba(69, 214, 214, .28);
}
html[data-theme="orange"] {
    --sider-bg-1: #4a2c0c;
    --sider-bg-2: #2a1806;
    --sider-top: #5c370f;
    --sider-accent: #ffb04d;
    --sider-accent-soft: rgba(255, 176, 77, .28);
}
html[data-theme="dark"] {
    --sider-bg-1: #171a21;
    --sider-bg-2: #101218;
    --sider-top: #1b1f28;
    --sider-accent: #4bd486;
    --sider-accent-soft: rgba(75, 212, 134, .26);
}

/* 文字与分隔（中性白，任何底色的主题都通用） */
:root,
html[data-theme] {
    --sider-ink: rgba(255, 255, 255, .90);
    --sider-ink-2: rgba(255, 255, 255, .74);
    --sider-ink-3: rgba(255, 255, 255, .50);
    --sider-line: rgba(255, 255, 255, .10);
    --sider-hover: rgba(255, 255, 255, .075);
    --sider-active: rgba(255, 255, 255, .15);
    --sider-active-ring: rgba(255, 255, 255, .10);
}
html[data-theme="dark"] {
    --sider-line: rgba(255, 255, 255, .08);
    --sider-hover: rgba(255, 255, 255, .06);
    --sider-active: rgba(255, 255, 255, .12);
    --sider-active-ring: rgba(255, 255, 255, .08);
}

/* —— 底板 —— */
.sider {
    background:
        radial-gradient(140% 55% at 0% 0%, rgba(255, 255, 255, .07), transparent 62%),
        linear-gradient(180deg, var(--sider-bg-1) 0%, var(--sider-bg-2) 100%);
    border-right: 1px solid rgba(0, 0, 0, .18);
    box-shadow: 1px 0 0 rgba(255, 255, 255, .04) inset, 2px 0 12px rgba(9, 20, 44, .16);
}

/* —— 顶部标识 —— */
.sider-brand {
    border-bottom: 1px solid var(--sider-line);
    background: linear-gradient(180deg, rgba(255, 255, 255, .05), transparent);
}
.sider-brand .logo {
    background: var(--brand);
    color: #fff;
    box-shadow: 0 2px 6px rgba(0, 0, 0, .24), 0 0 0 1px rgba(255, 255, 255, .12) inset;
}
.sider-brand b { color: #fff; }
.sider-brand span {
    color: rgba(255, 255, 255, .72);
    background: rgba(255, 255, 255, .1);
    border-color: rgba(255, 255, 255, .14);
}

/* —— 菜单 —— */
.sider .menu { scrollbar-color: rgba(255, 255, 255, .22) transparent; }
.sider .menu::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .2); }
.sider .menu::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, .3); }

.sider .menu-head { color: var(--sider-ink-2); }
.sider .menu-head .ic { color: var(--sider-ink-3); }
.sider .menu-head .chev { color: var(--sider-ink-3); opacity: .8; }
.sider .menu-head:hover {
    background: var(--sider-hover);
    color: #fff;
}
.sider .menu-head:hover .ic { color: #fff; }

/* 展开的分组标题：全部展开后只让「当前所在分组」用亮色强调，其余保持中性，避免整列花掉 */
.sider .menu-group.open > .menu-head { color: var(--sider-ink); }
.sider .menu-group.cur > .menu-head { color: #fff; font-weight: 500; }
.sider .menu-group.cur > .menu-head .ic { color: var(--sider-accent); }

/* 激活：主题色淡块 + 左侧亮色竖条（对应参考图「工作台」那块） */
.sider .menu-head.on,
.sider .menu-link.on {
    position: relative;
    background: linear-gradient(90deg, var(--sider-accent-soft) 0%, rgba(255, 255, 255, .12) 100%);
    color: #fff;
    font-weight: 500;
    box-shadow: 0 0 0 1px var(--sider-active-ring) inset;
}
.sider .menu-head.on::before,
.sider .menu-link.on::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    width: 3px;
    height: 16px;
    margin-top: -8px;
    border-radius: 0 3px 3px 0;
    background: var(--sider-accent);
}
.sider .menu-head.on:hover { background: linear-gradient(90deg, var(--sider-accent-soft) 0%, rgba(255, 255, 255, .19) 100%); }
.sider .menu-head.on .ic,
.sider .menu-head.on:hover .ic { color: #fff; }

/* 二级项 */
.sider .menu-link { color: var(--sider-ink-2); }
.sider .menu-link:hover { background: var(--sider-hover); color: #fff; }
.sider .menu-link.on:hover { background: linear-gradient(90deg, var(--sider-accent-soft) 0%, rgba(255, 255, 255, .19) 100%); }
.sider .menu-link.soon { color: var(--sider-ink-3); }
.sider .menu-link.soon:hover { background: none; color: var(--sider-ink-3); }

/* 徽标 */
.sider .menu-badge {
    background: rgba(255, 255, 255, .12);
    color: rgba(255, 255, 255, .82);
}
.sider .menu-link.on .menu-badge { background: rgba(255, 255, 255, .24); color: #fff; }

/* —— 底部状态条 —— */
.sider-foot {
    border-top: 1px solid var(--sider-line);
    color: var(--sider-ink-3);
    background: rgba(0, 0, 0, .12);
}
.sider-foot .live {
    background: var(--sider-accent);
    box-shadow: 0 0 0 3px var(--sider-accent-soft);
}

/* 折叠/展开按钮与移动端遮罩保持原有逻辑，仅额外做移动端侧栏阴影 */
@media (max-width: 900px) {
    .sider { box-shadow: 8px 0 24px rgba(9, 20, 44, .35); }
}

/* ══════════════════════════════════════════════════════════
   页面头部（标题 + 说明 + 右上角操作）
   列表页：右上角「新增XX」；表单页：右上角「返回列表」
   ══════════════════════════════════════════════════════════ */
.page-head {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    margin: 2px 0 16px;
}
.page-head .ph-main { min-width: 0; }
.page-head h1 {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -.2px;
    color: var(--ink);
}
.page-head h1 .ph-meta {
    font-size: 12px;
    font-weight: 400;
    color: var(--ink-3);
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--panel-2);
    border: 1px solid var(--line);
}
.page-head .sub { margin: 5px 0 0; font-size: 12.5px; color: var(--ink-3); }
.page-head .ph-act {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

/* 「新增」按钮：图标比文字略小，视觉重量与字重对齐 */
.btn svg { width: 15px; height: 15px; flex: none; }
.btn.sm svg { width: 13px; height: 13px; }

/* ══════════════════════════════════════════════════════════
   独立表单页（新增 / 编辑）：卡片内两列栅格 + 底部操作条
   ══════════════════════════════════════════════════════════ */
.form-card { padding: 20px 22px; }
.form-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px 20px;
}
.form-grid .field { min-width: 0; }
.form-grid .full { grid-column: 1 / -1; }
.form-grid .field > label { font-size: 12.5px; }

/* 只读信息字段（创建时间等系统写入的值）：与输入框同高同栅格，但视觉退一档 */
.ro-val {
    display: flex;
    align-items: center;
    height: 34px;
    padding: 0 11px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm);
    background: var(--panel-2);
    color: var(--ink-2);
    font-size: 13.5px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* 表单页的统计卡：固定列宽，卡片增减时不会拉成一整行 */
.form-sec .kpis { grid-template-columns: repeat(auto-fill, 168px); }

/* 表单分区：标题 + 组内栅格 */
.form-sec + .form-sec { margin-top: 22px; padding-top: 18px; border-top: 1px dashed var(--line); }
.form-sec > h3 {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 14px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ink-2);
}
.form-sec > h3 .tag { font-weight: 400; }

/* 底部操作条 */
.form-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px solid var(--line-soft);
}
.form-foot .hint { margin: 0 0 0 auto; }

/* 表单页右侧提示卡（表格页说明用） */
.form-tip { font-size: 12.5px; line-height: 1.8; color: var(--ink-3); margin: 0; }
.form-tip + .form-tip { margin-top: 8px; }

/* 危险操作区（编辑态删除） */
.danger-zone {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 14px 16px;
    border: 1px solid var(--err-line);
    border-radius: var(--radius-sm);
    background: var(--err-bg);
}
.danger-zone .dz-tx { min-width: 0; }
.danger-zone .dz-tx b { display: block; font-size: 13px; color: var(--err); }
.danger-zone .dz-tx span { font-size: 12.5px; color: var(--ink-3); }
.danger-zone form { margin-left: auto; }

/* 删除区里的项目数据：四个小胶囊排一行，0 值淡下去。
   数字直接摆在「能不能删」的说明下面，不用再回上面找 KPI。 */
.danger-zone .dz-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 9px;
}
.danger-zone .dz-facts span {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    padding: 2px 9px;
    border: 1px solid var(--err-line);
    border-radius: 10px;
    background: color-mix(in srgb, var(--panel) 72%, transparent);
    font-size: 11.5px;
    line-height: 1.6;
    color: var(--ink-3);
    white-space: nowrap;
}
.danger-zone .dz-facts i {
    font-style: normal;
    font-weight: 600;
    font-size: 12px;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}
.danger-zone .dz-facts span.is-zero { opacity: .55; }
.danger-zone.is-locked .dz-facts span { border-color: var(--line); }

@media (max-width: 720px) {
    .page-head { margin-bottom: 14px; gap: 10px; }
    .page-head h1 { font-size: 16.5px; }
    .page-head .ph-act { margin-left: 0; width: 100%; }
    .page-head .ph-act .btn { flex: 1; }
    .form-grid { grid-template-columns: minmax(0, 1fr); }
    .form-card { padding: 16px 14px; }
    .danger-zone { flex-direction: column; align-items: flex-start; }
    .danger-zone form { margin-left: 0; }
}

/* 表单里的开关标签：避免被 .field label 的 12.5px 缩水，并给绝对定位的隐形 input 一个定位父级 */
.field > label.switch,
.form-grid .field > label.switch {
    font-size: 13.5px;
    font-weight: 400;
    color: var(--ink-2);
}
.switch { position: relative; }

/* ══════════════════════════════════════════════════════════
   项目管理 · 在造船位（船体动效）
   ──────────────────────────────────────────────────────────
   设计约束：
   1. 颜色一律走主题变量，切绿/蓝/青/橙/暗夜时船体与水面跟着变；
   2. 动画只动 transform / opacity，跑在合成层，不触发重排；
   3. 系统开启「减少动态效果」时全部静止，只剩静态图形。
   ══════════════════════════════════════════════════════════ */

/* ── 船体图形本体（_ship.php 输出，列表首列与泊位条共用） ── */
.ship-art {
    /* 描边 / 船体 / 甲板货 三档，全部由主题品牌色派生 */
    --sk: var(--brand);
    --sf: var(--brand-50);     /* 兜底：不支持 color-mix 的老浏览器 */
    --sd: var(--brand-100);
    display: block;
    overflow: visible;
}
/* 品牌色按比例混进面板色：船体是「实一点」的浅色，靠描边撑形，比纯 rgba 更饱满 */
@supports (color: color-mix(in srgb, red, blue)) {
    .ship-art {
        --sf: color-mix(in srgb, var(--brand) 13%, var(--panel));
        --sd: color-mix(in srgb, var(--brand) 30%, var(--panel));
    }
}
.ship-art .hull   { fill: var(--sf); stroke: var(--sk); stroke-width: 1.8; stroke-linejoin: round; }
.ship-art .super  { fill: var(--panel); stroke: var(--sk); stroke-width: 1.6; stroke-linejoin: round; }
.ship-art .bridge { fill: var(--sf); stroke: var(--sk); stroke-width: 1.4; }
.ship-art .funnel { fill: var(--sk); opacity: .72; }
.ship-art .mast   { stroke: var(--sk); stroke-width: 1.4; opacity: .65; }
.ship-art .cargo  { fill: var(--sd); stroke: var(--sk); stroke-width: 1.2; }
.ship-art .port   { fill: var(--sk); opacity: .42; }

/* 空船（没导图纸）：整船灰化，和绿水面的对比一眼可辨 */
.ship-art.is-muted { --sk: #c3cad3; --sf: #f2f4f7; --sd: #e6e9ee; }
html[data-theme="dark"] .ship-art.is-muted { --sk: #4c535f; --sf: #23232b; --sd: #2b2b34; }

/* ── 船坞卡片 ──
   卡片里只有水面（标题与图例已去掉），所以 .dock 不留内边距，水直接贴边； */
.dock { overflow: hidden; padding: 0; }

/* 水面画布：底色从面板色渐到品牌色淡调，暗色主题自动变深 */
.dock-water {
    position: relative;
    height: 224px;
    overflow: hidden;
    background: linear-gradient(180deg, var(--panel) 0%, var(--brand-fade) 100%);
}
.water-band {
    position: absolute;
    left: 0; right: 0; top: 172px; bottom: 0;
    background: linear-gradient(180deg, var(--brand-fade), var(--brand-50));
    box-shadow: inset 0 1px 0 var(--panel);
}
/* 两道浪：一深一浅反向横移，速度不同才有「水在流」的感觉 */
.wave {
    position: absolute;
    left: 0;
    width: 200%;
    height: 32px;
    pointer-events: none;
    color: var(--brand);
}
.wave svg { display: block; width: 100%; height: 100%; }
.wave svg path { fill: currentColor; }
.wave.w1 { top: 162px; z-index: 3; opacity: .16; animation: waveDrift 19s linear infinite; }
.wave.w2 { top: 169px; z-index: 4; opacity: .10; animation: waveDrift 13s linear infinite reverse; }
@keyframes waveDrift { to { transform: translateX(-50%); } }

/* ── 泊位轨道 ──
   船位排成一条横向轨道，溢出部分由底部时间轴（.dock-tl）拖动查看。
   berth 预留 padding-top 作为悬停气泡的容身空间，气泡才不会顶到
   滚动容器的上边界被裁掉一半。 */
.berths {
    position: absolute;
    left: 0; right: 0; bottom: 44px;
    z-index: 5;
    display: flex;
    align-items: flex-end;
    gap: 18px;
    padding: 0 34px;      /* 左右留出翻页箭头的位置，首尾船不被遮住 */
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    overscroll-behavior-x: contain;
}
.berths::-webkit-scrollbar { display: none; }
/* 拖 thumb 时关掉平滑滚动，否则滑块会滞后于指针 */
.berths.dragging { scroll-behavior: auto; }

.berth {
    position: relative;
    flex: none;
    width: 180px;
    padding-top: 96px;
    transition: transform .25s ease;
    animation: berthIn .55s cubic-bezier(.22, .68, .36, 1) backwards;
    animation-delay: calc(var(--i, 0) * 90ms);
}
/* 整艘船可点：盖一层透明链接，气泡不挡点击 */
.berth-hit { position: absolute; inset: 96px 0 0; z-index: 2; border-radius: 8px; }
.berth:hover { transform: translateY(-3px); }
.berth-hit:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
@keyframes berthIn {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* 船体浮动：--lift 承载「静态位移」，避免和 keyframes 的 transform 互相覆盖。
   动画挂在 .ship-stage 上而不是 svg 上——船号铭牌是 stage 的兄弟节点，
   只有整层一起浮动，字才不会脱离船体。 */
.ship-stage {
    position: relative;
    display: block;
    width: 100%;
}
.ship-stage > .ship-art {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 300 / 130;   /* 没有 width/height 属性时 SVG 会拿默认 150px，比例锁死才不塌 */
}

.berth > .ship-stage {
    --lift: 0px;
    animation: shipBob 4.8s ease-in-out infinite;
    transform-origin: 50% 80%;
}
.berth:nth-child(even) > .ship-stage { animation-delay: -2.2s; }
@keyframes shipBob {
    0%, 100% { transform: translateY(var(--lift)) rotate(0deg); }
    35%      { transform: translateY(calc(var(--lift) - 2.4px)) rotate(-.35deg); }
    70%      { transform: translateY(calc(var(--lift) + 1.6px)) rotate(.25deg); }
}

/* ── 船体侧板上的铭牌：左船号 + 右状态胶囊 ──
   定位用百分比对齐 SVG 的船体侧板（viewBox 里船体是 y 62~114、x 18~274）：
   67.7% = 88/130 是侧板中线，左 6% / 右 8.7% 正好落在船体边界内。
   这样船宽随断点变化时铭牌自动跟着缩放，不用写两套数值。 */
.ship-plate {
    position: absolute;
    left: 7%;
    right: 9.5%;
    top: 67.7%;
    z-index: 3;
    display: flex;
    align-items: center;
    gap: 5px;
    transform: translateY(-50%);
    pointer-events: none;
}
.ship-no {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 10.5px;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: .2px;
    color: var(--ink);       /* 浅主题深字、暗主题浅字，船体本身也是对应的浅/深底 */
    text-shadow: 0 1px 0 color-mix(in srgb, var(--panel) 55%, transparent);
}
.st-plate {
    flex: none;
    margin-left: auto;
    padding: 1px 5px 1.5px;
    border-radius: 8px;
    background: var(--st-c);
    color: #fff;
    font-size: 9.5px;
    font-style: normal;
    font-weight: 600;
    line-height: 1.35;
    letter-spacing: .3px;
    white-space: nowrap;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .18);
}

/* 悬停气泡 */
.bubble {
    position: absolute;
    left: 50%;
    bottom: 86px;
    z-index: 8;
    min-width: 184px;
    padding: 8px 10px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--panel);
    box-shadow: 0 8px 24px rgba(16, 24, 40, .12);
    opacity: 0;
    pointer-events: none;
    transform: translate(-50%, 6px);
    transition: opacity .18s, transform .18s;
}
.bubble::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -5px;
    width: 8px; height: 8px;
    margin-left: -4px;
    background: var(--panel);
    border-right: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    transform: rotate(45deg);
}
.berth:hover .bubble { opacity: 1; transform: translate(-50%, 0); }
.bubble b { display: block; margin-bottom: 3px; font-size: 12.5px; color: var(--ink); }
.bubble .bl { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--ink-3); }
.bubble .bl i { font-style: normal; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.bubble .bl2 { margin-top: 3px; font-size: 11px; color: var(--ink-3); }
.bubble .warnline { margin-top: 4px; font-size: 11px; color: var(--warn); }

/* ── 船多时的左右翻页箭头 ── */
.dock-nav {
    position: absolute;
    top: 92px;
    z-index: 8;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 46px;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: color-mix(in srgb, var(--panel) 88%, transparent);
    color: var(--ink-2);
    cursor: pointer;
    box-shadow: 0 2px 10px rgba(16, 24, 40, .07);
    transition: color .14s, border-color .14s;
}
.dock-nav[hidden] { display: none; }
.dock-nav.prev { left: 7px; }
.dock-nav.next { right: 7px; }
.dock-nav:hover { color: var(--brand); border-color: var(--brand-100); }
.dock-nav:disabled { opacity: .32; cursor: default; color: var(--ink-3); border-color: var(--line); }
.dock-nav svg { width: 15px; height: 15px; }

/* ── 底部时间轴：拖动 thumb 或点轨道，让船坞左右移动 ── */
.dock-tl {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    z-index: 7;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 22px 9px;
    background: linear-gradient(180deg, transparent, var(--brand-50));
}
.dock-tl[hidden] { display: none; }
.tl-cap { flex: none; font-size: 11px; color: var(--ink-3); letter-spacing: .6px; }
.tl-num { flex: none; font-size: 11px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.tl-track {
    position: relative;
    flex: 1;
    height: 4px;
    border-radius: 2px;
    background: color-mix(in srgb, var(--ink-3) 26%, transparent);
    cursor: pointer;
    touch-action: none;
}
.tl-track::before {   /* 把 4px 的可见条加高成 20px 的点击热区 */
    content: "";
    position: absolute;
    left: 0; right: 0; top: -9px; bottom: -9px;
}
.tl-thumb {
    position: absolute;
    top: 50%;
    left: 0;
    height: 8px;
    margin-top: -4px;
    min-width: 34px;
    border-radius: 4px;
    background: var(--brand);
    box-shadow: 0 1px 3px color-mix(in srgb, var(--brand) 38%, transparent);
    cursor: grab;
    touch-action: none;
    transition: box-shadow .14s, background .14s;
}
/* 握把纹：中间三道短横 */
.tl-thumb::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 10px;
    height: 2px;
    margin: -1px 0 0 -5px;
    border-radius: 1px;
    background: rgba(255, 255, 255, .75);
    box-shadow: 0 -3px 0 rgba(255, 255, 255, .55), 0 3px 0 rgba(255, 255, 255, .55);
}
.tl-thumb:hover { box-shadow: 0 2px 9px color-mix(in srgb, var(--brand) 52%, transparent); }
.tl-thumb:active,
.tl-thumb.is-drag { cursor: grabbing; }
.tl-thumb:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }

/* ── 列表首列：小图标 + 船号（td 本身保持 table-cell，内层用 flex 对齐） ── */
.ship-cell-in { display: flex; align-items: center; gap: 9px; }
.ship-cell .ship-ico { flex: none; display: block; width: 34px; }
.ship-cell .ship-ico .ship-art { width: 34px; height: auto; transition: transform .22s; }
.ship-table tbody tr:hover .ship-cell .ship-art { transform: translateY(-1.5px) translateX(1px); }
.ship-cell b { font-weight: 600; }
/* 0 值淡出：有数据的数字才有视觉重量 */
.ship-table td.num.zero { color: var(--ink-3); font-weight: 400; }

/* 表格行入场：70ms 错峰，读完一屏时视线自然往下走 */
.ship-table tbody tr {
    animation: rowIn .45s cubic-bezier(.22, .68, .36, 1) backwards;
    animation-delay: calc(var(--i, 0) * 70ms);
}
@keyframes rowIn {
    from { opacity: 0; transform: translateY(7px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ── 窄屏 ── */
@media (max-width: 720px) {
    .dock-water { height: 184px; }
    .water-band { top: 142px; }
    .wave.w1 { top: 132px; }
    .wave.w2 { top: 139px; }
    .berths { gap: 12px; padding: 0 14px; bottom: 40px; }
    .berth { width: 148px; padding-top: 16px; }
    .berth-hit { inset: 16px 0 0; }
    .ship-no { font-size: 9px; }
    .st-plate { font-size: 8.5px; padding: 0 4px 1px; }
    .dock-nav { display: none; }          /* 触屏直接拖时间轴，不需要箭头 */
    .dock-tl { padding: 6px 14px 8px; gap: 8px; }
    .tl-num { display: none; }
    .bubble { display: none; }            /* 触屏没有 hover，气泡只会闪 */
    .ship-cell .ship-ico { width: 26px; }
    .ship-cell .ship-ico .ship-art { width: 26px; }
}

/* ── 无障碍：系统要求减少动态效果时全部静止 ── */
@media (prefers-reduced-motion: reduce) {
    .wave,
    .berth,
    .berth > .ship-stage,
    .ship-table tbody tr {
        animation: none !important;
    }
    .berth, .berth > .ship-stage, .bubble { transition: none; }
}

/* ══════════════════════════════════════════════════════════
   删除保护：有下游数据的项目不允许删除
   ──────────────────────────────────────────────────────────
   按钮禁用态刻意保留 ghost 描边（不变成红色块），
   因为它表达的是「暂不可用」而不是「危险操作」。
   ══════════════════════════════════════════════════════════ */
.btn[disabled],
.btn:disabled {
    opacity: .45;
    cursor: not-allowed;
    box-shadow: none;
    filter: saturate(.6);
}
/* 禁用后不能再有点击反馈，否则用户以为点到了 */
.btn[disabled]:hover,
.btn:disabled:hover,
.btn[disabled]:active,
.btn:disabled:active {
    background: var(--panel);
    border-color: var(--line);
    color: var(--ink-2);
    transform: none;
}

/* 列表首列的锁标记：只在不可删的项目上出现 */
.ship-cell .lock-ico {
    flex: none;
    width: 13px;
    height: 13px;
    color: var(--ink-3);
    opacity: .75;
}

/* 首列 ID：系统自增编号，等宽数字 + 淡色，不抢船号的注意力 */
.ship-table td.ship-id {
    font-variant-numeric: tabular-nums;
    color: var(--ink-3);
    font-weight: 500;
    white-space: nowrap;
}
.ship-table tbody tr:hover td.ship-id { color: var(--ink-2); }

/* 操作列挤了 4 个按钮：把行内按钮收窄一点，1440 下刚好不出横向滚动条 */
.ship-table td:last-child .btn.sm {
    padding: 0 8px;
    margin-right: 2px;
}

/* 船名 / 船东是自由文本：单行 + 省略号，超长不再把整张表顶宽（完整内容在 title 里） */
.ship-table td:nth-child(4) { max-width: 208px; overflow: hidden; text-overflow: ellipsis; }
.ship-table td:nth-child(5) { max-width: 148px; overflow: hidden; text-overflow: ellipsis; }

/* 表单页的锁定态危险区：从「红色警告」改为「中性提示」 */
.danger-zone.is-locked {
    border-color: var(--line);
    background: var(--panel-2);
}
.danger-zone.is-locked .dz-tx b { color: var(--ink-2); }
.danger-zone.is-locked .dz-tx span { color: var(--ink-3); }

/* ══════════════════════════════════════════════════════════
   图纸导入（套料图 PDF 拆页）
   ══════════════════════════════════════════════════════════ */

/* ── 步骤条 ── */
.steps-bar {
    display: flex;
    align-items: center;
    gap: 0;
    margin: 0 0 16px;
    padding: 12px 16px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}
.steps-bar .sb { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink-3); }
.steps-bar .sb b {
    width: 22px; height: 22px; border-radius: 50%;
    display: grid; place-items: center; flex: none;
    font-size: 12px; font-weight: 600;
    background: var(--panel-3); border: 1px solid var(--line); color: var(--ink-3);
}
.steps-bar .sb.on { color: var(--ink); }
.steps-bar .sb.on b { background: var(--brand); border-color: var(--brand); color: #fff; }
.steps-bar .sb.done b { background: var(--brand-50); border-color: var(--brand-100); color: var(--brand); }
.steps-bar .sb-bar { flex: 1; height: 1px; background: var(--line); margin: 0 12px; min-width: 18px; }

/* ── 拖拽上传区 ── */
.drop-zone {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 28px 20px;
    border: 1.5px dashed var(--brand-100);
    border-radius: 10px;
    background: var(--brand-50);
    cursor: pointer;
    text-align: center;
    transition: border-color .16s, background .16s;
}
.drop-zone:hover, .drop-zone.on { border-color: var(--brand); background: var(--brand-100); }
.drop-zone input[type=file] { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.drop-zone .dz-ico {
    width: 40px; height: 40px; margin-bottom: 6px;
    display: grid; place-items: center;
    border-radius: 10px; background: var(--panel); border: 1px solid var(--brand-100);
    color: var(--brand);
}
.drop-zone .dz-ico svg { width: 20px; height: 20px; }
.drop-zone b { font-size: 13.5px; color: var(--ink); font-weight: 600; }
.drop-zone .dz-sub { font-size: 12px; color: var(--ink-3); }

/* 已选文件 */
.file-line {
    display: flex;
    align-items: center;
    gap: 11px;
    margin-top: 12px;
    padding: 11px 13px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--panel-2);
}
.file-line .fl-ico {
    flex: none; width: 34px; height: 26px;
    display: grid; place-items: center;
    border-radius: 4px; background: var(--err-bg); border: 1px solid var(--err-line);
    color: var(--err); font-size: 10.5px; font-weight: 700; letter-spacing: .5px;
}
.file-line .fl-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.file-line .fl-main b { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-line .fl-main i { font-size: 11.5px; color: var(--ink-3); font-style: normal; }

.field-tip { margin: 0; font-size: 12px; color: var(--ink-3); line-height: 1.6; }
.field-tip b { color: var(--brand); }

/* ── 核对表 ── */
.pdf-review { padding: 16px 18px; }
.pdf-table td { padding: 8px 10px; }
.pdf-table .cmd-input {
    width: 100%; height: 30px; padding: 0 9px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12.5px; letter-spacing: .2px;
}
.pdf-table .cmd-input.is-bad { border-color: var(--err); background: var(--err-bg); }
.pdf-table tr.row-bad { background: var(--err-bg); }
.pdf-table tr.row-bad:hover { filter: brightness(.985); }
.nest-ref { font-size: 12.5px; color: var(--ink-2); }
.nest-ref i { font-style: normal; font-size: 11.5px; color: var(--ink-3); margin-left: 5px; }
.lnk { color: var(--brand); font-size: 12.5px; text-decoration: none; }
.lnk:hover { text-decoration: underline; }

/* 页面类型标签 */
.kind-tag {
    display: inline-flex; align-items: center;
    height: 21px; padding: 0 8px; border-radius: 11px;
    font-size: 11.5px; border: 1px solid var(--line);
    background: var(--panel-2); color: var(--ink-3); white-space: nowrap;
}
.kind-tag.k-drawing { background: var(--brand-50); border-color: var(--brand-100); color: var(--brand); }

/* 状态胶囊（沿用 .st 前缀，避免和 .tag 冲突） */
.st {
    display: inline-flex; align-items: center; gap: 4px;
    height: 21px; padding: 0 8px; border-radius: 11px;
    font-size: 11.5px; border: 1px solid transparent; white-space: nowrap;
}
.st::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex: none; }
.st.ok   { background: var(--ok-bg);   border-color: var(--ok-line);   color: var(--ok); }
.st.err  { background: var(--err-bg);  border-color: var(--err-line);  color: var(--err); }
.st.warn { background: var(--warn-bg); border-color: var(--warn-line); color: var(--warn); }
.st.info { background: var(--info-bg); border-color: var(--info-line); color: var(--info); }

/* ── 导入说明卡 ── */
.pdf-help { margin-top: 16px; }
.hl-list { margin: 0; padding-left: 20px; font-size: 12.8px; line-height: 2; color: var(--ink-2); }
.hl-list b { color: var(--brand); }
.hl-list code { background: var(--panel-2); padding: 1px 5px; border-radius: 4px; font-size: 12px; }

/* ── 图纸清单：缩略图网格 ── */
.thumb-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(196px, 1fr));
    gap: 14px;
}
.tcard {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    transition: transform .18s, box-shadow .18s, border-color .18s;
}
.tcard:hover { transform: translateY(-2px); border-color: var(--brand-100); box-shadow: 0 8px 20px rgba(16,24,40,.08); }
.tcard.is-bad { border-color: var(--err-line); }
.tcard .tc-art {
    position: relative;
    display: block;
    aspect-ratio: 220 / 156;
    background: var(--panel-2);
    border-bottom: 1px solid var(--line-soft);
    overflow: hidden;
}
.tcard .tc-art img { width: 100%; height: 100%; object-fit: contain; display: block; background: #fff; }
.tcard .tc-skeleton {
    position: absolute; inset: 0;
    display: grid; place-items: center;
    font-size: 11.5px; color: var(--ink-3);
    background: repeating-linear-gradient(135deg, var(--panel-2) 0 6px, var(--panel-3) 6px 12px);
}
/* 右上角识别状态标记：只用图形，不写文字
   ok 绿勾 / bad 红叹号 / none 灰色虚线空圈（未识别） */
.tcard .hot-badge {
    position: absolute; right: 6px; top: 6px;
    width: 22px; height: 22px;
    border-radius: 50%;
    display: grid; place-items: center;
    box-shadow: 0 1px 4px rgba(16,24,40,.18);
    transition: transform .15s;
    z-index: 2;
}
.tcard .tc-art:hover .hot-badge { transform: scale(1.08); }
.tcard .hot-badge svg { width: 13px; height: 13px; display: block; }
.tcard .hb-ok  { background: rgba(18,183,106,.95); color: #fff; }
.tcard .hb-bad { background: rgba(240,68,56,.95);  color: #fff; }
.tcard .hb-none {
    background: rgba(255,255,255,.86);
    color: var(--ink-3);
    border: 1px dashed var(--line);
    box-shadow: none;
}
.tcard .tc-multi {
    position: absolute; right: 6px; bottom: 6px;
    padding: 0 6px; height: 18px; line-height: 18px;
    border-radius: 9px; background: rgba(31,34,37,.72); color: #fff;
    font-size: 10.5px;
}
.tcard .tc-body { padding: 10px 11px 11px; }
.tcard .tc-top { display: flex; align-items: center; gap: 6px; row-gap: 4px; flex-wrap: wrap; margin-bottom: 5px; }
.tcard .tc-seq {
    width: 22px; height: 22px; border-radius: 6px;
    display: grid; place-items: center; flex: none;
    background: var(--brand-50); color: var(--brand);
    font-size: 11.5px; font-weight: 700;
}
/* 图纸卡片上的所属批次：只在「全部批次」视图出现，
   形状比序号小、比正文淡，读起来是「图纸 N → 属于批次 N74」 */
.tcard .tc-batch {
    margin-left: auto;
    padding: 1px 6px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--panel-2);
    font-size: 10.5px;
    font-weight: 600;
    line-height: 1.5;
    letter-spacing: .2px;
    color: var(--ink-3);
    white-space: nowrap;
}
.tcard .tc-cmdrow { display: flex; align-items: center; gap: 6px; min-width: 0; }
.tcard .tc-cmd {    display: block; font-size: 12px; color: var(--ink-2);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    flex: 0 1 auto; min-width: 0;
}
/* 切割指令后的识别状态点：颜色与缩略图右上角角标一致
   绿=识别正确 红=识别有误 灰虚=未识别；点本身不带文字，hover 出说明 */
.hd-dot {
    flex: 0 0 auto;
    width: 7px; height: 7px;
    border-radius: 50%;
    display: inline-block;
    transition: box-shadow .15s;
}
.hd-dot.is-ok   { background: #12b76a; box-shadow: 0 0 0 2.5px rgba(18,183,106,.16); }
.hd-dot.is-bad  { background: #f04438; box-shadow: 0 0 0 2.5px rgba(240,68,56,.16); }
.hd-dot.is-none { background: transparent; border: 1px dashed var(--ink-3); box-shadow: none; }
.tcard:hover .hd-dot.is-bad { box-shadow: 0 0 0 3.5px rgba(240,68,56,.2); }
/* 切割指令后的 gen 文件徽章：实心 G，绿=有 gen / 灰=没有 */
.gen-badge { flex: 0 0 auto; display: inline-flex; align-items: center; line-height: 0; }
.gen-badge.is-on  { color: #16a34a; }
.gen-badge.is-off { color: #9ca3af; }
.gen-badge svg { display: block; }
/* 识别状态徽章：与 G 同形的圆角方框，绿勾 / 红叹号 / 灰虚线问号 */
.hot-badge2 { flex: 0 0 auto; display: inline-flex; align-items: center; line-height: 0; }
.hot-badge2.is-ok   { color: #12b76a; }
.hot-badge2.is-bad  { color: #f04438; }
.hot-badge2.is-none { color: #9ca3af; }
.hot-badge2 svg { display: block; }
/* 零件数 / 页码小字：紧跟在状态标签后面 */
.tcard .tc-info { font-size: 11.5px; color: var(--ink-3); white-space: nowrap; }

/* 识别错误时卡片底部的「AI 识别」按钮：小胶囊，只在这一种状态下出现 */.tcard .tc-act { margin-top: 7px; }
.tcard .tc-ai {
    display: inline-flex; align-items: center; gap: 5px;
    height: 24px; padding: 0 9px;
    border: 1px solid var(--brand-100);
    border-radius: 12px;
    background: var(--brand-50);
    color: var(--brand);
    font-size: 11.5px; font-weight: 600;
    cursor: pointer;
    transition: background .15s, border-color .15s;
}
.tcard .tc-ai svg { width: 12px; height: 12px; }
.tcard .tc-ai:hover { background: #fff; border-color: var(--brand); }

/* 详情页操作区里的「AI 识别」：和 ghost 按钮同尺寸，用品牌色区分 */
.btn-ai {
    border-color: var(--brand-100) !important;
    background: var(--brand-50) !important;
    color: var(--brand) !important;
    font-weight: 600;
}
.btn-ai:hover { background: #fff !important; border-color: var(--brand) !important; }

/* 前附表 */
.front-docs .front-list { display: flex; gap: 10px; flex-wrap: wrap; }
.front-item {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 12px; min-width: 190px;
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--panel-2); text-decoration: none;
    transition: border-color .16s, background .16s;
}
.front-item:hover { border-color: var(--brand-100); background: var(--panel); }
.front-item .fi-kind {
    flex: none; padding: 0 7px; height: 20px; line-height: 20px;
    border-radius: 10px; font-size: 11px;
    background: var(--info-bg); border: 1px solid var(--info-line); color: var(--info);
}
.front-item .fi-tx { display: flex; flex-direction: column; min-width: 0; }
.front-item .fi-tx b { font-size: 12.5px; color: var(--ink); }
.front-item .fi-tx i { font-size: 11px; color: var(--ink-3); font-style: normal; }

/* 空态 */
.empty-card {
    display: flex; flex-direction: column; align-items: center; gap: 8px;
    padding: 40px 20px; text-align: center;
}
.empty-card b { font-size: 14px; }
.empty-card span { font-size: 12.5px; color: var(--ink-3); max-width: 420px; line-height: 1.7; }

/* KPI 里的提醒数字 */
.kpi b.is-warn { color: var(--warn); }

@media (max-width: 720px) {
    .steps-bar { padding: 10px 12px; }
    .steps-bar .sb span { display: none; }
    .thumb-grid { grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 10px; }
    .drop-zone { padding: 22px 14px; }
    .pdf-review { padding: 14px 12px; }
}

/* ══════════════════════════════════════════════════════════
   切割任务：左侧图纸分类栏 + 任务详情
   ══════════════════════════════════════════════════════════ */

.nest-layout {
    display: grid;
    grid-template-columns: 288px minmax(0, 1fr);
    gap: 16px;
    align-items: start;
}
.nest-layout:has(.nest-dwg.is-off) { grid-template-columns: 44px minmax(0, 1fr); }
.nest-main { min-width: 0; }

/* 切割任务筛选卡里的状态 Tab：全部 / 待切割 / 已上机 / 切割完成 */
.seg-tabs {
    display: flex;
    gap: 4px;
    padding: 10px 0 12px;
    margin-bottom: 12px;
    border-bottom: 1px solid var(--line-soft);
}
.seg-tab {
    display: inline-flex;
    align-items: center;
    height: 28px;
    padding: 0 13px;
    border: 1px solid transparent;
    border-radius: 999px;
    color: var(--ink-2);
    font-size: 12.5px;
    text-decoration: none;
    transition: background .15s, color .15s, border-color .15s;
}
.seg-tab:hover { background: var(--panel-2); color: var(--brand); text-decoration: none; }
.seg-tab.on {
    background: var(--brand);
    border-color: var(--brand);
    color: #fff;
    font-weight: 600;
}
.seg-tab.on:hover { background: var(--brand-hover); border-color: var(--brand-hover); color: #fff; }

/* 切割任务：页面右上角的导出按钮（带当前筛选条件） */
.nest-tools { display: flex; justify-content: flex-end; margin: 0 0 10px; }
.nest-tools .btn svg { width: 15px; height: 15px; }

/* ── 导出表格弹窗：两个导出选项，做成整卡可点 ─────────────── */
.exp-modal { max-width: 520px; }
.exp-sub { margin: -6px 0 14px; font-size: 12.5px; color: var(--ink-3); }
.exp-sub b { color: var(--ink-2); font-weight: 600; }
.exp-opts { display: flex; flex-direction: column; gap: 10px; }
.exp-opt {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--panel-2);
    text-decoration: none;
    transition: border-color .16s, background .16s, transform .16s, box-shadow .16s;
}
.exp-opt:hover {
    border-color: var(--brand-100);
    background: var(--brand-50);
    transform: translateY(-1px);
    box-shadow: 0 6px 16px rgba(16, 24, 40, .07);
    text-decoration: none;
}
.exp-opt:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.exp-ico {
    width: 38px;
    height: 38px;
    border-radius: 9px;
    display: grid;
    place-items: center;
    flex: none;
    background: var(--brand);
    color: #fff;
}
.exp-ico.is-alt { background: var(--info, #2563eb); }
.exp-ico svg { width: 19px; height: 19px; }
.exp-tx { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.exp-tx b { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.exp-tx i { font-style: normal; font-size: 11.5px; color: var(--ink-3); line-height: 1.55; }
.exp-arrow { margin-left: auto; flex: none; color: var(--brand); font-size: 15px; }
html[data-theme="dark"] .exp-ico { color: #fff; }
.exp-tip { margin: 12px 0 0; font-size: 11.5px; color: var(--ink-3); }

/* ── 图纸栏 ── */
.nest-dwg {
    position: sticky;
    top: 12px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--sh-card);
    overflow: hidden;
}
.nd-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 11px 12px;
    border-bottom: 1px solid var(--line-soft);
}
.nd-head b { font-size: 13px; }
.nd-cnt {
    font-size: 11.5px;
    color: var(--ink-3);
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 9px;
    padding: 0 7px;
}
.nd-toggle {
    margin-left: auto;
    width: 24px; height: 24px;
    display: grid; place-items: center;
    border: 1px solid var(--line);
    border-radius: 5px;
    background: var(--panel);
    color: var(--ink-3);
    cursor: pointer;
    transition: border-color .16s, color .16s, transform .2s;
}
.nd-toggle:hover { border-color: var(--brand-100); color: var(--brand); }
.nest-dwg.is-off .nd-toggle { transform: rotate(180deg); }
.nest-dwg.is-off .nd-filter,
.nest-dwg.is-off .nd-list { display: none; }
.nest-dwg.is-off .nd-head b,
.nest-dwg.is-off .nd-cnt { display: none; }
.nest-dwg.is-off .nd-head { justify-content: center; padding: 11px 0; }
.nest-dwg.is-off .nd-toggle { margin: 0; }

.nd-filter { padding: 10px 12px 6px; display: flex; flex-direction: column; gap: 6px; }
.nd-filter input[type=search] { height: 30px; font-size: 12.5px; }
.nd-filter select { height: 30px; font-size: 12.5px; }

.nd-list {
    max-height: calc(100vh - 210px);
    overflow-y: auto;
    padding: 6px 8px 12px;
}
.nd-all {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 7px 9px;
    margin-bottom: 6px;
    border-radius: 6px;
    font-size: 12.5px;
    color: var(--ink-2);
    text-decoration: none;
    border: 1px solid transparent;
}
.nd-all span { margin-left: auto; font-size: 11.5px; color: var(--ink-3); }
.nd-all:hover { background: var(--panel-2); }
.nd-all.on {
    background: var(--brand-50);
    border-color: var(--brand-100);
    color: var(--brand);
    font-weight: 600;
}

.nd-group + .nd-group { margin-top: 8px; }
.nd-group-head {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 7px 9px 5px;
    font-size: 11.5px;
    color: var(--ink-3);
    letter-spacing: .3px;
}
.nd-group-head b { color: var(--ink-2); font-weight: 600; }
.nd-group-head span { margin-left: auto; }

/* 图纸卡片 */
.nd-card {
    display: flex;
    gap: 9px;
    padding: 7px;
    border: 1px solid transparent;
    border-radius: 7px;
    text-decoration: none;
    transition: background .14s, border-color .14s;
}
.nd-card:hover { background: var(--panel-2); border-color: var(--line); }
.nd-card.on { background: var(--brand-50); border-color: var(--brand-100); }
.nd-card.is-bad .nd-seq { color: var(--err); }
.nd-art {
    flex: none;
    width: 60px;
    height: 43px;
    border: 1px solid var(--line);
    border-radius: 4px;
    background: var(--panel-2);
    overflow: hidden;
    display: grid;
    place-items: center;
}
.nd-art img { width: 100%; height: 100%; object-fit: contain; background: #fff; display: block; }
.nd-noart { font-size: 10px; color: var(--ink-3); font-style: normal; }
.nd-tx { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.nd-seq { font-size: 12px; color: var(--ink-3); font-weight: 600; }
.nd-card.on .nd-seq { color: var(--brand); }
.nd-meta { display: flex; gap: 6px; font-size: 11px; color: var(--ink-3); }
.nd-meta i { font-style: normal; }
.nd-sec {
    padding: 0 5px;
    border-radius: 8px;
    background: var(--panel-3);
    color: var(--ink-2);
}
.nd-cmd {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11px;
    color: var(--ink-2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.nd-empty { padding: 14px 10px; font-size: 12px; color: var(--ink-3); line-height: 1.7; }

/* 选中提示条 */
.nd-cur {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 12px;
    padding: 9px 13px;
    border: 1px solid var(--brand-100);
    border-radius: var(--radius-sm);
    background: var(--brand-50);
    font-size: 12.5px;
    color: var(--ink-2);
}
.nd-cur b { color: var(--brand); }
.nd-cur code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12px;
    color: var(--ink);
    background: var(--panel);
    border: 1px solid var(--brand-100);
    border-radius: 4px;
    padding: 1px 5px;
}
.nd-cur .btn { margin-left: auto; }

/* ── 切割任务详情 ── */
.ct-head {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 14px 18px;
}
.ct-main { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; }
.ct-label { font-size: 11.5px; color: var(--ink-3); letter-spacing: .5px; }
.ct-cmd {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: .3px;
    color: var(--ink);
}
.ct-act { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }

.ct-parts td { vertical-align: middle; }
.ct-parts .mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12.5px;
    color: var(--ink-2);
    white-space: nowrap;
}
.ct-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ink);
    letter-spacing: .1px;
}
.ct-parts.is-pdf td { background: var(--panel-2); }
.ct-parts.is-pdf tbody tr:hover td { background: var(--panel-3); }

/* 对应图纸卡 */
.ct-dwg { display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-start; }
.ct-dwg-art {
    flex: none;
    display: block;
    width: 260px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--panel-2);
}
.ct-dwg-art img { display: block; width: 100%; height: auto; background: #fff; }
.ct-dwg-art:hover { border-color: var(--brand-100); }
.ct-dwg-tx { min-width: 180px; flex: 1; display: flex; flex-direction: column; gap: 9px; }
.ct-dwg-tx .kv { display: flex; gap: 10px; font-size: 12.5px; }
.ct-dwg-tx .kv b { flex: none; width: 68px; color: var(--ink-3); font-weight: 400; }
.ct-dwg-tx .kv span { color: var(--ink-2); }
.ct-dwg-tx .kv .mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12px;
}
.ct-dwg-act { display: flex; gap: 8px; margin-top: 2px; }

@media (max-width: 1080px) {
    .nest-layout { grid-template-columns: minmax(0, 1fr); }
    .nest-dwg { position: static; }
    .nest-dwg.is-off { display: none; }
    .nd-list { max-height: 320px; }
    .nd-card { flex: 1 1 168px; }
    .nd-list { display: block; }
    .nd-group { display: flex; flex-wrap: wrap; gap: 6px; }
    .nd-group-head { flex: 1 1 100%; }
}
@media (max-width: 720px) {
    .ct-head { padding: 12px 14px; }
    .ct-cmd { font-size: 15px; }
    .ct-act { margin-left: 0; width: 100%; }
    .ct-act .btn { flex: 1; }
    .ct-dwg-art { width: 100%; }
    .ct-dwg-tx { min-width: 0; }
}

/* 图纸栏卡片的船号 / 分段标签 */
.nd-ship { color: var(--ink-2); font-weight: 500; }
.nest-dwg .nd-sec {
    display: inline-block;
    padding: 0 5px;
    border-radius: 8px;
    background: var(--panel-3);
    border: 1px solid var(--line-soft);
    color: var(--ink-2);
    font-style: normal;
    line-height: 15px;
    font-size: 10.5px;
}
.nest-dwg .nd-sec.more { color: var(--ink-3); background: transparent; }
.nd-meta { flex-wrap: wrap; row-gap: 3px; }
.nd-cur .nd-sec,
.nb-tags .nd-sec {
    display: inline-block;
    padding: 0 6px;
    border-radius: 8px;
    background: var(--panel);
    border: 1px solid var(--line);
    color: var(--ink-2);
    font-style: normal;
    line-height: 16px;
    font-size: 11px;
    vertical-align: 1px;
    margin-left: 4px;
}
.nd-cur .nd-sec { background: var(--brand-50); border-color: var(--brand-100); color: var(--brand); }
/* 船号与分段号标签等高，避免基线错位 */
.nb-tags .nd-ship,
.nb-tags .nd-sec { line-height: 18px; font-size: 11px; }
.nb-tags .nd-ship { color: var(--ink-2); }
.nd-cur .nd-ship-none { color: var(--ink-3); }

/* ── 分段栏（图纸管理左侧）：分段号大字 + 统计 ── */
.nd-seg { align-items: center; }
.nd-seg .seg-badge {
    flex: none;
    width: 42px;
    height: 42px;
    display: grid;
    place-items: center;
    border-radius: 7px;
    background: var(--brand-50);
    border: 1px solid var(--brand-100);
    color: var(--brand);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .2px;
}
.nd-seg.on .seg-badge { background: var(--brand); border-color: var(--brand); color: #fff; }
.nd-seg.is-empty .seg-badge {
    background: var(--panel-3);
    border-color: var(--line);
    color: var(--ink-3);
}
.nd-seg .seg-no {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .2px;
    color: var(--ink);
}
.nd-seg.on .seg-no { color: var(--brand); }
.nd-seg .seg-stat {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    color: var(--ink-3);
}
.nd-seg .seg-stat b { color: var(--ink-2); font-weight: 600; font-variant-numeric: tabular-nums; }
.nd-seg.on .seg-stat b { color: var(--brand); }
.nd-seg .seg-stat i { font-style: normal; color: var(--line); }

@media (max-width: 1080px) {
    .nd-seg { flex: 1 1 200px; }
}

/* ── 切割任务左侧栏：图纸号（批次）卡片 ──
   一张卡 = 图纸管理里的大图纸号（N74 / N74P），
   卡片上给船号 + 分段号 + 任务/图纸/零件统计。 */
.nd-batch {
    position: relative;          /* 铅笔按钮绝对定位到右下角 */
    flex-direction: column;
    align-items: stretch;
    gap: 5px;
    padding: 9px 11px 10px;
    margin-bottom: 5px;
    border: 1px solid var(--line-soft);
    background: var(--panel);
}
/* 整卡可点：透明覆盖层，铅笔按钮压在它上面（z-index 更高） */
.nb-hit { position: absolute; inset: 0; border-radius: 7px; z-index: 1; }
.nb-hit:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* 卡片右下角的「编辑批次」铅笔：每张卡一个，常驻低透明度，悬停变品牌色 */
.nb-edit {
    position: absolute;
    right: 6px;
    bottom: 6px;
    z-index: 2;
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    cursor: pointer;
    border-radius: 5px;
    color: var(--ink-3);
    opacity: .6;
    transition: color .14s, background .14s, opacity .14s;
}
.nb-edit svg { width: 13px; height: 13px; display: block; }
.nb-edit:hover {
    opacity: 1;
    color: var(--brand);
    background: var(--brand-50);
}
.nb-edit:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; opacity: 1; }
.nd-batch.on .nb-edit { opacity: .85; color: var(--brand); }
.nd-batch:hover { background: var(--panel-2); border-color: var(--line); }
.nd-batch.on { background: var(--brand-50); border-color: var(--brand-100); }

.nb-top { display: flex; align-items: center; gap: 7px; min-width: 0; }
.nb-no {
    font-size: 14.5px;
    letter-spacing: .3px;
    /* 批次号用深主题色（--brand-pressed），比纯黑更有辨识度，跟主题一起换色 */
    color: var(--brand-pressed);
    font-variant-numeric: tabular-nums;
}
/* 暗夜下 --brand-pressed 太暗，换亮一档的 brand-hover 保证可读 */
html[data-theme="dark"] .nb-no { color: var(--brand-hover); }
.nd-batch.on .nb-no { color: var(--brand); }
.nb-wait {
    margin-left: auto;
    flex: none;
    padding: 0 6px;
    border-radius: 9px;
    font-size: 10.5px;
    font-style: normal;
    line-height: 16px;
    background: var(--warn-bg);
    border: 1px solid var(--warn-line);
    color: var(--warn);
}
.nb-tags { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.nb-stat {
    display: flex;
    align-items: center;
    gap: 4px;
    padding-right: 24px;      /* 让开右下角的铅笔按钮 */
    font-size: 11px;
    color: var(--ink-3);
}
.nb-stat b { color: var(--ink-2); font-weight: 600; font-variant-numeric: tabular-nums; }
.nb-stat i { font-style: normal; color: var(--line); }
.nd-batch.on .nb-stat,
.nd-batch.on .nb-stat b { color: var(--brand); }

@media (max-width: 1080px) {
    .nd-batch { flex: 1 1 240px; }
}

/* ══════════════════════════════════════════════════════════
   批次管理：一个批次一张卡，卡里摊开它的多个分段
   ══════════════════════════════════════════════════════════ */

.bt-grid { display: flex; flex-direction: column; gap: 14px; margin-top: 16px; }

.bt-card { padding: 0; overflow: hidden; }

/* ── 卡头：批次号 + 状态 + 船号 + 统计 + 操作 ── */
.bt-head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 13px 18px;
    border-bottom: 1px solid var(--line-soft);
    background: linear-gradient(180deg, var(--panel) 0%, var(--panel-2) 100%);
}
.bt-no {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 18px;
    font-weight: 700;
    letter-spacing: .4px;
    color: var(--ink);
    line-height: 1.2;
}
.bt-ship {
    font-size: 12.5px;
    color: var(--ink-2);
    padding: 0 7px;
    line-height: 19px;
    border-radius: 10px;
    background: var(--panel-3);
    border: 1px solid var(--line-soft);
}
.bt-proj {
    font-size: 11.5px;
    color: var(--ink-3);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.bt-stat {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    color: var(--ink-3);
}
.bt-stat b { color: var(--ink-2); font-weight: 600; font-variant-numeric: tabular-nums; }
.bt-stat i { font-style: normal; color: var(--line); }
.bt-act { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }

/* ── 分段行 ── */
.bt-segs { padding: 6px 12px 8px; }

.bt-seg {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
    padding: 8px 8px 8px 10px;
    border-radius: 7px;
    border: 1px solid transparent;
    transition: background .14s, border-color .14s;
}
.bt-seg + .bt-seg { margin-top: 1px; }
.bt-seg:hover { background: var(--panel-2); border-color: var(--line-soft); }
.bt-seg .seg-no {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--ink);
    letter-spacing: .2px;
    min-width: 96px;
}
.bt-seg .seg-nm { font-size: 12.5px; color: var(--ink-3); }
.bt-seg .seg-meta {
    font-size: 11.5px;
    color: var(--ink-3);
    font-variant-numeric: tabular-nums;
}
.bt-seg .seg-act {
    margin-left: auto;
    display: flex;
    gap: 12px;
    opacity: .55;
    transition: opacity .14s;
}
.bt-seg:hover .seg-act { opacity: 1; }

/* 待登记：琥珀色虚线 + 左侧竖条，与已登记区分开 */
.bt-seg.is-todo {
    border-style: dashed;
    border-color: var(--warn-line);
    background: var(--warn-bg);
}
.bt-seg.is-todo .seg-no { color: var(--warn); }
.bt-seg.is-todo .seg-meta { color: var(--warn); opacity: .85; }

.bt-empty {
    margin: 0;
    padding: 12px 8px;
    font-size: 12.5px;
    color: var(--ink-3);
    line-height: 1.7;
}

/* ── 卡脚 ── */
.bt-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 18px;
    border-top: 1px solid var(--line-soft);
    background: var(--panel-2);
}
.bt-hint { font-size: 12px; color: var(--ink-3); }
.bt-foot .btn { margin-left: auto; }

.tag.sm { height: 19px; padding: 0 7px; font-size: 11px; }

@media (max-width: 720px) {
    .bt-head { padding: 11px 13px; }
    .bt-no { font-size: 16px; }
    .bt-act { margin-left: 0; width: 100%; }
    .bt-act .btn { flex: 1; }
    .bt-segs { padding: 4px 6px 6px; }
    .bt-seg { padding: 7px 6px; gap: 7px; }
    .bt-seg .seg-no { min-width: 0; }
    .bt-seg .seg-act { margin-left: 0; width: 100%; justify-content: flex-end; opacity: 1; }
    .bt-foot { padding: 9px 13px; flex-wrap: wrap; }
    .bt-foot .btn { margin-left: 0; width: 100%; }
}

/* 批次卡上的工程编号（左侧栏 project/batch、production/nest 共用） */
.nb-proj {
    margin-left: auto;
    font-size: 10.5px;
    font-style: normal;
    color: var(--ink-3);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* 空批次也统一用同款主题色：有没有图纸看下面的统计数字，不靠压淡批次号来区分 */

/* ══════════════════════════════════════════════════════════
   批次管理：右侧分段明细（批次基本信息卡已去掉，编辑入口在左栏右下角）
   ══════════════════════════════════════════════════════════ */

/* ── 分段明细表 ── */
.bt-table td { vertical-align: middle; }
.bt-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.bt-table .mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px;
    letter-spacing: .2px;
}
.bt-table .dim { color: var(--ink-3); font-size: 12.5px; }

/* 图纸号（导入时从 PDF 首页识别）：一串 30 位左右的编号，限宽省略，完整值走 title */
.dwg-no {
    display: inline-block;
    max-width: 210px;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: bottom;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12px;
    letter-spacing: .2px;
    color: var(--ink-2);
}

/* 图纸列表：11 列，行内边距收紧一点，1440 下不出横向滚动 */
.dwg-table th,
.dwg-table td { padding-left: 5px; padding-right: 5px; white-space: nowrap; }
.dwg-table .dwg-no { max-width: 262px; font-size: 13.5px; letter-spacing: 0; }
.dwg-table .btn.sm { padding: 3px 5px; font-size: 11.5px; }
.dwg-table td:last-child { white-space: nowrap; }
/* 船号与项目同列两行：船号在上，项目号在下（省一列，1440 下表格不横向溢出） */
.dwg-ship b { display: block; font-size: 12.5px; font-weight: 600; }
.dwg-ship i { display: block; font-style: normal; font-size: 11px; line-height: 1.4; color: var(--ink-3); }
.dwg-table .op-link { margin-left: 6px; font-size: 12px; color: var(--brand); text-decoration: none; }
.dwg-table .op-link:hover { text-decoration: underline; }
/* 列多时横向滚动，操作列固定在右侧，不用滚到底也能点 */
.dwg-table th:last-child,
.dwg-table td:last-child {
    position: sticky;
    right: 0;
    background: var(--panel);
    box-shadow: -8px 0 12px -10px rgba(16, 24, 40, .25);
}
.dwg-no.is-empty { font-family: inherit; font-size: 13px; color: var(--ink-3); }
/* 同批次多张图纸时的序号角标：#1 #2 …（单张图纸不显示） */
.dwg-seq {
    display: inline-block;
    margin-right: 5px;
    padding: 0 4px;
    border-radius: 4px;
    font-style: normal;
    font-size: 11px;
    line-height: 16px;
    font-variant-numeric: tabular-nums;
    color: var(--brand);
    background: color-mix(in srgb, var(--brand) 12%, transparent);
    vertical-align: 1px;
}
/* 带序号的行把图纸号再收窄一点，序号占的宽从编号里省出来，1440 下不挤出横向滚动 */
.dwg-table .dwg-no-cell .dwg-no { max-width: 232px; }
/* 可点开的图纸单号：新窗口打开原始图纸 PDF */
.dwg-no.is-link {
    color: var(--brand);
    text-decoration: none;
    border-bottom: 1px dashed color-mix(in srgb, var(--brand) 45%, transparent);
    transition: color .14s, border-color .14s;
}
.dwg-no.is-link:hover {
    text-decoration: none;
    border-bottom-color: var(--brand);
    border-bottom-style: solid;
}
.dwg-no.is-link:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
    border-radius: 3px;
}
.bt-table tr.row-todo td { background: var(--warn-bg); }
.bt-table tr.row-todo:hover td { filter: brightness(.985); }
.bt-table tr.row-todo .mono { color: var(--warn); }
.bt-todo-tx { color: var(--warn); }

/* 分段编辑弹窗：字段两列，窄屏一列；底部按钮右对齐 */
.seg-modal { max-width: 520px; }
.seg-modal .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.seg-modal input,
.seg-modal select { height: 34px; }
.seg-modal-hint { margin: 10px 0 0; }

/* 批次编辑弹窗：比分段弹窗宽一点，字段两列 */
.batch-modal { max-width: 560px; }
.batch-modal .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.batch-modal input,
.batch-modal select { height: 34px; }
.bme-hint { margin: 10px 0 0; }

/* 项目编辑弹窗：字段与批次弹窗同宽同布局 */
.ship-modal { max-width: 560px; }
.ship-modal .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ship-modal input,
.ship-modal select { height: 34px; }
.shm-hint { margin: 10px 0 0; }
/* 底部左侧的「图纸 / 删除批次…」入口：靠左淡显，不进主按钮区 */
.bme-more {
    margin-right: auto;
    align-self: center;
    font-size: 12.5px;
    color: var(--ink-3);
    text-decoration: none;
    border-bottom: 1px dashed var(--line);
    transition: color .14s, border-color .14s;
}
.bme-more:hover { color: var(--brand); border-bottom-color: var(--brand-100); }

/* 批次弹窗底部「删除空批次」：仅在名下无任何数据时露出按钮 */
.bme-del {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--line);
    font-size: 12.5px;
    color: var(--ink-3);
}
.bme-del-tx { flex: 1 1 200px; min-width: 0; line-height: 1.5; }

/* 图纸编辑弹窗：标题里的批次号小字 */
.sm-batch { font-size: 12.5px; font-weight: 400; color: var(--ink-3); margin-left: 2px; }
body.modal-open { overflow: hidden; }

.modal-foot {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--line-soft);
}

/* 只读输入框（增加人） */
.ro-input {
    background: var(--panel-2) !important;
    color: var(--ink-2) !important;
    cursor: default;
}

@media (max-width: 720px) {
    .seg-modal .form-grid,
    .batch-modal .form-grid,
    .ship-modal .form-grid { grid-template-columns: minmax(0, 1fr); }
    .modal-foot { flex-direction: column-reverse; }
    .modal-foot .btn { width: 100%; }
    .bme-more { margin: 2px auto 0; }
}

/* 左栏批次卡的船号 / 日期标签：跟着内容走，不被挤压换行 */
.nb-tags { flex-wrap: wrap; row-gap: 4px; }
.nb-tags .nd-ship,
.nb-tags .nd-sec { white-space: nowrap; flex: none; }

/* 分段明细标题右侧的「新增分段」：与统计文字垂直居中对齐 */
.card > h2 .right .btn { vertical-align: middle; }
.card > h2 .right .seg-sum { display: inline-flex; align-items: center; gap: 4px; }
.card > h2 .right .seg-sum b { color: var(--ink-2); font-weight: 600; font-variant-numeric: tabular-nums; }

/* 分段明细的「新增分段」已移到标题右侧（弹窗形式），表尾那行不再需要 */

/* ══════════════════════════════════════════════════════════
   项目状态：未开工 / 建设中 / 完成
   ──────────────────────────────────────────────────────────
   三种状态的差别不只在颜色，动效也不一样：
     未开工 idle     —— 灰、静止（animation: none），像靠在码头没动
     建设中 building —— 正常起伏 + 船首尾迹循环扩散（在航行）
     完成   done     —— 满色、浮动更慢更小（抛锚稳泊）+ 桅杆挂旗飘动

   颜色全部走固定的 --st-*（定义见文件头注释），不跟主题品牌色走。
   ══════════════════════════════════════════════════════════ */

/* ── 状态色（船体派生变量优先级最高，覆盖 is-muted） ── */
.ship-art.st-idle {
    --sk: #c3cad3;
    --sf: #f2f4f7;
    --sd: #e6e9ee;
    opacity: .78;
}
html[data-theme="dark"] .ship-art.st-idle {
    --sk: #4c535f;
    --sf: #23232b;
    --sd: #2b2b34;
    opacity: .6;
}
/* 完成：满色 + 略加饱和，一眼看出是「成品」 */
.ship-art.st-done { filter: saturate(1.18); }
html[data-theme="dark"] .ship-art.st-done { filter: saturate(1.3) brightness(1.06); }

/* ── 动画差异（挂在 .ship-stage 上，船号铭牌跟着一起浮动） ── */
/* 未开工：完全静止，连起伏都不要 */
.berth.st-idle > .ship-stage { animation: none; }
/* 建设中：正常起伏（沿用 shipBob），外加尾迹 */
.berth.st-building > .ship-stage { animation: shipBob 4.8s ease-in-out infinite; }
/* 完成：抛锚，浮动幅度更小、周期更长（稳） */
.berth.st-done > .ship-stage {
    animation: shipMoor 7.6s ease-in-out infinite;
}
@keyframes shipMoor {
    0%, 100% { transform: translateY(var(--lift)) rotate(0deg); }
    45%      { transform: translateY(calc(var(--lift) - 0.9px)) rotate(-.12deg); }
    75%      { transform: translateY(calc(var(--lift) + 0.6px)) rotate(.1deg); }
}

/* 尾迹：船首前方两道弧线，循环向外扩散淡出 */
.ship-art .wake path {
    fill: none;
    stroke: var(--sk);
    stroke-width: 1.6;
    stroke-linecap: round;
    opacity: 0;
}
.berth.st-building .ship-art .wake path:nth-child(1) { animation: wakeOut 3.6s ease-out infinite; }
.berth.st-building .ship-art .wake path:nth-child(2) { animation: wakeOut 3.6s ease-out infinite .5s; }
@keyframes wakeOut {
    0%   { opacity: 0;   transform: translateX(-6px) scaleX(.6); }
    22%  { opacity: .5; }
    100% { opacity: 0;   transform: translateX(9px) scaleX(1.08); }
}

/* 完工旗：桅杆顶的小旗，缓慢飘两下停一下 */
.ship-art .flag path { fill: var(--st-done); opacity: .85; transform-origin: 208px 8px; }
.berth.st-done .ship-art .flag path { animation: flagWave 3.4s ease-in-out infinite; }
@keyframes flagWave {
    0%, 100% { transform: skewX(0deg) scaleX(1); }
    35%      { transform: skewX(-7deg) scaleX(.94); }
    70%      { transform: skewX(4deg) scaleX(1.02); }
}

/* 列表首列小图标：尾迹/旗子太小看不清，直接不显示，只靠颜色区分 */
.ship-ico .wake,
.ship-ico .flag { display: none; }

/* ── 船身上的状态胶囊 ── */
.st-plate.st-idle     { background: var(--st-idle); }
.st-plate.st-building { background: var(--st-build); }
.st-plate.st-done     { background: var(--st-done); }

/* ── 状态圆点（筛选 tab / 图例） ── */
.st-dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex: none;
    vertical-align: 1px;
    margin-left: 4px;
}
.st-dot.st-idle     { background: var(--st-idle); box-shadow: 0 0 0 2px color-mix(in srgb, var(--st-idle) 22%, transparent); }
.st-dot.st-building { background: var(--st-build); box-shadow: 0 0 0 2px color-mix(in srgb, var(--st-build) 24%, transparent); animation: dotPulse 2.4s ease-in-out infinite; }
.st-dot.st-done     { background: var(--st-done); box-shadow: 0 0 0 2px color-mix(in srgb, var(--st-done) 22%, transparent); }
@keyframes dotPulse {
    0%, 100% { transform: scale(1);   opacity: 1; }
    50%      { transform: scale(1.22); opacity: .8; }
}

/* 状态文字（表单/提示里的纯文本态） */
.st-tx { font-style: normal; font-weight: 600; }
.st-tx.st-idle     { color: var(--st-idle-t); }
.st-tx.st-building { color: var(--st-build-t); }
.st-tx.st-done     { color: var(--st-done-t); }

/* ── 状态标签（列表单元格） ── */
.st-tag { white-space: nowrap; }
.st-tag.st-idle {
    background: color-mix(in srgb, var(--st-idle) 12%, var(--panel));
    border-color: color-mix(in srgb, var(--st-idle) 26%, transparent);
    color: var(--st-idle-t);
}
.st-tag.st-building {
    background: color-mix(in srgb, var(--st-build) 12%, var(--panel));
    border-color: color-mix(in srgb, var(--st-build) 26%, transparent);
    color: var(--st-build-t);
}
.st-tag.st-done {
    background: color-mix(in srgb, var(--st-done) 12%, var(--panel));
    border-color: color-mix(in srgb, var(--st-done) 26%, transparent);
    color: var(--st-done-t);
}

/* ── 状态筛选 tabs ── */
.st-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 12px 0 4px;
}
.st-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 30px;
    padding: 0 11px;
    border: 1px solid var(--line);
    border-radius: 15px;
    background: var(--panel);
    font-size: 12.5px;
    color: var(--ink-2);
    text-decoration: none;
    transition: border-color .14s, background .14s, color .14s;
}
.st-tab:hover { border-color: var(--brand-100); color: var(--brand); background: var(--brand-50); }
.st-tab b {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--ink-3);
    font-size: 11.5px;
}
.st-tab.on {
    border-color: var(--brand);
    background: var(--brand-50);
    color: var(--brand);
    font-weight: 600;
}
.st-tab.on b { color: var(--brand); }
/* 选中态也走状态色：这样「完成」tab 不会还是绿的，和船身上的青胶囊一致 */
.st-tab.is-idle.on {
    border-color: color-mix(in srgb, var(--st-idle) 38%, transparent);
    background: color-mix(in srgb, var(--st-idle) 10%, var(--panel));
    color: var(--st-idle-t);
}
.st-tab.is-idle.on b   { color: var(--st-idle-t); }
.st-tab.is-building.on {
    border-color: color-mix(in srgb, var(--st-build) 40%, transparent);
    background: color-mix(in srgb, var(--st-build) 10%, var(--panel));
    color: var(--st-build-t);
}
.st-tab.is-building.on b { color: var(--st-build-t); }
.st-tab.is-done.on {
    border-color: color-mix(in srgb, var(--st-done) 40%, transparent);
    background: color-mix(in srgb, var(--st-done) 10%, var(--panel));
    color: var(--st-done-t);
}
.st-tab.is-done.on b   { color: var(--st-done-t); }
.st-tab .st-dot { margin-left: 0; }

@media (max-width: 720px) {
    .st-tab { height: 28px; padding: 0 9px; font-size: 12px; }
}

/* 减少动态效果：所有船一律静止，只留颜色区分 */
@media (prefers-reduced-motion: reduce) {
    .berth > .ship-stage,
    .berth.st-idle > .ship-stage,
    .berth.st-building > .ship-stage,
    .berth.st-done > .ship-stage { animation: none !important; }
    .ship-art .wake path,
    .ship-art .flag path,
    .st-dot { animation: none !important; }
    .ship-art .wake { display: none; }
}


/* ==================== 批次列表左栏（project/block、project/batch）====================
   白卡片放在白栏里看不出边界，所以这一栏整体压深一档：
   栏底比 --panel 暗、卡片保持纯白 + 实边 + 轻投影，卡片自然浮起来。
   颜色全部走局部变量，暗夜主题只需换一组变量（见下方），不用重写规则。
   只作用于加了 .nd-deep 的两页，production/nest 的图纸栏不受影响。 */
.nest-dwg.nd-deep {
    --ndp-bg: #eef1f5;
    --ndp-head-1: #e9eef4;
    --ndp-head-2: #e3e9f0;
    --ndp-line: #dbe2ea;
    --ndp-line-2: #d5dde6;
    --ndp-all: #e3e8ef;
    --ndp-all-hover: #dce3eb;
    --ndp-card: #ffffff;
    --ndp-card-line: #d8e0e9;
    --ndp-card-line-hover: #b9c6d6;
    --ndp-on: color-mix(in srgb, var(--brand) 12%, #fff);
    --ndp-stat: #6b7686;
    --ndp-stat-i: #c3ccd8;
    --ndp-shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 8px 20px -16px rgba(16, 24, 40, .28);

    background: var(--ndp-bg);
    border-color: var(--ndp-line);
    box-shadow: var(--ndp-shadow);
}
.nd-deep .nd-head {
    background: linear-gradient(180deg, var(--ndp-head-1), var(--ndp-head-2));
    border-bottom-color: var(--ndp-line);
}
.nd-deep .nd-head b { font-weight: 700; letter-spacing: .2px; }
.nd-deep .nd-cnt {
    background: var(--ndp-card);
    border-color: var(--ndp-line-2);
    color: var(--ink-2);
    font-weight: 600;
}
.nd-deep .nd-toggle { background: var(--ndp-card); border-color: var(--ndp-line-2); color: var(--ink-2); }
.nd-deep .nd-toggle:hover { border-color: var(--brand); color: var(--brand); }

/* 筛选控件用白底实边，跟压深的栏底分开 */
.nd-deep .nd-filter input[type=search],
.nd-deep .nd-filter select { background: var(--ndp-card); border-color: var(--ndp-line-2); }
.nd-deep .nd-filter input[type=search]:focus,
.nd-deep .nd-filter select:focus { border-color: var(--brand); }

/* 「全部批次」：常态比栏底再深一档，选中转品牌色 */
.nd-deep .nd-all {
    background: var(--ndp-all);
    border-color: var(--ndp-line-2);
    color: var(--ink-2);
    font-weight: 600;
}
.nd-deep .nd-all span { color: var(--ink-2); }
.nd-deep .nd-all:hover { background: var(--ndp-all-hover); border-color: var(--ndp-card-line-hover); }
.nd-deep .nd-all.on {
    background: var(--ndp-on);
    border-color: var(--brand);
    color: var(--brand);
}
.nd-deep .nd-all.on span { color: var(--brand); }

/* 分组标题（船号 N 批） */
.nd-deep .nd-group-head b { color: var(--ink); }

/* 卡片：实底 + 实边 + 轻投影，一眼能数清有几张 */
.nd-deep .nd-card,
.nd-deep .nd-batch {
    background: var(--ndp-card);
    border: 1px solid var(--ndp-card-line);
    box-shadow: 0 1px 2px rgba(16, 24, 40, .05);
}
.nd-deep .nd-card:hover,
.nd-deep .nd-batch:hover {
    background: var(--ndp-card);
    border-color: var(--ndp-card-line-hover);
    box-shadow: 0 2px 6px rgba(16, 24, 40, .10);
}
/* 选中：品牌浅底 + 左侧实心色条，比只换边框更醒目 */
.nd-deep .nd-card.on,
.nd-deep .nd-batch.on {
    background: var(--ndp-on);
    border-color: var(--brand);
    box-shadow: inset 3px 0 0 var(--brand), 0 2px 6px rgba(16, 24, 40, .08);
}

/* 卡内文字在压深底上提一档对比 */
.nd-deep .nb-stat { color: var(--ndp-stat); }
.nd-deep .nb-stat b { color: var(--ink); }
.nd-deep .nb-stat i { color: var(--ndp-stat-i); }
.nd-deep .nd-batch.on .nb-stat,
.nd-deep .nd-batch.on .nb-stat b { color: var(--brand); }
.nd-deep .nd-ship { color: var(--ink-2); }
.nd-deep .nd-empty { color: var(--ink-2); }

/* 暗夜：加深方向反过来（栏底要比卡片亮一档），否则一片亮灰很刺眼 */
html[data-theme="dark"] .nest-dwg.nd-deep {
    --ndp-bg: #22222a;
    --ndp-head-1: #2c2c36;
    --ndp-head-2: #272730;
    --ndp-line: #34343f;
    --ndp-line-2: #3a3a46;
    --ndp-all: #2c2c36;
    --ndp-all-hover: #34343f;
    --ndp-card: #1b1b21;
    --ndp-card-line: #33333e;
    --ndp-card-line-hover: #474757;
    --ndp-on: color-mix(in srgb, var(--brand) 20%, #1b1b21);
    --ndp-stat: #9aa3b2;
    --ndp-stat-i: #4d4d5c;
    --ndp-shadow: 0 1px 2px rgba(0, 0, 0, .45), 0 8px 20px -16px rgba(0, 0, 0, .9);
}
html[data-theme="dark"] .nd-deep .nd-card,
html[data-theme="dark"] .nd-deep .nd-batch { box-shadow: 0 1px 2px rgba(0, 0, 0, .4); }
html[data-theme="dark"] .nd-deep .nd-card:hover,
html[data-theme="dark"] .nd-deep .nd-batch:hover { box-shadow: 0 2px 8px rgba(0, 0, 0, .5); }
html[data-theme="dark"] .nd-deep .nd-card.on,
html[data-theme="dark"] .nd-deep .nd-batch.on { box-shadow: inset 3px 0 0 var(--brand), 0 2px 8px rgba(0, 0, 0, .45); }

/* ── 图纸标题栏识别值（切割任务 · 工艺与材料信息） ──────────────
   框内 11 项里，指令号 / 规格 / 材质并入原有格子；其余 8 项新增行，
   统一挂一个「图纸」小胶囊，跟系统 / .gen 数据区分开。 */
.tb-row th { white-space: nowrap; }
.tb-src {
    display: inline-block;
    margin-left: 5px;
    padding: 1px 6px;
    border: 1px solid var(--brand-100);
    border-radius: 9px;
    background: var(--brand-50);
    color: var(--brand);
    font-size: 10.5px;
    font-weight: 500;
    line-height: 1.5;
    vertical-align: 1px;
    white-space: nowrap;
}
.tb-val {
    color: var(--ink);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.tb-unit { margin-left: 2px; font-size: 11.5px; color: var(--muted); }
.tb-row td { font-variant-numeric: tabular-nums; }
@media (max-width: 720px) {
    .tb-row th { white-space: normal; }
}

/* ── 图纸清单：本批次的总图纸（文件夹图标 + 卡片） ─────────────
   一条总图纸 = 一份原始 PDF = 一个文件夹卡片；整张卡片本身就是链接。
   配色比页面底色(#f4f6f8)深一档，卡片才「站」得出来。 */
.sheet-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
    gap: 12px;
}
.sheet-card {
    display: flex;
    flex-direction: column;
    min-width: 0;
    padding: 13px 14px 14px;
    border: 1px solid #dde3ec;
    border-radius: var(--radius);
    background: #eaeef4;
    color: inherit;
    text-decoration: none;
    transition: transform .16s, border-color .16s, background .16s, box-shadow .16s;
}
.sheet-card:hover {
    transform: translateY(-2px);
    border-color: var(--brand-100);
    background: color-mix(in srgb, var(--brand) 9%, #eef2f7);
    box-shadow: 0 6px 18px rgba(16, 24, 40, .1);
}
.sheet-card:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
html[data-theme="dark"] .sheet-card { border-color: #33333f; background: #24242f; }
html[data-theme="dark"] .sheet-card:hover {
    border-color: var(--brand-100);
    background: color-mix(in srgb, var(--brand) 12%, #24242f);
    box-shadow: 0 6px 18px rgba(0, 0, 0, .5);
}
.sheet-card .sc-head { display: flex; align-items: center; gap: 10px; }
/* 图标右侧那两行：图号 + 原始文件名 */
.sheet-card .sc-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.sheet-card .sc-ico {
    width: 42px; height: 42px;
    flex: none;
    display: grid; place-items: center;
    border: 1px solid #cfd8e4;
    border-radius: 10px;
    background: #fff;
    color: var(--brand);
}
html[data-theme="dark"] .sheet-card .sc-ico { border-color: #3a3a47; background: #1b1b23; }
.sheet-card .sc-ico svg { width: 24px; height: 24px; }
.sheet-card .sc-seq {
    flex: none;
    align-self: flex-start;
    padding: 1px 7px;
    border: 1px solid #d5dde8;
    border-radius: 9px;
    background: #fff;
    color: var(--ink-3);
    font-size: 11px;
    font-weight: 600;
    line-height: 1.6;
    font-variant-numeric: tabular-nums;
}
html[data-theme="dark"] .sheet-card .sc-seq { border-color: #3a3a47; background: #1b1b23; }
/* 图号 28 位，卡片宽度有限：最多折两行，靠 line-clamp 收口，避免被省略号吃掉后半段 */
.sheet-card .sc-no {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    margin-top: 0;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--ink);
    overflow: hidden;
    overflow-wrap: anywhere;
    word-break: break-all;
}
.sheet-card .sc-file {
    display: block;
    margin-top: 0;
    min-width: 0;
    font-size: 11px;
    line-height: 1.3;
    color: #6b7480;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
html[data-theme="dark"] .sheet-card .sc-file { color: var(--ink-3); }
.sheet-card .sc-file i { margin-left: 5px; font-style: normal; color: var(--muted); }
.sheet-card .sc-stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 6px;
    margin-top: 11px;
    padding-top: 9px;
    border-top: 1px solid #dbe2ec;
}
html[data-theme="dark"] .sheet-card .sc-stats { border-top-color: #33333f; }
.sheet-card .sc-stats > span { display: flex; align-items: baseline; gap: 4px; min-width: 0; }
.sheet-card .sc-stats b {
    font-size: 16px;
    font-weight: 600;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}
.sheet-card .sc-stats span span { font-size: 11.5px; color: var(--ink-3); white-space: nowrap; }

/* 当前正在看的那条总图纸：白底 + 品牌色实边 + 左侧色条，扫一眼就知道自己在哪一条。
   号位把「#序号」换成「当前」徽标，避免和选中边框抢注意力。 */
.sheet-card.is-on,
.sheet-card.is-on:hover {
    border-color: var(--brand);
    background: var(--panel);
    box-shadow: inset 3px 0 0 var(--brand), 0 2px 10px rgba(16, 24, 40, .08);
}
html[data-theme="dark"] .sheet-card.is-on,
html[data-theme="dark"] .sheet-card.is-on:hover {
    border-color: var(--brand);
    background: #2c2c38;
    box-shadow: inset 3px 0 0 var(--brand), 0 2px 10px rgba(0, 0, 0, .5);
}
.sheet-card.is-on .sc-ico {
    border-color: var(--brand);
    background: var(--brand);
    color: #fff;
}
.sheet-card .sc-on {
    flex: none;
    align-self: flex-start;
    padding: 1px 8px;
    border: 1px solid var(--brand);
    border-radius: 9px;
    background: var(--brand-50);
    color: var(--brand);
    font-size: 11px;
    font-weight: 600;
    line-height: 1.6;
    white-space: nowrap;
}
.sheet-folders .sf-cnt {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.sheet-folders > h2 .right form { display: inline-flex; margin: 0; }
@media (max-width: 720px) {
    .sheet-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; }
    .sheet-card { padding: 11px 12px; }
    .sheet-folders .sf-cnt { display: none; }
}

/* ── 图纸清单：左侧「图纸索引」栏（序号 / 切割指令 / 零件数量）──────
   「图纸」卡片本身变成两栏：标题横跨整行，下面左边索引栏、右边缩略图网格。
   索引栏 sticky 且自带滚动，84 张图纸也能快速定位；顶部搜索框即时过滤。 */
.dwg-card {
    /* 页内跳转到图纸卡片（#dwg）时留出 sticky 头部的高度，不被挡住 */
    scroll-margin-top: 108px;
    display: grid;
    grid-template-columns: 252px minmax(0, 1fr);
    grid-template-areas:
        "head head"
        "nav  grid";
    column-gap: 16px;
    align-items: start;
}
.dwg-card > h2 { grid-area: head; }
.dwg-card > .dwg-nav { grid-area: nav; }
.dwg-card > .thumb-grid { grid-area: grid; }

.dwg-nav {
    position: sticky;
    /* 站点头部是 sticky 的：header 56 + tabbar 42，吸顶时要让开这 98px，否则搜索框会被挡住 */
    top: 110px;
    display: flex;
    flex-direction: column;
    min-height: 260px;
    /* 高度跟着窗口走：铺满可视区（扣掉 56+42 的头部与下边距），不再固定 620px 上限。
       内容少也是整框，多了在 .dn-list 内部滚动，页面本身不再被索引栏撑高。 */
    height: calc(100vh - 122px);
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--panel-2);
    overflow: hidden;
}
.dn-search {
    position: relative;
    flex: none;
    padding: 8px;
    border-bottom: 1px solid var(--line);
    background: var(--panel);
}
.dn-search svg {
    position: absolute;
    left: 17px; top: 50%;
    width: 14px; height: 14px;
    transform: translateY(-50%);
    color: var(--muted);
    pointer-events: none;
}
.dn-search input {
    width: 100%;
    height: 30px;
    padding: 0 8px 0 26px;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: var(--panel);
    color: var(--ink);
    font-size: 12.5px;
}
.dn-search input:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 2px var(--brand-50);
}
.dn-list {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 1px;
    scrollbar-width: thin;
}
.dn-item {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr) 44px;
    align-items: center;
    gap: 7px;
    width: 100%;
    padding: 5px 7px;
    border: 0;
    border-radius: 7px;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: background .12s, box-shadow .12s;
}
.dn-item:hover { background: var(--brand-50); }
/* .dn-item 设了 display:grid，会盖掉浏览器给 [hidden] 的 display:none，这里补回来 */
.dn-item[hidden] { display: none; }
.dn-item:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.dn-item.is-on { background: var(--brand-50); box-shadow: inset 2px 0 0 var(--brand); }
.dn-item .dn-seq {
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-3);
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.dn-item .dn-cmd {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 5px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11.5px;
    color: var(--ink);
}
.dn-item .dn-cmd-t {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dn-item .dn-cnt {
    flex: none;
    font-size: 11px;
    color: var(--ink-3);
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* 索引表头：序号 / 切割指令 / 零件数，列宽与 .dn-item 完全对齐 */
/* 「全部图纸（N）」：搜索框下方的一行筛选复位入口，点亮＝当前没有过滤 */
.dn-all {
    flex: none;
    display: flex;
    align-items: baseline;
    gap: 4px;
    margin: 8px 8px 4px;
    padding: 6px 9px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--panel);
    color: var(--ink-2);
    font: inherit;
    font-size: 12.5px;
    text-align: left;
    text-decoration: none; /* 详情页上是 <a>，别带链接下划线 */
    cursor: pointer;
    transition: border-color .12s, background .12s, color .12s;
}
.dn-all:hover { border-color: var(--brand-100); color: var(--ink); text-decoration: none; }
.dn-all-n {
    margin-left: auto;
    font-weight: 500;
    color: var(--ink-3);
    font-variant-numeric: tabular-nums;
}
.dn-all.is-on {
    border-color: var(--brand);
    background: var(--brand-50);
    color: var(--brand);
    font-weight: 600;
}
.dn-all.is-on .dn-all-n { color: var(--brand); }

.dn-head {
    flex: none;
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr) 44px;
    gap: 7px;
    padding: 7px 13px 6px;
    border-bottom: 1px solid var(--line);
    background: var(--panel);
    font-size: 11px;
    font-weight: 500;
    color: var(--muted);
    letter-spacing: .2px;
}
.dn-head span:first-child,
.dn-head span:last-child { text-align: right; }
.dn-empty {
    margin: 0;
    padding: 12px 10px 14px;
    font-size: 12px;
    color: var(--muted);
    text-align: center;
}
.dn-empty[hidden] { display: none; }

/* ---------- 图纸详情（右侧：上部图纸 + 下部零件清单） ---------- */
.dwg-detail {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.dd-view {
    border: 1px solid var(--line);
    border-radius: 10px;
    overflow: hidden;
    background: var(--panel-2);
}
.dd-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--line);
    background: var(--panel);
}
.dd-title { display: flex; align-items: center; gap: 8px; min-width: 0; }
.dd-cmd {
    min-width: 0;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px;
    font-weight: 600;
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dd-tags { flex: none; display: flex; gap: 5px; }
.dd-act { flex: none; margin-left: auto; display: flex; gap: 6px; }
.dd-frame { background: #fff; }
.dd-frame iframe {
    display: block;
    width: 100%;
    /* 上部图纸占满一屏多半：再高零件清单就要滚很远才看得到 */
    height: clamp(420px, 60vh, 820px);
    border: 0;
    background: #fff;
}
html[data-theme="dark"] .dd-frame,
html[data-theme="dark"] .dd-frame iframe { background: #1b1b23; }

/* 大图：导入时按 1500 宽生成的 PNG，点一下进查看器 */
.dd-shot {
    margin: 0;
    padding: 10px;
    background: #fff;
    text-align: center;
}
.dd-shot img {
    display: block;
    margin: 0 auto;
    width: auto;
    height: auto;
    max-width: 100%;
    /* 详情页缩略图固定约 500px 高，看细节点开大图 */
    max-height: 500px;
    cursor: zoom-in;
}
.dd-shot figcaption {
    margin-top: 6px;
    font-size: 11.5px;
    color: var(--muted);
}
html[data-theme="dark"] .dd-shot { background: #14141a; }

/* 多页图纸：每页保持同样高度，横向并排、可左右滑动看后面几页 */
.dd-strip {
    display: flex;
    gap: 10px;
    padding: 10px;
    overflow-x: auto;
    overflow-y: hidden;
    background: #fff;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
}
.dd-strip .dd-sheet {
    flex: none;
    padding: 0;
    margin: 0;
    scroll-snap-align: start;
}
.dd-strip .dd-sheet img {
    /* 不改高度：跟单页一样最多 500px，宽度按比例，不压缩不变形 */
    max-height: 500px;
    max-width: none;
    width: auto;
}
.dd-strip .dd-sheet figcaption { padding-bottom: 2px; }
html[data-theme="dark"] .dd-strip { background: #14141a; }

/* ---------- 大图查看器 ---------- */
.pv-box {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: flex;
    flex-direction: column;
    /* 半透明遮罩：能看见下面的页面轮廓，又不至于干扰看图 */
    background: rgba(8, 10, 14, .68);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}
.pv-box[hidden] { display: none; }
.pv-bar {
    flex: none;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 14px;
    background: rgba(0, 0, 0, .35);
    color: #e6e8ee;
    font-size: 12.5px;
    flex-wrap: wrap;
    row-gap: 8px;
}
.pv-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    color: #cfd4de;
}
.pv-ctrl { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.pv-ctrl button,
.pv-ctrl .pv-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 30px;
    min-width: 30px;
    padding: 0 10px;
    border: 1px solid rgba(255, 255, 255, .22);
    border-radius: 7px;
    background: rgba(255, 255, 255, .07);
    color: #e6e8ee;
    font-size: 12.5px;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
}
.pv-ctrl button:hover,
.pv-ctrl .pv-link:hover { background: rgba(255, 255, 255, .16); }
#pvPct {
    min-width: 46px;
    text-align: center;
    font-variant-numeric: tabular-nums;
    color: #cfd4de;
}
.pv-stage {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 16px;
    overflow: auto;
    cursor: grab;
}
.pv-stage.is-drag { cursor: grabbing; }
.pv-stage img {
    display: block;
    max-width: none;
    background: #fff;
    box-shadow: 0 12px 44px rgba(0, 0, 0, .55);
}
/* 手机上工具条放不下一行：标题独占一行，按钮平分第二行 */
@media (max-width: 640px) {
    .pv-bar { padding: 8px 10px; }
    .pv-name { flex: 1 1 100%; }
    .pv-ctrl {
        margin-left: 0;
        width: 100%;
        justify-content: space-between;
        gap: 6px;
    }
    .pv-ctrl button,
    .pv-ctrl .pv-link { padding: 0 8px; font-size: 12px; }
}
.dd-none {
    margin: 0;
    padding: 26px 14px;
    font-size: 12.5px;
    color: var(--muted);
    text-align: center;
}

/* 详情页：预览图还没生成时的占位（代替原来内嵌 PDF 的 iframe） */
.dd-noshot {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 260px;
    margin: 10px;
    padding: 30px 20px;
    border: 1.5px dashed var(--line);
    border-radius: 10px;
    background: #fbfbfd;
    text-align: center;
}
.dd-noshot-ico {
    width: 46px;
    height: 46px;
    color: #c3c9d4;
    margin-bottom: 2px;
}
.dd-noshot-tt {
    margin: 0;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text);
}
.dd-noshot-tip {
    margin: 0;
    font-size: 12px;
    color: var(--muted);
    max-width: 380px;
    line-height: 1.65;
}
.dd-noshot .btn { margin-top: 6px; }
.dd-noshot .btn:disabled { opacity: .7; cursor: default; }
html[data-theme="dark"] .dd-noshot { background: #14141a; }
html[data-theme="dark"] .dd-noshot-ico { color: #4a505c; }
.dd-pages {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 8px 12px;
    border-top: 1px solid var(--line);
    background: var(--panel);
}
.dd-pg {
    height: 26px;
    padding: 0 11px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--panel-2);
    color: var(--ink-2);
    font-size: 12px;
    cursor: pointer;
}
.dd-pg:hover { border-color: var(--brand-100); color: var(--ink); }
.dd-pg.is-on {
    border-color: var(--brand);
    background: var(--brand-50);
    color: var(--brand);
    font-weight: 600;
}
.dd-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 20px;
    padding: 9px 12px;
    /* 信息条在图纸上方：上下都加分隔线 */
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    background: var(--panel);
    font-size: 12.5px;
    color: var(--ink-2);
}
.dd-meta i { margin-right: 6px; font-style: normal; color: var(--muted); }
.dd-meta .mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-weight: 500;
}
.dd-parts h3 {
    display: flex;
    align-items: center;
    margin: 0 0 9px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ink);
}
.dd-parts h3 .right { margin-left: auto; font-size: 12.5px; font-weight: 400; color: var(--ink-3); }
.dd-parts h3 .right b { color: var(--ink); font-weight: 600; }
.dd-parts .table-wrap {
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--panel);
    /* 零件多的图纸（几十上百件）也只在表内滚，不把整页拉长 */
    max-height: 560px;
    overflow: auto;
}
.dd-parts .table-wrap thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--thead-bg);
}

@media (max-width: 960px) {
    .dwg-card {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas:
            "head"
            "nav"
            "grid";
        row-gap: 12px;
    }
    .dwg-nav { position: static; height: min(58vh, 380px); min-height: 0; }
}

/* ---------- 图纸画布（测试功能） ---------- */
.dc-box {
    position: fixed;
    inset: 0;
    z-index: 1260;
    display: flex;
    flex-direction: column;
    gap: 0;
    padding: 18px;
    background: rgba(8, 10, 14, .72);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
}
.dc-box[hidden] { display: none; }
.dc-bar {
    flex: none;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    row-gap: 8px;
    padding: 9px 12px;
    border-radius: 10px 10px 0 0;
    background: var(--panel);
    border-bottom: 1px solid var(--line);
}
.dc-title {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ink);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    max-width: 60vw;
    white-space: nowrap;
}
/* 标题里的图号部分：太长才省略，不能把后面的统计和状态挤掉 */
.dc-title .dc-tt-name {
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}
/* 已识别 N 块 / 共 M 件：数字单独给 class，方便和正文区分 */
.dc-title .dc-tt-nums {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    flex: none;
    font-size: 12px;
    font-weight: 400;
    color: var(--ink-3);
    font-family: -apple-system, "Segoe UI", "Microsoft YaHei", sans-serif;
}
.dc-title .dc-n {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px;
    font-weight: 700;
    color: var(--brand);
    padding: 0 1px;
}
.dc-title .dc-n.is-bad { color: #D92D20; }
/* 清单件数：分母是「本页块数」时，把清单总件数作为补充信息放在旁边，
   不参与比较，所以压暗、字号小一号 */
.dc-title .dc-tt-sub {
    flex: none;
    font-size: 11.5px;
    color: var(--ink-4, var(--ink-3));
    opacity: .8;
    font-family: -apple-system, "Segoe UI", "Microsoft YaHei", sans-serif;
}
.dc-title .dc-slash {
    font-style: normal;
    color: var(--line);
    margin: 0 2px;
}
/* 识别状态胶囊：三态三色 */
.dc-title .dc-st {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex: none;
    height: 20px;
    padding: 0 8px;
    border-radius: 10px;
    font-size: 11.5px;
    font-weight: 600;
    font-family: -apple-system, "Segoe UI", "Microsoft YaHei", sans-serif;
}
.dc-title .dc-st .dc-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}
.dc-title .dc-st-none { color: var(--ink-3); background: var(--panel-2); border: 1px dashed var(--line); }
.dc-title .dc-st-ok   { color: #0E9F6E; background: rgba(18,183,106,.10); border: 1px solid rgba(18,183,106,.28); }
.dc-title .dc-st-bad  { color: #D92D20; background: rgba(240,68,56,.10);  border: 1px solid rgba(240,68,56,.28); }
.dc-tabs { display: flex; gap: 6px; }
.dc-tab {
    height: 26px;
    padding: 0 10px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--panel-2);
    color: var(--ink-2);
    font-size: 12px;
    cursor: pointer;
}
.dc-tab.is-on { background: var(--brand); border-color: var(--brand); color: #fff; }
.dc-ctrl { margin-left: auto; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.dc-ctrl button {
    height: 28px;
    min-width: 28px;
    padding: 0 10px;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: var(--panel-2);
    color: var(--ink-2);
    font-size: 12.5px;
    cursor: pointer;
}
.dc-ctrl button:hover { border-color: var(--brand); color: var(--brand); }
.dc-ctrl button.is-on { background: var(--brand); border-color: var(--brand); color: #fff; }
/* 工具条里的「AI 识别」：紧跟在自动识别后面，用品牌色描边区分 */
.dc-ctrl button#dcAiBtn { border-color: var(--brand); color: var(--brand); }
.dc-ctrl button#dcAiBtn:hover { background: #fff; }
.dc-ctrl button#dcAiBtn:disabled { opacity: .55; cursor: default; }
/* 工具条最右侧「关闭」：主题色实底，和页头主按钮同款 */
.dc-ctrl button#dcCloseBtn {
    background: var(--brand);
    border-color: var(--brand);
    color: #fff;
    font-weight: 500;
}
.dc-ctrl button#dcCloseBtn:hover { background: var(--brand-hover); border-color: var(--brand-hover); color: #fff; }
.dc-ctrl button#dcCloseBtn:active { background: var(--brand-pressed); border-color: var(--brand-pressed); }
#dcPct {
    min-width: 46px;
    text-align: center;
    font-size: 12px;
    color: var(--ink-3);
    font-variant-numeric: tabular-nums;
}
.dc-main {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    background: var(--panel);
    border-radius: 0 0 10px 10px;
    overflow: hidden;
}
.dc-stage {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    background:
        linear-gradient(0deg, rgba(0, 0, 0, .04) 1px, transparent 1px) 0 0/24px 24px,
        linear-gradient(90deg, rgba(0, 0, 0, .04) 1px, transparent 1px) 0 0/24px 24px,
        #1a1d24;
    cursor: grab;
    touch-action: none;
}
.dc-stage.is-drag { cursor: grabbing; }
.dc-world {
    position: absolute;
    left: 0;
    top: 0;
    transform-origin: 0 0;
    will-change: transform;
}
.dc-world img {
    display: block;
    max-width: none;
    background: #fff;
    box-shadow: 0 10px 40px rgba(0, 0, 0, .5);
    user-select: none;
    -webkit-user-drag: none;
}
/* pdf.js 渲染出来的底图：位置/尺寸由脚本按「可视区」动态设置 */
#dcCanvas {
    position: absolute;
    left: 0;
    top: 0;
    display: block;
    background: #fff;
    box-shadow: 0 10px 40px rgba(0, 0, 0, .5);
}
#dcCanvas[hidden] { display: none; }
#dcSvg {
    position: absolute;
    left: 0;
    top: 0;
    overflow: visible;
}
.dc-poly {
    /* 自动识别出来的热区要「看得见但别抢戏」：淡淡的一层红底 + 一圈细线。
       红色是车间标注/切割的惯用色，和图纸的黑白线条对比也最清楚。 */
    fill: rgba(240, 68, 56, .10);
    stroke: rgba(240, 68, 56, .45);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
    cursor: pointer;
    transition: fill .12s, stroke .12s;
}
.dc-poly.is-hot { fill: rgba(240, 68, 56, .26); stroke: #f04438; }
.dc-poly.is-sel { fill: rgba(208, 48, 80, .34); stroke: #d03050; stroke-width: 2.5; }
.dc-hint {
    position: absolute;
    left: 50%;
    top: 18px;
    transform: translateX(-50%);
    margin: 0;
    padding: 7px 14px;
    border-radius: 999px;
    background: rgba(0, 0, 0, .62);
    color: #e9ecf2;
    font-size: 12.5px;
    white-space: nowrap;
}
.dc-tip {
    position: absolute;
    padding: 4px 8px;
    border-radius: 6px;
    background: rgba(0, 0, 0, .78);
    color: #fff;
    font-size: 12px;
    pointer-events: none;
    white-space: nowrap;
    z-index: 3;
}
.dc-side {
    flex: none;
    width: 340px;
    display: flex;
    flex-direction: column;
    min-height: 0;
    border-left: 1px solid var(--line);
    background: var(--panel);
}
.dc-side-h {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 12px 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ink);
}
.dc-side-h span { color: var(--ink-3); font-weight: 400; font-size: 12px; }
.dc-search { flex: none; padding: 0 12px 8px; }
.dc-search input {
    width: 100%;
    height: 30px;
    padding: 0 10px;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: var(--input-bg);
    color: var(--ink);
    font-size: 12.5px;
}
.dc-list { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 8px 8px; }
.dc-tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.dc-tbl thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    padding: 6px 6px;
    background: var(--thead-bg);
    color: var(--ink-3);
    font-weight: 500;
    text-align: left;
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}
.dc-tbl thead th:nth-child(1) { width: 26px; }
.dc-tbl thead th:nth-child(3) { width: 48px; }
.dc-row { cursor: pointer; }
.dc-row td { padding: 6px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
.dc-row:hover, .dc-row.is-hot { background: rgba(24, 144, 255, .08); }
.dc-row.is-sel { background: rgba(24, 160, 88, .10); box-shadow: inset 3px 0 0 var(--brand); }
.dc-row.is-sel .dc-code { color: var(--brand); font-weight: 600; }
.dc-ck input { width: 14px; height: 14px; accent-color: var(--brand); cursor: pointer; }
.dc-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 150px;
}
.dc-qty { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink-2); }
.dc-note { color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 70px; }
.dc-stat {
    flex: none;
    display: flex;
    gap: 10px;
    padding: 10px 12px;
    border-top: 1px solid var(--line);
    background: var(--panel-2);
}
.dc-stat div {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 7px 10px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--panel);
}
.dc-stat span { font-size: 11.5px; color: var(--ink-3); }
.dc-stat b { font-size: 18px; color: var(--brand); font-variant-numeric: tabular-nums; }
.dc-acts { flex: none; display: flex; gap: 8px; padding: 0 12px 12px; }
.dc-acts .btn { flex: 1 1 0; justify-content: center; }
.dc-toast {
    position: fixed;
    left: 50%;
    bottom: 42px;
    transform: translateX(-50%);
    padding: 8px 18px;
    border-radius: 999px;
    background: rgba(0, 0, 0, .82);
    color: #fff;
    font-size: 13px;
    z-index: 3;
}
.dc-toast[hidden] { display: none; }
@media (max-width: 900px) {
    .dc-box { padding: 0; }
    .dc-bar, .dc-main { border-radius: 0; }
    .dc-side { width: 46vw; min-width: 240px; }
}

/* gen 压缩包上传：小按钮 + 隐藏 file，选完自动提交 */
.gen-up { display: inline-block; margin-right: 6px; }
.gen-up label.btn { cursor: pointer; }
/* 这个按钮现在是实底主题色：hover 只加深背景，文字必须保持白色，
   不能再沿用 ghost 时代的「文字变主题色」（否则绿底绿字看不清） */
.gen-up label.btn:hover {
    border-color: var(--brand-hover);
    background: var(--brand-hover);
    color: #fff;
}

/* ── 画布里的 gen 文件查看 ─────────────────────────── */
.dc-ctrl button#dcGenBtn { border-color: var(--brand); color: var(--brand); }
.dc-ctrl button#dcGenBtn:hover { background: #fff; }
.dc-ctrl button#dcGenBtn.is-on { background: var(--brand); border-color: var(--brand); color: #fff; }
.dc-gen { position: absolute; inset: 0; z-index: 6; display: flex; flex-direction: column; background: #0f1115; }
.dc-gen[hidden] { display: none; }
.dc-gen-bar { flex: none; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 8px 12px; background: #171a21; border-bottom: 1px solid #262b35; color: #d7dbe0; }
.dc-gen-bar b { font: 600 12.5px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: #e8ecf2; }
.dc-gen-bar span { font-size: 11.5px; color: #8b93a1; }
.dc-gen-bar input { flex: 1 1 220px; min-width: 150px; height: 28px; padding: 0 9px;
    border: 1px solid #2c323d; border-radius: 6px; background: #0f1115; color: #d7dbe0;
    font: inherit; font-size: 12.5px; outline: none; }
.dc-gen-bar input:focus { border-color: #4b6b9c; }
.dc-gen-dl, .dc-gen-bar button { flex: none; height: 28px; padding: 0 10px; border-radius: 6px;
    border: 1px solid #2c323d; background: #1d222b; color: #cfd6e2; font: inherit; font-size: 12.5px;
    display: inline-flex; align-items: center; text-decoration: none; cursor: pointer; white-space: nowrap; }
.dc-gen-dl:hover, .dc-gen-bar button:hover { border-color: #4b6b9c; color: #fff; }
.dc-gen-legend { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: #8b93a1;
    white-space: nowrap; }
.dc-gen-legend > i { width: 11px; height: 11px; border-radius: 2px; display: inline-block; flex: none; }
.dc-gen-legend .lg-arc { background: rgba(61,139,253,.28); border: 1px solid #3d8bfd; }
.dc-gen-legend .lg-rect { background: rgba(245,158,11,.22); border: 1px dashed #f59e0b; }
.dc-gen-legend > b { color: #d7dbe0; font-weight: 600; font-size: 11.5px; }

.dc-gen-body { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; background: #0e1117; }
.dc-gen-body svg { display: block; width: 100%; height: 100%; cursor: grab; touch-action: none; }
.dc-gen-body svg.is-grab { cursor: grabbing; }
/* 线宽不随缩放变粗（vector-effect），否则放大后轮廓线糊成一团 */
.dcg-plate { fill: #151a22; stroke: #46536b; stroke-width: 1; vector-effect: non-scaling-stroke; }
.dcg-part { fill: rgba(61,139,253,.13); stroke: #3d8bfd; stroke-width: 1;
    vector-effect: non-scaling-stroke; transition: fill .12s; }
.dcg-part:hover { fill: rgba(61,139,253,.34); }
.dcg-part.is-rect { fill: rgba(245,158,11,.12); stroke: #f59e0b; stroke-dasharray: 5 4; }
.dcg-part.is-rect:hover { fill: rgba(245,158,11,.3); }
.dcg-part.is-hi { fill: rgba(250,204,21,.4); stroke: #facc15; stroke-width: 1.8; }
.dcg-label { fill: #8fa6c2; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    pointer-events: none; letter-spacing: .2px; }

.dc-gen-empty { position: absolute; inset: 0; margin: 0; display: flex; align-items: center;
    justify-content: center; color: #8b93a1; font-size: 13px; }
.dc-gen-empty[hidden] { display: none; }

.dc-gen-tip { position: absolute; left: 0; top: 0; z-index: 3; pointer-events: none;
    padding: 7px 10px; border-radius: 8px; background: rgba(20,24,31,.96);
    border: 1px solid #2f3742; box-shadow: 0 8px 24px rgba(0,0,0,.45);
    color: #cfd6e2; font-size: 11.5px; line-height: 1.65; max-width: 320px; }
.dc-gen-tip[hidden] { display: none; }
.dc-gen-tip b { display: block; color: #e8ecf2; font-weight: 600; font-size: 12px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; word-break: break-all; }
.dc-gen-tip span { display: block; color: #8b93a1; }

/* ══════════════════════════════════════════════════════════
   图纸清单 · gen 覆盖率 + 批量上传弹窗
   ══════════════════════════════════════════════════════════ */
.sheet-folders .sf-gen {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 8px 2px 6px;
    border: 1px solid var(--line);
    border-radius: 20px;
    background: var(--panel-2);
    color: var(--ink-3);
    font-size: 11.5px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    line-height: 1.7;
}
.sheet-folders .sf-gen > svg { color: #9ca3af; display: block; flex: none; }
.sheet-folders .sf-gen b { color: var(--ok); font-weight: 600; }
.sheet-folders .sf-gen i {
    font-style: normal;
    color: var(--warn);
    padding-left: 5px;
    border-left: 1px solid var(--line);
    margin-left: 1px;
}
.sheet-folders .sf-gen-btn { display: inline-flex; align-items: center; gap: 5px; }
.sheet-folders .sf-gen-btn svg { width: 14px; height: 14px; flex: none; }

.genb-modal { max-width: 620px; }
.genb-modal h3 .genb-sub {
    margin-left: 6px;
    font-size: 12px;
    font-weight: 400;
    color: var(--ink-3);
}
.genb-sum {
    padding: 13px 15px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--panel-2);
}
.genb-nums { display: flex; align-items: flex-end; gap: 26px; }
.genb-nums .gsp { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.genb-nums b {
    font-size: 23px;
    line-height: 1.1;
    font-weight: 600;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}
.genb-nums .gsp i { font-style: normal; font-size: 11.5px; color: var(--ink-3); white-space: nowrap; }
.genb-nums .gsp.is-ok b { color: var(--ok); }
.genb-nums .gsp.is-miss b { color: var(--warn); }
.genb-bar {
    height: 6px;
    margin-top: 11px;
    border-radius: 3px;
    background: var(--track);
    overflow: hidden;
}
.genb-bar i {
    display: block;
    height: 100%;
    border-radius: 3px;
    background: linear-gradient(90deg, var(--brand), #52c41a);
    transition: width .35s ease;
}
.genb-note { margin: 8px 0 0; font-size: 12px; color: var(--ink-3); line-height: 1.6; }

.genb-missing { margin-top: 12px; }
.genb-lb { font-size: 12px; font-weight: 600; color: var(--ink-2); }
.genb-missing .genb-lb span { color: var(--warn); font-variant-numeric: tabular-nums; }
.genb-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin-top: 6px;
    max-height: 84px;
    overflow: auto;
}
.genb-chips code {
    padding: 2px 6px;
    border: 1px solid var(--line);
    border-radius: 4px;
    background: var(--panel-3);
    color: var(--ink-2);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11.5px;
    line-height: 1.6;
}

.genb-drop {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 14px;
    padding: 13px 14px;
    border: 1px dashed #c6cfdb;
    border-radius: var(--radius);
    background: var(--panel-2);
    cursor: pointer;
    transition: border-color .16s, background .16s;
}
.genb-drop:hover,
.genb-drop.is-over { border-color: var(--brand); background: var(--brand-fade); }
.genb-drop input[type="file"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}
.genb-drop-ico {
    width: 40px; height: 40px;
    flex: none;
    display: grid; place-items: center;
    border-radius: 10px;
    background: var(--brand-50);
    color: var(--brand);
}
.genb-drop-ico svg { width: 22px; height: 22px; }
.genb-drop-tt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.genb-drop-tt b { font-size: 13px; font-weight: 600; color: var(--ink); }
.genb-drop-tt i { font-style: normal; font-size: 11.5px; color: var(--ink-3); line-height: 1.5; }
.genb-pick {
    flex: none;
    max-width: 128px;
    text-align: right;
    font-size: 11.5px;
    color: var(--ink-3);
    font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
}

.genb-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 12px;
    margin-top: 14px;
}
.genb-radio {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 11px;
    border: 1px solid var(--line);
    border-radius: 20px;
    background: var(--panel);
    font-size: 12.5px;
    color: var(--ink-2);
    cursor: pointer;
    transition: border-color .16s, background .16s, color .16s;
}
.genb-radio input { margin: 0; accent-color: var(--brand); }
.genb-radio.is-on { border-color: var(--brand); background: var(--brand-50); color: var(--brand); }
.genb-hint { flex: 1 1 100%; font-size: 11.5px; color: var(--ink-3); }
.genb-check {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-top: 12px;
    font-size: 12.5px;
    color: var(--ink-2);
    cursor: pointer;
}
.genb-check input { margin: 0; accent-color: var(--brand); }

.genb-res {
    margin-top: 14px;
    padding: 12px 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--panel-2);
    font-size: 12.5px;
    color: var(--ink-2);
    max-height: 260px;
    overflow: auto;
}
.genb-res-main { font-size: 13px; color: var(--ink); }
.genb-res-main b { color: var(--ok); font-size: 16px; font-variant-numeric: tabular-nums; }
.genb-res em { font-style: normal; font-weight: 600; }
.genb-res .is-warn { color: var(--warn); }
.genb-res .is-bad { color: var(--err); }
.genb-res-sub { margin: 5px 0 0; color: var(--ink-3); }
.genb-res-list { margin-top: 9px; }
.genb-res-list > span { font-size: 11.5px; font-weight: 600; color: var(--ink-3); }
.genb-res-prog { margin: 10px 0 0; padding-top: 9px; border-top: 1px dashed var(--line); color: var(--ink-3); }
.genb-res-prog.is-done { color: var(--ok); }
.genb-res-err { color: var(--err); }

html[data-theme="dark"] .sheet-folders .sf-gen { border-color: #33333f; background: #1d1d24; }
html[data-theme="dark"] .genb-drop { border-color: #3a3a47; }

@media (max-width: 720px) {
    .sheet-folders .sf-gen { display: none; }
    .genb-nums { gap: 18px; }
    .genb-nums b { font-size: 20px; }
    .genb-drop { flex-wrap: wrap; }
    .genb-pick { max-width: none; text-align: left; padding-left: 52px; }
}
.sheet-folders > h2 .right { flex-wrap: wrap; justify-content: flex-end; }

/* ── 切割任务明细：图纸序号 + 图纸状态 ────────────── */
td.nst-seq {
    text-align: center;
    color: var(--ink-3);
    font-variant-numeric: tabular-nums;
    font-size: 12px;
}
td.nst { white-space: nowrap; }
td.nst .tag { margin: 1px 4px 1px 0; }
td.nst .tag:last-child { margin-right: 0; }
td.nst .nst-none { color: var(--ink-3); }

/* 切割任务明细：切割指令本身可点开详情（和「详情」按钮同一个页面） */
td .nst-cmd {
    color: var(--brand);
    font-weight: 600;
    text-decoration: none;
    border-bottom: 1px dashed color-mix(in srgb, var(--brand) 45%, transparent);
    transition: border-color .14s, color .14s;
}
td .nst-cmd:hover { border-bottom-color: var(--brand); border-bottom-style: solid; }
td .nst-cmd:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 3px; }

/* 批量上传失败时的诊断信息（服务器实际返回的片段） */
.genb-res-raw {
    margin: 8px 0 0;
    padding: 8px 10px;
    max-height: 120px;
    overflow: auto;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--panel-3);
    color: var(--ink-3);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11px;
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-all;
}

/* ── 图纸清单：本批次总图纸（7） + 前附表（3）并排 ───────────── */
.doc-top {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 3fr);
    gap: 16px;
    align-items: start;
    margin-bottom: 16px;
}
.doc-top.is-single { grid-template-columns: minmax(0, 1fr); }
.doc-top > .card { margin-bottom: 0; }

/* 前附表目录：页码 / 名称 / 查看 */
.front-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.front-table th,
.front-table td {
    padding: 8px 6px;
    border-bottom: 1px dashed var(--line);
    text-align: left;
    vertical-align: middle;
}
.front-table th {
    padding-top: 0;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ink-3);
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}
.front-table tbody tr:last-child td { border-bottom: none; }
.front-table .ft-page { width: 1%; white-space: nowrap; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.front-table .ft-act { width: 1%; text-align: right; white-space: nowrap; }
.front-table .fi-kind {
    display: inline-block;
    max-width: 100%;
    padding: 0 8px;
    height: 20px;
    line-height: 20px;
    border-radius: 10px;
    border: 1px solid var(--info-line);
    background: var(--info-bg);
    color: var(--info);
    font-size: 11px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
html[data-theme="dark"] .front-table .fi-kind { border-color: #2f4d6b; background: #17283a; color: #7cc0ff; }

@media (max-width: 1180px) {
    .doc-top { grid-template-columns: minmax(0, 1fr); }
}

/* ── 本批次总图纸：横向滑动，不再换行撑高；前附表与之等高 ───── */
.doc-top { align-items: stretch; }
.doc-top > .card { min-width: 0; }
.sheet-folders .sheet-grid {
    display: flex;
    flex-wrap: nowrap;
    gap: 12px;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 2px 2px 8px;
    scroll-snap-type: x proximity;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
}
.sheet-folders .sheet-card {
    flex: 0 0 260px;
    scroll-snap-align: start;
}
.sheet-folders .sheet-grid::-webkit-scrollbar { height: 6px; }
.sheet-folders .sheet-grid::-webkit-scrollbar-track { background: transparent; }
.sheet-folders .sheet-grid::-webkit-scrollbar-thumb { background: #cfd6e0; border-radius: 3px; }
html[data-theme="dark"] .sheet-folders .sheet-grid::-webkit-scrollbar-thumb { background: #3a3a47; }

/* 前附表：去掉表头，靠图标区分类型；行在原高度内垂直居中 */
.front-docs { display: flex; flex-direction: column; }
.front-docs .table-wrap {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    justify-content: safe center;
    overflow: auto;
}
.front-table { width: 100%; height: auto; }
.front-table td { padding: 7px 4px; }
.front-table .ft-name { white-space: nowrap; }
.front-table .ft-ico {
    width: 24px;
    height: 24px;
    margin-right: 8px;
    display: inline-grid;
    place-items: center;
    vertical-align: middle;
    border-radius: 7px;
    background: var(--panel-3);
    color: var(--ink-3);
}
.front-table .ft-ico svg { width: 14px; height: 14px; }
.front-table .ft-ico.k-history  { background: var(--info-bg); color: var(--info); }
.front-table .ft-ico.k-material { background: var(--warn-bg); color: var(--warn); }
.front-table .ft-ico.k-note     { background: var(--core-bg); color: var(--core); }
.front-table .ft-name-tx { font-size: 12.5px; font-weight: 500; color: var(--ink); vertical-align: middle; }

@media (max-width: 720px) {
    .sheet-folders .sheet-card { flex-basis: 220px; }
}

/* ── 总图纸卡片加宽 20%（260→312）并压矮；前附表跟着降高度 ───── */
.sheet-folders { padding: 13px 16px; }
.sheet-folders > h2 { margin-bottom: 10px; padding-bottom: 9px; }
.sheet-folders .sheet-grid { padding-bottom: 6px; }
.sheet-folders .sheet-card {
    flex: 0 0 312px;
    padding: 10px 12px 11px;
}
.sheet-folders .sheet-card .sc-ico { width: 36px; height: 36px; border-radius: 9px; }
.sheet-folders .sheet-card .sc-ico svg { width: 21px; height: 21px; }
.sheet-folders .sheet-card .sc-no { font-size: 12px; line-height: 1.3; }
.sheet-folders .sheet-card .sc-file { font-size: 10.5px; }
.sheet-folders .sheet-card .sc-stats { margin-top: 8px; padding-top: 7px; }
.sheet-folders .sheet-card .sc-stats b { font-size: 15px; }

.front-docs { padding: 13px 16px; }
.front-docs > h2 { margin-bottom: 8px; padding-bottom: 8px; }
.front-docs > h2 .right form { display: inline-flex; margin: 0; }
.front-docs > h2 .right .btn { height: 26px; padding: 0 9px; font-size: 12px; }
.front-table td { padding: 4px; }
.front-table .ft-ico { width: 22px; height: 22px; border-radius: 6px; }
.front-table .ft-ico svg { width: 13px; height: 13px; }

@media (max-width: 720px) {
    .sheet-folders .sheet-card { flex-basis: 264px; }
}

/* 图纸清单页头：用批次号替代「N 张」，做成醒目的实底徽标 */
.page-head h1 .ph-meta.is-batch {
    padding: 3px 11px;
    border-color: var(--brand);
    background: var(--brand);
    color: #fff;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .5px;
    box-shadow: 0 1px 3px rgba(16, 24, 40, .16);
}

/* ── 图纸缩略图卡片：整体缩小 30%，序号改成实底徽标 ───────── */
.thumb-grid {
    grid-template-columns: repeat(auto-fill, 156px);
    justify-content: start;
    gap: 10px;
}
.tcard .tc-body { padding: 8px 9px 9px; }
.tcard .tc-top { gap: 4px; row-gap: 3px; margin-bottom: 4px; }

/* 序号：品牌色实底 + 白字，做成一眼能看到的图标 */
.tcard .tc-seq {
    width: 24px;
    height: 24px;
    border-radius: 7px;
    background: var(--brand);
    color: #fff;
    font-size: 12px;
    font-weight: 700;
    line-height: 24px;
    box-shadow: 0 1px 3px rgba(16, 24, 40, .22);
}

.tcard .tc-info { font-size: 11px; }
.tcard .tc-cmdrow { gap: 4px; }
.tcard .tc-cmd { font-size: 11px; }
.tcard .tc-batch { padding: 0 5px; font-size: 10px; }
.tcard .hot-badge { width: 18px; height: 18px; right: 5px; top: 5px; }
.tcard .hot-badge svg { width: 11px; height: 11px; }
.tcard .tc-multi { height: 16px; line-height: 16px; padding: 0 5px; font-size: 10px; right: 5px; bottom: 5px; }
.tcard .gen-badge svg,
.tcard .hot-badge2 svg { width: 11px; height: 11px; }
.tcard .tc-ai { font-size: 10.5px; padding: 1px 6px; }

/* ── 图纸卡片「纸面化」────────────────────────────────────────
   每张缩略图外面留一圈白边 + 一层浅灰衬底，缩略图本身带细边框和投影，
   看起来就是一张张摊开的图纸，而不是把图片直接贴在卡片上。 */
.tcard {
    border-radius: 5px;
    border-color: rgba(16, 24, 40, .10);
    background: var(--panel);
    box-shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 6px 16px rgba(16, 24, 40, .06);
}
.tcard:hover {
    transform: translateY(-3px);
    border-color: var(--brand-100);
    box-shadow: 0 12px 26px rgba(16, 24, 40, .11);
}
.tcard .tc-art {
    padding: 6px;
    background: var(--panel-3);
    border-bottom: 1px solid var(--line-soft);
}
.tcard .tc-art img {
    border: 1px solid rgba(16, 24, 40, .16);
    border-radius: 1px;
    box-shadow: 0 1px 3px rgba(16, 24, 40, .10);
}
/* 悬停时图纸本身也轻轻抬一层，纸感更明显 */
.tcard:hover .tc-art img { box-shadow: 0 2px 7px rgba(16, 24, 40, .16); }
/* 角标跟着缩略图内缩，别压到纸边外面 */
.tcard .hot-badge { right: 9px; top: 9px; }
.tcard .tc-multi { right: 9px; bottom: 9px; }
.tcard.is-bad { border-color: var(--err-line); }
html[data-theme="dark"] .tcard {
    border-color: var(--line);
    box-shadow: 0 1px 2px rgba(0, 0, 0, .45), 0 4px 12px rgba(0, 0, 0, .30);
}
html[data-theme="dark"] .tcard .tc-art img { border-color: rgba(255, 255, 255, .18); }

@media (max-width: 720px) {
    .thumb-grid { grid-template-columns: repeat(auto-fill, 140px); gap: 8px; }
    .tcard .tc-art { padding: 5px; }
    .tcard .hot-badge { right: 8px; top: 8px; }
    .tcard .tc-multi { right: 8px; bottom: 8px; }
    .tcard .tc-seq { width: 22px; height: 22px; line-height: 22px; font-size: 11px; }
}

/* 卡片再压一档：正文区收紧，整体高度跟着宽度一起降 30% */
.tcard .tc-body { padding: 6px 8px; }
.tcard .tc-top { gap: 3px; row-gap: 2px; margin-bottom: 2px; }
.tcard .tc-seq { width: 22px; height: 22px; line-height: 22px; border-radius: 6px; font-size: 11.5px; }
.tcard .tc-info { font-size: 10.5px; }
.tcard .tc-cmdrow { gap: 3px; }
.tcard .tc-cmd { font-size: 10.5px; line-height: 1.2; }
.tcard .tc-batch { padding: 0 4px; font-size: 9.5px; }
.tcard .gen-badge svg,
.tcard .hot-badge2 svg { width: 10px; height: 10px; }
/* 指令号保持 11px，缩小后仍要能读清 */
.tcard .tc-cmd { font-size: 11px; }

/* 「本批次的总图纸」标题里的批次号：用主题色，和灰色正文拉开 */
.sheet-folders > h2 .sf-batch {
    margin-right: 2px;
    color: var(--brand);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-weight: 700;
    letter-spacing: .3px;
}

/* 左侧图纸索引：加宽切割指令列，长指令（19 位）也能完整显示 */
@media (min-width: 961px) {
    .dwg-card { grid-template-columns: 300px minmax(0, 1fr); }
}
.dn-item .dn-cmd { font-size: 12px; }

/* ── 材料清单：加了批次侧栏后右侧变窄，长文本列限宽省略 + 紧排，避免整表横向滚动 ── */
.mat-docs th,
.mat-docs td { padding-left: 8px; padding-right: 8px; }
.mat-docs th.md-num,
.mat-docs td.md-num { padding-left: 5px; padding-right: 5px; }
.mat-docs th.md-wrap { white-space: normal; line-height: 1.22; text-align: right; }
.mat-docs .md-clip {
    display: inline-block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}
/* 文件名做成链接并完整显示：用户要一眼看全清单文件名，不截断。
   超长文件名折行（而不是省略号），列宽固定 360px，整表仍在右侧栏宽度内 */
.mat-docs .md-file {
    display: block;
    max-width: 360px;
    color: var(--brand);
    font-weight: 600;
    text-decoration: none;
    white-space: normal;
    word-break: break-all;
    line-height: 1.45;
}
.mat-docs .md-file:hover { text-decoration: underline; }
.mat-docs .md-dwg  { max-width: 46px; }
@media (max-width: 1280px) {
    .mat-docs .md-dwg  { max-width: 46px; }
}

/* 余料库存：备注跟在「使用信息」下方（PDF 里使用信息常为空、备注有值） */
.rest-rm {
    display: block;
    margin-top: 2px;
    font-style: normal;
    font-size: 11.5px;
    color: var(--ink-3);
    max-width: 210px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mat-docs .md-tight { padding-left: 5px; padding-right: 5px; }
.mat-docs .md-proj  { max-width: 86px; }

/* 编辑材料清单弹窗：标题里的文件名收成一行省略，别把标题撑成两行 */
#matModal #mmFile {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    font-weight: 400;
    color: var(--ink-3);
    max-width: 520px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── 页头右上角操作区统一规范 ──────────────────────────────
   所有页面右上角按钮一律「主题色实底 + 白字 + 图标」，不要白底 ghost。
   这条兜底规则保证以后即便写成 btn ghost，在页头也按主操作渲染（danger 除外）。 */
.ph-act .btn.ghost {
    background: var(--brand);
    border-color: var(--brand);
    color: #fff;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .08);
}
.ph-act .btn.ghost:hover {
    background: var(--brand-hover);
    border-color: var(--brand-hover);
    color: #fff;
}
.ph-act .btn.ghost:active { background: var(--brand-hover); }
.ph-act .btn + .btn,
.ph-act .btn + form { margin-left: 8px; }
.ph-act form { display: inline-block; }
.ph-act .btn svg { width: 15px; height: 15px; }

/* ── 材料清单明细：左侧分类导航 + 右侧当前分类的表格 ── */
.mat-detail {
    display: grid;
    grid-template-columns: 236px minmax(0, 1fr);
    gap: 16px;
    align-items: start;
    margin-top: 4px;
}
.mat-main { min-width: 0; }
.mat-main > .card { margin-top: 0; }

.mat-cats {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 10px;
    position: sticky;
    top: 12px;
}
.mat-cats-head {
    display: flex;
    justify-content: space-between;
    padding: 2px 8px 10px;
    font-size: 12px;
    color: var(--ink-3);
}
.mat-cat {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 9px 10px;
    border-radius: 8px;
    text-decoration: none;
    color: var(--ink-2);
    font-size: 13px;
    line-height: 1.35;
    transition: background .12s;
}
.mat-cat + .mat-cat { margin-top: 2px; }
.mat-cat:hover { background: var(--panel-2); }
.mat-cat.on { background: var(--brand-50); color: var(--brand); font-weight: 600; }
.mat-cat i {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    display: grid;
    place-items: center;
    border-radius: 5px;
    background: var(--panel-3);
    color: var(--ink-3);
    font-style: normal;
    font-size: 11px;
}
.mat-cat.on i { background: var(--brand); color: #fff; }
.mat-cat > span { flex: 1; min-width: 0; }
.mat-cat .sub {
    display: block;
    margin-top: 1px;
    font-style: normal;
    font-size: 11px;
    font-weight: 400;
    color: var(--ink-3);
}
.mat-cat b {
    flex: 0 0 auto;
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-3);
    font-variant-numeric: tabular-nums;
}
.mat-cat.on b { color: var(--brand); }

@media (max-width: 1180px) {
    .mat-detail { grid-template-columns: 1fr; }
    .mat-cats { position: static; display: flex; flex-wrap: wrap; gap: 6px; padding: 8px; }
    .mat-cats-head { display: none; }
    .mat-cat { flex: 1 1 200px; }
    .mat-cat + .mat-cat { margin-top: 0; }
}

/* ── 材料清单详情顶部：左侧本批次清单列表 + 右侧 PDF 预览下载 ── */
.mat-top {
    display: grid;
    /* 和图纸详情页同一套比例：左 7 右 3（左宽右窄），窄屏再堆叠 */
    grid-template-columns: minmax(0, 7fr) minmax(0, 3fr);
    gap: 16px;
    /* 两栏等高：右侧 PDF 预览本来就高，左边若按内容高度会在下方留出大片空洞 */
    align-items: stretch;
    margin-bottom: 16px;
}
.mat-top > .card { margin-bottom: 0; display: flex; flex-direction: column; }

/* 左：清单卡片列表（横排，卡片固定 312px，多了横向滚动，和图纸页一致） */
.mat-file-list {
    display: flex;
    flex: 0 1 auto;
    flex-wrap: nowrap;
    gap: 12px;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 2px 2px 8px;
    scroll-snap-type: x proximity;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
}
.mat-file {
    flex: 0 0 312px;
    scroll-snap-align: start;
    padding: 10px 12px 11px;
}
.mat-file .sc-ico { width: 36px; height: 36px; border-radius: 9px; }
.mat-file .sc-ico svg { width: 21px; height: 21px; }
.mat-file .sc-no { font-size: 12px; line-height: 1.3; }
.mat-file .sc-file { font-size: 10.5px; }
.mat-file .sc-stats {
    margin-top: 8px;
    padding-top: 7px;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 6px 8px;
}
.mat-file .sc-stats b { font-size: 15px; }
/* 选中态保留品牌边框 + 左侧色条就够了，图标仍按参考图用白底绿文件夹 */
.mat-file.is-on .sc-ico {
    background: #fff;
    color: var(--brand);
    border-color: var(--brand);
}

/* 右：PDF 首页缩略图（点开弹窗看全文） */
.pdf-thumb-wrap {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 4px 0 2px;
}
.pdf-thumb {
    position: relative;
    display: block;
    width: 250px;
    max-width: 100%;
    /* 高度固定 150px：PDF 首页按宽度铺满后裁掉下半部分，只留页眉/表格区做预览 */
    height: 150px;
    border: 1px solid var(--line);
    border-radius: 8px;
    overflow: hidden;
    background: var(--panel-2);
    box-shadow: 0 1px 3px rgba(16, 24, 40, .08);
    transition: border-color .14s, box-shadow .14s, transform .14s;
}
.pdf-thumb:hover {
    border-color: var(--brand-100);
    box-shadow: 0 6px 16px rgba(16, 24, 40, .12);
    transform: translateY(-2px);
}
.pdf-thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top center;
}
.pdf-thumb-mask {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    background: rgba(16, 24, 40, .55);
    color: #fff;
    font-size: 12.5px;
    font-weight: 500;
    opacity: 0;
    transition: opacity .14s;
}
.pdf-thumb:hover .pdf-thumb-mask { opacity: 1; }
.pdf-thumb-mask svg { width: 16px; height: 16px; }
.pdf-thumb-ph {
    display: grid;
    place-items: center;
    height: 100%;
    color: var(--ink-3);
    font-size: 12px;
}
.pdf-tip { margin: 0; font-size: 12px; color: var(--ink-3); text-align: center; }
.pdf-tip a { color: var(--brand); text-decoration: none; margin-left: 4px; }
.pdf-tip a:hover { text-decoration: underline; }

/* PDF 查看弹窗 */
.pdf-view-modal {
    /* 预览要看整页表格，按视口 80% 宽给足空间（小屏再退回 94vw） */
    width: 80vw;
    max-width: 80vw;   /* 覆盖 .modal-box 默认的 760px，PDF 才看得清 */
}
@media (max-width: 960px) {
    .pdf-view-modal { width: 94vw; max-width: 94vw; }
}
/* 标题栏：文件名占满并省略，关闭按钮固定不换行（之前 ✕ 会被挤到第二行） */
.pdf-view-modal > h3 { gap: 12px; }
.pdf-view-modal > h3 > span:first-child {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.pdf-view-modal > h3 .right { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }
.pdf-modal-body {
    height: min(76vh, 820px);
    border: 1px solid var(--line);
    border-radius: 8px;
    overflow: hidden;
    background: var(--panel-2);
}
.pdf-modal-body iframe { width: 100%; height: 100%; border: 0; display: block; }

@media (max-width: 1180px) {
    .mat-top { grid-template-columns: 1fr; }
    .mat-file-list { max-height: 320px; }
}

/* PDF 卡片标题栏：3 成窄栏，标题与右侧操作挤在同一行 —— 标题可省略、操作不换行 */
.mat-pdf > h2 { flex-wrap: nowrap; gap: 8px; white-space: nowrap; }
.mat-pdf > h2 .mp-title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.mat-pdf h2 .right {
    flex: 0 0 auto;
    width: auto;
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: nowrap;
    gap: 5px;
}
.mat-pdf h2 .right form { display: inline-flex; margin: 0; }
.mat-pdf h2 .right .sf-cnt { font-size: 11px; }
.mat-pdf h2 .right .btn { height: 24px; padding: 0 7px; font-size: 11.5px; gap: 4px; }
.mat-pdf h2 .right .btn svg { width: 13px; height: 13px; }
/* 窄屏时卡片再窄 40px，标题会被挤成省略号：先让「页数 · 大小」让位（缩略图下方仍显示页数） */
@media (max-width: 1440px) {
    .mat-pdf h2 .right .sf-cnt { display: none; }
}
/* 更窄时一行实在挤不下，操作整块落到第二行，标题保持完整可读 */
@media (max-width: 1320px) {
    .mat-pdf > h2 { flex-wrap: wrap; row-gap: 8px; }
    .mat-pdf h2 .right { width: 100%; }
}

/* 材料清单里的「切割指令」：点进对应的切割任务详情 */
.nc-link {
    color: var(--brand);
    text-decoration: none;
    border-bottom: 1px dashed var(--brand-100);
}
.nc-link:hover { border-bottom-style: solid; }

/* ── 导出材料清单弹窗：分类勾选 ── */
.exp-modal { max-width: 520px; }
.exp-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 4px 0 10px;
}
.exp-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 11px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--panel);
    cursor: pointer;
    transition: border-color .12s, background .12s;
}
.exp-row:hover { border-color: var(--brand-100); background: var(--brand-50); }
.exp-row input { width: 15px; height: 15px; accent-color: var(--brand); flex: 0 0 auto; cursor: pointer; }
.exp-row .exp-name { flex: 1; min-width: 0; font-size: 13px; color: var(--ink); line-height: 1.35; }
.exp-row .exp-name em {
    display: block;
    margin-top: 1px;
    font-style: normal;
    font-size: 11.5px;
    color: var(--ink-3);
}
.exp-row b { flex: 0 0 auto; font-size: 12px; color: var(--ink-3); font-weight: 600; }
.exp-tools {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 2px 2px 12px;
    font-size: 12px;
    color: var(--ink-3);
}
.exp-tools a { color: var(--brand); text-decoration: none; }
.exp-tools a:hover { text-decoration: underline; }
.exp-tools .right { margin-left: auto; }
