devagent-ignition 0.1.0__py3-none-any.whl

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 (133) hide show
  1. devagent_hmi.py +471 -0
  2. devagent_ignition-0.1.0.dist-info/METADATA +204 -0
  3. devagent_ignition-0.1.0.dist-info/RECORD +133 -0
  4. devagent_ignition-0.1.0.dist-info/WHEEL +4 -0
  5. devagent_ignition-0.1.0.dist-info/entry_points.txt +2 -0
  6. devagent_spatial/__init__.py +1 -0
  7. devagent_spatial/_resources/README.md +187 -0
  8. devagent_spatial/_resources/RELEASE_MANIFEST.json +312 -0
  9. devagent_spatial/_resources/SHA256SUMS.txt +270 -0
  10. devagent_spatial/_resources/SOURCE_PROVENANCE.json +186 -0
  11. devagent_spatial/_resources/assets/agent.js +102 -0
  12. devagent_spatial/_resources/assets/creator.css +247 -0
  13. devagent_spatial/_resources/assets/creator_2d.mjs +16 -0
  14. devagent_spatial/_resources/assets/creator_original_r9.mjs +58 -0
  15. devagent_spatial/_resources/assets/creator_original_v8.mjs +120 -0
  16. devagent_spatial/_resources/assets/creator_r9_diagnostics.mjs +53 -0
  17. devagent_spatial/_resources/assets/creator_scene.mjs +128 -0
  18. devagent_spatial/_resources/assets/creator_ui.mjs +60 -0
  19. devagent_spatial/_resources/assets/customer_documents.js +110 -0
  20. devagent_spatial/_resources/assets/equipment_controls.mjs +27 -0
  21. devagent_spatial/_resources/assets/facility2d.css +24 -0
  22. devagent_spatial/_resources/assets/facility2d_app.mjs +45 -0
  23. devagent_spatial/_resources/assets/facility2d_core.mjs +114 -0
  24. devagent_spatial/_resources/assets/facility2d_simulation.mjs +167 -0
  25. devagent_spatial/_resources/assets/facility2d_viewer.html +7 -0
  26. devagent_spatial/_resources/assets/fallback_scene.js +17 -0
  27. devagent_spatial/_resources/assets/flow_geometry.mjs +218 -0
  28. devagent_spatial/_resources/assets/harness.js +78 -0
  29. devagent_spatial/_resources/assets/live_design_review.js +129 -0
  30. devagent_spatial/_resources/assets/operations_ui.js +305 -0
  31. devagent_spatial/_resources/assets/operator_viewer.html +64 -0
  32. devagent_spatial/_resources/assets/project_package.js +52 -0
  33. devagent_spatial/_resources/assets/r9_transport.mjs +70 -0
  34. devagent_spatial/_resources/assets/runtime_feed.js +30 -0
  35. devagent_spatial/_resources/assets/studio.html +139 -0
  36. devagent_spatial/_resources/assets/style.css +191 -0
  37. devagent_spatial/_resources/assets/test_workspace.html +195 -0
  38. devagent_spatial/_resources/assets/three_scene.js +442 -0
  39. devagent_spatial/_resources/assets/unified_engineer.js +101 -0
  40. devagent_spatial/_resources/assets/v076_fat_ui.js +40 -0
  41. devagent_spatial/_resources/assets/v078_command_ui.js +44 -0
  42. devagent_spatial/_resources/assets/viewer.html +45 -0
  43. devagent_spatial/_resources/assets/viewer.js +112 -0
  44. devagent_spatial/_resources/design-system.json +130 -0
  45. devagent_spatial/_resources/examples/CV101-command-contract-PENDING.json +30 -0
  46. devagent_spatial/_resources/examples/cv101_guided.json +272 -0
  47. devagent_spatial/_resources/examples/make_examples.py +36 -0
  48. devagent_spatial/_resources/examples/single_floor.json +444 -0
  49. devagent_spatial/_resources/examples/v0771_training_wizard.json +11 -0
  50. devagent_spatial/_resources/examples/warehouse-3floor-standard-2d.json +708 -0
  51. devagent_spatial/_resources/examples/warehouse-operations-synthetic.json +1186 -0
  52. devagent_spatial/_resources/examples/warehouse-v07-lab-bindings-PENDING.json +372 -0
  53. devagent_spatial/_resources/examples/warehouse.json +708 -0
  54. devagent_spatial/_resources/examples/water.json +288 -0
  55. devagent_spatial/_resources/reference/r9-golden/REFERENCE_SHA256.json +13 -0
  56. devagent_spatial/_resources/reference/r9-golden/web/app.mjs +745 -0
  57. devagent_spatial/_resources/reference/r9-golden/web/index.html +213 -0
  58. devagent_spatial/_resources/reference/r9-golden/web/lab_panel.mjs +53 -0
  59. devagent_spatial/_resources/reference/r9-golden/web/model.mjs +367 -0
  60. devagent_spatial/_resources/reference/r9-golden/web/state_adapter.mjs +78 -0
  61. devagent_spatial/_resources/reference/r9-golden/web/styles.css +76 -0
  62. devagent_spatial/_resources/reference/r9-original/README_R9.md +27 -0
  63. devagent_spatial/_resources/reference/r9-original/SHA256SUMS.txt +63 -0
  64. devagent_spatial/_resources/reference/r9-original/SNAPSHOT_SHA256SUMS.txt +16 -0
  65. devagent_spatial/_resources/reference/r9-original/flow_routes.json +527 -0
  66. devagent_spatial/_resources/reference/r9-original/flow_sim.py +117 -0
  67. devagent_spatial/_resources/reference/r9-original/lab_control.py +73 -0
  68. devagent_spatial/_resources/reference/r9-original/web/app.mjs +745 -0
  69. devagent_spatial/_resources/reference/r9-original/web/index.html +213 -0
  70. devagent_spatial/_resources/reference/r9-original/web/lab_panel.mjs +53 -0
  71. devagent_spatial/_resources/reference/r9-original/web/model.mjs +367 -0
  72. devagent_spatial/_resources/reference/r9-original/web/state_adapter.mjs +78 -0
  73. devagent_spatial/_resources/reference/r9-original/web/styles.css +76 -0
  74. devagent_spatial/_resources/reference/r9-original/web/vendor/LICENSE-three.txt +21 -0
  75. devagent_spatial/_resources/reference/r9-original/web/vendor/SHA256SUMS.txt +4 -0
  76. devagent_spatial/_resources/reference/r9-original/web/vendor/addons/controls/OrbitControls.js +1860 -0
  77. devagent_spatial/_resources/reference/r9-original/web/vendor/three.core.js +58773 -0
  78. devagent_spatial/_resources/reference/r9-original/web/vendor/three.module.js +18251 -0
  79. devagent_spatial/_resources/reference/v8-original/README.md +36 -0
  80. devagent_spatial/_resources/reference/v8-original/SHA256SUMS.txt +12 -0
  81. devagent_spatial/_resources/reference/v8-original/model.py +124 -0
  82. devagent_spatial/_resources/reference/v8-original/run_demo.sh +4 -0
  83. devagent_spatial/_resources/reference/v8-original/server.py +100 -0
  84. devagent_spatial/_resources/reference/v8-original/tests/browser_smoke.py +50 -0
  85. devagent_spatial/_resources/reference/v8-original/tests/test_v8.py +144 -0
  86. devagent_spatial/_resources/reference/v8-original/topology.json +24 -0
  87. devagent_spatial/_resources/reference/v8-original/web/app.js +114 -0
  88. devagent_spatial/_resources/reference/v8-original/web/index.html +22 -0
  89. devagent_spatial/_resources/reference/v8-original/web/simulator.html +1 -0
  90. devagent_spatial/_resources/reference/v8-original/web/simulator.js +6 -0
  91. devagent_spatial/_resources/reference/v8-original/web/style.css +16 -0
  92. devagent_spatial/_resources/sample_customer_inputs/Plant_Equipment_Register.csv +4 -0
  93. devagent_spatial/_resources/sample_customer_inputs/Plant_Flow_Requirements.txt +5 -0
  94. devagent_spatial/_resources/sample_customer_inputs/Raw_PLC_Tag_Export.csv +4 -0
  95. devagent_spatial/_resources/templates/warehouse_connections.csv +12 -0
  96. devagent_spatial/_resources/templates/warehouse_equipment.csv +21 -0
  97. devagent_spatial/_resources/templates/warehouse_signals.csv +34 -0
  98. devagent_spatial/_resources/templates/water_connections.csv +7 -0
  99. devagent_spatial/_resources/templates/water_equipment.csv +10 -0
  100. devagent_spatial/_resources/templates/water_signals.csv +12 -0
  101. devagent_spatial/agent_harness.py +299 -0
  102. devagent_spatial/agent_runtime.py +314 -0
  103. devagent_spatial/contract_opc_fat.py +216 -0
  104. devagent_spatial/contract_opc_source.py +265 -0
  105. devagent_spatial/control_intents.py +38 -0
  106. devagent_spatial/customer_intake.py +235 -0
  107. devagent_spatial/engineering_expertise.py +114 -0
  108. devagent_spatial/generator.py +201 -0
  109. devagent_spatial/ignition_native.py +234 -0
  110. devagent_spatial/ignition_project.py +144 -0
  111. devagent_spatial/live_lab_binding.py +128 -0
  112. devagent_spatial/model.py +297 -0
  113. devagent_spatial/native_reference.py +69 -0
  114. devagent_spatial/opc_snapshot.py +87 -0
  115. devagent_spatial/operations.py +284 -0
  116. devagent_spatial/operations_capture.py +47 -0
  117. devagent_spatial/operations_lab.py +64 -0
  118. devagent_spatial/original_r9.py +169 -0
  119. devagent_spatial/original_v8.py +81 -0
  120. devagent_spatial/preflight.py +140 -0
  121. devagent_spatial/preview_simulation.py +189 -0
  122. devagent_spatial/project_package.py +101 -0
  123. devagent_spatial/qualification.py +152 -0
  124. devagent_spatial/strict_json.py +29 -0
  125. devagent_spatial/studio.py +894 -0
  126. devagent_spatial/studio_workflow.py +277 -0
  127. devagent_spatial/test_reporting.py +87 -0
  128. devagent_spatial/v076_opc_fat.py +180 -0
  129. devagent_spatial/v078_commands.py +277 -0
  130. devagent_spatial/v078_native_commands.py +161 -0
  131. devagent_spatial/v07_fat.py +110 -0
  132. devagent_spatial/v07_native.py +318 -0
  133. devagent_spatial/v083_native.py +349 -0
