  :root{
    --bg:#07080a; --card:#0e1013; --panel:#0a0c0e; --line:#23262b; --line2:#2b2f36;
    --input:#14171b; --ink:#e9ebee; --dim:#8b9298; --dim2:#666d74;
    --blue:#2f6fd0; --blue-h:#3b7ee2; --green:#4fb477;
  }
  *{box-sizing:border-box}
  html,body{margin:0;background:var(--bg);color:var(--ink);
    font-family:"Segoe UI",-apple-system,"Microsoft YaHei","Noto Sans SC",Roboto,Arial,sans-serif;
    -webkit-font-smoothing:antialiased}
  .wrap{max-width:1220px;margin:16px auto 26px;padding:0 14px}
  .card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:14px 16px 16px}

  /* ── 卡片头 ───────────────────────── */
  .chead{display:flex;align-items:center;gap:9px;padding:2px 2px 12px}
  .cico{width:22px;height:22px;border-radius:50%;border:1.6px solid #cfd4d9;display:flex;
    align-items:center;justify-content:center;font-size:12px;color:#cfd4d9;flex:none}
  .ctitle{font-size:20px;font-weight:700;letter-spacing:.3px}
  .badge{margin-left:auto;font-size:12.5px;color:var(--dim);background:#14171b;
    border:1px solid var(--line2);border-radius:8px;padding:5px 10px;white-space:nowrap}

  /* ── 三栏 ─────────────────────────── */
  .cols{display:grid;grid-template-columns:minmax(250px,1fr) minmax(340px,1.5fr) minmax(250px,1fr);
    gap:16px;align-items:start}
  .col{min-width:0}
  .ch{font-size:15px;font-weight:600;margin:0 0 10px;display:flex;align-items:center;gap:6px}
  .ch i{font-style:normal;color:#c8ccd1;font-size:14px}

  /* ── 字段 ─────────────────────────── */
  .f{margin-bottom:11px}
  .f>label{display:block;font-size:12.5px;color:var(--dim);margin:0 0 6px 1px}
  .in{position:relative}
  .in input,.in select{width:100%;height:40px;background:var(--input);border:1px solid var(--line2);
    border-radius:8px;color:var(--ink);font-size:15px;padding:0 10px;outline:none;
    font-family:inherit;appearance:none}
  .in select{background-image:linear-gradient(45deg,transparent 50%,#8b9298 50%),
    linear-gradient(135deg,#8b9298 50%,transparent 50%);
    background-position:calc(100% - 15px) 17px,calc(100% - 10px) 17px;
    background-size:5px 5px,5px 5px;background-repeat:no-repeat;padding-right:30px}
  .in input:focus,.in select:focus{border-color:#3b6fb0;box-shadow:0 0 0 3px rgba(47,111,208,.18)}
  .in input[type=number]{padding-right:40px}
  .unit{position:absolute;right:11px;top:50%;transform:translateY(-50%);font-size:12.5px;
    color:var(--dim2);pointer-events:none}
  /* ★★★ 2026-10-13：预览面板 = **本机 Canvas 自绘** —— 拖 = **挪字的位置** ✓ 滚轮 = **缩放整个窗口** ✓
     （用户 2026-10-13 第 2 句：「滚轮不要调整字的大小，用作**窗口整体缩放**就行」✓ 并「掉旋转」✓）*/
  #qCv{display:block;width:100%;height:100%;cursor:move;touch-action:none;user-select:none}
  #qCv.grab{cursor:grabbing}
  /* ★★ 2026-10-13 用户：「做四个按钮**融入画布**：预览稿 / 设计稿 / 3D预览 / 现场合成」✓
     ⇒ 浮在画面上沿（半透明玻璃片 ✓ 不占一行 ✗ 也不挡画面 ✓）*/
  .prev{position:relative}
  /* ★★ 2026-10-13 我踩的坑 ✗：给 `#qCv{display:block}` / `.pvwait{display:flex}` 写了 display
     ⇒ **把元素的 `hidden` 属性盖掉了** ✗✗ ⇒ 那层"生成中"一直盖在画布上、把手势全吃掉 ✓
        （表现：拖不动 / 切到设计稿也还盖着画布 ✗ —— 属性上 hidden=true ✓ 视觉上却还在 ✗ 这种最难查 ✓）
     ⇒ 规矩：**hidden 就是真不显示** ✓（HTML 的本意 ✓ 用 !important 压住任何 class 的 display ✓）*/
  [hidden]{display:none !important}
  .ptabs{position:absolute;left:8px;top:8px;z-index:6;display:flex;gap:4px;
    background:rgba(10,12,16,.66);padding:3px;border-radius:10px;
    border:1px solid rgba(255,255,255,.10);backdrop-filter:blur(6px)}
  .ptab{appearance:none;border:0;background:transparent;color:var(--dim);
    font:600 12px/1 inherit;padding:6px 9px;border-radius:7px;cursor:pointer;white-space:nowrap}
  .ptab:hover{color:#fff;background:rgba(255,255,255,.07)}
  .ptab.on{background:var(--blue);color:#fff}
  .ptabs.busy{pointer-events:none;opacity:.55}      /* 出图/3D 中：标签临时点不动 ✓ 防重复 ✓ */
  .ptab .dot{display:inline-block;width:5px;height:5px;border-radius:50%;
    background:var(--warn,#e0a03c);margin-left:5px;vertical-align:middle}
  /* 生成中/等待里的提示（浮在画面中间 ✓）*/
  .pvwait{position:absolute;inset:0;z-index:5;display:flex;align-items:center;justify-content:center;
    flex-direction:column;gap:8px;background:rgba(8,10,14,.55);color:#e8e8ea;
    font:600 13px/1.5 inherit;text-align:center;padding:0 18px}
  .pvwait .k{width:26px;height:26px;border-radius:50%;border:2px solid rgba(255,255,255,.22);
    border-top-color:var(--blue);animation:spin .8s linear infinite}
  @keyframes spin{to{transform:rotate(360deg)}}
  /* 画面右下角的小链接（下载成品 ✓ 不占高度 ✓）*/
  .pvmore{position:absolute;right:8px;bottom:8px;z-index:6;display:flex;gap:6px;flex-wrap:wrap;
    justify-content:flex-end;max-width:70%}
  .pvmore a{background:rgba(10,12,16,.72);border:1px solid rgba(255,255,255,.12);border-radius:8px;
    padding:5px 8px;font-size:11.5px;color:#cfd3da;text-decoration:none}
  .pvmore a:hover{color:#fff;border-color:var(--blue)}
  /* ★★ 对话框（用户：「把下面空出来的位置做成对话框」✓）*/
  .dlg{margin-top:9px;border:1px solid var(--line);border-radius:11px;background:var(--panel2,rgba(255,255,255,.03));
    display:flex;flex-direction:column;overflow:hidden}
  .dlglog{max-height:168px;min-height:96px;overflow:auto;padding:9px 10px;display:flex;
    flex-direction:column;gap:7px}
  .dlglog .m{font-size:12.5px;line-height:1.55;color:var(--dim);white-space:pre-wrap;word-break:break-word}
  .dlglog .m.sys{border-left:2px solid var(--blue);padding-left:8px}
  .dlglog .m.ok{color:#8fd6a6;border-left-color:#3f9d5f}
  .dlglog .m.bad{color:#f0a3a3;border-left-color:#b4554f}
  .dlglog .m.me{color:#cfd3da;border-left:2px solid rgba(255,255,255,.22);padding-left:8px}
  .dlglog .m a{color:#9ec6ff}
  .dlglog .t{opacity:.55;font-size:11px;margin-right:6px}
  .dlgin{display:flex;gap:7px;padding:7px;border-top:1px solid var(--line)}
  .dlgin input{flex:1;min-width:0;background:var(--input);border:1px solid var(--line2);
    border-radius:9px;padding:9px 11px;color:#fff;font:400 13px/1.2 inherit}
  .dlgin input:focus{outline:0;border-color:var(--blue)}
  .dlgin button{appearance:none;border:0;background:var(--blue);color:#fff;border-radius:9px;
    padding:0 14px;font:700 13px inherit;cursor:pointer}
  /* ★ 撤销激活时：排版那一行 + ③层卡片**灰掉且不能动** ✓（看得见状态 ✓ 不假装还能改 ✗） */
  .trow.off, #layerCards.off{opacity:.38;pointer-events:none;filter:grayscale(.6)}
  #layerCards.off{min-height:34px}
  .pair{display:grid;grid-template-columns:1fr 1fr;gap:8px}
  /* ★ 2026-10-13（激活态）：哪段文字在被编辑 —— 那一行亮一圈 ✓（用户偏好：状态要看得见 ✓） */
  .f.act > .in{box-shadow:0 0 0 1.5px var(--blue);border-radius:9px}
  /* ★ 2026-10-13 用户：「长宽**加一个厚度在后面**」✓ ⇒ 尺寸行三格（长/宽/厚 ✓） */
  .pair3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:7px}
  .pair3 .unit{right:7px;font-size:11.5px}
  details.more{margin:2px 0 4px}
  details.more>summary{font-size:12.5px;color:var(--dim);cursor:pointer;padding:6px 1px;
    list-style:none;user-select:none}
  details.more>summary::-webkit-details-marker{display:none}
  details.more>summary:before{content:"▸ ";}
  details.more[open]>summary:before{content:"▾ ";}
  .mgrid{display:grid;grid-template-columns:1fr 1fr;gap:8px;padding:2px 0 4px}
  .mgrid .f{margin-bottom:9px}
  .mgrid .f>label{font-size:12px}
  .chk{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--dim);
    padding:9px 0 2px}
  .chk input{width:16px;height:16px;accent-color:var(--blue)}

  /* ── ★ 阶段 3.1/3.2（2026-10-12）：分层编辑器（层卡片 ✓ 拖拽换序 ✓ 1~5 层 ✓ 底板 ✓）
        快速通道**不放材料控件**（v2.1/v3「材质控件全部撤掉」✓ 材料走类型默认 ✓ 精修可改 ✓）── */
  .layers{display:flex;flex-direction:column;gap:6px}
  .lyc{display:grid;grid-template-columns:15px 58px 1fr 34px auto 22px;align-items:center;gap:6px;
    background:#12151a;border:1px solid var(--line2);border-radius:8px;padding:6px 7px;
    cursor:grab;user-select:none}
  .lyc[data-locked="1"]{cursor:default}
  .lyc.dragging{opacity:.4}
  .lyc.over{border-color:#3b6fb0;box-shadow:0 0 0 2px rgba(59,111,176,.25)}
  .lyc .grip{color:var(--dim2);font-size:13px;text-align:center;letter-spacing:-1px}
  .lyc .role{font-size:12.5px;color:#c9cdd2;white-space:nowrap;overflow:hidden}
  .lyc input[type=number]{height:27px;background:var(--input);border:1px solid var(--line2);
    border-radius:6px;color:var(--ink);font-size:13px;padding:0 6px;width:100%;outline:none}
  .lyc input[type=color]{height:25px;width:32px;background:none;border:1px solid var(--line2);
    border-radius:6px;padding:0 2px;cursor:pointer}
  .lyc .gl{display:flex;align-items:center;gap:4px;font-size:11.5px;color:var(--dim)}
  .lyc .gl input{width:14px;height:14px;accent-color:var(--blue)}
  .lyc .del{background:none;border:none;color:var(--dim2);font-size:14px;cursor:pointer;padding:0}
  .layerbar{display:flex;align-items:center;gap:10px;margin-top:7px;flex-wrap:wrap}
  .mini{background:#12151a;border:1px solid var(--line2);border-radius:7px;color:#c9cdd2;
    font-size:12.5px;padding:5px 10px;cursor:pointer;font-family:inherit}
  .hint{font-size:11.5px;color:var(--dim2)}
  /* 毫秒示意图：**必须**标「快速示意」✓ 不许冒充 CDR 真图 ✗
     ★ 价格小框（用户 2026-10-12：「估价做成一个小框只显示价格，详情」✓）：
       .psmall 更紧凑 ✓ 明细收进 #qDetail（默认 hidden ✓ 点「详情」才展开 ✓）*/
  /* ★ 2026-10-13 用户：「字体 字体大小 字距 轮廓 **做成一行，不用标识**，太占地方了」✓
     一行四件 ✓ 不显示字段标签 ✗ 靠单位（% / ‰）+ 悬浮说明认 ✓ 省掉 4 行高度 ✓ */
  /* 「＋ 加一行」新元素（用户 2026-10-13）*/
  .exadd{width:100%;margin:6px 0 4px;padding:7px 10px;border-radius:9px;border:1px dashed rgba(0,255,136,.45);background:rgba(0,255,136,.07);color:#8fe6bd;font:inherit;cursor:pointer}
  .exadd:hover{background:rgba(0,255,136,.14)}
  .exrow{display:grid;grid-template-columns:1fr 34px;gap:6px;align-items:center;margin:4px 0}
  .exrow input{width:100%;padding:7px 9px;border-radius:8px;border:1px solid #2a323d;background:#0e1116;color:#e8eef5;font:inherit}
  .exrow button{border-radius:8px;border:1px solid #2a323d;background:#161a21;color:#9fb0c2;cursor:pointer;font:inherit}
  .exrow button:hover{color:#ff8a8a;border-color:#5a2b2b}
  .trow{display:grid;grid-template-columns:minmax(0,1fr) 66px 72px auto;
    align-items:center;gap:6px;margin-top:11px}
  /* ⚠ 数字框的原生**上下小箭头**会吃掉 ~14px ⇒ "100" 被挤成 "10" ✗（实测截图发现 ✓）⇒ 藏掉 ✓ */
  .trow input[type=number]{-moz-appearance:textfield;appearance:textfield}
  .trow input[type=number]::-webkit-outer-spin-button,
  .trow input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
  /* ★ 2026-10-13 用户：「**大小用上下箭头**（点箭头±档 ✓ 按住滑动连续调 ✓）、
     **字距用左右箭头** ✓、**百分号省掉**」✓ —— 自己画的箭头（原生小箭头又丑又吃宽度 ✗）
     ⚠ 光标给 resize（ns/ew ✓）= 明示"能拖" ✓（用户偏好：光标随工具变 ✓）*/
  .nstep{height:33px;display:grid;align-items:center;gap:2px;padding:0 3px;
    background:var(--input);border:1px solid var(--line2);border-radius:7px;box-sizing:border-box}
  .nstep:focus-within{border-color:var(--blue)}
  .nstep.v{grid-template-columns:minmax(0,1fr) 11px;grid-template-rows:1fr 1fr}
  .nstep.v .inc{grid-column:2;grid-row:1}
  .nstep.v .dec{grid-column:2;grid-row:2}
  .nstep.v input{grid-column:1;grid-row:1 / span 2}
  .nstep.h{grid-template-columns:12px minmax(0,1fr) 12px}
  /* ★ 2026-10-13 用户：「**箭头放扁一点，数字放中间**」✓
     ⇒ 箭头改用 **CSS 三角**（4px 半宽 = 扁 ✓ 比字符更小更清晰 ✓ 尺寸完全可控 ✓）
        字符仍留在 DOM 里（无障碍/测试认得出 ✓）但视觉上 `font-size:0` 藏掉 ✓ */
  .nstep button{border:none;background:none;color:var(--dim2);padding:0;line-height:0;
    font-size:0;cursor:ns-resize;user-select:none;touch-action:none;height:100%}
  .nstep button::before{content:"";display:block;margin:0 auto;width:0;height:0;
    border:4px solid transparent}
  .nstep.v .inc::before{border-bottom-color:currentColor;margin-bottom:1px}
  .nstep.v .dec::before{border-top-color:currentColor;margin-top:1px}
  .nstep.h .dec::before{border-right-color:currentColor}
  .nstep.h .inc::before{border-left-color:currentColor}
  .nstep.h button{cursor:ew-resize}
  .nstep button:hover::before{filter:brightness(1.6)}
  .nstep button:active::before{filter:brightness(2)}
  /* ★ 2026-10-13 用户：「**箭头也框在框内**」✓ ⇒ 边框从「数字框自己」挪到**整格**（.nstep ✓）
     ⇒ 数字 + 箭头**同一个框**里 ✓（不再像两块拼起来的 ✗）；输入框本身去边框/背景（只留数字 ✓）；
     焦点给了整格（:focus-within 亮蓝边 ✓）因为输入框自己的 outline 关着 ✓ */
  .nstep input{height:100%;background:none;border:none;border-radius:0;color:var(--ink);
    font-size:13px;padding:0 3px;outline:none;width:100%;min-width:0;
    font-family:inherit;text-align:center}
  .trow .btog{display:flex;align-items:center;gap:5px;height:33px;padding:0 9px;border:1px solid var(--line2);
    border-radius:7px;background:var(--input);cursor:pointer;font-size:12.5px;color:var(--dim);
    white-space:nowrap;user-select:none}
  .trow .btog input{width:14px;height:14px;accent-color:var(--blue);margin:0}
  .trow .btog:has(input:checked){border-color:var(--blue);color:var(--ink)}
  /* ★ 2026-10-13 用户：「**加粗用 B 表示**」✓ ⇒ 开关字从「加粗」（两字 ~28px ✗）换成 **B**（~10px ✓）
     ⇒ 更省地方 ✓ 一眼看懂（跟 PS/AI 的 B 一致 ✓）；勾选框藏起来（视觉 ✓）但留在 DOM 里
       （id 没改 ✓ JS/存项目/测试照旧 ✓ `:has(input:checked)` 照样生效 ✓） */
  .trow .btog.b{position:relative;padding:0 11px;gap:0;justify-content:center}
  .trow .btog.b input{position:absolute;left:50%;top:50%;width:1px;height:1px;opacity:0;
    pointer-events:none;margin:0}
  .trow .btog.b b{font-size:15px;font-weight:800;letter-spacing:.2px;line-height:1}
  .trow .btog.b:has(input:checked){background:rgba(59,130,246,.16)}

  /* ★ 结构（层）分组（用户 2026-10-12：「结构层不够清晰，分成 字 和 底板 两块」✓）
     字 = 面板/字壳/内衬层 ✓；底板 = 背板那层 + 立体 50mm 的地脚板 ✓（两块分开看才清楚 ✓）*/
  .grp{margin-top:11px}
  .gh{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:13px;
    color:#dfe3e8;font-weight:600;margin:0 0 7px;padding-bottom:5px;
    border-bottom:1px solid var(--line2)}
  .gh .hint{font-weight:400}
  .qbox.psmall{padding:11px 12px}
  .qbox.psmall .qtotal{margin:2px 0 2px;min-height:30px}
  .qbox .qlab{display:flex;align-items:center;justify-content:space-between;gap:8px}
  #qDetail{margin-top:9px;border-top:1px solid var(--line2);padding-top:9px}
  #qImg{max-width:100%;max-height:252px;object-fit:contain;border-radius:4px}
  #qTag{font-size:11.5px;color:var(--dim2)}

  /* ── 中栏：预览 ───────────────────── */
  .prev{background:var(--panel);border:1px solid var(--line2);border-radius:10px;
    height:296px;display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:5px;text-align:center;padding:16px;overflow:hidden}
  .prev img{max-width:100%;max-height:264px;object-fit:contain;border-radius:4px}
  #prevPh{display:flex;flex-direction:column;align-items:center;gap:5px}
  .prev .ph{font-size:13.5px;color:var(--dim)}
  .prev .brand{font-size:34px;font-weight:800;letter-spacing:.5px;line-height:1.15;
    max-width:100%;overflow-wrap:anywhere}
  .prev .sub{font-size:13px;color:var(--dim2);letter-spacing:6px;padding-left:6px}
  .chips{display:flex;gap:16px;flex-wrap:wrap;margin:11px 2px 0;font-size:13.5px;color:#c9cdd2}
  .chips span{white-space:nowrap}
  /* （.tools / .tool 撤了 ✓ 用户 2026-10-13：「换原色和换底座 删掉」✓） */

  /* ── 右栏：估价 ───────────────────── */
  .qbox{border:1px solid var(--line2);border-radius:10px;padding:13px;background:#0d0f12}
  .qlab{font-size:12.5px;color:var(--dim)}
  .qtotal{display:flex;align-items:baseline;gap:8px;margin:7px 0 13px;min-height:34px}
  .qtotal .cur{color:var(--green);font-size:21px;font-weight:600}
  .qtotal .num{font-size:27px;font-weight:700;letter-spacing:.4px}
  .qline{display:flex;align-items:baseline;gap:8px;font-size:14px;padding:7.5px 0;
    border-top:1px solid #171a1e}
  .qline:first-of-type{border-top:0}
  .qline .v{margin-left:auto;color:var(--dim2);font-size:13.5px;white-space:nowrap}
  .qline.done .v{color:#cfd5db}
  .qempty{font-size:12.5px;color:var(--dim);line-height:1.6;padding:6px 0}
  .qsum{margin-top:2px}
  .qsum .qline{border-top:1px solid var(--line2);font-size:13px;color:#b9c0c6}
  .bomrow{display:flex;gap:9px;align-items:center;margin-top:11px;flex-wrap:wrap}
  .bomrow .pb{height:34px;font-size:12.5px;padding:0 12px;text-decoration:none;display:inline-flex;align-items:center}
  .bombox{position:fixed;inset:0;background:rgba(0,0,0,.62);z-index:58;display:flex;
    align-items:flex-start;justify-content:center;padding:56px 14px;overflow:auto}
  .bombox[hidden]{display:none}
  .bombox .bwrap{width:min(1000px,96vw);background:var(--card);border:1px solid var(--line2);
    border-radius:12px;overflow:hidden}
  .bombox .bhead{display:flex;align-items:center;gap:10px;padding:12px 14px;
    border-bottom:1px solid var(--line);font-size:14px}
  .bombox .bhead b{font-size:14px}
  .bombox .bhead .x{margin-left:auto;background:none;border:0;color:var(--dim);font-size:15px;
    cursor:pointer;font-family:inherit}
  .bombox .bbody{max-height:72vh;overflow:auto;padding:0 0 6px}
  .bomtbl{width:100%;border-collapse:collapse;font-size:12.5px}
  .bomtbl th,.bomtbl td{border-bottom:1px solid #171a1e;padding:8px 10px;text-align:left;vertical-align:top}
  .bomtbl th{background:#12151a;color:var(--dim);font-weight:500;position:sticky;top:0}
  .bomtbl td.n{text-align:right;white-space:nowrap;color:#cfd5db}
  .bomtbl td.d{color:var(--dim2);font-size:11.5px}
  .qnote{margin-top:12px;font-size:12.5px;color:var(--dim);line-height:1.65}
  #hint{margin-top:9px;font-size:12.5px;line-height:1.6;color:var(--dim)}
  #hint .warn{color:#d8b46a}
  #hint .err{color:#e08a7a}
  #hint .ok{color:#7fbf8f}

  /* ── 底部三大键 ───────────────────── */
  .bar{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:15px}
  .big{height:62px;border-radius:12px;border:1px solid var(--line2);background:#12151a;
    color:var(--ink);font-family:inherit;font-size:15.5px;display:flex;flex-direction:column;
    align-items:center;justify-content:center;gap:4px;cursor:pointer;transition:.12s}
  .big:hover{background:#171b21;border-color:#3d434b}
  .big .ic{font-size:14px;line-height:1;opacity:.85}
  .big.primary{background:var(--blue);border-color:var(--blue);font-weight:600}
  .big.primary:hover{background:var(--blue-h);border-color:var(--blue-h)}
  .big[disabled]{opacity:.55;cursor:default}

  /* ── 提示 / 登录条 ─────────────────── */
  #toast{position:fixed;right:16px;bottom:16px;background:#171b21;border:1px solid var(--line2);
    border-radius:10px;padding:11px 14px;font-size:13.5px;max-width:340px;line-height:1.55;
    opacity:0;transform:translateY(8px);transition:.18s;pointer-events:none;z-index:50}
  #toast.on{opacity:1;transform:none}
  #banner{display:none;max-width:1220px;margin:14px auto 0;padding:0 14px}
  #banner div{background:#2a1f12;border:1px solid #6b5124;color:#e6c98a;border-radius:10px;
    padding:11px 14px;font-size:13.5px}
  #banner a{color:#ffd47a;cursor:pointer;text-decoration:underline}

  /* ── 自己的登录门（独立站点用：这个域名下没有工作室的登录页）─────── */
  #gate{display:none;max-width:1220px;margin:14px auto 0;padding:0 14px}
  .gate{background:#101419;border:1px solid #2b3a4c;border-radius:12px;padding:14px 16px;
    display:flex;flex-wrap:wrap;align-items:center;gap:10px}
  .gate .gl{font-size:13.5px;color:#a9b6c4;margin-right:2px}
  .gate input{height:38px;background:var(--input);border:1px solid var(--line2);border-radius:8px;
    color:var(--ink);font-size:14.5px;padding:0 10px;outline:none;font-family:inherit;width:150px}
  .gate input#qPass{width:170px}
  .gate input:focus{border-color:#3b6fb0;box-shadow:0 0 0 3px rgba(47,111,208,.18)}
  .gate button{height:38px;padding:0 18px;border-radius:8px;border:1px solid var(--blue);
    background:var(--blue);color:#fff;font-size:14.5px;font-family:inherit;cursor:pointer}
  .gate button:hover{background:var(--blue-h)}
  .gate #qMsg{font-size:13px;color:#e08a7a}
  /* ── 项目条 + 打开项目弹层 ─────────────── */
  .pbar{display:flex;gap:10px;align-items:center;margin-top:13px;flex-wrap:wrap}
  .pb{height:38px;padding:0 15px;border-radius:9px;border:1px solid var(--line2);
    background:#12151a;color:#dfe3e7;font-family:inherit;font-size:13.5px;cursor:pointer;transition:.12s}
  .pb:hover{background:#171b21;border-color:#3d434b}
  .ptag{margin-left:auto;font-size:12.5px;color:var(--dim2);text-align:right}
  #plist{display:none;position:fixed;inset:0;background:rgba(0,0,0,.62);z-index:60;
    align-items:flex-start;justify-content:center;padding-top:56px}
  #plist.on{display:flex}
  .pwin{width:min(760px,92vw);background:var(--card);border:1px solid var(--line2);
    border-radius:12px;overflow:hidden}
  .phead{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;
    border-bottom:1px solid var(--line);font-size:14px}
  .phead button{background:none;border:0;color:var(--dim);font-size:15px;cursor:pointer;font-family:inherit}
  .prows{max-height:54vh;overflow:auto}
  .prow{display:grid;grid-template-columns:1fr auto;gap:6px 12px;padding:11px 14px;
    border-bottom:1px solid #171a1e;cursor:pointer;font-size:13.5px}
  .prow:hover{background:#151a20}
  .prow .m{color:var(--dim2);font-size:12.5px}
  .pfoot{padding:10px 14px;color:var(--dim);font-size:12.5px}
  .empty{padding:22px 14px;color:var(--dim);font-size:13.5px}

  /* ── 出图区 ── */
  .big.sm{height:46px;font-size:13.5px;flex-direction:row;gap:7px}
  .rfiles{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
  .rfiles a{font-size:12.5px;color:#9fc4ff;text-decoration:none;border:1px solid #2b3a52;
    background:#121a26;padding:5px 9px;border-radius:7px}
  .rfiles a:hover{border-color:#3d5a86;background:#16203054}

  /* ── 现场照片弹层 ── */
  .modal{position:fixed;inset:0;background:rgba(0,0,0,.66);z-index:62;display:flex;
    align-items:flex-start;justify-content:center;padding:40px 14px;overflow:auto}
  .modal[hidden]{display:none}
  .mwin{width:min(1040px,96vw);background:var(--card);border:1px solid var(--line2);
    border-radius:12px;overflow:hidden}
  .mhead{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid var(--line)}
  .mhead .mhint{font-size:12px;color:var(--dim2)}
  .mhead .x{margin-left:auto;background:none;border:0;color:var(--dim);font-size:15px;cursor:pointer;font-family:inherit}
  .mbody{padding:12px 14px 14px}
  .phdrop{border:1.5px dashed #3a4048;border-radius:10px;padding:26px 14px;text-align:center;
    font-size:13.5px;color:var(--dim);cursor:pointer}
  .phdrop.on{border-color:#4fb477;background:#101a13;color:#9fd8ae}
  .phstage{position:relative;display:inline-block;max-width:100%}
  .phstage img{display:block;max-width:100%;max-height:54vh;border-radius:8px}
  .phframe{position:absolute;border:2px solid #4fb477;box-shadow:0 0 0 9999px rgba(0,0,0,.34);
    cursor:move;box-sizing:border-box}
  .phframe .phh{position:absolute;right:-7px;bottom:-7px;width:15px;height:15px;background:#4fb477;
    border-radius:3px;cursor:nwse-resize}
  .phrow{display:flex;align-items:flex-end;gap:10px;margin-top:11px;flex-wrap:wrap}
  .phrow[hidden]{display:none}
  .phrow label{font-size:12px;color:var(--dim);display:flex;flex-direction:column;gap:4px}
  .phrow input{width:92px;height:34px;background:var(--input);border:1px solid var(--line2);
    border-radius:8px;color:var(--ink);font-size:13px;padding:0 8px;font-family:inherit}
  .phstat{margin-top:9px;font-size:12.5px;color:var(--dim);min-height:16px;line-height:1.5}
  .phstat .warn{color:#d8b46a}
  .phresult{margin-top:11px}
  .phresult img{max-width:100%;border-radius:8px;border:1px solid var(--line2)}
  .phnote{margin-top:11px;font-size:12.5px;color:var(--dim);line-height:1.7}

  @media (max-width:900px){
    .cols{grid-template-columns:1fr}
    .bar{grid-template-columns:1fr}
    .prev{height:230px}
  }
