cardbuddy 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +11 -11
  2. package/dist/cli.js +2 -2
  3. package/dist/config.js +3 -3
  4. package/dist/init.js +13 -13
  5. package/dist/mcp.js +1 -1
  6. package/dist/preview-editor/assets/{index-CU8zVA2P.css → index-7RzNd7tf.css} +1 -1
  7. package/dist/preview-editor/assets/{index-CPpLZZyi.js → index-C7N5n_qW.js} +80 -80
  8. package/dist/preview-editor/index.html +2 -2
  9. package/dist/skills-upgrade.js +1 -1
  10. package/dist/standalone.js +2 -2
  11. package/dist/vendored/card-editor/runtime/adapter.js +10 -11
  12. package/dist/vendored/mcp/client.mjs +50 -13
  13. package/dist/vendored/mcp/tools.mjs +13 -7
  14. package/dist/vendored/server/core/ai-chat.js +540 -183
  15. package/dist/vendored/server/core/assetProxy.js +1 -1
  16. package/dist/vendored/server/core/browser.js +1 -1
  17. package/dist/vendored/server/core/cardDigest.js +324 -0
  18. package/dist/vendored/server/core/cardExport.js +5 -5
  19. package/dist/vendored/server/core/cardFiles.js +1 -1
  20. package/dist/vendored/server/core/cardHistoryRemote.js +1 -1
  21. package/dist/vendored/server/core/cardImportMeta.js +1 -1
  22. package/dist/vendored/server/core/cardListCache.js +92 -10
  23. package/dist/vendored/server/core/cardPublish.js +11 -6
  24. package/dist/vendored/server/core/cardPublishVersions.js +8 -8
  25. package/dist/vendored/server/core/cardSave.js +14 -10
  26. package/dist/vendored/server/core/cardSidecar.js +3 -3
  27. package/dist/vendored/server/core/cardSync.js +35 -23
  28. package/dist/vendored/server/core/cardVersion.js +1 -1
  29. package/dist/vendored/server/core/index.js +6 -6
  30. package/dist/vendored/server/core/logger.js +1 -1
  31. package/dist/vendored/server/core/remoteCard.js +5 -5
  32. package/dist/vendored/server/core/skillPaths.js +1 -1
  33. package/dist/vendored/server/core/sliceUpload.js +4 -4
  34. package/dist/vendored/skills/README.md +13 -13
  35. package/dist/vendored/skills/card-doctor/SKILL.md +2 -2
  36. package/dist/vendored/skills/dsl-card-ai/SKILL.md +4 -4
  37. package/dist/vendored/skills/dsl-card-generator/SKILL.md +2 -2
  38. package/dist/vendored/skills/dsl-card-generator/references/amount_formatting.md +1 -1
  39. package/dist/vendored/skills/dsl-card-generator/references/build_protocol.md +54 -0
  40. package/dist/vendored/skills/dsl-card-generator/references/component_rules.md +2 -2
  41. package/dist/vendored/skills/dsl-card-generator/references/converge_protocol.md +36 -0
  42. package/dist/vendored/skills/dsl-card-generator/references/event_patterns.md +1 -1
  43. package/dist/vendored/skills/dsl-card-generator/references/generation_pitfalls.md +1 -1
  44. package/dist/vendored/skills/dsl-card-generator/references/image_to_card.md +1 -1
  45. package/dist/vendored/skills/dsl-card-generator/references/quickref.md +1 -1
  46. package/dist/vendored/skills/dsl-card-generator/references/recipes.md +4 -4
  47. package/dist/vendored/skills/dsl-card-generator/references/rules.md +1 -1
  48. package/dist/vendored/skills/dsl-card-generator/references/slices_convention.md +6 -6
  49. package/dist/vendored/skills/dsl-card-generator/scripts/inventory_schemas.py +1 -1
  50. package/dist/vendored/skills/dsl-card-generator/scripts/lib/scaffold.mjs +1 -1
  51. package/dist/vendored/skills/dsl-card-generator/scripts/lib/slice_dedupe.mjs +2 -2
  52. package/dist/vendored/skills/dsl-card-generator/vendor/preview/assets/standalone-CeVX_y-M.js +137 -0
  53. package/dist/vendored/skills/dsl-card-generator/vendor/preview/assets/standalone-DiEiY59H.css +1 -0
  54. package/dist/vendored/skills/dsl-card-generator/vendor/preview/standalone.html +2 -2
  55. package/dist/vendored/skills/{finmall-card-sync → platform-card-sync}/SKILL.md +26 -26
  56. package/dist/vendored/skills/{finmall-card-sync → platform-card-sync}/scripts/api_batch_sync.mjs +184 -162
  57. package/dist/vendored/skills/{finmall-card-sync → platform-card-sync}/scripts/slice_upload.mjs +48 -29
  58. package/dist/vendored/skills/{finmall-session-navigator → platform-session-navigator}/SKILL.md +13 -13
  59. package/dist/vendored/skills/{finmall-session-navigator → platform-session-navigator}/scripts/package-lock.json +2 -2
  60. package/dist/vendored/skills/{finmall-session-navigator → platform-session-navigator}/scripts/package.json +2 -2
  61. package/dist/vendored/skills/{finmall-session-navigator/scripts/finmall_login.mjs → platform-session-navigator/scripts/platform_login.mjs} +41 -31
  62. package/dist/vendored/skills/{finmall-session-navigator → platform-session-navigator}/scripts/session-manager.mjs +17 -17
  63. package/dist/vendored/skills/shared/README.md +21 -21
  64. package/dist/vendored/skills/shared/auth-model.md +8 -10
  65. package/dist/vendored/skills/shared/{finmall-config.mjs → platform-config.mjs} +10 -10
  66. package/dist/vendored/tools/{finmall-env.mjs → platform-env.mjs} +13 -13
  67. package/package.json +1 -1
  68. package/dist/vendored/skills/dsl-card-generator/vendor/preview/assets/standalone-BCLshIzC.css +0 -1
  69. package/dist/vendored/skills/dsl-card-generator/vendor/preview/assets/standalone-pP5kTKiI.js +0 -88