@@ -0,0 +1,186 @@
1
+ {
2
+ "schema": "devagent.spatial.source_provenance.v0.5.3",
3
+ "v083_review": {
4
+ "baseline_commit": "8fd225b05b532e713f82845b1c66d3c772651090",
5
+ "branch": "feature/v083-native-ignition-opc-commissioning",
6
+ "qualification": "V083_QUALIFICATION.json",
7
+ "backup_manifest": ".devagent-backups/precommit-20261026T000224Z/manifest.json",
8
+ "source_and_evidence_archive_sha256": "1c481f4d5c16ed147446512259f41d4bd54a6ef81bb907a5f071eb24968e0c6c",
9
+ "tracked_source_archive_sha256": "74b44181e6e182687509b51d5ad1906b94f296e38bde79bc187826721f99401a",
10
+ "genuine_reference_export_sha256": "e82c2ae0525c3f45196ff43957fe4bdee62459b259eba484b46c8a9c1904fe9d",
11
+ "reference_archive_in_commit": false,
12
+ "original_v8_r9_sources_modified": false,
13
+ "gateway_configuration_mutations_during_review": 0,
14
+ "authenticated_gateway_import": "NOT_EXECUTED",
15
+ "production": "HOLD",
16
+ "other_provenance_fields": "HISTORICAL_RECORDS_PRESERVED"
17
+ },
18
+ "baseline": "devagent-spatial-hmi-engine-v0_3_1-pretest.zip",
19
+ "baseline_sha256": "3aa54fe6a1c86832efdc4c2eb467c4e65598ba3ec9fdd3b823d0688fda51df4e",
20
+ "backed_up_before_modification": true,
21
+ "worktree_isolated_from_baseline": true,
22
+ "approved_r9_export_available": false,
23
+ "gateway_modified": false,
24
+ "studio_modified": false,
25
+ "r9_hmi_modified": false,
26
+ "derived_from_v041_zip": "devagent-spatial-hmi-engine-v0_4_1-r9-style.zip",
27
+ "derived_from_v041_zip_sha256": "158af402da5006b766b93755226b1945fe91eb3cdb4dad1a4f193a8c88a7eb0c",
28
+ "renderer_original_backup_path": ".source-backups/three_scene.js.v041",
29
+ "renderer_changed": "assets/three_scene.js",
30
+ "production_verification": "HOLD",
31
+ "derived_from_v042_zip": "devagent-spatial-hmi-engine-v0_4_2-spatial-lighting.zip",
32
+ "derived_from_v042_zip_sha256": "5fcc2d8ddcbbfc6392c7779f1f25d3fb1814f413263725d6fc1079e6e19dea3c",
33
+ "backup_created_before_mutation": true,
34
+ "baseline_backup_location": "Outside distributed ZIP: local v043_designlock_work/backups",
35
+ "modified_sources": [
36
+ "design-system.json",
37
+ "assets/style.css",
38
+ "assets/studio.html",
39
+ "assets/viewer.html",
40
+ "assets/viewer.js",
41
+ "assets/three_scene.js",
42
+ "devagent_spatial/model.py",
43
+ "devagent_spatial/studio.py"
44
+ ],
45
+ "test_artifacts": "tests/test_design_lock_v043.py",
46
+ "v05_source_archive": "devagent-spatial-hmi-engine-v0_4_3-designlock.zip",
47
+ "v05_source_sha256": "3e7b8ffd8d82198349906b8f005e0999572dfd8abc2280f649e5c43441e6c1da",
48
+ "v05_backup_before_changes": true,
49
+ "v051_parent_zip_sha256": "64f57c553a2f5d790460ddc1ad33a2cf97570354e07ef80955dea10ea618a81b",
50
+ "v051_fix_scope": "OpenAI request compatibility, safe provider error status, bounded timeouts, tests",
51
+ "v052_parent_zip": "devagent-spatial-hmi-engine-v0_5_1-openai-fix.zip",
52
+ "v052_parent_sha256": "e462237b20bf9a0019c4e95d6b1b071671669eb94bfda60507b2bce461ac2c92",
53
+ "v052_backup_before_mutation": true,
54
+ "v052_backup_location": "Outside distributed ZIP: /mnt/data/v052_work/devagent-spatial-hmi-engine-v0_5_1.BACKUP_BEFORE_TOPOLOGY_EDIT",
55
+ "v052_scope": "read-only conceptual 3D shared facility footprint and topology-anchored display routes; original customer model unmodified",
56
+ "v052_original_r9_viewer_source": "NOT_AVAILABLE_SCREENSHOTS_ONLY",
57
+ "v052r1_parent_zip_sha256": "a7912158c8c3245af26afacc196e1b3d72791ea862d95a6577a3cf11fb3ee9a8",
58
+ "v052r1_backup_before_mutation": true,
59
+ "v052r1_scope": "one allowlisted JS module resource / MIME type; three.js runtime and customer model unchanged",
60
+ "v052r1_r9_modified": false,
61
+ "v053_parent_zip": "devagent-spatial-hmi-engine-v0_5_2_r1-viewer-hotfix.zip",
62
+ "v053_parent_sha256": "72a06ecf8fe6d8b7c11862fea1131784833896baacae76c03dd878be22c99bbc",
63
+ "v053_original_R9_golden_archive_sha256": "eb54d1855789a9064f3f7153908a69f3b71067aa5b86d9448fa7bf04ee7e6465",
64
+ "v053_source_archive_supplied": true,
65
+ "v053_gold_reference_sha_manifest": "reference/r9-golden/REFERENCE_SHA256.json",
66
+ "v053_backup_first": true,
67
+ "v053_mutation_scope": [
68
+ "assets/three_scene.js",
69
+ "assets/r9_transport.mjs",
70
+ "devagent_spatial/generator.py",
71
+ "devagent_spatial/qualification.py",
72
+ "devagent_spatial/studio.py",
73
+ "tests/test_r9_golden_transport_v053.py"
74
+ ],
75
+ "v053_backups": "Created outside release at /mnt/data/r9_upgrade_work/backups-v053",
76
+ "v053_read_only_reference_not_used_for_runtime": true,
77
+ "v053_golden_runtime_import": false,
78
+ "v053_ignition_native_export_availability": "NOT_AVAILABLE",
79
+ "v053_r9_original_viewer_was_modified": false,
80
+ "v053_production_verification": "HOLD",
81
+ "v055_parent_zip": "DevAgent_V054_R9_Assembly_Candidate.zip",
82
+ "v055_parent_sha256": "8de7feadbfdda7242785f88c7ff32a24375d210cc0177abb9fa6d2b9d44132f4",
83
+ "v055_backup_before_mutation": true,
84
+ "v055_scope": "viewer-only gradient + WebGL alpha, lighting/shadow, translucent floors, contact occlusion, camera; colored but disabled command buttons",
85
+ "v055_r9_original_viewer_modified": false,
86
+ "v055_dgx_browser_visual_acceptance": "HOLD",
87
+ "v055_gateway_modified": false,
88
+ "v056_parent": "DevAgent_V055_R9_Depth_UI.zip",
89
+ "v056_parent_sha256": "e22e82ad53cb82c493126f9582ffd2154aa97eb11475e6deb53c627a3e304648",
90
+ "v056_backup_created_before_modification": true,
91
+ "v056_immutable_backup_location": "/mnt/data/devagent-v056-build/backups/v055-pristine-before-mutation",
92
+ "v056_scope": "Operational KPI and alarm read-only dashboard, customer mapping manifest, synthetic FAT replay, isolated Studio read-only capture/alias, browser engineering review",
93
+ "v056_original_r9_source_modified": false,
94
+ "v056_original_gateway_modified": false,
95
+ "v056_visual_acceptance": "HOLD_DGX_FIREFOX_REQUIRED",
96
+ "v056_studio_fat": "NOT_EXECUTED",
97
+ "v056_production_release": "HOLD",
98
+ "v057_parent_zip": "DevAgent_V056_R9_Operations_Lab.zip",
99
+ "v057_parent_sha256": "843bce59694d8ffd3a996907617b765a348f755df383b59a98e4c470581ae145",
100
+ "v057_backup_before_mutation": true,
101
+ "v057_change_scope": [
102
+ "devagent_spatial/studio.py",
103
+ "devagent_spatial/studio_workflow.py",
104
+ "assets/studio.html",
105
+ "assets/test_workspace.html",
106
+ "tests/test_studio_workspace_v057.py"
107
+ ],
108
+ "v057_operator_assets_byte_identical_to_v056": true,
109
+ "v057_studio_actual_execution": "PENDING_DGX",
110
+ "v057_production_release": "HOLD",
111
+ "v060_parent_zip": "DevAgent_V057_R3_Simple_Studio.zip",
112
+ "v060_parent_sha256": "aa860a20e87d89d45d4b72f5951ec6e7eba35388585b103bb9253ab1a8ad1db2",
113
+ "v060_backup_before_mutation": true,
114
+ "v060_source_backup": "in working environment devagent-v060-work/source-backup + unmodified parent ZIP",
115
+ "v060_scope": "isolated read-only Studio lab runtime feed into customer preview; no native Gateway deployment",
116
+ "v060_ignition_gateway_modified": false,
117
+ "v060_golden_r9_source_modified": false,
118
+ "v060_production_qualification": "HOLD",
119
+ "v07_parent_zip": "DevAgent_V065_Download.zip",
120
+ "v07_parent_zip_sha256": "dc0839faee398e63f03d9f8b0cbc690e7d4f5f634afcdba0f1a839790f5de6c2",
121
+ "v07_full_source_backup_created_before_modification": true,
122
+ "v07_build_isolated_from_original": true,
123
+ "v07_changes": [
124
+ "devagent_spatial/generator.py",
125
+ "devagent_spatial/v07_native.py",
126
+ "devagent_spatial/v07_fat.py",
127
+ "devagent_hmi.py",
128
+ "tests/test_studio_workspace_v057.py",
129
+ "tests/test_v07_native.py",
130
+ "documentation",
131
+ "pending binding manifest example"
132
+ ],
133
+ "v07_actual_r9_ignition_gateway_export_in_artifact": false,
134
+ "v07_actual_gateway_fat_executed": false,
135
+ "v07_production_decision": "HOLD",
136
+ "v076_extension": {
137
+ "parent_archive": "DevAgent_V0752_Standard_2D_Flow_Creator.zip",
138
+ "parent_sha256": "976bd0cc2d2da0ee255539e891e2756fc58d79fe03daa3e85aacc303fbdeec20",
139
+ "backup_created_before_mutation": "/mnt/data/devagent-backups/v0752-source-before-v076.tar.gz",
140
+ "modifications": [
141
+ "devagent_hmi.py",
142
+ "devagent_spatial/studio.py",
143
+ "devagent_spatial/v076_opc_fat.py",
144
+ "assets/studio.html",
145
+ "assets/unified_engineer.js",
146
+ "assets/v076_fat_ui.js",
147
+ "tests/test_v076_isolated_opc_fat.py",
148
+ "tests/test_v076_opc_fat_http.py"
149
+ ],
150
+ "actual_opc_runtime_test": "NOT_RUN_DEPENDENCY_ASYNCUA_MISSING",
151
+ "real_ignition_gateway": "NOT_VERIFIED",
152
+ "production": "HOLD"
153
+ },
154
+ "v0773_parent_zip": "DevAgent_V0772_Customer_Document_Intake.zip",
155
+ "v0773_parent_sha256": "f72f7ed210fc90a1c82d38837de41d0b566ed91da7453ab3b84181871f115580",
156
+ "v0773_backup": "devagent-backups/v0772-source-pre-v0773-20261022T013053Z.tar.gz",
157
+ "v0773_scope": "source-preserving generated HMI 2D/3D drilldown + locked per-device command intents, no PLC writes",
158
+ "v0773_production": "HOLD",
159
+ "v081_stage1": {
160
+ "base_commit": "25fbb123c40209c18afffc971e0f5bf756036048",
161
+ "backup_before_mutation": "/tmp/devagent-v081-stage1-backup.J0FsBc",
162
+ "original_v8_source": "devagent-warehouse-facility-overview-v8",
163
+ "original_v8_reference": "reference/v8-original",
164
+ "original_v8_source_manifest_sha256": "e33c098d594caad10b8f0300f955ebd3d3958bdc430f9934fac6ed178fa56258",
165
+ "original_v8_files_modified": false,
166
+ "original_r9_reference_modified": false,
167
+ "runtime": "LOOPBACK_IN_MEMORY_SYNTHETIC_ONLY",
168
+ "native_ignition": "NOT_TESTED",
169
+ "physical_plc": "NOT_VERIFIED",
170
+ "production": "HOLD"
171
+ },
172
+ "v082_stage2": {
173
+ "source": "user-supplied devagent-v1j-r9-compact-four-spiral-preview",
174
+ "original_source_tree_unchanged": true,
175
+ "snapshot_copy": "reference/r9-original",
176
+ "pinned_snapshot_manifest_sha256": "c1712712ab5e35f913b27f906e23deca2cbaba9b8737d705975a648a4b49592c",
177
+ "legacy_manifest_mismatch": "web/index.html mismatch; web/vendor/README.txt missing",
178
+ "ignition_native_export": "UNVERIFIED_OR_ABSENT",
179
+ "v081_baseline_commit": "25fbb123c40209c18afffc971e0f5bf756036048",
180
+ "backed_up_before_modification": true,
181
+ "focused_improvement_backup": "/tmp/devagent-v082-r9-backup-YE620I",
182
+ "reference_tree_modified": false,
183
+ "qualification_date": "2026-10-24",
184
+ "production": "HOLD"
185
+ }
186
+ }
@@ -0,0 +1,102 @@
1
+ /* DevAgent BYOM assistant — no credentials saved; human-approved draft only. */
2
+ (()=>{'use strict';
3
+ const el=id=>document.getElementById(id);
4
+ const names=['name','industry','layout','palette','description','equipment_csv','connections_csv','signals_csv','requirements'];
5
+ let draft=null;
6
+ // Connection gate is a browser-session workflow requirement, not a substitute for server authentication.
7
+ // The API secret is never written to browser persistence, cookies, the failure ledger or the DOM.
8
+ let testedConnection=null;
9
+ const signature=()=>JSON.stringify(conn());
10
+ const onboarding=el('byom-onboarding');
11
+ const mount=el('byom-form-mount');
12
+ const settings=el('ai-settings');
13
+ mount.appendChild(settings);
14
+ settings.classList.remove('hidden');
15
+ function setConnected(ok){
16
+ el('creator-ui-shell').hidden=!ok;
17
+ onboarding.classList.toggle('completed',ok);
18
+ onboarding.classList.remove('reconfiguring');
19
+ el('header-ai-status').hidden=!ok;
20
+ el('header-ai-status').setAttribute('aria-expanded','false');
21
+ if(ok){
22
+ const provider=el('ai-provider').selectedOptions[0].textContent;
23
+ el('header-ai-label').textContent=`Connected · ${provider}`;
24
+ el('header-ai-status').setAttribute('aria-label',`Connected to ${provider}. Open AI connection settings`);
25
+ }
26
+ el('connection-indicator').textContent=ok?`Connected · ${el('ai-provider').selectedOptions[0].textContent}`:'Not connected';
27
+ el('connection-indicator').classList.toggle('is-connected',ok);
28
+ el('ai-continue').hidden=!ok;
29
+ el('byom-change').hidden=!ok;
30
+ el('byom-phase').textContent=ok?'AI CONNECTED · READY FOR CUSTOMER INPUTS':'STEP 00 · CONNECTION REQUIRED';
31
+ document.dispatchEvent(new CustomEvent('devagent:ai-connection',{detail:{connected:ok}}));
32
+ }
33
+ function revoke(){
34
+ if(!testedConnection)return;
35
+ testedConnection=null;draft=null;el('ai-approval').classList.add('hidden');
36
+ el('ai-connection-status').textContent='Connection changed — test again to continue';
37
+ setConnected(false);
38
+ }
39
+ function openConnection(){
40
+ // Visiting the visible connection box must not invalidate a successful test.
41
+ // Editing provider, model or credentials is what revokes the session gate.
42
+ if(testedConnection&&testedConnection===signature()){
43
+ onboarding.classList.add('reconfiguring');
44
+ el('header-ai-status').setAttribute('aria-expanded','true');
45
+ }
46
+ onboarding.scrollIntoView({behavior:'smooth',block:'start'});el('ai-provider').focus();}
47
+ window.DevAgentAIFlow={isConnected:()=>Boolean(testedConnection&&testedConnection===signature()),
48
+ requireConnection:()=>{if(testedConnection&&testedConnection===signature())return true;openConnection();return false;},
49
+ openConnection,
50
+ };
51
+ document.addEventListener('devagent:project-reset',()=>{
52
+ draft=null;el('ai-approval').classList.add('hidden');el('ai-result').classList.add('hidden');
53
+ });
54
+ setConnected(false);
55
+ for(const id of ['ai-provider','ai-model','ai-endpoint','ai-key']){
56
+ el(id).addEventListener('input',revoke);el(id).addEventListener('change',revoke);
57
+ }
58
+ el('byom-change').addEventListener('click',openConnection);
59
+ el('header-ai-status').addEventListener('click',()=>{
60
+ if(!testedConnection||testedConnection!==signature())return;
61
+ const opening=!onboarding.classList.contains('reconfiguring');
62
+ onboarding.classList.toggle('reconfiguring',opening);
63
+ el('header-ai-status').setAttribute('aria-expanded',String(opening));
64
+ if(opening){onboarding.scrollIntoView({behavior:'smooth',block:'start'});el('ai-provider').focus();}
65
+ else el('header-ai-status').focus();
66
+ });
67
+ el('ai-continue').addEventListener('click',()=>{if(testedConnection&&testedConnection===signature())el('creator-ui-shell').scrollIntoView({behavior:'smooth',block:'start'});});
68
+ function updateProviderHelp(){
69
+ const p=el('ai-provider').value,local=p==='ollama'||p==='vllm';
70
+ el('ai-key-field').hidden=local;
71
+ el('ai-model').placeholder=local?'Enter your installed local model ID':'Enter exact model ID from your provider';
72
+ el('model-id-tip').textContent=local?'Use the model name installed on your DGX (not a sample name).':'Use the exact model ID available to your account.';
73
+ }
74
+ el('ai-provider').addEventListener('change',()=>{
75
+ // Do not forward an old cloud key after the provider changes.
76
+ el('ai-key').value='';revoke();updateProviderHelp();
77
+ });
78
+ updateProviderHelp();
79
+
80
+ const conn=()=>({provider:el('ai-provider').value,model:el('ai-model').value.trim(),
81
+ endpoint:el('ai-endpoint').value.trim(),api_key:el('ai-key').value});
82
+ const current=()=>Object.fromEntries(names.map(k=>[k,el(k).value]));
83
+ const status=(s)=>{el('ai-result').classList.remove('hidden');el('ai-result').textContent=s;};
84
+ const send=async(path,body)=>{const ctl=new AbortController();const timer=setTimeout(()=>ctl.abort(),60000);
85
+ try{const resp=await fetch(path,{method:'POST',headers:{'Content-Type':'application/json','X-DevAgent-Request':'agent-session-v1'},body:JSON.stringify(body),signal:ctl.signal});
86
+ const data=await resp.json();return {ok:resp.ok,data};}finally{clearTimeout(timer);}};
87
+ el('ai-toggle').addEventListener('click',openConnection);
88
+ el('ai-test').addEventListener('click',async()=>{const btn=el('ai-test');btn.disabled=true;el('ai-connection-status').textContent='Testing provider…';
89
+ try{const r=await send('/api/ai/test',conn());if(r.ok){testedConnection=signature();el('ai-connection-status').textContent=`Connection test PASS · ${r.data.provider} / ${r.data.model}`;
90
+ setConnected(true);el('header-ai-status').focus();
91
+ }else{testedConnection=null;setConnected(false);el('ai-connection-status').textContent=`HOLD: ${r.data.reason||r.data.status}`;}}
92
+ catch(e){testedConnection=null;setConnected(false);el('ai-connection-status').textContent='HOLD: Provider timeout or connection failure';}finally{btn.disabled=false;}});
93
+ el('ai-draft').addEventListener('click',async()=>{if(!window.DevAgentAIFlow.requireConnection())return;const btn=el('ai-draft');btn.disabled=true;draft=null;el('ai-approval').classList.add('hidden');status('Analyzing customer input using a customer-selected model…');
94
+ try{const r=await send('/api/agent/draft',{connection:conn(),request:el('ai-request').value,wizard:current()});
95
+ if(!r.ok){status(`HOLD: ${r.data.reason||r.data.status}\n${r.data.detail||''}`);return;}
96
+ const d=r.data;const info=d.tool_results?.find(x=>x.tool==='validate_engineering_contract');
97
+ status(`${d.status}\n${d.explanation||''}\nEngineering: ${info?.status||'NOT_VERIFIED'} • Assets: ${info?.equipment_count??'?'} • Proposed signals: ${info?.signals_proposed??'?'}\nQuestions: ${(d.questions||[]).join(' | ')||'None'}\nNo change has been applied yet.`);
98
+ if(d.status==='DRAFT_REQUIRES_HUMAN_REVIEW'&&d.fields){draft=d.fields;el('ai-approval').classList.remove('hidden');}
99
+ }catch(e){status('HOLD: Model connection failed or timed out. Existing project unchanged.');}finally{btn.disabled=false;}});
100
+ el('ai-apply').addEventListener('click',()=>{if(!draft)return;for(const k of names){if(typeof draft[k]==='string'){el(k).value=draft[k];el(k).dispatchEvent(new Event('input',{bubbles:true}));}}
101
+ status('DRAFT APPLIED TO FORM ONLY. Review each tab and run deterministic validation. No HMI build, deployment, PLC write or FAT PASS occurred.');draft=null;el('ai-approval').classList.add('hidden');});
102
+ })();
@@ -0,0 +1,247 @@
1
+ /* DevAgent Creator V0.7.2. Modern customer workspace; Operator R9/HMI data logic unchanged. */
2
+ :root{color-scheme:light;--bg:#f4f7f9;--panel:#fff;--card:#f7fafb;--border:#e1e8ee;--text:#172434;--muted:#6c7b8b;--accent:#077f92;--warm:#ae692a;--ok:#087b69;--blue:#136d9f}
3
+ *{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;min-height:100vh;background:#f4f7f9!important;color:#172434;font:14px/1.55 Inter,'Segoe UI',sans-serif;letter-spacing:0;-webkit-font-smoothing:antialiased}p{color:#718093}button,input,select,textarea{font:inherit}button{cursor:pointer;transition:transform .16s,box-shadow .16s,background .16s,border-color .16s}button:not(:disabled):hover{transform:translateY(-1px);filter:none}a{color:#127c94}button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,summary:focus-visible{outline:3px solid #48c3d6;outline-offset:2px}
4
+ .app-header{display:flex;justify-content:space-between;align-items:center;gap:18px;padding:15px max(38px,calc((100vw - 1760px)/2));background:#fff!important;border-bottom:1px solid #e3eaf0;box-shadow:none;position:relative;z-index:8;min-height:84px}
5
+ .brand-lockup,.header-right{display:flex;align-items:center;gap:14px}.brand-mark{width:45px;height:45px;display:flex;align-items:center;justify-content:center;gap:1px;border-radius:13px;background:#102636;color:#fff;font-weight:850;font-size:18px;letter-spacing:-.12em;box-shadow:0 6px 16px #10263618}.brand-mark span:nth-child(2){color:#58d9e7}.brand-title .eyebrow{font-weight:800;color:#8693a1;letter-spacing:.16em;font-size:9px}.breadcrumb-divider{padding:0 7px;color:#cad3db}.brand-title h1{font-size:19px;font-weight:800;letter-spacing:-.045em;line-height:1.2;margin:4px 0 0;color:#1b2c3a}.release-pill{color:#298b9b;background:#e6f7fa;border:1px solid #c9ecf1;border-radius:5px;padding:4px 6px;margin-left:7px;font-size:9px;font-weight:850;letter-spacing:.04em;vertical-align:middle}.header-context{font-size:10px;font-weight:760;letter-spacing:.1em;color:#a0acb6;margin-right:10px}.header-context b{color:#384c5e}.app-header .pill{border:1px solid #dceae7;background:#f0faf7;color:#286658;font-size:10px;font-weight:780;letter-spacing:.05em;padding:9px 13px;border-radius:35px;white-space:nowrap}.lab-dot,.watermark-dot{display:inline-block;width:7px;height:7px;border-radius:100%;background:#29bd9b;margin-right:5px;box-shadow:0 0 0 3px #29bd9b19}.lab-secondary{color:#628b83}
6
+ .wrap{max-width:1760px;display:grid;grid-template-columns:minmax(540px,.93fr) minmax(570px,1.07fr);gap:23px;padding:28px 39px 90px;margin:auto;align-items:start}.wrap>section{min-width:0}.eyebrow{font-size:10px;letter-spacing:.14em;font-weight:800;color:#0c8795}.hero{border:1px solid #dfebee;border-radius:19px;background:linear-gradient(130deg,#fff 8%,#f2fcfb 67%,#e2f5f5);padding:28px 32px 24px;margin-bottom:14px;position:relative;overflow:hidden;min-height:215px;box-shadow:0 10px 30px #173a4b08}.hero-copy{position:relative;z-index:2}.hero .eyebrow{color:#118695;font-size:10px;letter-spacing:.16em}.eyebrow-dot{display:inline-block;width:7px;height:7px;margin-right:7px;background:#15b99f;border-radius:50%;box-shadow:0 0 0 5px #18b49f14}.eyebrow-slash{padding:0 7px;color:#bdced2}.hero h2{font-size:clamp(27px,2.23vw,38px);line-height:1.09;font-weight:810;letter-spacing:-.055em;max-width:600px;color:#142c3d;margin:14px 0 9px}.hero h2 span{color:#118c9e}.hero p{font-size:12px;line-height:1.62;margin:0 0 15px;max-width:480px;color:#617586}.quick-pills{display:flex;flex-wrap:wrap;gap:7px}.quick-pills span{display:inline-flex;align-items:center;border:1px solid #cde5e7;border-radius:6px;padding:5px 9px;background:#ffffffba;color:#47707e;font-size:10px;font-weight:760}.quick-pills span::before{content:'✓';margin-right:7px;color:#16a58f;font-weight:850}.hero-deco{position:absolute;right:-80px;top:-45px;width:340px;height:280px;pointer-events:none;opacity:.8}.hero-orbit{position:absolute;border-radius:50%;border:1px solid #a6dadd8a;transform:rotate(-25deg)}.orbit-1{width:330px;height:180px;right:-40px;top:30px}.orbit-2{width:260px;height:125px;right:2px;top:64px}.hero-line{position:absolute;width:260px;height:2px;right:32px;top:124px;background:linear-gradient(90deg,transparent,#53bec9,transparent);transform:rotate(-30deg)}.hero-node{position:absolute;width:42px;height:22px;border-radius:5px;transform:skewY(-17deg) rotate(10deg);background:#e2faf8;box-shadow:6px 7px #92c9d1,7px 8px 0 1px #5da5b5}.node-a{right:208px;top:150px}.node-b{right:126px;top:103px}.node-c{right:50px;top:61px}
7
+ .guided-bar{display:flex;align-items:center;gap:12px;padding:12px 13px;border-radius:14px;border:1px solid #dbe8ee;background:#fff;margin-bottom:21px;box-shadow:0 4px 16px #19394b06}.guided-icon{display:grid;place-items:center;width:39px;height:39px;flex:0 0 auto;border-radius:11px;background:#e8f9fa;color:#0d97a4;font-size:21px}.guided-copy{flex:1;min-width:0}.guided-copy b{display:block;color:#283d4e;font-weight:800;font-size:12px}.guided-copy small{display:block;color:#81919e;font-size:10px;margin-top:1px}.guided-bar button{white-space:nowrap;border-radius:9px;background:#113947!important;border:1px solid #113947!important;color:#fff!important;font-size:11px;font-weight:820;min-height:40px;padding:8px 14px;box-shadow:0 5px 11px #082c3824}.guided-bar button span{margin-left:7px;font-size:15px}
8
+ .workspace-heading{display:flex;align-items:end;justify-content:space-between;gap:12px;margin:2px 0 12px}.workspace-heading h3{font-size:21px;letter-spacing:-.045em;font-weight:810;margin:4px 0 0;color:#203446}.workspace-progress{font-size:10px;letter-spacing:.09em;color:#81939e;font-weight:760}.workspace-progress b{color:#188d9b;margin-left:3px}
9
+ .steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:5px;background:#eaf0f3;border:1px solid #e2eaf0;border-radius:13px;padding:5px;margin-bottom:10px}.step{background:transparent;border:1px solid transparent;border-radius:9px;min-height:52px;color:#7d8d99;padding:10px 7px;font-size:11px;font-weight:780;line-height:1.22;white-space:normal;box-shadow:none}.step.active{background:#fff;color:#0d7185;border:1px solid #c9e2e8;box-shadow:0 2px 6px #1e445710}.step:hover:not(.active){background:#f9fbfc;color:#3f5e70}.step::first-letter{color:#0e9bad}
10
+ .panel{background:#fff;border:1px solid #e1e9ef;border-radius:15px;box-shadow:0 8px 25px #21415108;padding:25px 28px;margin-bottom:13px;color:#253748}.panel:not(.active-panel){display:none}.panel h2{font-size:24px;letter-spacing:-.045em;color:#203345;font-weight:800;line-height:1.22}.panel>p{font-size:12px;color:#758694;line-height:1.68;margin:0 0 18px}.panel .eyebrow{color:#188c9a}.panel .notice,.notice{background:#edf8fa;border:1px solid #dcf0f2;border-left:3px solid #4bbcca;color:#4c7c86;font-size:11px;padding:12px 14px;border-radius:7px;line-height:1.6}.panel .notice{margin-top:17px}label{color:#415565;font-size:11px;letter-spacing:.015em;font-weight:780;margin:0 0 7px;display:block}input,textarea,select{color:#294353;background:#f9fbfc;border:1px solid #dce6ec;border-radius:9px;padding:11px 13px;font-size:12px;min-height:42px;box-shadow:none}input::placeholder,textarea::placeholder{color:#a1b1bd}input:hover,select:hover,textarea:hover{border-color:#9fcbd4}input:focus,select:focus,textarea:focus{border-color:#40b4c4;background:#fff;box-shadow:0 0 0 4px #45aaba18;outline:0}textarea{font-size:11.5px;min-height:125px;resize:vertical}small.tip,.tip{font-size:10px!important;color:#8b9da9!important;line-height:1.55}.fields{margin-top:16px}.grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.preset-row{gap:7px;margin-bottom:11px}.preset-row button{min-height:37px;padding:8px 11px;background:#f3f8fa;border:1px solid #dce9ef;color:#506879;border-radius:8px;font-size:10.5px;font-weight:740}.preset-row button.guided{background:#e2f7f8;border-color:#bce6e8;color:#0b8190}.file-row input[type=file]{font-size:10px;border-style:dashed;background:#f5fafb;padding:10px}.upload-metadata{background:#f4f8fb;border:1px solid #e3ebf0;color:#5c7384;border-radius:9px;font-size:11px;padding:12px;margin-top:13px}.upload-metadata b{color:#2b495c}
11
+ button{background:#fff;border:1px solid #d4e1e8;color:#486477;border-radius:9px;font-size:12px;font-weight:730;min-height:41px;padding:9px 14px}button.primary{background:#137f95;border:1px solid #137f95;color:#fff;box-shadow:0 7px 15px #0f8da126}button:disabled{opacity:.4;cursor:not-allowed;transform:none}.actions{display:flex;justify-content:space-between;gap:9px;flex-wrap:wrap;margin:20px 0 13px}.action-left,.action-right{display:flex;align-items:center;gap:8px}.action-right .compact{font-size:11px;color:#8394a0;margin-right:3px}.status{background:#f6f9fb;border-color:#d9e6ea;color:#3a5361;min-height:62px;font-size:11px;line-height:1.65;border-radius:9px}.status.pass{color:#137766;background:#edfaf5;border-color:#abe2d2}.status.hold{color:#9b5f25;background:#fff7ee;border-color:#f0d7b1}.success{border:1px solid #bcdfcf;border-radius:11px;background:#eff9f4;color:#235e4f}.success p{color:#557568}.success a,#success a{background:#137f95!important;border:1px solid #137f95!important;color:#fff!important;border-radius:8px!important;padding:10px 12px!important;font-size:11px!important;text-decoration:none;display:inline-flex;align-items:center}.hidden{display:none!important}
12
+ .info-drawer{margin:11px 0;border-radius:13px;border:1px solid #dee8ef;background:#fff;overflow:hidden}.info-drawer summary{list-style:none;padding:16px 17px;display:flex;align-items:center;gap:12px;cursor:pointer}.info-drawer summary::-webkit-details-marker{display:none}.drawer-icon{border-radius:10px;background:#eef6f9;width:37px;height:37px;color:#168c9c;display:grid;place-items:center;font-size:17px;font-weight:800;flex-shrink:0}.drawer-icon.spark{font-size:22px}.info-drawer summary span:nth-child(2){flex:1}.info-drawer summary strong{display:block;font-size:12px;color:#314759}.info-drawer summary small{display:block;font-size:10px;color:#889aa9;margin-top:3px}.info-drawer summary>b{font-size:17px;color:#82939d}.info-drawer[open] summary>b{transform:rotate(180deg)}.info-drawer[open] summary{border-bottom:1px solid #e9eff3}.onboard{background:transparent;border:0;padding:18px 20px 20px;margin:0}.onboard h3{font-size:17px;color:#264253}.onboard p{font-size:11px;color:#7c91a0}.source-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.source-card{background:#f6fafb;border:1px solid #e2edf0;border-radius:10px;padding:13px}.source-card b{font-size:11px;color:#304e61}.source-card span{font-size:10px;color:#718a99;line-height:1.5}.source-card em{font-size:9px;color:#129390}.ai-drawer .agent-panel{border:0;border-radius:0;margin:0;background:#fff;color:#374d5d;padding:18px 20px}.agent-top strong{font-size:13px;color:#294657}.agent-panel .compact,.agent-panel p{color:#7b909e!important}.agent-panel textarea{background:#f8fbfc;color:#264254;max-height:150px}.agent-panel .status{background:#f5f9fb}.agent-settings{border-top-color:#e5edf1}
13
+ .aside{position:sticky;top:20px;align-self:start;color:#ecf8ff}.aside>.panel{display:block}.preview-shell{background:#0a1b29!important;border:1px solid #213f50!important;border-radius:18px;padding:0!important;overflow:hidden;box-shadow:0 24px 55px #0d2c4140;margin-bottom:13px}.preview-header{background:#101f2d;padding:20px 23px;border-bottom:1px solid #284557;display:flex;align-items:center;justify-content:space-between;gap:11px}.preview-header .eyebrow{color:#7d9ba9;font-size:9px;font-weight:830;letter-spacing:.15em}.preview-header h2{font-size:21px;color:#effafd;letter-spacing:-.03em;font-weight:790;margin:7px 0 0}.preview-header h2 span{color:#69dae0;font-size:14px;margin-left:4px}.preview-mode{color:#8ef0e3;border:1px solid #3c746b;background:#163b3e;font-size:9px;white-space:nowrap;border-radius:20px;padding:7px 10px;font-weight:850;letter-spacing:.05em}.preview-stage{height:clamp(365px,37vw,525px);border-bottom:1px solid #25465b;position:relative;overflow:hidden;background:radial-gradient(ellipse 68% 55% at 54% 54%,#214359,#0e2538 62%,#071622 100%)}.preview-stage:before{content:"";pointer-events:none;position:absolute;inset:0;opacity:.32;background:linear-gradient(150deg,transparent,#122e3d44),repeating-linear-gradient(0deg,#537b861c 0px,#537b861c 1px,transparent 1px,transparent 34px),repeating-linear-gradient(90deg,#537b861c 0px,#537b861c 1px,transparent 1px,transparent 34px);mask-image:linear-gradient(transparent,#000)}.preview-stage>canvas,.preview-stage>svg{position:absolute;inset:0;width:100%;height:100%;touch-action:none}.stage-watermark{position:absolute;top:16px;left:17px;background:#112b3dcc;border:1px solid #315468;border-radius:7px;color:#a1cbd6;padding:7px 9px;font-size:9px;letter-spacing:.07em;font-weight:780;z-index:3;pointer-events:none}.watermark-dot{background:#61caba;width:6px;height:6px;box-shadow:none}.preview-empty{height:100%;display:flex;justify-content:center;align-items:center;flex-direction:column;text-align:center;position:relative;z-index:2;padding:30px}.preview-empty .cube{font-size:57px;color:#7bdde1;font-weight:300;text-shadow:0 0 55px #52bbc8;animation:cube-float 5s ease-in-out infinite}.preview-empty strong{font-size:17px;font-weight:750;color:#e8f7fb;margin-top:9px}.preview-empty p{font-size:12px;line-height:1.65;max-width:260px;color:#87aabd}.stage-actions{display:flex;gap:5px;position:absolute;right:15px;bottom:15px;z-index:3;padding:4px;border-radius:9px;background:#051c2bdd;border:1px solid #335567}.stage-actions button{background:transparent;border:0;border-radius:6px;color:#94b5c4;min-height:32px;padding:6px 11px;font-size:10px;font-weight:820}.stage-actions button:hover{background:#174359;color:#fff}.stage-footer{background:#0d2030;padding:16px 21px}.stage-row{display:flex;align-items:center;justify-content:space-between;gap:10px}.stage-row strong{color:#e0eff7;font-size:12px}.stage-row small{color:#83aabc;font-size:10px}.stage-details{border-top:1px solid #274757;margin-top:11px;padding-top:10px;color:#94b4c4;font-size:11px;line-height:1.6}.stage-details b{color:#e0f4fa}.stage-error{font-size:10px;color:#f4c686}.stage-legend{padding:11px 21px 14px;border-top:1px solid #1e3b4d;color:#819dad;font-size:10px;line-height:1.55;background:#0b1b2a}.stage-legend b{color:#b2d0dc}
14
+ .aside>.panel:not(.preview-shell){background:#fff;border:1px solid #e1eaf0;border-radius:14px;padding:20px 22px;box-shadow:0 5px 18px #21415109;margin-bottom:12px;color:#2b4457}.aside>.panel:not(.preview-shell) .eyebrow{color:#1d919c}.aside>.panel:not(.preview-shell) h2{font-size:17px;color:#294052;font-weight:780;letter-spacing:-.04em}.aside .row{padding:9px 0;border-color:#e6edf1}.aside .row span{color:#778a99;font-size:11px}.aside .row b{color:#395466;font-size:11px}.aside .compact{color:#7e91a0;font-size:10px}.readiness{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:9px;margin:14px 0 10px}.readiness-item{background:#f5f9fb;border:1px solid #e3ecf0;border-radius:9px;padding:12px 5px;text-align:center}.readiness-item b{display:block;font-size:21px;line-height:1.2;color:#253e50;font-weight:810;letter-spacing:-.04em}.readiness-item span{display:block;color:#8296a4;font-size:9px;margin-top:5px}.readiness-item.warn{background:#fff7ef;border-color:#f4e5d1}.readiness-item.warn b{color:#af783e}.trust-note,#model-help{color:#78909e;font-size:10px;line-height:1.65}.aside>.panel:last-child{display:none}
15
+ @keyframes cube-float{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}
16
+ @media(min-width:1650px){.wrap{grid-template-columns:minmax(590px,.87fr) minmax(670px,1.13fr)}.preview-stage{height:535px}}
17
+ @media(max-width:1170px){.wrap{grid-template-columns:minmax(0,1fr) minmax(400px,.88fr);padding:23px 24px;gap:17px}.hero{padding:23px}.hero h2{font-size:30px}.preview-stage{height:390px}.header-context{display:none}}
18
+ @media(max-width:975px){.wrap{grid-template-columns:1fr;max-width:760px;margin:auto}.aside{position:static;display:grid;grid-template-columns:1fr 1fr;gap:12px}.preview-shell{grid-column:1/-1}.preview-stage{height:420px}.aside>.panel:nth-child(3){display:none}}
19
+ @media(max-width:600px){.app-header{padding:11px 15px;min-height:70px}.brand-mark{height:38px;width:38px}.brand-title h1{font-size:16px}.brand-title .eyebrow{font-size:8px}.header-right .pill{font-size:8px;padding:7px 8px}.lab-secondary{display:none}.wrap{padding:16px 12px 40px;gap:13px}.hero{padding:23px 21px;min-height:auto}.hero h2{font-size:28px}.hero-deco{opacity:.25}.hero p{font-size:11px}.guided-bar{flex-wrap:wrap;padding:11px}.guided-bar button{width:100%}.workspace-heading h3{font-size:19px}.steps{grid-template-columns:repeat(2,1fr)}.step{min-height:42px}.panel{padding:20px}.panel h2{font-size:21px}.grid,.source-cards{grid-template-columns:1fr}.aside{display:block}.preview-stage{height:335px}.app-header .pill{max-width:144px;overflow:hidden}}
20
+ @media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important}html{scroll-behavior:auto}}
21
+ /* HTML hidden is authoritative: never overlay the empty state on a populated studio. */
22
+ [hidden]{display:none!important}
23
+ /* V0.7.3 — surfaced engineering copilot, design language preserved */
24
+ .copilot-bar{margin:12px 0 20px;background:linear-gradient(115deg,#f7fdfd 0%,#eaf8fa 100%);border:1px solid #c7e8ec;box-shadow:0 8px 25px #0a657012;border-radius:15px;padding:18px 20px;color:#2a4659}
25
+ .copilot-heading{display:flex;align-items:flex-start;gap:13px}.copilot-icon{flex:0 0 37px;height:37px;border-radius:12px;background:#0d7183;color:#fff;display:grid;place-items:center;font-size:25px;box-shadow:0 5px 13px #127a9126}
26
+ .copilot-heading strong{display:block;color:#15374a;letter-spacing:-.03em;font-weight:800;font-size:15px;margin:5px 0}.copilot-heading p{font-size:11px;line-height:1.55;color:#617f8c;margin:0}
27
+ .copilot-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}.copilot-actions button{background:#fff;color:#226178;border-color:#c5dfe6;font-size:11px;min-height:37px;padding:8px 11px}.copilot-actions button.primary{background:#107c92;color:#fff;border-color:#107c92}.copilot-results{margin-top:12px;border:1px solid #c3e0e5;border-radius:9px;padding:13px;background:#fff;color:#36566a;white-space:pre-wrap;overflow-wrap:anywhere;max-height:165px;overflow:auto;font-size:11px;line-height:1.55}.copilot-approval{margin-top:12px;display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;font-size:11px;color:#5d7b86}.copilot-approval button{background:#e3f6f7;color:#0b7884;border-color:#a8dbdc;font-size:11px}
28
+ @media(max-width:600px){.copilot-bar{padding:15px}.copilot-actions button{flex:1;min-width:130px}}
29
+
30
+ /* V0.7.4 — AI-first customer onboarding; customer inputs stay in the existing four-step wizard */
31
+ .byom-onboarding{max-width:1460px;margin:24px auto 8px;padding:26px 30px;border:1px solid #c8e4e5;border-radius:22px;background:linear-gradient(128deg,#f4fcfc 0%,#fff 58%,#e9f5f7 100%);box-shadow:0 20px 55px #193f5015;color:#223e50}
32
+ .byom-topline{display:flex;align-items:center;justify-content:space-between;gap:12px}.byom-identity{font-size:10px;font-weight:850;letter-spacing:.17em;color:#0b7985}.byom-spark{font-size:18px;vertical-align:middle;margin-right:5px}.byom-phase{border:1px solid #badbdc;border-radius:40px;padding:8px 12px;font-size:10px;font-weight:780;color:#0e7d85;background:#ebfaf8}
33
+ .byom-head{display:grid;grid-template-columns:minmax(0,1fr) minmax(420px,.95fr);gap:40px;margin:24px 0 20px}.byom-kicker{color:#2492a1;font-size:10px;letter-spacing:.15em;font-weight:800}.byom-head h2{font-size:clamp(27px,3.2vw,45px);line-height:1.12;letter-spacing:-.05em;margin:11px 0 12px;color:#193c4d}.byom-head h2 span{color:#0d95a2}.byom-head p{color:#617b88;max-width:655px;font-size:13px;line-height:1.7;margin:0}.byom-progress{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;align-content:center}.byom-progress span{padding:14px 15px;border:1px solid #e0edef;border-radius:12px;background:#fff;color:#92a5ac;font-size:12px;font-weight:800}.byom-progress b{font-size:12px;color:#344e60;margin-left:7px}.byom-progress .byom-current{border-color:#76cfd3;background:#e7f9f9;color:#06858f}.byom-progress .byom-current b{color:#116577}
34
+ .byom-form-mount{padding:23px 24px;border-radius:15px;border:1px solid #d8e7ec;background:#fff}.byom-form-mount .agent-settings{margin:0;padding:0;border:0}.byom-form-mount .grid{grid-template-columns:repeat(2,minmax(0,1fr))}.byom-form-mount label{color:#4c6876;font-size:11px}.byom-form-mount input,.byom-form-mount select{background:#f7fafb;color:#253e4d;border:1px solid #ccdce2;min-height:45px}.byom-form-mount .compact{color:#657e88;line-height:1.6;font-size:11px}.byom-form-mount #ai-test{background:#0a8093;color:white;border:0;font-weight:800;margin-top:7px;padding:12px 20px}.byom-form-mount #ai-connection-status{display:inline-block;margin-left:10px}.byom-bottom{display:flex;justify-content:space-between;align-items:center;gap:15px;margin-top:14px;color:#667e8c;font-size:10px;line-height:1.5}.byom-bottom button{background:#0d8093;border:0;color:#fff;font-weight:750}
35
+ .byom-onboarding.completed{padding:15px 22px;margin-bottom:0;background:linear-gradient(110deg,#ebfaf6,#f9fdfc)}.byom-onboarding.completed .byom-head,.byom-onboarding.completed .byom-form-mount{display:none}.byom-onboarding.completed .byom-topline{margin-bottom:10px}.byom-onboarding.completed .byom-bottom{margin-top:0}
36
+ .ai-required-review{display:flex;gap:12px;align-items:center;justify-content:space-between;margin:18px 0 5px;padding:14px 16px;border:1px solid #c5e5e6;border-radius:12px;background:#f0fbfb;color:#466977;font-size:11px;line-height:1.5}.ai-required-review b{color:#136e7e}.ai-required-review button{background:#087e91;color:white;border:0;font-size:11px;white-space:nowrap;font-weight:800}
37
+ @media(max-width:975px){.byom-onboarding{margin:18px 22px}.byom-head{grid-template-columns:1fr;gap:18px}.byom-progress{grid-template-columns:repeat(4,minmax(0,1fr))}.byom-progress span{font-size:11px}.byom-progress b{display:block;margin:4px 0 0}}
38
+ @media(max-width:600px){.byom-onboarding{margin:12px;padding:18px;border-radius:15px}.byom-head h2{font-size:29px}.byom-topline{align-items:flex-start}.byom-phase{font-size:8px}.byom-progress{grid-template-columns:repeat(2,minmax(0,1fr))}.byom-form-mount{padding:15px}.byom-form-mount .grid{grid-template-columns:1fr}.byom-bottom,.ai-required-review{flex-direction:column;align-items:flex-start}.ai-required-review button{width:100%}}
39
+
40
+ /* Guarantee the AI-first setup cannot be visually bypassed by grid CSS. */
41
+ #creator-ui-shell[hidden],#byom-change[hidden]{display:none!important}
42
+
43
+ /* V0.7.4.1 — Always-visible connection card. Never hide provider/model after a successful test. */
44
+ .byom-onboarding{max-width:1460px;margin:18px auto 4px;padding:18px 22px;border-radius:17px;background:#effbfa}
45
+ .byom-onboarding:not(.completed){max-width:940px;margin-top:36px}
46
+ .byom-onboarding .byom-head{display:none}
47
+ .byom-onboarding .byom-topline{margin-bottom:14px}
48
+ .byom-onboarding .byom-form-mount,.byom-onboarding.completed .byom-form-mount{display:block!important;margin:0;padding:0;background:none;border:0}
49
+ .connect-card{padding:18px 20px;background:#fff;border:1px solid #d5e8ec;border-radius:15px;box-shadow:0 7px 22px #174a5910}
50
+ .connect-card-head{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:14px}
51
+ .connect-card-head h2{font-size:22px!important;line-height:1.2;letter-spacing:-.035em;margin:4px 0;color:#1a3949}
52
+ .connect-card-head h2 span{font-size:15px;color:#4c8491;font-weight:550}
53
+ .connect-card-head p{font-size:11px;color:#67818e;margin:0;line-height:1.55}
54
+ .connection-indicator{font-weight:800;font-size:11px;color:#926b35;background:#fff9ef;padding:8px 12px;border:1px solid #ecdcc7;border-radius:20px;white-space:nowrap}
55
+ .connection-indicator.is-connected{background:#e9f8f2;border-color:#bbdfcf;color:#187b59}
56
+ .connection-fields{display:grid;grid-template-columns:minmax(160px,1fr) minmax(200px,1.1fr) minmax(200px,1.15fr);align-items:start;gap:14px}
57
+ .byom-form-mount .connection-fields>div>label{font-size:12px;color:#416372;margin:0 0 8px}
58
+ .byom-form-mount .connection-fields input,.byom-form-mount .connection-fields select{font-size:13px;border-radius:9px;min-height:44px;background:#f7fafb}
59
+ .field-optional{font-weight:500;font-size:10px;color:#74929a}
60
+ .model-id-tip{display:block;font-size:10px;color:#708f99;padding-top:6px;line-height:1.35}
61
+ .connection-advanced{margin:10px 0 0;border:0}
62
+ .connection-advanced summary{cursor:pointer;color:#167e90;font-size:11px;font-weight:700;padding:7px 0;list-style:revert}
63
+ .connection-advanced-fields{margin-top:8px;max-width:680px}
64
+ .connection-advanced-fields label{color:#557582;font-size:11px}
65
+ .connection-actions{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:9px}
66
+ .byom-form-mount #ai-test{margin:0;padding:12px 21px;border-radius:9px}
67
+ .byom-form-mount #ai-connection-status{margin:0;font-size:11px;font-weight:700;color:#317485;flex:1}
68
+ .byom-form-mount #ai-continue{color:#167389;background:#ecf9fb;border:1px solid #c4e7ea;border-radius:9px;font-size:11px;font-weight:800;min-height:43px}
69
+ .connection-privacy{margin:9px 0 0!important;padding-top:8px;border-top:1px solid #e8f0f3;font-size:10px!important}
70
+ .byom-onboarding.completed{padding:12px 20px;margin-bottom:8px}
71
+ .byom-onboarding.completed .byom-topline{margin-bottom:10px}
72
+ .byom-onboarding.completed .byom-bottom{display:none}
73
+ .byom-onboarding:not(.completed) .byom-bottom{margin-top:12px}
74
+ @media(max-width:900px){.connection-fields{grid-template-columns:1fr 1fr}.connection-fields>div:last-child{grid-column:1/-1}}
75
+ @media(max-width:600px){.byom-onboarding,.byom-onboarding.completed{margin:12px;padding:11px}.connect-card{padding:14px}.connect-card-head{align-items:flex-start;flex-direction:column}.connection-fields{grid-template-columns:1fr}.connection-fields>div:last-child{grid-column:auto}.connection-actions{align-items:stretch;flex-direction:column}.byom-form-mount #ai-continue{width:100%}.byom-form-mount #ai-connection-status{flex:initial}}
76
+ /* Existing Change AI provider control stays keyboard-accessible after connection. */
77
+ .byom-onboarding.completed .byom-bottom{display:flex;margin-top:7px}
78
+ .byom-onboarding.completed .byom-bottom>span{display:none}
79
+ .byom-onboarding.completed .byom-bottom button{background:transparent;color:#14758c;border:1px solid #cee6e9;border-radius:9px;padding:6px 12px;min-height:30px;font-size:10px}
80
+
81
+ /* V0.7.5: single customer workflow. Legacy AI utilities remain internal, not a second UI. */
82
+ .copilot-bar,.ai-drawer,.ai-required-review,#step-3 > .actions{display:none!important}
83
+ .unified-engineer{margin:14px 0 20px;padding:25px;border:1px solid #b8e3e4;border-radius:18px;background:linear-gradient(138deg,#effcf9,#eff8fc 70%,#fff);box-shadow:0 10px 36px #123a4d10}
84
+ .unified-kicker{color:#148393;font-size:10px;font-weight:900;letter-spacing:.14em}
85
+ .unified-head{display:flex;justify-content:space-between;gap:15px;align-items:flex-start;margin-top:8px}
86
+ .unified-head h2{font-size:22px;letter-spacing:-.035em;color:#103447;margin:4px 0 7px}
87
+ .unified-head p{color:#557484;font-size:12px;line-height:1.55;max-width:680px;margin:0}
88
+ #engineer-stage-badge{white-space:nowrap;background:#fff;border:1px solid #c5dedf;border-radius:30px;color:#337c89;font-weight:800;font-size:10px;padding:9px 12px}
89
+ .unified-status-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-top:18px}
90
+ .unified-status-grid>div{border:1px solid #dfedf0;background:#ffffffad;border-radius:10px;padding:12px;min-width:0}
91
+ .unified-status-grid small{display:block;color:#78929a;font-size:10px;font-weight:750;text-transform:uppercase;letter-spacing:.04em}
92
+ .unified-status-grid b{display:block;color:#1b4a5d;margin-top:6px;font-size:12px;overflow-wrap:anywhere}
93
+ .unified-actions{margin-top:14px;display:flex;gap:12px;align-items:center;flex-wrap:wrap}
94
+ .unified-actions button{border-radius:10px;background:#087a91;min-height:48px;padding:13px 20px;color:#fff;font-weight:850}
95
+ .unified-actions span{color:#76929a;font-size:11px}
96
+ .unified-results{margin-top:13px;white-space:pre-wrap;overflow-wrap:anywhere;background:#fff;border:1px solid #d7e8ea;border-radius:10px;padding:16px;font-size:12px;line-height:1.65;color:#244c5a;max-height:420px;overflow:auto}
97
+ .unified-results.hold{border-color:#e4cbbb;background:#fff9f2;color:#8c4c34}
98
+ .unified-approval{margin-top:12px;background:#fff;border:1px solid #b2dbd3;padding:17px;border-radius:12px}
99
+ .unified-approval p{margin:0 0 12px;font-size:12px;color:#315866;line-height:1.55}
100
+ .unified-affirm{display:flex!important;gap:9px;align-items:flex-start;line-height:1.4;font-size:12px!important;color:#214c59!important;margin-bottom:15px!important}
101
+ .unified-affirm input{width:18px!important;height:18px;min-width:18px;margin:0!important;accent-color:#0b8296}
102
+ .unified-approval button{background:#087a91!important;color:#fff!important;font-weight:800;border-radius:9px;min-height:46px}
103
+ @media(max-width:720px){.unified-head{display:block}.unified-status-grid{grid-template-columns:1fr}.unified-engineer{padding:17px}}
104
+
105
+ /* Engineering tool, not landing page: show guided inputs and AI engine immediately. */
106
+ .hero{display:none!important}
107
+
108
+
109
+ .layout-help{margin:10px 0 4px;font-size:11px;color:#547a88;line-height:1.6}
110
+ /* V0.7.5.1 — Minimal post-connection chrome.
111
+ The setup form remains required before the first successful model test.
112
+ Once connected, the primary app header is the only always-visible AI status.
113
+ Clicking that badge temporarily reveals the form for reconfiguration. */
114
+ .byom-onboarding.completed:not(.reconfiguring){display:none!important}
115
+ .byom-onboarding.completed.reconfiguring{display:block!important}
116
+ .byom-onboarding.completed.reconfiguring .byom-form-mount{display:block!important}
117
+ .byom-onboarding.completed .byom-bottom{display:none!important}
118
+ .app-header .header-ai-status{
119
+ display:inline-flex;align-items:center;justify-content:center;gap:7px;
120
+ padding:7px 12px;min-height:33px;border-radius:999px;
121
+ background:#e9f8f2;color:#167b58;border:1px solid #bbdfcf;
122
+ font-size:11px;font-weight:800;white-space:nowrap;box-shadow:none;
123
+ }
124
+ .app-header .header-ai-status[hidden]{display:none!important}
125
+ .header-ai-dot{height:7px;width:7px;border-radius:50%;background:#1fb18b;flex:0 0 7px}
126
+ .app-header .header-ai-status:hover{background:#ddf4eb;border-color:#85ccb1}
127
+ .app-header .header-ai-status:focus-visible{outline:3px solid #38c6bc;outline-offset:3px}
128
+ @media(max-width:600px){.header-right{gap:7px}.app-header .header-ai-status{padding:6px 9px;font-size:10px;min-height:30px}}
129
+ @media(max-width:600px){
130
+ .app-header{flex-wrap:wrap;justify-content:flex-start;gap:10px}
131
+ .app-header .header-right{width:100%;justify-content:flex-start;gap:8px}
132
+ .app-header .header-context{display:none}
133
+ }
134
+
135
+ /* V0.7.5.2 — Visual style choice, not a second AI generation path */
136
+ .design-choice-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:14px}
137
+ .design-choice{display:flex;flex-direction:column;align-items:flex-start;gap:7px;text-align:left;min-height:125px;padding:16px;border:1px solid #cddfe5;border-radius:12px;background:#fbfdff;color:#234452}
138
+ .design-choice strong{font-size:13px;font-weight:850}.design-choice small{font-size:10px;color:#728b99}.design-choice.selected{border-color:#158ca0;box-shadow:0 0 0 2px #38aeb22b;background:#eefbfb}
139
+ .design-thumb{font-size:20px;letter-spacing:8px;display:block;max-width:100%;color:#3f94a5}.design-thumb-2d{font-size:16px;letter-spacing:2px;color:#218ca0}
140
+ @media(max-width:540px){.design-choice-cards{grid-template-columns:1fr}.design-choice{min-height:110px}}
141
+
142
+ /* Customer-sourced document intake, within Step 01; no second HMI workflow. */
143
+ .customer-documents{margin-top:22px;border:1px solid #b9dce3;background:linear-gradient(140deg,#f1fbfb,#fff);border-radius:13px;padding:19px;color:#173d4e}
144
+ .customer-documents h3{font-size:19px;letter-spacing:-.03em;margin:7px 0}.customer-documents p{font-size:12px;line-height:1.65;color:#536f7c}
145
+ .customer-documents input[type=file]{max-width:100%;width:100%;background:white}.customer-source-types,.customer-source-note{color:#607d88;font-size:11px}
146
+ .customer-source-list{display:grid;gap:6px;margin-top:9px}.customer-source-item{border:1px solid #d4e5e9;background:#fff;border-radius:8px;padding:9px 11px;font-size:12px}
147
+ .customer-source-list .source-state{font-weight:750;color:#027b8e}.customer-source-preview{white-space:pre-wrap;word-break:break-word;background:#eaf3f6;border:1px solid #d7e5ea;border-radius:8px;padding:10px;max-height:200px;overflow:auto;font-size:11px}
148
+ .customer-doc-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.customer-doc-actions button{font-weight:700;font-size:12px}.customer-consent{display:flex;align-items:flex-start;gap:9px;margin:12px 0;font-size:12px;line-height:1.45}
149
+ .customer-consent input{width:auto;min-height:auto;margin:3px}.customer-doc-draft{white-space:pre-wrap;background:#f8fcfd;padding:12px;border-radius:8px;border:1px solid #acdce4;font-size:12px;line-height:1.5}
150
+ #customer-doc-apply{background:#08798d;color:white;margin-top:10px}
151
+
152
+ /* V0.7.9 — compact engineering workspace. Existing R9/V8 HMI files unchanged. */
153
+ .wrap{padding-top:18px;gap:18px}.app-header{min-height:66px;padding-top:10px;padding-bottom:10px}
154
+ .guided-bar{margin-bottom:10px}.guided-copy small{display:none}
155
+ .unified-engineer{margin:9px 0 14px;padding:16px 18px;border-radius:14px}
156
+ .unified-head h2{font-size:19px;margin:0}.unified-head p{font-size:11px;margin-top:4px}
157
+ .unified-status-grid{margin-top:12px}.unified-status-grid>div{padding:9px 11px}
158
+ .unified-actions{margin-top:10px}.unified-actions button{min-height:40px;padding:9px 16px}
159
+ .workspace-heading{margin:0 0 8px}.workspace-heading h3{font-size:19px}.steps{margin-bottom:8px}
160
+ .panel{padding:19px 21px;margin-bottom:9px}.panel h2{font-size:21px}.panel>p{margin:0 0 8px}
161
+ .layout-help,.customer-source-types,#model-help{display:none!important}
162
+ .customer-documents{padding:15px!important;margin-top:14px!important}
163
+ .customer-documents h3{margin:2px 0 10px!important;font-size:18px!important}
164
+ .customer-documents .eyebrow{margin:0}.customer-documents .customer-source-note{display:block;margin:10px 0 0}
165
+ .customer-documents #customer-source-status{font-size:11px}
166
+ .customer-documents .customer-consent{font-size:11px!important}
167
+ .preview-header{padding:16px 20px}.preview-stage{height:clamp(380px,38vw,570px)}
168
+ .stage-legend{font-size:10px!important}.preview-shell{overflow:hidden}
169
+ .compact-assurance{padding:0!important}.compact-assurance>summary{display:flex;justify-content:space-between;cursor:pointer;list-style:none;padding:16px 18px;font-weight:800;color:#304a5a}.compact-assurance>summary::-webkit-details-marker{display:none}.compact-assurance .assurance-body{padding:0 18px 15px}.compact-assurance .row{padding:8px 0}
170
+ .live-hmi-panel{border-top:1px solid #264d5c;background:#0a1b28}
171
+ .live-hmi-top{height:39px;display:flex;justify-content:space-between;align-items:center;padding:0 15px;color:#d8effa;font-size:12px}
172
+ .live-hmi-top span{color:#b9a676;font-size:9px;font-weight:800;letter-spacing:.08em}
173
+ .live-hmi-panel iframe{height:min(64vh,730px);min-height:440px;display:block;width:100%;border:0;background:#071824}
174
+ .preview-shell:has(.live-hmi-panel:not(.hidden)) .preview-stage{display:none}
175
+ .preview-shell:has(.live-hmi-panel:not(.hidden)) .stage-footer{display:none}
176
+ .preview-shell:has(.live-hmi-panel:not(.hidden)) .stage-legend{display:none}
177
+ .design-review{margin-top:16px;background:#f5fbfc;border:1px solid #bfdfe7;border-radius:14px;padding:15px}
178
+ .design-review-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.design-review h3{font-size:20px;margin:2px 0;color:#1a3949}
179
+ .review-lab{font-size:9px;font-weight:850;letter-spacing:.08em;color:#966829;background:#fff8e9;border:1px solid #f1dcba;border-radius:50px;padding:5px 9px}
180
+ .review-intro{font-size:11px!important;margin:5px 0 12px!important;color:#577b89!important}
181
+ .review-chat-log{min-height:66px;max-height:175px;overflow:auto;padding:6px;display:grid;gap:7px}
182
+ .review-msg{max-width:92%;border-radius:12px;padding:9px 12px;font-size:11px;line-height:1.5;white-space:pre-wrap;overflow-wrap:anywhere}
183
+ .review-msg.assistant{justify-self:start;background:#fff;border:1px solid #dceaf1;color:#446373}.review-msg.user{justify-self:end;background:#d9f4f3;color:#17515a}
184
+ .review-chat-form{display:flex;gap:7px;margin-top:10px}.review-chat-form input{flex:1;min-width:0;background:#fff}.review-chat-form button{white-space:nowrap;border-radius:9px;background:#087e93;color:#fff;font-weight:750}
185
+ .review-tools{display:flex;gap:7px;flex-wrap:wrap;margin-top:9px}.review-tools button{min-height:32px;padding:5px 10px;background:#fff;border:1px solid #d0e0e8;color:#416474;font-size:11px}
186
+ .review-disclaimer{display:block;font-size:10px;color:#758d98;margin-top:10px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
187
+ @media(max-width:980px){.live-hmi-panel iframe{min-height:470px;height:620px}}@media(max-width:600px){.review-chat-form{flex-wrap:wrap}.review-chat-form button{width:100%}}
188
+
189
+ /* V0.7.9.1 — complete HMI review (same generated viewer, not a second mock-up). */
190
+ .full-hmi-review.hidden{display:none!important}
191
+ .full-hmi-review{position:fixed;inset:0;z-index:12000;background:#081825;display:grid;grid-template-rows:auto minmax(0,1fr);overflow:hidden;color:#e9f4fb}
192
+ .full-review-header{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:70px;background:#0b2030;border-bottom:1px solid #2a5466;padding:12px 22px}
193
+ .full-review-header h2{font-size:21px;margin:4px 0;color:#f0f8fc}.full-review-overline{font-size:10px;color:#62baca;letter-spacing:.14em;font-weight:850}
194
+ .full-review-header-actions{display:flex;gap:11px;align-items:center;flex-wrap:wrap}.full-review-header-actions button,.full-review-header-actions a{padding:10px 12px;border-radius:7px;border:1px solid #355870;color:#d4e9f3;background:#102f41;font-size:12px;text-decoration:none;font-weight:800;cursor:pointer}
195
+ .full-review-lab{font-size:10px;font-weight:850;color:#eac78a;letter-spacing:.04em}.full-review-main{display:grid;grid-template-columns:minmax(0,1fr) 330px;min-height:0;overflow:hidden}
196
+ .full-hmi-viewer-slot{min-width:0;min-height:0;overflow:hidden;display:flex;background:#081723}
197
+ .full-hmi-viewer-slot .live-hmi-panel{height:100%;width:100%;display:flex;flex-direction:column;border:0;min-height:0}
198
+ .full-hmi-viewer-slot .live-hmi-top{flex:0 0 38px;background:#0c2634}
199
+ .full-hmi-viewer-slot #live-hmi-frame{flex:1 1 0;height:100%!important;min-height:0!important;border:0;min-width:0;width:100%;background:#0b1d29}
200
+ .full-hmi-editor-slot{min-width:0;min-height:0;overflow-y:auto;background:#eef7fa;border-left:1px solid #19475b;padding:14px}
201
+ .full-hmi-editor-slot .design-review{display:block!important;margin:0;box-shadow:none;border:0;padding:9px;background:transparent}
202
+ .full-hmi-editor-slot .review-chat-log{min-height:170px;max-height:min(45vh,450px);align-content:start}
203
+ .full-hmi-editor-slot .review-chat-form{flex-wrap:wrap}.full-hmi-editor-slot .review-chat-form input{flex-basis:100%;min-height:42px}.full-hmi-editor-slot .review-chat-form button{width:100%}
204
+ .hmi-inline-actions{display:flex;align-items:center;gap:14px}.hmi-inline-actions button{border:1px solid #37667c;background:#153649;color:#e3f5fa;border-radius:6px;padding:5px 9px;font-size:11px;font-weight:800;cursor:pointer}
205
+ body.full-hmi-review-open{overflow:hidden}
206
+ @media(max-width:1080px){.full-review-main{grid-template-columns:minmax(0,1fr) 275px}.full-review-lab{display:none}.full-review-header{padding:10px 14px}.full-review-header h2{font-size:17px}}
207
+ @media(max-width:760px){.full-review-main{grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr) minmax(210px,32vh)}.full-hmi-editor-slot{border-left:0;border-top:1px solid #19475b;padding:6px 12px}.full-hmi-editor-slot .review-chat-log{min-height:45px;max-height:80px}.full-hmi-editor-slot .review-intro{display:none}.full-hmi-editor-slot .review-chat-form{flex-wrap:nowrap}.full-hmi-editor-slot .review-chat-form input{flex-basis:auto}.full-hmi-editor-slot .review-chat-form button{width:auto}.full-review-header-actions a{display:none}}
208
+
209
+ .full-hmi-viewer-slot #open-full-hmi-review{display:none!important}
210
+
211
+ /* V0.7.9.2 customer project package intake */
212
+ .project-package{padding:18px;border:1px solid #bfdce6;background:linear-gradient(120deg,#e8f9f8,#fff);border-radius:12px;margin:16px 0 12px}.project-package h3{margin:9px 0;font-size:17px;color:#123046}.project-package p,.project-package small{color:#56758b;font-size:12px;line-height:1.55}.project-package input{width:100%;margin:12px 0}.project-package .package-result{font-size:12px;white-space:pre-line;color:#23566d;padding:9px 0}.project-package select{width:100%;margin:8px 0 12px}.project-package button{border:0;background:#057e91;color:white;font-size:12px;font-weight:800;padding:10px 15px;border-radius:6px;cursor:pointer}.project-package [hidden]{display:none}
213
+
214
+ /* V0.8.1 Stage 1 — source-backed Original V8 selection and safe blank-project reset. */
215
+ .new-project-button{min-height:34px!important;padding:7px 11px!important;border-color:#bcdfe5!important;background:#eefafb!important;color:#08788b!important;font-size:10px!important;font-weight:850!important;white-space:nowrap}
216
+ .creator-start{margin:0 0 12px;padding:17px 18px;border:1px solid #cce3e8;border-radius:14px;background:linear-gradient(120deg,#f5fbfc,#fff);box-shadow:0 6px 22px #123b4b0a;color:#233f50}
217
+ .creator-start-head{display:flex;align-items:flex-start;justify-content:space-between;gap:15px;margin-bottom:12px}.creator-start-head h2{margin:4px 0 3px;font-size:18px;letter-spacing:-.035em;color:#153649}.creator-start-head p{font-size:10.5px;margin:0;line-height:1.5;color:#647f8d}.creator-start-head>button{min-height:34px;padding:7px 11px;border-color:#d6e4e9;color:#617887;background:#fff;font-size:10px;white-space:nowrap}
218
+ .creator-start-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:9px}.creator-start-card{min-height:94px;padding:17px;text-align:left;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;border:1px solid #d4e4e9;background:#fff;color:#244354;border-radius:11px;box-shadow:none}.creator-start-card strong{font-size:14px;line-height:1.35;margin:0 0 5px}.creator-start-card small{font-size:10px;color:#69838f;line-height:1.45}.creator-start-card.selected{border-color:#168fa2;background:#eaf9fa;box-shadow:0 0 0 2px #36aeb629}.blank-project-card{background:#f9fbfc}
219
+ .original-v8-panel{background:#07131c;border-top:1px solid #294c5f}.original-v8-toolbar{min-height:48px;padding:8px 12px;display:flex;align-items:center;justify-content:space-between;gap:10px;background:#0e2533;border-bottom:1px solid #29495a}.original-v8-toolbar b{display:block;color:#e6f5fa;font-size:11px}.original-v8-toolbar span{display:block;color:#74a3ae;font-size:8px;letter-spacing:.09em;margin-top:2px}.original-v8-toolbar>div:last-child{display:flex;gap:6px}.original-v8-toolbar a{border:1px solid #315a6d;border-radius:5px;background:#173548;color:#d5edf3;text-decoration:none;padding:6px 8px;font-size:9px;font-weight:800;white-space:nowrap}.original-v8-panel iframe{display:block;width:100%;height:min(74vh,790px);min-height:600px;border:0;background:#0b141e}
220
+ .preview-shell:has(.original-v8-panel:not(.hidden)) .preview-stage,.preview-shell:has(.original-v8-panel:not(.hidden)) .stage-footer,.preview-shell:has(.original-v8-panel:not(.hidden)) .stage-legend{display:none}
221
+ @media(max-width:740px){.creator-start-head{display:block}.creator-start-head>button{margin-top:9px}.creator-start-cards{grid-template-columns:1fr}.creator-start-card{min-height:114px}.new-project-button{order:2}.original-v8-toolbar{align-items:flex-start;flex-direction:column}.original-v8-panel iframe{min-height:690px}}
222
+
223
+ /* V0.8.2: source-backed R9 spatial viewer in its own operator viewport. */
224
+ .original-r9-panel{margin-top:12px;border:1px solid #34556c;border-radius:12px;overflow:hidden;background:#07121f}
225
+ .original-r9-toolbar{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:10px 13px;background:#102738;color:#edf7ff;flex-wrap:wrap}
226
+ .original-r9-toolbar b{display:block;font-size:13px}
227
+ .original-r9-toolbar span{display:block;font-size:10px;color:#eac88a;margin-top:4px}
228
+ .original-r9-toolbar a{font-size:12px;color:#9de6fb;font-weight:700}
229
+ .original-r9-panel iframe{width:100%;height:min(78vh,860px);min-height:570px;display:block;border:0;background:#07121f}
230
+ .original-r9-card{border-color:#345a76!important;background:linear-gradient(130deg,#eaf8fb,#effcfb)!important}
231
+ .original-r9-card.selected{outline:3px solid #37aabb;outline-offset:1px}
232
+ @media(max-width:750px){.original-r9-panel iframe{height:620px;min-height:440px}}
233
+
234
+ /* Full-width original R9 operator focus without changing the R9 design itself.
235
+ Back to Creator is visible; header New Project/Clear Existing remain safe. */
236
+ .preview-shell:has(.original-r9-panel:not(.hidden)) .preview-stage,
237
+ .preview-shell:has(.original-r9-panel:not(.hidden)) .stage-footer,
238
+ .preview-shell:has(.original-r9-panel:not(.hidden)) .stage-legend{display:none}
239
+ body[data-active-demo="original-r9"] .wrap{display:block;max-width:1560px}
240
+ body[data-active-demo="original-r9"] .wrap>section:not(.aside){display:none}
241
+ body[data-active-demo="original-r9"] .aside{position:static;display:block}
242
+ body[data-active-demo="original-r9"] .aside>.panel:not(.preview-shell){display:none}
243
+ body[data-active-demo="original-r9"] .original-r9-panel iframe{height:min(82vh,950px);min-height:650px}
244
+ .r9-preview-actions{display:flex;align-items:center;gap:9px}
245
+ .r9-preview-actions button{padding:6px 12px;border:1px solid #447188;background:#173b50;color:#d9f3fc;font-weight:750;font-size:12px;min-height:35px}
246
+ @media(min-width:1050px){.creator-start-cards{grid-template-columns:repeat(3,minmax(0,1fr))}}
247
+ @media(max-width:740px){body[data-active-demo="original-r9"] .original-r9-panel iframe{min-height:520px;height:74vh}}
@@ -0,0 +1,16 @@
1
+ import {collectFloors,renderFacility2D} from './facility2d_core.mjs';
2
+ export function makeCreator2D(host,onPick){
3
+ let model=null,selected='',activeFloor=null;
4
+ const root=document.createElement('div');root.className='creator-flow2d';root.style.cssText='position:absolute;inset:0;display:none;background:#0b1f2d;z-index:4';
5
+ const chooser=document.createElement('select');chooser.setAttribute('aria-label','2D preview floor');chooser.style.cssText='position:absolute;top:18px;right:18px;z-index:4;padding:7px 10px;border-radius:6px;border:1px solid #376078;background:#103044;color:#d9eff8;width:auto;font-size:11px';
6
+ const svg=document.createElementNS('http://www.w3.org/2000/svg','svg');svg.style.cssText='width:100%;height:100%';
7
+ root.append(svg,chooser);host.append(root);
8
+ function draw(){if(!model)return;renderFacility2D(svg,model.assets||[],model.connections||[],{floor:activeFloor,selected,onSelect(a){selected=a.id;onPick(a);draw();},onPortal(f){activeFloor=f;chooser.value=f;selected='';draw();}});}
9
+ function paint(data){model=data;if(!data){svg.replaceChildren();return;}
10
+ const floorList=collectFloors(data.assets);chooser.replaceChildren();
11
+ for(const floor of floorList)chooser.append(new Option('Floor '+floor,floor));
12
+ if(!floorList.includes(activeFloor))activeFloor=floorList[0]||'1';
13
+ chooser.value=activeFloor;draw();}
14
+ chooser.addEventListener('change',()=>{activeFloor=chooser.value;draw();});
15
+ return {root,paint,activate(active){root.style.display=active?'block':'none';},dispose(){root.remove();}};
16
+ }