@@ -0,0 +1 @@
1
+ .ce_map_view[data-v-b297e8af]{background-position:50%;background-repeat:no-repeat;background-size:100% 100%;width:100%;height:100%;min-height:160px;position:relative}.ce_map_grid[data-v-b297e8af]{width:100%;height:100%;position:absolute;inset:0}.ce_map_center[data-v-b297e8af]{pointer-events:none;flex-direction:column;align-items:center;display:flex;position:absolute;top:50%;left:50%;transform:translate(-50%,-100%)}.ce_map_pin[data-v-b297e8af]{filter:drop-shadow(0 2px 3px #00000040)}.ce_map_markname[data-v-b297e8af]{color:#333;white-space:nowrap;text-overflow:ellipsis;background:#ffffffe6;border-radius:4px;max-width:160px;margin-top:2px;padding:2px 6px;font-size:12px;line-height:1.3;overflow:hidden}.ce_multicolumn[data-v-5e1d2a01]{box-sizing:border-box;min-height:24px}.ce_divider{background-color:#00000026;width:100%;height:1px}.ce_image{aspect-ratio:16/9;display:flex}.ce_image_fill{background-position:50%;background-repeat:no-repeat;background-size:100% 100%;width:100%;height:100%}.ce_input{border:0;width:100%}.ce_input:focus{outline:none}.ce_text{text-overflow:ellipsis;box-orient:vertical;word-wrap:break-word;word-break:break-all;white-space:pre-line;text-align:left;-webkit-box-orient:vertical;width:fit-content;display:-webkit-box;display:-ms-flexbox;overflow:hidden}.ce_multitext{width:fit-content;display:flex}.ce_svgsymbols,.ce_svgcode{fill:#000;width:100%;height:100%}.ce_svgcode svg{width:100%;height:100%;fill:inherit}.ce_icon{font-size:0}.ce_button{-webkit-user-select:none;user-select:none;background-color:#0000;border:0}.ce_button.ce_button_disabled{color:#9a9a9a!important;background-color:#e6e6e6!important;border:none!important}.ce_map{position:relative}.ce_map .ce_map_view{background-position:50%;background-repeat:no-repeat;background-size:100% 100%;width:100%;height:100%}.ce_map .ce_map_view svg{width:100%;height:100%}.ce_map .ce_map_placeholder{z-index:1000;width:100%;height:100%;position:absolute;inset:0}.ce_svgcheckstyle{width:100%;height:100%}.ce_check_group .ce_check_list{flex-wrap:wrap;display:flex;overflow:hidden}.ce_check_group .ce_check_item{cursor:pointer;align-items:center;display:flex}.ce_check_group .ce_check_icon{flex:none;font-size:0}.ce_check_group .ce_check_text{text-overflow:ellipsis;white-space:nowrap;flex:auto;overflow:hidden}.ce_svgradiostyle{width:100%;height:100%}.ce_radio_button .ce_radio_item{cursor:pointer;align-items:center;display:flex}.ce_radio_button .ce_radio_icon{font-size:0}.ce_slider{align-items:center;display:flex}.ce_slider .ce_slider_rect{width:100%;position:relative}.ce_slider .ce_slider_bar{width:0;height:100%;position:absolute;top:0;left:0}.ce_slider .ce_slider_con{position:absolute;top:50%;left:0;transform:translateY(-50%)translate(-50%)}.ce_slider .ce_slider_block{background-repeat:no-repeat;background-size:100% 100%}.ce_slider .ce_hover,.ce_slider .ce_dragging{transform:scale(1.2)}.ce_video{position:relative}.ce_video .ce_video_elem{width:100%;height:100%}.ce_video .ce_video_poster{cursor:pointer;width:100%;height:100%;position:absolute;top:0;left:0}.ce_viewcontainer{width:100%}.ce_root{color:#000;flex-direction:column;line-height:1.5;display:flex;position:relative;overflow:hidden}.ce_row{display:flex}.ce_column{flex-direction:column;max-width:100%;display:flex}.ce_singlecolumn{flex-direction:column;width:100%;display:flex}.ce_multicolumn{justify-content:space-between;width:100%;display:flex}.ce_listlayout{width:100%}.ce_listlayout .ce_listlayout_con{box-sizing:border-box;flex-direction:column;width:100%;display:flex}.ce_listlayout .ce_listlayout_item{width:100%;display:flex}.ce_listlayout .ce_listlayout_horizontal{flex-flow:row;width:100%;height:100%;display:flex;overflow:auto hidden}.ce_listlayout .ce_listlayout_horizontal::-webkit-scrollbar{display:none}.ce_listlayout .ce_listlayout_horizontal .ce_listlayout_item{width:auto;height:100%;display:flex}.ce_gridlayout{flex-wrap:wrap;width:100%;display:flex}.ce_gridlayout .ce_gridlayout_item{width:100%;display:flex}.ce_absolutelayout{flex-direction:column;display:flex;position:relative}.ce_absolutelayout>*{z-index:1;position:absolute}.ce_absolutelayout_bottomright>*{z-index:1;position:static}:root{--bg-app:#0e0f13;--bg-bar:#15171c;--bg-panel:#181b21;--bg-stage:#0b0c0f;--bg-input:#1b1e25;--bg-hover:#232733;--bg-active:#2b2f3d;--bg-pop:#1c1f26f5;--bg-soft:#0f1219;--border:#2a2e38;--border-strong:#353b48;--text:#e8eaf0;--text-dim:#949aab;--text-faint:#626a7d;--accent:#6b83f7;--accent-2:#5a6ff0;--accent-soft:#6b83f724;--accent-border:#6b83f773;--accent-hover:#8195f9;--danger:#f87171;--danger-soft:#f8717124;--danger-hover:#ef4444;--warn:#fbbf24;--warn-soft:#fbbf2424;--warn-border:#fbbf2466;--warn-hover:#f59e0b;--on-warn:#0f1115;--ok:#34d399;--ok-soft:#34d39929;--ok-border:#34d39973;--ok-strong:#34d399;--purple:#a78bfa;--purple-soft:#a78bfa29;--purple-hover:#c4b5fd;--ok-solid:#17734a;--on-ok:#fff;--info:#6b83f7;--info-soft:#6b83f724;--info-border:#6b83f773;--on-accent:#0f1115;--stream-shine:#fff;--radius:8px;--radius-sm:6px;--shadow-pop:#0000008c;--shadow-card:#00000080;--shadow-drawer:#00000073;--shadow-toast:#00000047;--scrim:#0000008c;--scrim-soft:#00000073;--scrim-faint:#0006;--scrim-modal:#080a108c;--scrim-modal-blur:2px;--bar-grad:linear-gradient(180deg, #171a20, #131519);--splitter:#5b6cff;--splitter-size:4px;--splitter-grip:#ffffff47;--overlay-tint:#ffffff08;--overlay-tint-strong:#ffffff47;--err-item-fg:#ffb3a3;--api-item-fg:#bcd3ff;--api-item-border:#7c8cff33;--api-item-bg:#384c890f;--copy-ok:#8fe39a;--tag-ok-fg:#1a7f37;--tag-ok-bg:#1a7f3724;--tag-warn-fg:#b58105;--tag-warn-bg:#b5810529;--log-warn-fg:#e0b341;--log-warn-bg:#e0b34124;--log-warn-border:#e0b34159;--scroll-thumb:#949aab47;--scroll-thumb-hover:#949aab73;--scroll-thumb-idle:#949aab24;--jt-key:#9db4ff;--jt-string:#8fe39a;--jt-number:#f0b86e;--jt-boolean:#f08e8e;--jt-null:#626a7d;--jt-faint:#8b93a7;--jt-ring:#9db4ff40;--jt-del-fg:#f08e8e;--jt-del-bg:#f0646426;--jt-add-bg:#9db4ff1a;--st-label:#ccc;--st-id:#8b93a7;--st-badge-bg:#6b83f7;--st-badge-fg:#fff;--st-hl-bg:#6b83f747;--code-comment:#6b7280;--code-punc:#9ca3af;--code-prop:#f0883e;--code-str:#7ee787;--code-num:#79c0ff;--code-kw:#ff7b72;--code-fn:#d2a8ff;--code-var:#ffa657;--code-binding:#56d4dd;--type-string:var(--code-str);--type-number:var(--code-num);--type-boolean:var(--code-kw);--type-array:var(--code-fn);--type-object:var(--code-prop);--space-0:0;--space-1:4px;--space-2:8px;--space-3:12px;--space-4:16px;--space-5:20px;--space-6:24px;--space-7:32px;--space-8:40px;--space-9:48px;--fs-xs:11px;--lh-xs:16px;--fs-sm:12px;--lh-sm:18px;--fs-base:13px;--lh-base:20px;--fs-md:14px;--lh-md:22px;--fs-lg:15px;--lh-lg:22px;--fs-xl:16px;--lh-xl:24px;--fs-2xl:20px;--lh-2xl:28px;--radius-xs:4px;--radius-md:8px;--radius-lg:10px;--radius-xl:12px;--radius-2xl:16px;--radius-pill:999px;--ctrl-xs:24px;--ctrl-sm:28px;--ctrl-md:32px;--ctrl-lg:36px;--ctrl-xl:40px;--row-h:28px;--icon-xs:12px;--icon-sm:14px;--icon-md:16px;--icon-lg:20px;--icon-xl:24px;--stroke:1.75;--hairline:1px;--shadow-1:0 1px 2px var(--shadow-card);--shadow-2:0 4px 12px var(--shadow-card);--shadow-3:0 8px 24px var(--shadow-card);--shadow-4:0 20px 64px var(--shadow-pop);--shadow-5:-20px 0 32px var(--shadow-drawer);--z-base:1;--z-sticky:20;--z-overlay-low:50;--z-overlay:60;--z-pop:70;--z-panel:100;--z-modal:1000;--z-deviceui:1100;--z-appmodal:2000;--z-appmodal-top:2050;--z-toast-app:2100}@media (resolution>=2x),(-webkit-device-pixel-ratio>=2){:root{--hairline:.5px}}:root[data-theme=light]{--bg-app:#f4f6fa;--bg-bar:#fff;--bg-panel:#fff;--bg-stage:#e9edf4;--bg-input:#f6f8fb;--bg-hover:#f1f4f9;--bg-active:#e4e9f2;--bg-pop:#fffffffa;--bg-soft:#eef2f8;--border:#e2e8f0;--border-strong:#cbd5e1;--text:#1e293b;--text-dim:#475569;--text-faint:#5f6b7d;--accent:#4f6bf2;--accent-2:#3d57d9;--accent-soft:#4f6bf21a;--accent-border:#4f6bf259;--accent-hover:#3d57d9;--danger:#ef4444;--danger-soft:#ef44441a;--danger-hover:#dc2626;--warn:#f59e0b;--warn-soft:#f59e0b1f;--warn-border:#f59e0b66;--warn-hover:#d97706;--on-warn:#0f1115;--ok:#10b981;--ok-soft:#10b9811f;--ok-border:#10b98166;--ok-strong:#047857;--ok-solid:#047857;--on-ok:#fff;--info:#4f6bf2;--info-soft:#4f6bf21a;--info-border:#4f6bf259;--purple:#7c3aed;--purple-soft:#7c3aed1a;--purple-hover:#6d28d9;--on-accent:#fff;--stream-shine:#3142b8;--radius:8px;--radius-sm:6px;--shadow-pop:#0f172a24;--shadow-card:#0f172a1a;--shadow-drawer:#0f172a1f;--shadow-toast:#0f172a1a;--scrim:#0f172a66;--scrim-soft:#0f172a4d;--scrim-faint:#0f172a38;--bar-grad:linear-gradient(180deg, #fff, #f6f8fc);--splitter:#4f6bf2;--splitter-size:4px;--splitter-grip:#0f172a2e;--overlay-tint:#0f172a08;--overlay-tint-strong:#0f172a14;--err-item-fg:#b91c1c;--api-item-fg:#3d57d9;--api-item-border:#4f6bf238;--api-item-bg:#4f6bf20f;--copy-ok:#047857;--tag-ok-fg:#047857;--tag-ok-bg:#10b9811a;--tag-warn-fg:#b45309;--tag-warn-bg:#f59e0b1a;--log-warn-fg:#b45309;--log-warn-bg:#f59e0b1a;--log-warn-border:#f59e0b59;--scroll-thumb:#0f172a29;--scroll-thumb-hover:#0f172a47;--scroll-thumb-idle:#0f172a14;--jt-key:#953800;--jt-string:#0a3069;--jt-number:#116329;--jt-boolean:#cf222e;--jt-null:#57606a;--jt-faint:#6b7280;--jt-ring:#4f6bf247;--jt-del-fg:#cf222e;--jt-del-bg:#cf222e1f;--jt-add-bg:#4f6bf21a;--st-label:#1e293b;--st-id:#64748b;--st-badge-bg:#4f6bf2;--st-badge-fg:#fff;--st-hl-bg:#4f6bf224;--code-comment:#6e7781;--code-punc:#6e7781;--code-prop:#953800;--code-str:#0a3069;--code-num:#0550ae;--code-kw:#cf222e;--code-fn:#8250df;--code-var:#953800;--code-binding:#0d9488;--type-string:#116329;--type-boolean:#a40e26;--type-array:#6639ba}:root[data-accent]{--accent-soft:color-mix(in srgb, var(--accent) 14%, transparent);--accent-border:color-mix(in srgb, var(--accent) 45%, transparent);--splitter:var(--accent);--st-badge-bg:var(--accent);--st-badge-fg:#0f1115;--st-hl-bg:color-mix(in srgb, var(--accent) 28%, transparent);--jt-ring:color-mix(in srgb, var(--accent) 28%, transparent);--jt-add-bg:color-mix(in srgb, var(--accent) 10%, transparent);--api-item-border:color-mix(in srgb, var(--accent) 20%, transparent);--api-item-bg:color-mix(in srgb, var(--accent) 6%, transparent);--api-item-fg:color-mix(in srgb, var(--accent) 62%, #fff)}:root[data-theme=light][data-accent]{--accent-soft:color-mix(in srgb, var(--accent) 10%, transparent);--accent-border:color-mix(in srgb, var(--accent) 35%, transparent);--st-badge-fg:#fff;--st-hl-bg:color-mix(in srgb, var(--accent) 14%, transparent);--jt-add-bg:color-mix(in srgb, var(--accent) 10%, transparent);--api-item-border:color-mix(in srgb, var(--accent) 22%, transparent);--api-item-fg:var(--accent)}:root[data-accent=yellow]{--accent:#f2c24f;--accent-hover:#f7d273;--accent-2:#dda93b}:root[data-theme=light][data-accent=yellow]{--accent:#a16207;--accent-hover:#854d0e;--accent-2:#854d0e}:root[data-accent=green]{--accent:#5cc97a;--accent-hover:#7bd895;--accent-2:#45b063}:root[data-theme=light][data-accent=green]{--accent:#15803d;--accent-hover:#166534;--accent-2:#166534}:root[data-accent=orange]{--accent:#f5943e;--accent-hover:#f8ae63;--accent-2:#e07e2a}:root[data-theme=light][data-accent=orange]{--accent:#c2410c;--accent-hover:#9a3412;--accent-2:#9a3412}*{box-sizing:border-box;outline:none}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit;color:inherit;margin:0}html,body{background:var(--bg-app);height:100%;color:var(--text);-webkit-font-smoothing:antialiased;margin:0;font-family:PingFang SC,-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif}#app{height:100vh;overflow:hidden}@supports ((-moz-appearance:none)){*{scrollbar-width:thin;scrollbar-color:var(--scroll-thumb) transparent}}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-thumb{background:var(--scroll-thumb-idle);border-radius:8px;transition:background-color .2s}:has(:hover)::-webkit-scrollbar-thumb{background:var(--scroll-thumb)}.st-expr:hover .st-expr__editor::-webkit-scrollbar-thumb{background:var(--scroll-thumb)}.st-code:hover .st-code__editor::-webkit-scrollbar-thumb{background:var(--scroll-thumb)}.debug__scope-raw:hover .debug__raw-editor::-webkit-scrollbar-thumb{background:var(--scroll-thumb)}.dlg:hover .dlg__msg::-webkit-scrollbar-thumb{background:var(--scroll-thumb)}::-webkit-scrollbar-thumb:hover{background:var(--scroll-thumb-hover)}::-webkit-scrollbar-thumb:active{background:var(--scroll-thumb-hover)}::-webkit-scrollbar-track{background:0 0}.app{background:var(--bg-app);flex-direction:column;height:100vh;display:flex}.app__bar{background:var(--bar-grad);border-bottom:var(--hairline) solid var(--border);flex:none;align-items:center;gap:12px;height:48px;padding:0 16px;display:flex;position:relative}.app__bar-lock{z-index:calc(var(--z-pop) + 10);cursor:progress;background:0 0;position:absolute;inset:0}.app__bar--locked .dd__pop,.app__bar--locked .csel__pop,.app__bar--locked .app__dev-svc-panel,.app__bar--locked .app__theme-panel{pointer-events:none}.app__btn--remote.is-processing:disabled{opacity:1;cursor:progress}.app__logo{letter-spacing:.01em;color:var(--text);white-space:nowrap;align-items:center;gap:8px;font-family:Avenir Next,Avenir,Futura,Century Gothic,Helvetica Neue,Segoe UI,system-ui,PingFang SC,Microsoft YaHei,sans-serif;font-size:15px;font-weight:600;display:flex}.app__logo-icon{width:var(--icon-xl);height:var(--icon-xl);display:block}.app__logo-version{font-size:var(--fs-xs);letter-spacing:.02em;color:var(--text-faint);font-weight:500;line-height:1}.app__btn{height:var(--ctrl-md);background:var(--bg-input);color:var(--text);border:1px solid var(--border-strong);cursor:pointer;white-space:nowrap;border-radius:8px;flex:none;align-items:center;gap:6px;padding:0 12px;font-size:13px;transition:background .15s,border-color .15s,transform 50ms;display:inline-flex}.app__btn:hover:not(:disabled){background:var(--bg-hover);color:var(--accent)}.app__btn:active:not(:disabled){transform:translateY(1px)}.app__btn:disabled{opacity:.5;cursor:default}.app__btn--icon{height:var(--ctrl-md);aspect-ratio:1;justify-content:center;padding:0}.app__btn--active{background:var(--accent-soft);color:var(--accent);border-color:var(--accent-border)}.app__bar .app__btn--icon{height:var(--ctrl-sm)}.app__btn-group{align-items:center;display:flex}.app__btn-group .app__btn--icon{aspect-ratio:auto;border-radius:0;padding:0 8px}.app__btn-group .app__btn--icon:first-child{border-top-left-radius:6px;border-bottom-left-radius:6px}.app__btn-group .app__btn--icon:not(:first-child){margin-left:-1px}.app__btn-group .app__btn--icon:last-child{border-top-right-radius:6px;border-bottom-right-radius:6px}.app__btn--remote{height:var(--ctrl-sm);background:var(--accent-soft);color:var(--accent);border-color:var(--accent-border);padding:0 10px;font-size:12px}.app__btn--remote:hover:not(:disabled){background:var(--accent);color:var(--on-accent);border-color:var(--accent)}.app__btn--remote.app__btn--warn{background:var(--warn-soft);color:var(--warn);border-color:var(--warn-border)}.app__btn--remote.app__btn--warn:hover:not(:disabled){background:var(--warn);color:var(--on-accent);border-color:var(--warn)}.app__remote-menu{display:inline-flex;position:relative}.app__remote-menu .app__btn--remote{gap:6px}.app__icon--chev{transition:transform .15s}.app__remote-item--save:hover{background:var(--accent-soft);color:var(--accent)}.app__remote-item--upload:hover{background:var(--warn-soft);color:var(--warn)}.app__remote-item--sync:hover{background:var(--ok-soft);color:var(--ok)}.app__remote-item--publish:hover{background:var(--purple-soft);color:var(--purple)}.app__op-group{display:inline-flex}.app__op-group>.app__btn{background:var(--bg-input);color:var(--text);border:1px solid var(--border);height:var(--ctrl-sm);border-radius:0;margin-left:-1px;padding:0 10px;font-size:12px}.app__op-group>.app__btn:first-child{border-top-left-radius:var(--radius-sm,6px);border-bottom-left-radius:var(--radius-sm,6px);margin-left:0}.app__op-group>.app__btn:last-child{border-top-right-radius:var(--radius-sm,6px);border-bottom-right-radius:var(--radius-sm,6px)}.app__op-group>.app__btn:hover:not(:disabled){z-index:var(--z-base);border-color:var(--border-strong);background:var(--bg-hover);position:relative}.app__op-group>.app__btn:disabled{opacity:.5;cursor:default}.app__btn--history-save.is-dirty:disabled{background:var(--bg-input);color:var(--text);border-color:var(--border-strong);box-shadow:none;opacity:.5;cursor:default}.app__btn--history-save.is-dirty:not(:disabled){background:var(--accent);color:var(--on-accent);border-color:var(--accent)}.app__btn--history-save.is-dirty:not(:disabled):hover{background:var(--accent-2);border-color:var(--accent-2)}.app__bar-actions{align-items:center;gap:12px;margin-left:auto;display:flex}@media (width<=1180px){.app__op-group>.app__btn{padding:0 8px}.app__op-group>.app__btn>span{display:none}.app__btn--remote{padding:0 8px}.app__btn--remote>span{display:none}}@media (width<=1024px){.app__bar{gap:8px;padding:0 10px}.app__bar-actions{gap:8px}.app__logo-version{display:none}.app__badge{padding:2px 6px}.app__badge-text{display:none}.csel-combo{min-width:120px}}.app__dev-svc{display:inline-flex;position:relative}.app__btn--warn{background:var(--warn-soft);color:var(--warn);border-color:var(--warn-border)}.app__btn--connected{background:var(--ok-soft);color:var(--ok);border-color:var(--ok-border)}.app__btn--connected:hover:not(:disabled){background:var(--ok-soft);color:var(--ok-strong);border-color:var(--ok)}.app__btn--reconnecting{background:var(--warn-soft);color:var(--warn);border-color:var(--warn-border)}.app__btn--disconnected{background:var(--danger-soft);color:var(--danger);border-color:var(--danger)}.app__dev-svc-mask{z-index:var(--z-overlay);position:fixed;inset:0}.app__dev-svc-panel{z-index:var(--z-pop);background:var(--bg-panel);border:1px solid var(--border-strong);border-radius:var(--radius-lg);width:300px;box-shadow:var(--shadow-3);color:var(--text);text-align:left;transform-origin:100% 0;position:absolute;top:calc(100% + 8px);right:0;overflow:hidden}.app__dev-svc-head{border-bottom:var(--hairline) solid var(--border);justify-content:space-between;align-items:center;gap:8px;padding:7px 8px 7px 12px;display:flex}.app__dev-svc-title{color:var(--text);font-size:12px;font-weight:600}.app__dev-svc-close{width:22px;height:22px;color:var(--text-faint);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;font-size:14px;line-height:1;transition:background .15s,color .15s;display:inline-flex}.app__dev-svc-close:before{content:"✕"}.app__dev-svc-close:hover{background:var(--bg-hover);color:var(--text)}.app__dev-svc-body{flex-direction:column;gap:12px;padding:12px;display:flex}.app__dev-svc-row{color:var(--text-dim);justify-content:space-between;align-items:center;gap:8px;font-size:11px;display:flex}.app__dev-svc-row--col{flex-direction:column;align-items:stretch;gap:6px}.app__dev-svc-row input[type=text],.app__dev-svc-row input[type=password]{width:100%;min-width:0;height:var(--ctrl-sm);background:var(--bg-input);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);outline:none;padding:0 10px;font-family:inherit;font-size:12px;transition:border-color .15s,box-shadow .15s}.app__dev-svc-row input[type=text]:focus,.app__dev-svc-row input[type=password]:focus{border-color:var(--accent-border);box-shadow:0 0 0 2px var(--accent-soft)}.app__dev-svc-row input::placeholder{color:var(--text-faint)}.app__dev-svc-row .switch{flex:none}.app__dev-svc-hint{border-radius:var(--radius-sm);background:var(--warn-soft);color:var(--warn);margin:0;padding:6px 8px;font-size:11px;line-height:1.55}.app__dev-svc-actions{justify-content:flex-end;gap:8px;display:flex}.app__nosvc-banner{color:var(--warn,#e0a23a);background:var(--warn-soft,#e0a23a1f);padding:8px 14px;font-size:13px}.app__nosvc-banner--disconnected{color:var(--danger,#ef4444);background:var(--danger-soft,#ef44441f)}.app__extreload-banner{color:var(--info,#0079f2);background:var(--info-soft,#0079f21f)}.app__theme{display:inline-flex;position:relative}.app__theme-mask{z-index:var(--z-overlay);position:fixed;inset:0}.app__theme-panel{z-index:var(--z-pop);background:var(--bg-panel);border:1px solid var(--border-strong);border-radius:var(--radius-lg);width:236px;box-shadow:var(--shadow-3);color:var(--text);text-align:left;transform-origin:100% 0;position:absolute;top:calc(100% + 8px);right:0;overflow:hidden}.app__theme-head{border-bottom:var(--hairline) solid var(--border);justify-content:space-between;align-items:center;gap:8px;padding:7px 8px 7px 12px;display:flex}.app__theme-title{color:var(--text);font-size:12px;font-weight:600}.app__theme-close{width:22px;height:22px;color:var(--text-faint);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;font-size:14px;line-height:1;transition:background .15s,color .15s;display:inline-flex}.app__theme-close:before{content:"✕"}.app__theme-close:hover{background:var(--bg-hover);color:var(--text)}.app__theme-body{flex-direction:column;gap:14px;padding:12px;display:flex}.app__theme-label{color:var(--text-dim);justify-content:space-between;align-items:baseline;gap:8px;margin-bottom:7px;font-size:11px;display:flex}.app__theme-label-note{color:var(--text-faint)}.app__theme-seg{background:var(--bg-input);border:1px solid var(--border);border-radius:var(--radius-md);gap:2px;padding:2px;display:flex}.app__theme-seg-btn{border-radius:var(--radius-sm);height:26px;color:var(--text-dim);cursor:pointer;background:0 0;border:1px solid #0000;flex:1 1 0;justify-content:center;align-items:center;gap:5px;padding:0;font-size:12px;transition:background .15s,color .15s,border-color .15s;display:inline-flex}.app__theme-seg-btn:hover{color:var(--text)}.app__theme-seg-btn.is-active{background:var(--bg-panel);border-color:var(--border-strong);color:var(--text);box-shadow:var(--shadow-1)}.app__theme-seg-icon{width:13px;height:13px}.app__theme-swatches{grid-template-columns:repeat(4,1fr);gap:4px;display:grid}.app__theme-swatch{border-radius:var(--radius-md);color:var(--text-dim);cursor:pointer;background:0 0;border:1px solid #0000;flex-direction:column;align-items:center;gap:6px;padding:7px 0 5px;font-size:11px;transition:background .15s,color .15s,border-color .15s;display:flex}.app__theme-swatch:hover{background:var(--bg-hover);color:var(--text)}.app__theme-swatch.is-active{background:var(--accent-soft);border-color:var(--accent-border);color:var(--text)}.app__theme-dot{width:22px;height:22px;box-shadow:inset 0 0 0 1px var(--border);border-radius:50%;transition:box-shadow .15s}.app__theme-swatch.is-active .app__theme-dot{box-shadow:inset 0 0 0 1px var(--border), 0 0 0 2px var(--bg-panel), 0 0 0 3px var(--accent)}.app__theme-hint{color:var(--text-faint);margin:0;padding:0 12px 12px;font-size:11px;line-height:1.6}.switch{cursor:pointer;vertical-align:middle;background:0 0;border:none;margin:0;padding:0;line-height:0;display:inline-flex}.switch--disabled{cursor:not-allowed;opacity:.5}.switch__track{background:var(--bg-input);border:1px solid var(--border-strong);box-sizing:border-box;border-radius:999px;width:36px;height:20px;transition:background .18s,border-color .18s;display:inline-block;position:relative}.switch__thumb{background:var(--text-faint);border-radius:50%;width:16px;height:16px;transition:transform .18s,background .18s;position:absolute;top:50%;left:2px;transform:translateY(-50%)}.switch--on .switch__track{background:var(--accent);border-color:var(--accent)}.switch--on .switch__thumb{background:var(--on-accent);transform:translateY(-50%)translate(16px)}.app__badge{border:1px solid var(--border-strong);background:var(--bg-input);color:var(--text-dim);-webkit-user-select:none;user-select:none;white-space:nowrap;border-radius:999px;flex:none;align-items:center;gap:5px;padding:2px 9px;font-size:11px;font-weight:600;display:inline-flex}.app__badge-dot{background:var(--text-faint);border-radius:50%;flex:none;width:7px;height:7px}.app__badge--ok{color:var(--ok);border-color:var(--ok-border);background:var(--ok-soft)}.app__badge--ok .app__badge-dot{background:var(--ok)}.app__badge--error{color:var(--danger);border-color:var(--danger-soft);background:var(--danger-soft)}.app__badge--error .app__badge-dot{background:var(--danger)}.app__badge--pending{color:var(--warn);border-color:var(--warn-border);background:var(--warn-soft)}.app__badge--pending .app__badge-dot{background:var(--warn);animation:1s ease-in-out infinite app-badge-pulse}.app__badge--nopython,.app__badge--fail{color:var(--text-faint);border-color:var(--border);background:var(--bg-input)}.app__badge--nopython .app__badge-dot,.app__badge--fail .app__badge-dot{background:var(--text-faint)}@keyframes app-badge-pulse{0%,to{opacity:1}50%{opacity:.3}}.app__badge.is-celebrating{animation:.5s app-badge-pop}@keyframes app-badge-pop{0%{transform:scale(1)}35%{transform:scale(1.18)}to{transform:scale(1)}}.app__confetti{pointer-events:none;z-index:9999;position:fixed}.app__confetti-bit{background:linear-gradient(135deg, #fffffff2 0%, var(--c,#52c41a) 42%, color-mix(in srgb, var(--c,#52c41a) 62%, #000) 100%);clip-path:var(--clip,polygon(50% 0%, 0% 100%, 100% 100%));opacity:var(--o,.9);filter:drop-shadow(0 0 1px #0000002e);border-radius:0;animation:.7s ease-out forwards app-confetti-fly;position:absolute;top:0;left:0;transform:translate(-50%,-50%)}@keyframes app-confetti-fly{0%{opacity:var(--o,.9);transform:translate(calc(-50% + var(--sx,0px)), calc(-50% + var(--sy,0px))) rotate(0deg) scale(.4)}to{opacity:0;transform:translate(calc(-50% + var(--sx,0px) + var(--tx)), calc(-50% + var(--sy,0px) + var(--ty))) rotate(var(--rot)) scale(1)}}.app__icon{width:15px;height:15px;display:block}.app__icon--spin{animation:.8s linear infinite app__spin}@keyframes app__spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.app__stage{flex:auto;min-height:0;display:flex;position:relative}.workside{border-left:var(--hairline) solid var(--border);flex-direction:column;flex:auto;min-width:0;min-height:0;display:flex}.workside__bar{flex:none;order:2}.workside__panels{flex-direction:column;flex:none;order:1;display:flex}.workside__cols{flex:auto;min-width:0;min-height:0;display:flex;position:relative}.phone{background:radial-gradient(circle at 30% 20%, #7c8cff0d, transparent 60%), var(--bg-stage);flex-direction:column;flex:none;justify-content:center;align-items:center;min-height:0;display:flex;overflow:hidden}.phone__frame{flex:auto;justify-content:center;align-items:center;width:100%;min-height:0;display:flex;position:relative;overflow:hidden}.phone__scaler{isolation:isolate;flex-direction:column;width:100%;height:100%;display:flex;position:relative}.splitter{top:0;bottom:0;left:calc(var(--preview-width) - 3px);cursor:col-resize;touch-action:none;width:6px;z-index:var(--z-sticky);transition:background .15s;position:absolute}.splitter--api{left:auto;right:calc(var(--api-panel-width,360px) - 3px)}.splitter:after{content:"";top:0;bottom:0;left:calc((6px - var(--splitter-size)) / 2);width:var(--splitter-size);background:linear-gradient(to bottom, transparent 0%, var(--splitter) 50%, transparent 100%);opacity:0;transition:opacity .15s;position:absolute}.splitter:hover:after,.splitter.is-dragging:after{opacity:1}.phone--dragging,.phone--dragging *{-webkit-user-select:none!important;user-select:none!important;cursor:col-resize!important}.canvas-bar{border-bottom:var(--hairline) solid var(--border);flex:none;align-items:center;gap:4px;width:100%;height:32px;padding:0 8px;display:flex}.canvas-bar .dd__pop{z-index:calc(var(--z-deviceui) + 1)}.canvas-bar__spacer{flex:auto}.canvas-bar__chip{height:24px;color:var(--text-dim);white-space:nowrap;cursor:pointer;border-radius:5px;align-items:center;gap:6px;padding:0 8px;font-size:11.5px;transition:background .15s,color .15s;display:inline-flex}.canvas-bar__chip:hover,.dd--open>.dd__trigger--slot .canvas-bar__chip{background:var(--bg-hover);color:var(--text)}.canvas-bar__chev{width:10px;height:10px;color:var(--text-faint)}.canvas-bar__icn{width:13px;height:13px;color:var(--text-faint);flex:none}.canvas-bar__swatch{border:1px solid var(--border-strong);border-radius:3px;flex:none;width:10px;height:10px}.canvas-bar__swatch--white{background:#fff}.canvas-bar__swatch--gray{background:#f0f0f0}.canvas-bar__swatch--black{background:#1c1c1e}.canvas-bar__swatch--checker{background-color:#fff;background-image:linear-gradient(45deg,#cfcfcf 25%,#0000 25% 75%,#cfcfcf 75%),linear-gradient(45deg,#cfcfcf 25%,#0000 25% 75%,#cfcfcf 75%);background-position:0 0,3px 3px;background-size:6px 6px}.canvas-bar__size{font-variant-numeric:tabular-nums;color:var(--text-faint);white-space:nowrap;padding:0 4px;font-family:SF Mono,JetBrains Mono,Menlo,Consolas,monospace;font-size:11px}.canvas-bar__iconbtn{width:24px;height:24px;color:var(--text-faint);cursor:pointer;background:0 0;border:none;border-radius:5px;flex:none;justify-content:center;align-items:center;padding:0;transition:background .15s,color .15s;display:inline-flex}.canvas-bar__iconbtn:hover:not(:disabled){background:var(--bg-hover);color:var(--accent)}.canvas-bar__iconbtn:disabled{opacity:.4;cursor:default}.canvas-bar__iconbtn.is-loading svg{animation:.8s linear infinite canvas-bar-spin}@keyframes canvas-bar-spin{to{transform:rotate(360deg)}}.canvas-bar--tight .canvas-bar__size,.canvas-bar--tight .canvas-bar__txt{display:none}.statusbar__conn-icon{flex:none;width:14px;height:14px}.statusbar .app__btn--connected,.statusbar .app__btn--reconnecting,.statusbar .app__btn--disconnected,.statusbar .app__btn--warn{background:0 0;border:none;padding:0 10px}.statusbar .app__btn--reconnecting{color:var(--warn)}.statusbar .app__btn--disconnected{color:var(--danger)}.statusbar .app__btn--warn{color:var(--warn)}.statusbar .app__btn--connected{color:var(--text-dim)}.statusbar .app__btn--connected:hover:not(:disabled){background:var(--bg-hover);color:var(--text);border-color:#0000}button.statusbar__conn{cursor:pointer;font:inherit}.statusbar__conn:hover{background:var(--bg-hover)}.vc-sketch-presets{border-top-color:var(--border)!important}.phone-viewport{width:100%;min-height:0;box-shadow:0 12px 48px var(--shadow-pop);cursor:default;flex:auto;position:relative}.phone__screen{scrollbar-width:none;-ms-overflow-style:none;width:100%;height:100%;padding:16px;position:relative;overflow:hidden auto}.phone__screen--bg-checker{background-color:#fff;background-image:linear-gradient(45deg,#cfcfcf 25%,#0000 25% 75%,#cfcfcf 75%),linear-gradient(45deg,#cfcfcf 25%,#0000 25% 75%,#cfcfcf 75%);background-position:0 0,8px 8px;background-size:16px 16px}.phone__screen--bg-white{background:#fff}.phone__screen--bg-gray{background:#f0f0f0}.phone__screen--bg-black{background:#1c1c1e}.phone__screen::-webkit-scrollbar{display:none}.ce-sel-overlay{pointer-events:none;box-sizing:border-box;z-index:var(--z-overlay-low);background:#4285f42e;position:absolute}.ce-guides{pointer-events:none;z-index:var(--z-overlay-low);position:absolute;top:0;left:0}.ce-guide{background:#68ffff;position:absolute}.ce-guide--v{width:1px;height:100%;top:0;transform:translate(-.5px)}.ce-guide--h{width:100%;height:1px;left:0;transform:translateY(-.5px)}.debug{min-width:var(--debug-min,33.333vw);background:var(--bg-panel);flex-direction:column;flex:auto;display:flex}.apipanel{width:var(--api-panel-width,360px);background:var(--bg-panel);border-left:var(--hairline) solid var(--border);flex-direction:column;flex:none;min-width:0;max-width:100%;min-height:0;display:flex}.apipanel__head{border-bottom:var(--hairline) solid var(--border);flex:none;align-items:center;gap:8px;height:40px;padding:0 12px;display:flex}.apipanel__title{color:var(--text);white-space:nowrap;font-size:13px;font-weight:600}.apipanel__spacer{flex:auto}.apipanel__btn{width:28px;height:28px;color:var(--text-dim);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:8px;flex:none;justify-content:center;align-items:center;padding:0;transition:background .15s,color .15s,border-color .15s,transform 50ms;display:inline-flex}.apipanel__btn:hover:not(:disabled){background:var(--bg-hover);border-color:var(--border);color:var(--text)}.apipanel__btn:active:not(:disabled){transform:translateY(1px)}.apipanel__btn:disabled{opacity:.5;cursor:default}.apipanel__body{flex-direction:column;flex:auto;display:flex;overflow:auto}.apipanel__body>.empty-state{flex:auto;min-height:0}.apipanel__body>.debug__list{flex:none}.apipanel__tools{align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-3);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);z-index:var(--z-sticky);flex:none;display:flex;position:sticky;top:0;left:0}.apipanel__filter-wrap{flex:auto;align-items:center;min-width:0;display:flex;position:relative}.apipanel__search-ic{color:var(--text-faint);pointer-events:none;position:absolute;top:50%;left:9px;transform:translateY(-50%)}.apipanel__filter{width:100%;min-width:0;height:var(--ctrl-sm);background:var(--bg-input);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);outline:none;flex:auto;padding:0 10px 0 30px;font-family:inherit;font-size:12px;transition:border-color .15s,box-shadow .15s}.apipanel__filter::placeholder{color:var(--text-faint)}.apipanel__filter:focus{border-color:var(--accent-border);box-shadow:0 0 0 2px var(--accent-soft)}.apipanel__follow{width:var(--ctrl-sm);height:var(--ctrl-sm);border-radius:var(--radius-sm);color:var(--text-faint);cursor:pointer;background:0 0;border:1px solid #0000;flex:none;justify-content:center;align-items:center;padding:0;transition:background .15s,color .15s,border-color .15s;display:inline-flex}.apipanel__follow:hover{background:var(--bg-hover);border-color:var(--border);color:var(--text)}.apipanel__follow.is-on{color:var(--accent);background:var(--accent-soft)}.apipanel__right{flex:none;align-items:center;gap:6px;display:flex}.apipanel__meta{font-variant-numeric:tabular-nums;color:var(--text-faint);white-space:nowrap;font-family:SF Mono,JetBrains Mono,Menlo,Consolas,monospace;font-size:10px}.apipanel__op{width:var(--ctrl-sm);height:var(--ctrl-sm);border-radius:var(--radius-sm);color:var(--text-faint);cursor:pointer;background:0 0;border:1px solid #0000;flex:none;justify-content:center;align-items:center;padding:0;transition:background .15s,color .15s,border-color .15s;display:inline-flex}.apipanel__op:hover{background:var(--bg-hover);border-color:var(--border);color:var(--text)}.apipanel__op--del:hover{background:var(--danger-soft);border-color:var(--danger-border);color:var(--danger)}.empty-state{min-height:100%;color:var(--text-faint);flex-direction:column;justify-content:center;align-items:center;gap:12px;padding:16px;display:flex}.empty-state__badge{background:var(--bg-hover);border:1px dashed var(--border-strong);width:48px;height:48px;color:var(--text-faint);border-radius:50%;justify-content:center;align-items:center;display:inline-flex}.empty-state__badge svg{width:20px;height:20px}.empty-state__hint{max-width:240px;color:var(--text-faint);text-align:center;margin:0;font-size:11px;line-height:1.6}.debug__tabs{border-bottom:var(--hairline) solid var(--border);display:flex}.debug__tab{height:39px;color:var(--text-dim);cursor:pointer;background:0 0;border:none;flex:1;padding:10px 8px;font-size:13px;transition:color .15s;position:relative}.debug__tab:hover{color:var(--text)}.debug__tab--active{color:var(--accent)}.debug__tab--active:after{content:"";background:var(--accent);height:2px;position:absolute;bottom:-1px;left:20%;right:20%}.debug__count{background:var(--bg-hover);min-width:16px;color:var(--text-dim);border-radius:999px;margin-left:5px;padding:0 5px;font-size:12px;display:inline-block}.debug__body{flex:auto;position:relative;overflow:auto}.hist{flex-direction:column;min-height:100%;display:flex}.hist__bar{border-bottom:var(--hairline) solid var(--border);align-items:center;gap:8px;padding:8px 12px;display:flex}.hist>.empty-state{flex:auto;min-height:0}.hist__title{color:var(--text-dim);font-size:12px}.hist__count{color:var(--text-faint);margin-left:auto;font-size:11px}.hist__refresh{border-radius:var(--radius-sm);width:24px;height:24px;color:var(--text-dim);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.hist__refresh svg{width:14px;height:14px}.hist__refresh:hover{background:var(--bg-hover);color:var(--text)}.hist__refresh:disabled{cursor:default;opacity:.6}.hist__refresh.is-busy svg{animation:.8s linear infinite app__spin}.hist__loading{text-align:center;color:var(--text-faint);padding:40px 0;font-size:12px}.hist__timeline{padding:8px 12px 16px}.hist__group+.hist__group{margin-top:2px}.hist__group-label{color:var(--text-faint);letter-spacing:.02em;padding:6px 0 4px 22px;font-size:11px}.hist__item{gap:10px;display:flex}.hist__rail{flex:none;justify-content:center;width:12px;display:flex;position:relative}.hist__rail:after{content:"";background:var(--border-strong);width:1px;position:absolute;top:16px;bottom:-2px}.hist__timeline .hist__item:last-child .hist__rail:after{display:none}.hist__dot{z-index:1;background:var(--bg-panel);border:1.5px solid var(--border-strong);border-radius:50%;width:8px;height:8px;margin-top:5px;position:relative}.hist__card{background:var(--bg-panel);border:var(--hairline) solid var(--border);border-radius:var(--radius-sm);flex:1;min-width:0;margin-bottom:8px}.hist__card-head{align-items:baseline;gap:8px;padding:7px 10px 4px;display:flex}.hist__time{color:var(--text);font-variant-numeric:tabular-nums;font-size:12px}.hist__rel{color:var(--text-faint);font-size:11px}.hist__id{color:var(--text-faint);margin-left:auto;font-size:11px}.hist__badge{border:var(--hairline) solid var(--border-strong);color:var(--text-dim);border-radius:999px;padding:1px 6px;font-size:10px;line-height:1.5}.hist__restore{border:var(--hairline) solid var(--border);border-radius:var(--radius-xs);height:22px;color:var(--text-dim);cursor:pointer;background:0 0;flex:none;align-self:center;align-items:center;gap:4px;margin-left:4px;padding:0 8px;font-size:11px;line-height:1;transition:background .15s,border-color .15s,color .15s;display:inline-flex}.hist__restore:hover{background:var(--bg-hover);border-color:var(--border-strong);color:var(--text)}.hist__restore svg{width:12px;height:12px}.hist__restore:disabled{cursor:default;opacity:.6}.hist__restore.is-busy svg{animation:.8s linear infinite app__spin}.hist__card-body{gap:10px;padding:2px 10px 10px;display:flex}.hist__thumb{border:var(--hairline) solid var(--border);border-radius:var(--radius-xs);background:var(--bg-hover);cursor:zoom-in;flex:none;justify-content:center;align-items:center;width:84px;height:120px;display:flex;overflow:hidden}.hist__thumb img{object-fit:cover;object-position:top center;width:100%;height:100%;display:block}.hist__thumb:hover{border-color:var(--border-strong)}.hist__thumb--broken,.hist__thumb--none{color:var(--text-faint);cursor:default;font-size:10px}.hist__info{flex:1;min-width:0}.hist__tags{flex-wrap:wrap;gap:4px;display:flex}.hist__tag{border:1px solid var(--border-strong);color:var(--text-dim);border-radius:999px;padding:3px 6px;font-size:10px;line-height:1}.hist__tag--ok{color:var(--ok);border-color:var(--ok)}.hist__tag--danger{color:var(--danger);border-color:var(--danger)}.hist__tag--warn{color:var(--warn);border-color:var(--warn)}.hist__tag--accent{color:var(--accent);border-color:var(--accent)}.hist__tag--muted{color:var(--text-faint)}.hist__meta{color:var(--text-faint);margin-top:6px;font-size:11px;line-height:1.6}.hist__more{border:var(--hairline) solid var(--border-strong);color:var(--text-dim);cursor:pointer;background:0 0;border-radius:999px;margin:2px auto 0;padding:5px 14px;font-size:11px;display:block}.hist__more:hover{background:var(--bg-hover);color:var(--text)}.hist__more:disabled{cursor:default;opacity:.6}.hist__preview-mask{z-index:var(--z-appmodal);background:var(--scrim-modal);-webkit-backdrop-filter:blur(var(--scrim-modal-blur));backdrop-filter:blur(var(--scrim-modal-blur));justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.hist__preview-img{border-radius:var(--radius);max-width:92%;max-height:88%;box-shadow:var(--shadow-pop)}.hist__preview-x{background:var(--bg-panel);border:var(--hairline) solid var(--border);border-radius:var(--radius-sm);width:26px;height:26px;color:var(--text-dim);cursor:pointer;justify-content:center;align-items:center;padding:0;display:inline-flex;position:absolute;top:10px;right:10px}.hist__preview-x svg{width:13px;height:13px}.hist__preview-x:hover{color:var(--text);border-color:var(--border-strong)}.debug__meta{flex-direction:column;min-height:100%;margin:0;padding:0 12px 12px;display:flex}.debug__meta>.empty-state{flex:auto;min-height:0}.debug__empty{color:var(--text-faint);text-align:center;margin:0;font-size:13px}.debug__meta-list{flex-direction:column;gap:8px;margin:0;display:flex}.debug__meta-row{grid-template-columns:88px 1fr;align-items:baseline;gap:8px;font-size:13px;display:grid}.debug__meta-row dt{color:var(--text-faint);margin:0}.debug__meta-row dd{color:var(--text);word-break:break-all;margin:0}.debug__meta-row code{font-family:var(--mono,ui-monospace, monospace);background:var(--bg-hover);border-radius:4px;padding:1px 5px;font-size:12px}.debug__meta-muted{color:var(--text-faint);font-size:12px}.debug__version{font-family:var(--mono,ui-monospace, monospace);background:var(--bg-hover);color:var(--accent);border-radius:4px;padding:1px 5px;font-size:12px}.debug__meta-refresh{vertical-align:middle;border:var(--hairline) solid var(--border);width:20px;height:20px;color:var(--text-faint);cursor:pointer;background:0 0;border-radius:4px;justify-content:center;align-items:center;margin-left:6px;padding:0;transition:background .15s,color .15s;display:inline-flex}.debug__meta-refresh:hover:not(:disabled){background:var(--bg-hover);color:var(--accent)}.debug__meta-refresh svg{width:14px;height:14px}.debug__meta-copy{vertical-align:middle;border:var(--hairline) solid var(--border);width:20px;height:20px;color:var(--text-faint);cursor:pointer;background:0 0;border-radius:4px;justify-content:center;align-items:center;margin-left:6px;padding:0;transition:background .15s,color .15s;display:inline-flex}.debug__meta-copy:hover:not(:disabled){background:var(--bg-hover);color:var(--accent)}.debug__meta-copy svg{width:14px;height:14px}.debug__meta-history{vertical-align:middle;border:var(--hairline) solid var(--border);width:20px;height:20px;color:var(--text-faint);cursor:pointer;background:0 0;border-radius:4px;justify-content:center;align-items:center;margin-left:6px;padding:0;transition:background .15s,color .15s;display:inline-flex}.debug__meta-history:hover:not(:disabled){background:var(--bg-hover);color:var(--accent)}.debug__meta-history svg{width:14px;height:14px}.pv-mask{z-index:var(--z-appmodal-top);background:var(--scrim-modal);-webkit-backdrop-filter:blur(var(--scrim-modal-blur));backdrop-filter:blur(var(--scrim-modal-blur));justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.pv-card{background:var(--bg-panel);border:1px solid var(--border);width:640px;max-width:calc(100vw - 32px);max-height:min(640px,100vh - 64px);box-shadow:0 18px 50px var(--shadow-card);color:var(--text);box-sizing:border-box;border-radius:14px;flex-direction:column;padding:16px 0 0;display:flex;overflow:hidden}.pv-head{border-bottom:var(--hairline) solid var(--border);flex:none;align-items:center;gap:10px;padding:0 16px 12px;display:flex}.pv-head__title{flex:auto;align-items:center;gap:8px;min-width:0;font-size:15px;font-weight:600;display:flex}.pv-head__title .app__icon{width:16px;height:16px;color:var(--accent)}.pv-head__count{color:var(--text-faint);font-size:12px;font-weight:400}.pv-head__close{width:26px;height:26px;color:var(--text-faint);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;justify-content:center;align-items:center;padding:0;transition:background .15s,color .15s;display:inline-flex}.pv-head__close:hover{background:var(--bg-hover);color:var(--text)}.pv-head__close .app__icon{width:14px;height:14px}.pv-loading{text-align:center;color:var(--text-faint);padding:32px 16px;font-size:13px}.pv-scroll{overscroll-behavior:contain;flex:auto;min-height:0;overflow-y:auto}.pv-table{border-collapse:collapse;width:100%;font-size:13px}.pv-table__th{text-align:left;color:var(--text-faint);white-space:nowrap;border-bottom:var(--hairline) solid var(--border-strong);padding:8px 14px;font-size:12px;font-weight:500}.pv-table__row+.pv-table__row .pv-table__td{border-top:var(--hairline) solid var(--border)}.pv-table__td{color:var(--text-dim);vertical-align:middle;padding:9px 14px}.pv-table__td--version{white-space:nowrap}.pv-table__td--time{white-space:nowrap;font-variant-numeric:tabular-nums}.pv-table__th--version{width:128px}.pv-table__th--status{width:88px}.pv-version{font-family:var(--mono,ui-monospace, monospace);color:var(--text);font-size:12px}.pv-badge{color:var(--accent);background:var(--accent-soft);border-radius:999px;margin-left:6px;padding:0 6px;font-size:11px;line-height:1.6;display:inline-block}.debug__tag--done{color:var(--text-dim);background:var(--bg-hover)}.pv-more{text-align:center;color:var(--accent);margin:0;padding:10px 14px;font-size:12px}.pv-more--idle{color:var(--text-faint)}.pv-table__th--op{width:76px}.pv-table__td--op{white-space:nowrap}.pv-op{width:22px;height:22px;color:var(--text-dim);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;justify-content:center;align-items:center;padding:0;transition:color .15s,background .15s,border-color .15s;display:inline-flex}.pv-op+.pv-op{margin-left:4px}.pv-op .app__icon{width:14px;height:14px}.pv-op:disabled{cursor:default;color:var(--text-faint);opacity:.38}.pv-op.is-busy{color:var(--accent);opacity:1}.pv-op--stop:hover:not(:disabled){color:var(--danger);border-color:var(--danger-hover);background:var(--danger-soft)}.pv-op--stop.is-busy{color:var(--danger)}.pv-op--publish:hover:not(:disabled){color:var(--accent);border-color:var(--accent-border);background:var(--accent-soft)}.debug__link{color:var(--accent);cursor:pointer;text-decoration:none}.debug__link:hover{text-decoration:underline}.debug__meta-err{color:var(--danger);font-size:12px}.debug__meta-hint{z-index:1;background:var(--bg-panel);border-bottom:var(--hairline) solid var(--border);color:var(--text-faint);margin:0 -12px 8px;padding:10px 12px;font-size:12px;line-height:1.6;position:sticky;top:0}.statepanel{background:var(--bg-panel);border-top:var(--hairline) solid var(--border-strong);flex-direction:column;flex:none;height:240px;min-height:120px;max-height:60vh;display:flex;position:relative;overflow:hidden}.statepanel__head{height:var(--ctrl-lg);border-bottom:var(--hairline) solid var(--border);color:var(--text);flex:none;align-items:center;gap:8px;padding:0 12px;font-size:13px;display:flex}.panelhead__edge{cursor:row-resize;-webkit-user-select:none;user-select:none;height:6px;z-index:var(--z-sticky);position:absolute;top:-3px;left:0;right:0}.panelhead__edge:after{content:"";left:0;right:0;top:calc((6px - var(--splitter-size)) / 2);height:var(--splitter-size);background:linear-gradient(to right, transparent 0%, var(--splitter) 50%, transparent 100%);opacity:0;transition:opacity .15s;position:absolute}.panelhead__edge:hover:after,.panelhead__edge.is-dragging:after{opacity:1}.statepanel__title{letter-spacing:.2px;font-weight:600}.statepanel__title code{font-family:var(--mono,ui-monospace, SFMono-Regular, Menlo, monospace);color:var(--text-dim);background:var(--bg-hover);border-radius:4px;padding:1px 5px;font-size:12px}.statepanel__close{width:24px;height:24px;color:var(--text-dim);cursor:pointer;border-radius:var(--radius-xs);background:0 0;border:none;justify-content:center;align-items:center;margin-left:auto;padding:0;transition:background .15s,color .15s;display:inline-flex}.statepanel__close:hover{background:var(--bg-hover);color:var(--text)}.statepanel__close svg{display:block}.statepanel__tree{flex:auto;padding:0;display:flex;overflow:hidden}.debug__tag{border-radius:999px;padding:1px 8px;font-size:12px;line-height:1.6;display:inline-block}.debug__tag--ok{color:var(--ok-strong);background:var(--ok-soft)}.debug__tag--warn{color:var(--tag-warn-fg);background:var(--tag-warn-bg)}.debug__tag--err{color:var(--danger);background:var(--danger-soft)}.debug__list{margin:0;padding:0 12px 8px;list-style:none}.debug__item{word-break:normal;overflow-wrap:anywhere;border-radius:8px;margin-bottom:6px;padding:9px 11px;font-size:12px;line-height:1.6}.debug__item--err{border-left:2px solid var(--danger);border-bottom:var(--hairline) solid var(--border);color:var(--err-item-fg);word-break:normal;background:0 0;border-radius:0;grid-template-columns:52px 84px minmax(0,1fr);align-items:baseline;gap:8px;margin-bottom:0;padding:3px 12px 3px 10px;font-size:11px;line-height:1.45;display:grid}.debug__item--err:last-child{border-bottom:none}.debug__item--err:hover{background:var(--danger-soft)}.debug__item--err .debug__kind{color:var(--danger);text-overflow:ellipsis;white-space:nowrap;opacity:1;font-family:SF Mono,JetBrains Mono,Menlo,Consolas,monospace;font-size:10px;overflow:hidden}.err__msg{word-break:break-word;min-width:0}.debug__item--api{border:1px solid var(--api-item-border);color:var(--api-item-fg);background:var(--api-item-bg);margin-bottom:8px}.debug__item--api:last-child{margin-bottom:0}.debug__item--api .debug__kind{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:SF Mono,JetBrains Mono,Menlo,Consolas,monospace;font-size:12px;line-height:1.6;overflow:hidden}.debug__kind{opacity:.85;font-weight:600}.debug__api-row{justify-content:space-between;align-items:center;gap:8px;display:flex}.debug__copy-ic{width:24px;height:22px;color:var(--text-faint);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;flex:none;justify-content:center;align-items:center;padding:0;transition:background .15s,color .15s,border-color .15s;display:inline-flex}.debug__copy-ic:hover{background:var(--bg-hover);border-color:var(--border);color:var(--text)}.debug__copy-ok{color:var(--copy-ok);font-size:14px;line-height:1}.apt{color:var(--text-dim);margin-top:4px;font-family:SF Mono,JetBrains Mono,Menlo,Consolas,monospace;font-size:12px;line-height:1.6}.apt__list{margin:0;padding:0;list-style:none}.apt__node{position:relative}.apt__branch,.apt__leaf{cursor:pointer;border-radius:4px;align-items:baseline;gap:4px;padding:1px 4px;display:flex}.apt .jt__colon{margin-left:-4px}.apt .jt__key{flex-shrink:0}.apt .jt__val,.apt .jt__preview{min-width:0}.apt__branch:hover,.apt__leaf:hover{background:var(--bg-hover)}.apt__caret{text-align:center;width:12px;color:var(--text-faint);-webkit-user-select:none;user-select:none;flex:none;font-size:9px;transition:transform .15s;transform:rotate(0)}.apt__caret--open{color:var(--accent);transform:rotate(90deg)}.apt__caret--leaf{visibility:hidden}.apt__children{border-left:var(--hairline) solid var(--border);margin-left:4px;padding-left:16px}.apt__close{color:var(--text-faint);padding:1px 4px 1px 20px}.debug__scope-wrap{flex-direction:column;min-height:0;display:flex;position:absolute;inset:0}.debug__copied{color:var(--accent);margin:0 8px;font-size:12px}.debug__copy{background:var(--bg-input);height:26px;color:var(--text-dim);border:1px solid var(--border-strong);cursor:pointer;border-radius:7px;align-items:center;gap:5px;padding:0 10px;font-size:12px;transition:background .15s,border-color .15s,color .15s;display:inline-flex}.debug__copy:hover{background:var(--bg-hover);border-color:var(--accent-border);color:var(--text)}.debug__copy-icn{flex:none;width:13px;height:13px}.debug__copy--primary:hover{background:var(--ok-soft);border-color:var(--ok-border);color:var(--ok)}.debug__copy--warn:hover{background:var(--warn-soft);border-color:var(--warn-border);color:var(--warn)}.debug__sep{width:var(--hairline);background:var(--border-strong);height:16px;margin:0 2px}.debug__scope-wrap--raw{flex-direction:column;min-height:0;display:flex}.debug__scope-raw{flex-direction:column;flex:auto;min-height:0;display:flex}.debug__raw-editor{background:var(--bg-input);width:100%;min-height:160px;color:var(--text);tab-size:2;white-space:pre;outline:none;flex:auto;padding:12px 14px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.6;overflow:auto}.debug__raw-editor .token.property,.debug__raw-editor .token.tag,.debug__raw-editor .token.boolean,.debug__raw-editor .token.number,.debug__raw-editor .token.constant,.debug__raw-editor .token.symbol,.vars-dlg__code .token.property,.vars-dlg__code .token.tag,.vars-dlg__code .token.boolean,.vars-dlg__code .token.number,.vars-dlg__code .token.constant,.vars-dlg__code .token.symbol{color:var(--code-prop)}.debug__raw-editor .token.selector,.debug__raw-editor .token.attr-name,.debug__raw-editor .token.string,.debug__raw-editor .token.char,.debug__raw-editor .token.builtin,.vars-dlg__code .token.selector,.vars-dlg__code .token.attr-name,.vars-dlg__code .token.string,.vars-dlg__code .token.char,.vars-dlg__code .token.builtin{color:var(--code-str)}.debug__raw-editor .token.operator,.debug__raw-editor .token.entity,.debug__raw-editor .token.url,.vars-dlg__code .token.operator,.vars-dlg__code .token.entity,.vars-dlg__code .token.url{color:var(--code-num)}.debug__raw-editor .token.punctuation,.vars-dlg__code .token.punctuation{color:var(--code-punc)}.debug__raw-editor .token.keyword,.debug__raw-editor .token.null,.vars-dlg__code .token.keyword,.vars-dlg__code .token.null{color:var(--code-kw)}.debug__raw-editor .token.function,.debug__raw-editor .token.class-name,.vars-dlg__code .token.function,.vars-dlg__code .token.class-name{color:var(--code-fn)}.raw-err-bar{color:var(--danger,#ef4444);background:var(--danger-soft,#ef44441f);flex:none;align-items:center;gap:6px;padding:4px 10px;font-size:11px;line-height:1.5;display:flex}.raw-err-bar__icn{flex:0 0 12px;width:12px;height:12px}.raw-err-bar__msg{flex:auto;min-width:0}.raw-err-bar__close{width:18px;height:18px;color:inherit;opacity:.7;cursor:pointer;background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;font-size:11px;line-height:1;transition:opacity .12s;display:inline-flex}.raw-err-bar__close:hover{opacity:1}.vars{flex-direction:column;height:100%;min-height:0;display:flex;position:relative}.vars__list{flex-direction:column;flex:auto;gap:2px;min-height:0;margin:0;padding:8px 8px 52px;list-style:none;display:flex;overflow-y:auto}.vars__row{-webkit-user-select:none;user-select:none;border-radius:6px;align-items:center;gap:6px;padding:4px 6px;transition:background .12s;display:flex}.vars__row:hover{background:var(--bg-hover)}.vars__key{text-overflow:ellipsis;white-space:nowrap;max-width:46%;color:var(--text);flex:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;overflow:hidden}.vars__type{border-radius:var(--radius-pill);background:var(--bg-active);color:var(--text-dim);flex:none;padding:1px 6px;font-size:10px;line-height:1.5}.vars__type--string{color:var(--type-string);background:color-mix(in srgb, var(--type-string) 14%, transparent)}.vars__type--number{color:var(--type-number);background:color-mix(in srgb, var(--type-number) 14%, transparent)}.vars__type--boolean{color:var(--type-boolean);background:color-mix(in srgb, var(--type-boolean) 14%, transparent)}.vars__type--array{color:var(--type-array);background:color-mix(in srgb, var(--type-array) 14%, transparent)}.vars__type--object{color:var(--type-object);background:color-mix(in srgb, var(--type-object) 14%, transparent)}.vars__mock{background:var(--warn-soft);width:14px;height:14px;color:var(--warn);border-radius:50%;flex:none;justify-content:center;align-items:center;font-size:9px;line-height:1;display:inline-flex}.vars__name{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--text-faint);flex:auto;font-size:11px;overflow:hidden}.vars__ops{opacity:0;flex:none;gap:2px;transition:opacity .12s;display:inline-flex}.vars__row:hover .vars__ops,.vars__row:focus-within .vars__ops{opacity:1}.vars__op{width:20px;height:20px;color:var(--text-faint);cursor:pointer;background:0 0;border:none;border-radius:4px;justify-content:center;align-items:center;padding:0;transition:background .12s,color .12s;display:inline-flex}.vars__op svg{width:13px;height:13px;display:block}.vars__op:hover{background:var(--bg-active);color:var(--text)}.vars__op--del:hover{background:var(--danger-soft);color:var(--danger)}.vars__op:disabled,.vars__op:disabled:hover{color:var(--text-faint);opacity:.35;cursor:default;background:0 0}.vars__op .debug__copy-ok{font-size:12px}.vars__fabs,.structab__fabs,.debug__scope-foot{background:var(--bg-bar);border:1px solid var(--border-strong);box-shadow:0 6px 18px var(--shadow-toast);border-radius:7px;align-items:center;padding:0;display:flex;position:absolute;bottom:10px;right:10px;overflow:hidden}.vars__fabs .debug__copy,.structab__fabs .debug__copy,.debug__scope-foot .debug__copy{background:0 0;border:none;border-radius:0;height:28px;padding:0 12px}.vars__fabs .debug__copy:hover,.structab__fabs .debug__copy:hover,.debug__scope-foot .debug__copy:hover{background:var(--bg-hover);border-color:#0000}.vars__fabs .debug__copy+.debug__copy,.structab__fabs .debug__copy+.debug__copy{border-left:var(--hairline) solid var(--border)}.debug__scope-foot .debug__sep{width:var(--hairline);background:var(--border);align-self:stretch;height:auto;margin:0}.debug__scope-foot .debug__copy--primary:hover{background:var(--ok-soft);color:var(--ok);border-color:#0000}.debug__scope-foot .debug__copy--warn:hover{background:var(--warn-soft);color:var(--warn);border-color:#0000}.structab{flex-direction:column;height:100%;min-height:100%;display:flex;position:relative}.structab>.st{flex:auto;height:auto;min-height:0;padding-bottom:48px;overflow-y:auto}.schemaview{z-index:var(--z-modal,1000);background:var(--scrim-modal);-webkit-backdrop-filter:blur(var(--scrim-modal-blur));backdrop-filter:blur(var(--scrim-modal-blur));flex-direction:column;padding:4vh 4vw;display:flex;position:fixed;inset:0}.schemaview__bar{background:var(--bg-bar);border:1px solid var(--border);border-bottom:none;border-radius:10px 10px 0 0;flex:none;align-items:center;gap:10px;padding:8px 14px;display:flex}.schemaview__title{color:var(--text);align-items:center;gap:8px;font-size:13px;font-weight:600;display:inline-flex}.schemaview__card{background:var(--bg-active);border:1px solid var(--border);color:var(--text-dim);border-radius:5px;padding:1px 7px;font-size:12px;font-style:normal;font-weight:400}.schemaview__meta{color:var(--text-faint);font-size:12px}.schemaview__acts{align-items:center;gap:4px;margin-left:auto;display:inline-flex}.schemaview__btn{width:26px;height:26px;color:var(--text-dim);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:0;transition:background .15s,color .15s;display:inline-flex}.schemaview__btn svg{width:15px;height:15px}.schemaview__btn:hover{background:var(--bg-hover);color:var(--text)}.schemaview__btn.is-done{color:var(--ok)}.schemaview__body{background:var(--bg-bar);border:1px solid var(--border);border-radius:0 0 10px 10px;flex:auto;min-height:0;overflow:auto}.schemaview__tree{padding:10px 14px 16px;font-size:12px}.vars__mockhead{border-bottom:var(--hairline) solid var(--border);flex:none;align-items:center;gap:8px;padding:5px 10px;display:flex}.vars__back{background:var(--bg-bar);border:1px solid var(--border-strong);height:24px;color:var(--text);cursor:pointer;border-radius:6px;flex:none;align-items:center;gap:4px;padding:0 9px 0 7px;font-size:12px;font-weight:500;transition:background .15s,color .15s,border-color .15s;display:inline-flex}.vars__back:hover{background:var(--accent-soft);border-color:var(--accent-border);color:var(--accent)}.vars__back svg{width:12px;height:12px}.vars__mocktitle{color:var(--text-faint);font-size:11px}.ni-panel.vars-dlg{width:560px;height:auto;min-height:0;max-height:80vh}.vars-dlg .ni-field-label i{color:var(--danger);margin-right:2px;font-style:normal}.ni-field-row--top{align-items:flex-start}.ni-field-row--top .ni-field-label{line-height:var(--ctrl-sm)}.vars-dlg__ctrl{flex:auto;min-width:0}.vars-type-pick{align-items:center;gap:8px;min-width:0;display:flex}.vars-type-pick .vars__type{flex:none}.vars-type-pick__name{white-space:nowrap;text-overflow:ellipsis;min-width:3em;color:var(--text);flex:none;overflow:hidden}.vars-dlg__code,.vars-dlg__str{min-height:171.6px;max-height:264px}.vars-dlg__code{background:var(--bg-input);border:1px solid var(--border-strong);min-width:0;color:var(--text);tab-size:2;white-space:pre;border-radius:6px;outline:none;flex:auto;padding:8px 12px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.6;transition:border-color .15s;overflow:auto}.vars-dlg__code:focus{border-color:var(--accent)}.ni-input.vars-dlg__str{resize:vertical;height:auto;padding:8px 12px;line-height:1.6;overflow:auto}.vars-dlg__desc{resize:vertical;height:auto;min-height:90.8px;max-height:140px;line-height:1.6}.vars-dlg__err{color:var(--danger);margin:2px 0 0;font-size:11px}.ni-panel.newcard-dlg{width:420px;height:auto;min-height:0;max-height:80vh}.newcard-dlg .ni-field-label i{color:var(--danger);margin-right:2px;font-style:normal}.newcard-dlg .ni-body{padding:14px 0}.newcard-dlg .ni-scroll{padding:0 16px;overflow:visible}.newcard-dlg .ni-field-row:last-of-type{margin-bottom:0}.newcard-dlg__err{color:var(--danger);margin:12px 0 0;font-size:11px}.newcard-dlg .ni-input.newcard-dlg__input--dup,.newcard-dlg .ni-input.newcard-dlg__input--dup:focus{border-color:var(--danger)}.vars__mockhint{color:var(--text-faint);margin-left:auto;font-size:11px}.statusbar{background:var(--bg-bar);border-top:var(--hairline) solid var(--border);height:28px;color:var(--text-dim);-webkit-user-select:none;user-select:none;flex:none;order:3;align-items:stretch;padding:0 2px;font-size:12px;display:flex}.statusbar__spacer{flex:auto}.statusbar__item{white-space:nowrap;cursor:default;align-items:center;gap:5px;height:100%;padding:0 10px;display:inline-flex}.statusbar__item--right{color:var(--text-faint)}.statusbar__item--prob{cursor:pointer;color:var(--text-dim);background:0 0;border:none;border-radius:0;font-weight:400}.statusbar__item--prob:hover{color:var(--text)}.statusbar__item--prob.is-error,.statusbar__item--prob.is-error:hover{color:var(--danger)}.statusbar__item--prob.is-ok{color:var(--text-faint);cursor:default}.statusbar__item--prob.is-ok:hover{color:var(--text-faint)}.statusbar__icon{font-size:14px;line-height:1}.statusbar__icon.is-dirty{color:var(--warn)}.errpanel{background:var(--bg-panel);border-top:var(--hairline) solid var(--border-strong);flex-direction:column;flex:none;height:240px;min-height:120px;max-height:60vh;display:flex;position:relative;overflow:hidden}.errpanel__head{height:var(--ctrl-lg);border-bottom:var(--hairline) solid var(--border);color:var(--text);flex:none;align-items:center;gap:8px;padding:0 12px;font-size:13px;display:flex}.errpanel__title{letter-spacing:.2px;font-weight:600}.errpanel__actions{align-items:center;gap:6px;margin-left:auto;display:flex}.errpanel__iconbtn{width:24px;height:24px;color:var(--text-dim);cursor:pointer;border-radius:var(--radius-xs);background:0 0;border:none;justify-content:center;align-items:center;padding:0;transition:background .15s,color .15s;display:inline-flex}.errpanel__iconbtn:hover:not(:disabled){background:var(--bg-hover);color:var(--text)}.errpanel__iconbtn svg{display:block}.errpanel__iconbtn:disabled{opacity:.35;cursor:not-allowed}.errpanel__clear:hover:not(:disabled){color:var(--danger)}.errpanel__tabs{flex:none;align-self:stretch;align-items:stretch;gap:2px;margin-left:4px;display:flex}.errpanel__tab{height:100%;color:var(--text-dim);cursor:pointer;background:0 0;border:none;align-items:center;gap:5px;padding:0 10px;font-size:12px;transition:color .15s;display:inline-flex;position:relative}.errpanel__tab:hover{color:var(--text)}.errpanel__tab--active{color:var(--accent)}.errpanel__tab--active:after{content:"";background:var(--accent);height:2px;position:absolute;bottom:-1px;left:20%;right:20%}.errpanel__tab-count{background:var(--bg-hover);min-width:16px;color:var(--text-faint);text-align:center;border-radius:999px;padding:0 5px;font-size:11px;line-height:15px}.errpanel__tab--active .errpanel__tab-count{background:var(--accent-soft);color:var(--accent)}.errpanel__tab-count.is-hit,.errpanel__tab--active .errpanel__tab-count.is-hit{background:var(--danger-soft);color:var(--danger)}.errpanel__body{flex:auto;padding:4px 0 6px;overflow:auto}.errpanel__body .empty-state{gap:8px;padding:20px 16px}.errpanel__body .empty-state__badge{width:40px;height:40px}.errpanel__body .empty-state__badge svg{width:18px;height:18px}.errpanel__body .empty-state__hint{max-width:460px}.errpanel__body--term{color:#e8eaf0;background:#14161c;padding:0}.svclog{padding:6px 0 10px;font-family:SF Mono,JetBrains Mono,Menlo,Consolas,monospace;font-size:11.5px;line-height:1.55}.svclog__line{white-space:pre-wrap;word-break:break-word;border-left:2px solid #0000;min-height:1.55em;padding:0 12px;display:flex}.svclog__line:hover{background:#ffffff0b}.svclog__line--ok{border-left-color:#34d3998c}.svclog__line--warn{border-left-color:var(--warn);background:#fbbf2412}.svclog__line--error{border-left-color:var(--danger);background:#f8717114}.svclog__text{min-width:0}.svclog__meta{color:var(--text-faint);white-space:nowrap;align-items:center;gap:5px;margin-left:8px;font-size:11px;display:inline-flex}.svclog__dot{background:var(--text-faint);border-radius:50%;width:6px;height:6px;margin-left:4px}.svclog__dot.is-live{background:var(--ok);box-shadow:0 0 0 2px var(--ok-soft)}.svclog__follow.is-on{color:var(--accent)}.errpanel__iconbtn.is-done{color:var(--ok)}.debug__list--log{flex-direction:column;display:flex}.log__item{border-bottom:var(--hairline) solid var(--border);grid-template-columns:52px 44px minmax(0,1fr);align-items:baseline;gap:8px;padding:2px 12px;display:grid}.log__item:last-child{border-bottom:none}.log__item:hover{background:var(--bg-input)}.log__time,.err__time{font-variant-numeric:tabular-nums;color:var(--text-faint);font-family:SF Mono,JetBrains Mono,Menlo,Consolas,monospace;font-size:10px}.log__tag{text-transform:uppercase;letter-spacing:.3px;color:var(--text-dim);background:var(--bg-hover);border:none;border-radius:3px;justify-self:start;padding:0 5px;font-family:SF Mono,JetBrains Mono,Menlo,Consolas,monospace;font-size:10px;font-weight:600;line-height:14px}.log__tag--info{color:var(--accent);background:var(--accent-soft)}.log__tag--warn{color:var(--log-warn-fg);background:var(--log-warn-bg)}.log__tag--error{color:var(--danger);background:var(--danger-soft)}.log__content{min-width:0;color:var(--text);flex-wrap:wrap;flex:auto;align-items:flex-start;gap:3px 8px;font-family:SF Mono,JetBrains Mono,Menlo,Consolas,monospace;font-size:11px;line-height:1.45;display:flex}.log__val{white-space:pre-wrap;word-break:break-word}.log__json{flex:100%;padding:0}.log__json .apt{margin-top:0;font-size:11px;line-height:1.4}.log__json .apt__branch--root{cursor:pointer;border-radius:4px}.log__json .apt__list--nested{border-left:var(--hairline) solid var(--border);margin-left:4px;padding-left:14px}.log__empty{color:var(--text-faint)}.alert-layer{z-index:var(--z-modal);position:absolute;inset:0}.alert-mask{background:#0000008c;padding:16px;display:flex;position:absolute;inset:0}.alert-mask--bottom{justify-content:center;align-items:flex-end}.alert-mask--top{justify-content:center;align-items:flex-start}.alert-mask--center{justify-content:center;align-items:center}.alert-mask--left{justify-content:flex-start;align-items:center}.alert-mask--right{justify-content:flex-end;align-items:center}.alert-panel{background:#fff;border-radius:12px;width:100%;max-width:100%;max-height:92vh;animation:.2s ease-out alert-pop;overflow:hidden auto;box-shadow:0 18px 60px #00000080}@keyframes alert-pop{0%{opacity:0;transform:scale(.96)translateY(8px)}to{opacity:1;transform:scale(1)translateY(0)}}.alert-mask--center .alert-panel,.alert-mask--left .alert-panel,.alert-mask--right .alert-panel{border-radius:12px}.device-ui{z-index:var(--z-deviceui);pointer-events:none;position:absolute;inset:0}.phone-viewport .van-toast{z-index:var(--z-deviceui);position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.dlg-mask{pointer-events:auto;background:#00000073;justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.dlg{text-align:center;background:#fff;border-radius:12px;width:288px;max-width:82%;padding:24px 20px 0;animation:.2s ease-out dlg-pop;box-shadow:0 12px 40px #00000059}@keyframes dlg-pop{0%{opacity:0;transform:scale(.94)}to{opacity:1;transform:scale(1)}}.dlg__title{color:#333;font-size:16px;font-weight:600}.dlg__msg{color:#666;text-align:left;word-break:break-all;white-space:pre-wrap;max-height:320px;margin-top:10px;font-size:14px;line-height:1.5;overflow-y:auto}.dlg__title+.dlg__msg{margin-top:12px}.dlg__btns{border-top:var(--hairline) solid #e8e8e8;margin:18px -20px 0;display:flex}.dlg__btn{cursor:pointer;background:0 0;border:none;flex:1 1 0;min-width:0;padding:14px 0;font-size:15px}.dlg__btn--ok{color:#1677ff;font-weight:500}.dlg__btn--cancel{color:#1677ff;border-right:var(--hairline) solid #e8e8e8}.dlg__btn--cancel.dlg__btn--gray{color:#888}.apptoast{z-index:var(--z-toast-app);color:#fff;pointer-events:none;background:#111111d1;border-radius:10px;align-items:center;gap:8px;max-width:76%;padding:12px 20px;font-size:14px;line-height:1.4;display:inline-flex;position:fixed;top:56px;left:50%;transform:translate(-50%);box-shadow:0 6px 24px #00000047}.apptoast__icon{background:var(--text-faint);border-radius:50%;flex:none;justify-content:center;align-items:center;width:18px;height:18px;display:inline-flex}.apptoast--ok .apptoast__icon{background:var(--ok)}.apptoast--err .apptoast__icon{background:var(--danger)}.apptoast--warn .apptoast__icon{background:var(--warn);color:var(--on-warn)}.apptoast__icon-svg{fill:none;stroke:#fff;stroke-width:2.6px;stroke-linecap:round;stroke-linejoin:round;width:12px;height:12px}.apptoast__msg{word-break:break-all}.apptoast-fade-enter-active,.apptoast-fade-leave-active{transition:opacity .2s,transform .2s}.apptoast-fade-enter,.apptoast-fade-leave-to{opacity:0;transform:translate(-50%,-8px)}.dlg-fade-enter-active,.dlg-fade-leave-active{transition:opacity .18s}.dlg-fade-enter,.dlg-fade-leave-to{opacity:0}.pk-mask{pointer-events:auto;background:#0006;align-items:flex-end;display:flex;position:absolute;inset:0}.pk-sheet{background:#fff;border-radius:12px 12px 0 0;width:100%;animation:.2s ease-out pk-up}@keyframes pk-up{0%{transform:translateY(100%)}to{transform:translateY(0)}}.pk-bar{box-sizing:border-box;border-bottom:var(--hairline) solid #eef0f2;justify-content:space-between;align-items:center;height:44px;padding:0 16px;display:flex}.pk-bar__title{color:#333;font-size:15px;font-weight:600}.pk-bar__btn{cursor:pointer;background:0 0;border:none;padding:4px 2px;font-size:15px}.pk-bar__btn--cancel{color:#888}.pk-bar__btn--ok{color:#1677ff;font-weight:600}.picker-fade-enter-active,.picker-fade-leave-active{transition:opacity .18s}.picker-fade-enter,.picker-fade-leave-to{opacity:0}.rp-mask{z-index:var(--z-appmodal);background:var(--scrim-modal);-webkit-backdrop-filter:blur(var(--scrim-modal-blur));backdrop-filter:blur(var(--scrim-modal-blur));justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.rp-card{background:var(--bg-panel);border:1px solid var(--border);width:300px;max-width:calc(100vw - 32px);box-shadow:0 18px 50px var(--shadow-card);color:var(--text);border-radius:14px;overflow:hidden}.rp-head{border-bottom:var(--hairline) solid var(--border);justify-content:space-between;align-items:center;padding:12px 14px;display:flex}.rp-title{font-size:14px;font-weight:600}.rp-x{width:26px;height:26px;color:var(--text-dim);cursor:pointer;background:0 0;border:none;border-radius:7px;font-size:20px;line-height:1;transition:background .15s,color .15s}.rp-x:hover{background:var(--bg-hover);color:var(--text)}.rp-body{flex-direction:column;align-items:center;padding:18px 16px 16px;display:flex}.rp-qr-wrap{box-sizing:border-box;background:#fff;border-radius:10px;justify-content:center;align-items:center;width:220px;height:220px;padding:8px;display:flex;position:relative}.rp-qr{width:204px;height:204px;display:block}.rp-qr--loading{width:100%;height:100%;color:var(--text-placeholder);justify-content:center;align-items:center;font-size:14px;display:flex}.rp-qr--blurred{filter:blur(7px);opacity:.55;transition:filter .25s,opacity .25s}.rp-qr-loading{background:#ffffff80;border-radius:12px;flex-direction:column;justify-content:center;align-items:center;gap:10px;display:flex;position:absolute;inset:0}.rp-spinner{border:3px solid #10131a2e;border-top-color:var(--accent);border-radius:50%;width:30px;height:30px;animation:.8s linear infinite rp-spin}.rp-loading-text{color:var(--text-dim);font-size:13px}@keyframes rp-spin{to{transform:rotate(360deg)}}.rp-tip{color:var(--text-dim);text-align:center;margin:12px 0 10px;font-size:12.5px}.rp-url{align-items:center;gap:8px;width:100%;display:flex}.rp-url-text{min-width:0;color:var(--text-dim);background:var(--bg-input);border:1px solid var(--border);text-overflow:ellipsis;white-space:nowrap;border-radius:7px;flex:auto;padding:6px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;overflow:hidden}.rp-copy{border:1px solid var(--accent-border);background:var(--accent);color:var(--on-accent);cursor:pointer;border-radius:7px;flex:none;padding:6px 10px;font-size:12px;transition:background .15s,opacity .15s}.rp-copy:hover:not(:disabled){background:var(--accent-hover)}.rp-copy:disabled{opacity:.5;cursor:default}.app--chrome-off .app__stage{justify-content:center}.app--chrome-off .phone-viewport{box-shadow:none}.app--chrome-off .phone__screen{width:375px;margin:0 auto;padding:0}.rp-warn{color:var(--warn);text-align:center;margin:10px 0 0;font-size:11.5px;line-height:1.5}.login-mask{z-index:var(--z-appmodal);background:var(--scrim-modal);-webkit-backdrop-filter:blur(var(--scrim-modal-blur));backdrop-filter:blur(var(--scrim-modal-blur));justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.login-modal{background:var(--bg-panel);border:1px solid var(--border);width:320px;max-width:calc(100vw - 32px);box-shadow:0 18px 50px var(--shadow-card);color:var(--text);box-sizing:border-box;border-radius:14px;padding:18px 18px 16px}.login-modal__title{margin-bottom:6px;font-size:15px;font-weight:600}.login-modal__desc{color:var(--text-dim);margin-bottom:14px;font-size:12px;line-height:1.5}.login-modal__row{align-items:center;gap:10px;margin-bottom:12px;display:flex}.login-modal__label{color:var(--text-dim);flex:0 0 36px;font-size:13px}.login-modal__input{min-width:0;height:34px;color:var(--text);background:var(--bg-input);border:1px solid var(--border);box-sizing:border-box;border-radius:8px;outline:none;flex:auto;padding:0 10px;font-size:13px}.login-modal__input:focus{border-color:var(--accent)}.login-modal__error{color:var(--danger);margin-bottom:10px;font-size:12px}.login-modal__actions{justify-content:flex-end;gap:10px;margin-top:4px;display:flex}.login-modal__btn{border:1px solid var(--border);cursor:pointer;border-radius:8px;padding:7px 14px;font-size:13px;transition:background .15s,opacity .15s,border-color .15s}.login-modal__btn--ghost{color:var(--text-dim);background:0 0}.login-modal__btn--ghost:hover:not(:disabled){background:var(--bg-hover);color:var(--text)}.login-modal__btn--primary{border-color:var(--accent-border);background:var(--accent);color:var(--on-accent)}.login-modal__btn--primary:hover:not(:disabled){background:var(--accent-hover)}.login-modal__btn:disabled{opacity:.5;cursor:default}.confirm-mask{z-index:var(--z-appmodal);background:var(--scrim-modal);-webkit-backdrop-filter:blur(var(--scrim-modal-blur));backdrop-filter:blur(var(--scrim-modal-blur));justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.confirm-modal{background:var(--bg-panel);border:1px solid var(--border);width:360px;max-width:calc(100vw - 32px);box-shadow:0 18px 50px var(--shadow-card);color:var(--text);box-sizing:border-box;border-radius:14px;padding:18px 18px 16px}.confirm-modal__title{align-items:center;gap:8px;margin-bottom:8px;font-size:15px;font-weight:600;display:flex}.confirm-modal__title.is-danger{color:var(--danger)}.confirm-modal__title.is-warn{color:var(--warn)}.confirm-modal__icon{flex:none;width:18px;height:18px}.confirm-modal__icon :is(path,line,polyline,circle,rect){vector-effect:non-scaling-stroke}.confirm-modal__desc{color:var(--text-dim);white-space:pre-line;word-break:break-word;margin-bottom:16px;font-size:12.5px;line-height:1.6}.confirm-modal__actions{justify-content:flex-end;gap:10px;display:flex}.confirm-modal__btn{border:1px solid var(--border);cursor:pointer;border-radius:8px;padding:7px 16px;font-size:13px;transition:background .15s,opacity .15s,border-color .15s}.confirm-modal__btn--ghost{color:var(--text-dim);background:0 0}.confirm-modal__btn--ghost:hover{background:var(--bg-hover);color:var(--text)}.confirm-modal__btn--primary{border-color:var(--accent-border);background:var(--accent);color:var(--on-accent)}.confirm-modal__btn--primary:hover{background:var(--accent-hover)}.confirm-modal__btn--danger{border-color:var(--danger);background:var(--danger);color:var(--on-accent)}.confirm-modal__btn--danger:hover{background:var(--danger-hover)}.confirm-modal__btn--warn{border-color:var(--warn);background:var(--warn);color:var(--on-warn)}.confirm-modal__btn--warn:hover{background:var(--warn-hover)}.pop-enter-active{transition:opacity .15s,transform .26s cubic-bezier(.34,1.56,.64,1)}.pop-leave-active{transition:opacity .12s,transform .12s}.pop-enter-from,.pop-leave-to{opacity:0;transform:translateY(6px)scale(.95)}.modal-enter-active,.modal-leave-active{transition:opacity .2s}.modal-leave-active{transition:opacity .16s}.modal-enter-from,.modal-leave-to{opacity:0}.modal-enter-active .modal-card{transition:transform .34s cubic-bezier(.34,1.56,.64,1)}.modal-leave-active .modal-card{transition:transform .16s}.modal-enter-from .modal-card{transform:translateY(14px)scale(.94)}.modal-leave-to .modal-card{transform:translateY(6px)scale(.98)}html,body,#app{width:100%;height:100%;margin:0;padding:0}.card-preview{background:#fff;justify-content:center;align-items:flex-start;width:100%;min-height:100%;display:flex}.card-preview .phone__screen{height:auto;min-height:100%;margin:0 auto;padding:0;overflow:hidden}
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>CardBuddy Standalone Card Preview</title>
7
- <script type="module" crossorigin src="/assets/standalone-pP5kTKiI.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/standalone-BCLshIzC.css">
7
+ <script type="module" crossorigin src="/assets/standalone-CeVX_y-M.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/standalone-DiEiY59H.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="app"></div>
@@ -1,23 +1,23 @@
1
1
  ---
2
- name: finmall-card-sync
3
- description: 通过 API 把 FinMall UAT 卡片列表项纯接口同步进本工程的 src/cards(card-list IDC10001.do + 按 cardId 取 schema 的 IDC10012.do),从已登录的浏览器页面拉取,下载封面图、根据卡片变量派生运行时 data.json 并保存可复用产物;也负责把卡片引用的 src/slices 切图上传到 FinMall 图片库(CC0000.do)并把 schema 里的 /slices/ 引用改写为 @filestore/ 线上地址(scripts/slice_upload.mjs)。不依赖编辑器 UI,也不做 Monaco DOM 抓取。当 Codex 需要拉取或刷新 FinMall 卡片的封面 / schema / data 文件,或需要上传切图拿到图片在线地址时使用。
2
+ name: platform-card-sync
3
+ description: 通过 API 把远端 UAT 卡片列表项纯接口同步进本工程的 src/cards(card-list IDC10001.do + 按 cardId 取 schema 的 IDC10012.do),从已登录的浏览器页面拉取,下载封面图、根据卡片变量派生运行时 data.json 并保存可复用产物;也负责把卡片引用的 src/slices 切图上传到远端图片库(CC0000.do)并把 schema 里的 /slices/ 引用改写为 @filestore/ 线上地址(scripts/slice_upload.mjs)。不依赖编辑器 UI,也不做 Monaco DOM 抓取。当 Codex 需要拉取或刷新远端卡片的封面 / schema / data 文件,或需要上传切图拿到图片在线地址时使用。
4
4
  ---
5
5
 
6
- # FinMall 卡片同步
6
+ # 远端卡片同步
7
7
 
8
- 通过 API 把 FinMall 的卡片从 UAT 卡片列表同步进 `src/cards/<englishCardId>/`。
8
+ 通过 API 把远端的卡片从 UAT 卡片列表同步进 `src/cards/<englishCardId>/`。
9
9
 
10
10
  ## 前置条件
11
11
 
12
- 1. 先使用 `finmall-session-navigator` 打开并鉴权卡片列表页。
12
+ 1. 先使用 `platform-session-navigator` 打开并鉴权卡片列表页。
13
13
  2. 保持已启动的 Chrome 以远程调试模式运行(端口由 `CARDBUDDY_CDP_PORT` 配置,默认 `9222`)。
14
- 3. 确保 `skills/finmall-session-navigator/scripts/node_modules/playwright` 存在;本 skill 复用该依赖。
14
+ 3. 确保 `skills/platform-session-navigator/scripts/node_modules/playwright` 存在;本 skill 复用该依赖。
15
15
 
16
16
  ## 环境配置
17
17
 
18
18
  域名、appId、workspaceId 等从工程环境配置读取。优先级:环境变量 > `.env.cb.local` > `.env.cb` > 内置默认值。
19
19
 
20
- 完整配置表见 `finmall-session-navigator` 的 SKILL.md。每次运行通过下方 CLI 参数覆盖时,参数优先于配置文件。
20
+ 完整配置表见 `platform-session-navigator` 的 SKILL.md。每次运行通过下方 CLI 参数覆盖时,参数优先于配置文件。
21
21
 
22
22
  ## 快速开始
23
23
 
@@ -26,7 +26,7 @@ description: 通过 API 把 FinMall UAT 卡片列表项纯接口同步进本工
26
26
  在工程根目录运行批量同步:
27
27
 
28
28
  ```bash
29
- node skills/finmall-card-sync/scripts/api_batch_sync.mjs --startPage 1
29
+ node skills/platform-card-sync/scripts/api_batch_sync.mjs --startPage 1
30
30
  ```
31
31
 
32
32
  > 使用任意 Node 22+(如托管运行时 `~/.workbuddy/binaries/node/versions/<ver>/bin/node`)。脚本会自动把 `127.0.0.1` 从 `HTTP_PROXY` 中排除,以便访问本地 Chrome 调试端口。
@@ -38,15 +38,15 @@ node skills/finmall-card-sync/scripts/api_batch_sync.mjs --startPage 1
38
38
  - `--maxCards 10`:限制同步卡片数量(便于冒烟测试)。
39
39
  - `--outRoot src/cards`:覆盖输出根目录(相对于工程根)。
40
40
  - `--cdpUrl http://127.0.0.1:9222`:覆盖 Chrome CDP 端点。
41
- - `--appId 100042 --workspaceId dev`:覆盖 FinMall 应用 / 工作空间标识(默认来自 `.env.cb`)。
41
+ - `--appId 100042 --workspaceId dev`:覆盖远端应用 / 工作空间标识(默认来自 `.env.cb`)。
42
42
 
43
43
  ## 鉴权
44
44
 
45
45
  **完整鉴权模型(不用 Cookie / `_sessionId` 双层编码 / 列表接口不鉴权的坑 / `_sessionId` 存在 ≠ 服务端有效 / token 头使用纪律 / Playwright Chrome 150 兼容性补丁)见 `shared/auth-model.md` §一、§二**——跨 skill 集中陈述的权威方。本节只列与本同步 skill 直接相关的操作要点:
46
46
 
47
- - 每个 `IDC1xxxx.do` 调用都必须带 `token` 请求头(取 localStorage `_sessionId`,双层编码,仅在页面上下文内使用)。本 skill 的 `finmallPost` 在 `page.evaluate` 内部读取它并直接使用——**绝不要**把该值拷贝到 Node 侧、打印日志或落盘。
47
+ - 每个 `IDC1xxxx.do` 调用都必须带 `token` 请求头(取 localStorage `_sessionId`,双层编码,仅在页面上下文内使用)。本 skill 的 `platformPost` 在 `page.evaluate` 内部读取它并直接使用——**绝不要**把该值拷贝到 Node 侧、打印日志或落盘。
48
48
  - `IDC10001.do`(卡片列表)**不**鉴权,所以会话早已失效时列表页仍能完整渲染。而 `IDC10012.do` 这类鉴权接口随后就会报 `BLEC0006 会话超时`。仅凭可见页面内容判断登录状态是不可靠的。
49
- - **同步时遇到 `会话超时`**:重新运行 `finmall-session-navigator` 刷新会话即可;若导航器报告 `hasSession:true / attempts:0` 但同步仍报超时,按 `auth-model.md` §1.4 的指引——`localStorage.clear()` 后重登。
49
+ - **同步时遇到 `会话超时`**:重新运行 `platform-session-navigator` 刷新会话即可;若导航器报告 `hasSession:true / attempts:0` 但同步仍报超时,按 `auth-model.md` §1.4 的指引——`localStorage.clear()` 后重登。
50
50
 
51
51
  ## 输出约定
52
52
 
@@ -73,7 +73,7 @@ node skills/finmall-card-sync/scripts/api_batch_sync.mjs --startPage 1
73
73
 
74
74
  ### 空白卡片(远端无 schemaValue)
75
75
 
76
- `IDC10012.do` 返回 `errorCode: "0"` 但**没有 `schemaValue`**,不一定是入参主键错误——卡片在 FinMall 侧新建后从未保存过 schema(空白卡)时就是这个响应。这是**合法状态**,必须允许同步到本地,不能整批失败。
76
+ `IDC10012.do` 返回 `errorCode: "0"` 但**没有 `schemaValue`**,不一定是入参主键错误——卡片在远端侧新建后从未保存过 schema(空白卡)时就是这个响应。这是**合法状态**,必须允许同步到本地,不能整批失败。
77
77
 
78
78
  判定与落盘规则(`scripts/api_batch_sync.mjs`):
79
79
 
@@ -86,13 +86,13 @@ node skills/finmall-card-sync/scripts/api_batch_sync.mjs --startPage 1
86
86
 
87
87
  > 注意:有 `schemaValue` 的正常卡**不受影响**,仍是远端覆盖本地的老行为。
88
88
 
89
- 这些请求用 `page.evaluate(fetch(...))` 在 FinMall 页面内发起,发送上述 `token` 请求头。以 `@filestore/` 开头的封面路径用 `finmallConfig.filestoreUrl()`(基址来自环境配置)拼成完整 URL。
89
+ 这些请求用 `page.evaluate(fetch(...))` 在远端页面内发起,发送上述 `token` 请求头。以 `@filestore/` 开头的封面路径用 `platformConfig.filestoreUrl()`(基址来自环境配置)拼成完整 URL。
90
90
 
91
91
  ### 网络超时闸门(必须保留)
92
92
 
93
- `page.evaluate` **没有默认超时**:页面里一个永不 settle 的 `fetch` 会让整次同步永久挂起,没有任何日志——实测一次全量同步因此卡死 6 分钟以上且零输出。FinMall 后端与 Filestore 对不存在的对象都可能不响应(既不返回也不报错)。
93
+ `page.evaluate` **没有默认超时**:页面里一个永不 settle 的 `fetch` 会让整次同步永久挂起,没有任何日志——实测一次全量同步因此卡死 6 分钟以上且零输出。远端后端与 Filestore 对不存在的对象都可能不响应(既不返回也不报错)。
94
94
 
95
- 因此 `finmallPost` 与 `saveCover` 都做了**内层 `AbortController` + 外层 `Promise.race`** 双重设防:
95
+ 因此 `platformPost` 与 `saveCover` 都做了**内层 `AbortController` + 外层 `Promise.race`** 双重设防:
96
96
 
97
97
  | 环境变量 | 默认值 | 作用 |
98
98
  |---|---|---|
@@ -114,7 +114,7 @@ node skills/finmall-card-sync/scripts/api_batch_sync.mjs --startPage 1
114
114
  ## 切图上传(`/slices/` → `@filestore/` 线上地址)
115
115
 
116
116
  `scripts/slice_upload.mjs` 实现 `slices_convention.md` 的「③ 远程同步」阶段:把卡片引用的
117
- `src/slices/` 切图上传到 FinMall 图片库,产出「本地文件 ↔ 线上地址」映射,并把卡片里的
117
+ `src/slices/` 切图上传到远端图片库,产出「本地文件 ↔ 线上地址」映射,并把卡片里的
118
118
  `/slices/<name>` 引用改写为线上地址,使卡片推到远端后取得到图。
119
119
 
120
120
  ### 触发方式(**没有任何自动上传路径**)
@@ -122,7 +122,7 @@ node skills/finmall-card-sync/scripts/api_batch_sync.mjs --startPage 1
122
122
  | 入口 | 范围 | 说明 |
123
123
  |---|---|---|
124
124
  | 编辑器顶栏「远端 → 切图上传」 | 当前卡片 | 用户点击才执行,先二次确认;`card-editor/App.vue → uploadCardSlices()` → `POST /__slice-upload` |
125
- | MCP `card_slice_upload` | 单卡(`cardId` 必填) | 需 dev server + FinMall 登录态,不支持离线降级 |
125
+ | MCP `card_slice_upload` | 单卡(`cardId` 必填) | 需 dev server + 远端登录态,不支持离线降级 |
126
126
  | CLI(下方命令) | 默认全部卡片,可 `--cardId` 收窄 | 批量补做 / 排障用 |
127
127
 
128
128
  保存、版本推送、同步都**不会**顺带上传切图。若卡片仍引用 `/slices/`,推上去线上就是取不到图——
@@ -130,11 +130,11 @@ node skills/finmall-card-sync/scripts/api_batch_sync.mjs --startPage 1
130
130
 
131
131
  ```bash
132
132
  # 单卡(等价于顶栏按钮)
133
- node skills/finmall-card-sync/scripts/slice_upload.mjs --cardId pointsDetail
133
+ node skills/platform-card-sync/scripts/slice_upload.mjs --cardId pointsDetail
134
134
  # 全部卡片里仍引用 /slices/ 的切图
135
- node skills/finmall-card-sync/scripts/slice_upload.mjs
135
+ node skills/platform-card-sync/scripts/slice_upload.mjs
136
136
  # 只看计划不上传不写盘
137
- node skills/finmall-card-sync/scripts/slice_upload.mjs --dry-run
137
+ node skills/platform-card-sync/scripts/slice_upload.mjs --dry-run
138
138
  ```
139
139
 
140
140
  常用选项:`--only=a.png,b.png`(指定文件)、`--all`(连未被引用的切图一起传)、
@@ -145,7 +145,7 @@ node skills/finmall-card-sync/scripts/slice_upload.mjs --dry-run
145
145
  ### 接口契约(`CC0000.do`,已实测)
146
146
 
147
147
  ```
148
- POST {baseUrl}/ubomp-web/CC0000.do?sassAppId=<FINMALL_APP_ID>&sassWorkspaceId=<FINMALL_WORKSPACE_ID>
148
+ POST {baseUrl}/ubomp-web/CC0000.do?sassAppId=<PLATFORM_APP_ID>&sassWorkspaceId=<PLATFORM_WORKSPACE_ID>
149
149
  Content-Type: multipart/form-data
150
150
  fileName = 客服.png # 纯文本原文件名
151
151
  file = <二进制> # 带 filename 与 Content-Type: image/png
@@ -207,7 +207,7 @@ headers: token / iCIFID / eCIFID = localStorage._sessionId(只在页面上下
207
207
 
208
208
  | 现象 | 原因 / 处理 |
209
209
  |---|---|
210
- | `FinMall 上传失败 [errorCode=BLEC0006]` | 会话超时;脚本已自动重登重试,仍失败就重跑 `finmall-session-navigator` |
210
+ | `远端上传失败 [errorCode=BLEC0006]` | 会话超时;脚本已自动重登重试,仍失败就重跑 `platform-session-navigator` |
211
211
  | 汇总里出现「悬空引用」 | schema 引用了 `src/slices` 下不存在的文件(常见于 `generate_cards.mjs` 全量运行清空过切图),先 `git checkout -- src/slices/` 或重跑生成 |
212
212
  | CLI 跑完进程不退出 | 已修:CLI 末尾显式 `process.exit`(后台 Chrome 的 CDP 连接会挂住事件循环);Chrome 进程本身按约定常驻不关 |
213
213
  | 想撤销改写 | `git checkout -- src/cards/<id>/`;清单里的地址仍有效,重跑一次即可再改写回来 |
@@ -217,7 +217,7 @@ headers: token / iCIFID / eCIFID = localStorage._sessionId(只在页面上下
217
217
  编辑器顶栏「远端 → 推送」走 `POST /__save`(`saveCardToRemote`)。**推送成功后**,服务端会用无头
218
218
  Chrome 渲染当前卡片(`server/core/screenshot.js → generateCardCover`:透明底、与卡片实际渲染尺寸
219
219
  1:1 的 PNG),再把这张图作为**远端列表预览图**上传(`uploadCardPreview` → `IDC10014.do`),
220
- 使 FinMall 卡片列表的缩略图与刚推上去的内容一致。
220
+ 使远端卡片列表的缩略图与刚推上去的内容一致。
221
221
 
222
222
  | 项 | 值 |
223
223
  |---|---|
@@ -233,8 +233,8 @@ POST {baseUrl}/ubomp-web/IDC10014.do # 注意:sassAppId/Workspace 走
233
233
  Content-Type: multipart/form-data
234
234
  cardId = 10000363 # 数字型 cardId(= schema.pageId)
235
235
  file = <二进制 PNG> # filename = <cardId>.png
236
- sassAppId = <FINMALL_APP_ID>
237
- sassWorkspaceId = <FINMALL_WORKSPACE_ID>
236
+ sassAppId = <PLATFORM_APP_ID>
237
+ sassWorkspaceId = <PLATFORM_WORKSPACE_ID>
238
238
  headers: token = localStorage._sessionId(只在页面上下文内读取,不出页面)
239
239
  ```
240
240
 
@@ -242,7 +242,7 @@ headers: token = localStorage._sessionId(只在页面上下文内读取,不
242
242
  纯文本字段);②`sassAppId/Workspace` 在表单里;③filename 固定 `<cardId>.png`(抓包里该 part 的
243
243
  Content-Type 是 `application/octet-stream`,照抄);④鉴权头只有 `token`。
244
244
 
245
- 响应判定按 FinMall 通用信封做**宽松**处理(`parsePreviewUploadResponse`):空响应体视为成功;
245
+ 响应判定按远端通用信封做**宽松**处理(`parsePreviewUploadResponse`):空响应体视为成功;
246
246
  非 JSON 非空(网关 HTML 错误页)报错;`header.errorCode` 与 `body.errorCode` **逐个**检查
247
247
  (不能用 `a || b` 短路——`header.errorCode='0'` 会把 body 的业务错误盖掉);成功时尽力取
248
248
  `body.picUrl | previewUrl | imageUrl | filePath | url`,取不到不影响「上传成功」。命中