android-midscene-automation 0.2.3 → 1.1.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 (525) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/README.md +63 -1
  3. package/artemis-main/.dockerignore +15 -0
  4. package/artemis-main/.env.example +34 -0
  5. package/artemis-main/CONTRIBUTING.md +35 -0
  6. package/artemis-main/Dockerfile +68 -0
  7. package/artemis-main/LICENSE +202 -0
  8. package/artemis-main/Makefile +115 -0
  9. package/artemis-main/README.md +322 -0
  10. package/artemis-main/README_CN.md +320 -0
  11. package/artemis-main/apps/__init__.py +15 -0
  12. package/artemis-main/apps/admin_console/__init__.py +19 -0
  13. package/artemis-main/apps/admin_console/core/__init__.py +13 -0
  14. package/artemis-main/apps/admin_console/core/config.py +43 -0
  15. package/artemis-main/apps/admin_console/core/security.py +178 -0
  16. package/artemis-main/apps/admin_console/core/state.py +243 -0
  17. package/artemis-main/apps/admin_console/database/__init__.py +13 -0
  18. package/artemis-main/apps/admin_console/database/connection.py +60 -0
  19. package/artemis-main/apps/admin_console/database/repositories/__init__.py +13 -0
  20. package/artemis-main/apps/admin_console/database/repositories/session_repository.py +564 -0
  21. package/artemis-main/apps/admin_console/database/repositories/step_repository.py +512 -0
  22. package/artemis-main/apps/admin_console/database/repositories/trace_repository.py +133 -0
  23. package/artemis-main/apps/admin_console/index.html +3787 -0
  24. package/artemis-main/apps/admin_console/replay_manager.py +2585 -0
  25. package/artemis-main/apps/admin_console/routers/__init__.py +13 -0
  26. package/artemis-main/apps/admin_console/routers/media.py +198 -0
  27. package/artemis-main/apps/admin_console/routers/replay.py +91 -0
  28. package/artemis-main/apps/admin_console/routers/sessions.py +239 -0
  29. package/artemis-main/apps/admin_console/routers/steps.py +109 -0
  30. package/artemis-main/apps/admin_console/routers/stream.py +56 -0
  31. package/artemis-main/apps/admin_console/routers/system.py +761 -0
  32. package/artemis-main/apps/admin_console/routers/tasks.py +517 -0
  33. package/artemis-main/apps/admin_console/schemas/__init__.py +13 -0
  34. package/artemis-main/apps/admin_console/schemas/task_schema.py +47 -0
  35. package/artemis-main/apps/admin_console/server.py +508 -0
  36. package/artemis-main/apps/admin_console/services/__init__.py +13 -0
  37. package/artemis-main/apps/admin_console/services/device_stream_service.py +137 -0
  38. package/artemis-main/apps/admin_console/services/ipc_service.py +262 -0
  39. package/artemis-main/apps/admin_console/services/media_service.py +623 -0
  40. package/artemis-main/apps/admin_console/services/model_service.py +148 -0
  41. package/artemis-main/apps/admin_console/services/task_preset_catalog.py +514 -0
  42. package/artemis-main/apps/admin_console/services/task_queue_service.py +1719 -0
  43. package/artemis-main/apps/admin_console/services/worker_process_io.py +144 -0
  44. package/artemis-main/apps/showcase_ui/README.md +31 -0
  45. package/artemis-main/apps/showcase_ui/angular.json +132 -0
  46. package/artemis-main/apps/showcase_ui/package-lock.json +9472 -0
  47. package/artemis-main/apps/showcase_ui/package.json +39 -0
  48. package/artemis-main/apps/showcase_ui/proxy.conf.json +23 -0
  49. package/artemis-main/apps/showcase_ui/public/favicon.ico +0 -0
  50. package/artemis-main/apps/showcase_ui/public/logo.png +0 -0
  51. package/artemis-main/apps/showcase_ui/public/logo.svg +56 -0
  52. package/artemis-main/apps/showcase_ui/src/app/app.component.html +24 -0
  53. package/artemis-main/apps/showcase_ui/src/app/app.component.scss +49 -0
  54. package/artemis-main/apps/showcase_ui/src/app/app.component.spec.ts +42 -0
  55. package/artemis-main/apps/showcase_ui/src/app/app.component.ts +32 -0
  56. package/artemis-main/apps/showcase_ui/src/app/app.config.ts +29 -0
  57. package/artemis-main/apps/showcase_ui/src/app/app.routes.ts +27 -0
  58. package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream-startup.spec.ts +108 -0
  59. package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream.component.html +1436 -0
  60. package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream.component.scss +3973 -0
  61. package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream.component.ts +2235 -0
  62. package/artemis-main/apps/showcase_ui/src/app/components/chat-interface/chat-interface.component.html +380 -0
  63. package/artemis-main/apps/showcase_ui/src/app/components/chat-interface/chat-interface.component.scss +1171 -0
  64. package/artemis-main/apps/showcase_ui/src/app/components/chat-interface/chat-interface.component.ts +270 -0
  65. package/artemis-main/apps/showcase_ui/src/app/components/floating-video-player/floating-video-player.component.html +433 -0
  66. package/artemis-main/apps/showcase_ui/src/app/components/floating-video-player/floating-video-player.component.scss +987 -0
  67. package/artemis-main/apps/showcase_ui/src/app/components/floating-video-player/floating-video-player.component.ts +632 -0
  68. package/artemis-main/apps/showcase_ui/src/app/components/legacy-agent-stream/legacy-agent-stream.component.html +130 -0
  69. package/artemis-main/apps/showcase_ui/src/app/components/legacy-agent-stream/legacy-agent-stream.component.scss +406 -0
  70. package/artemis-main/apps/showcase_ui/src/app/components/legacy-agent-stream/legacy-agent-stream.component.ts +74 -0
  71. package/artemis-main/apps/showcase_ui/src/app/components/nav-switcher/nav-switcher.component.scss +115 -0
  72. package/artemis-main/apps/showcase_ui/src/app/components/nav-switcher/nav-switcher.component.ts +52 -0
  73. package/artemis-main/apps/showcase_ui/src/app/core/data/smart-tasks.data.ts +334 -0
  74. package/artemis-main/apps/showcase_ui/src/app/core/i18n/language.service.spec.ts +55 -0
  75. package/artemis-main/apps/showcase_ui/src/app/core/i18n/language.service.ts +61 -0
  76. package/artemis-main/apps/showcase_ui/src/app/core/i18n/translate.pipe.ts +11 -0
  77. package/artemis-main/apps/showcase_ui/src/app/core/i18n/zh-cn.ts +651 -0
  78. package/artemis-main/apps/showcase_ui/src/app/core/models/markdown.model.ts +43 -0
  79. package/artemis-main/apps/showcase_ui/src/app/core/models/pro-tuning.model.spec.ts +47 -0
  80. package/artemis-main/apps/showcase_ui/src/app/core/models/pro-tuning.model.ts +165 -0
  81. package/artemis-main/apps/showcase_ui/src/app/core/models/session.model.ts +85 -0
  82. package/artemis-main/apps/showcase_ui/src/app/core/models/stream.model.ts +246 -0
  83. package/artemis-main/apps/showcase_ui/src/app/core/models/system.model.ts +118 -0
  84. package/artemis-main/apps/showcase_ui/src/app/core/services/task-recommendation.service.ts +111 -0
  85. package/artemis-main/apps/showcase_ui/src/app/pages/home/home.component.html +2130 -0
  86. package/artemis-main/apps/showcase_ui/src/app/pages/home/home.component.scss +5204 -0
  87. package/artemis-main/apps/showcase_ui/src/app/pages/home/home.component.ts +1189 -0
  88. package/artemis-main/apps/showcase_ui/src/app/pages/legacy-workspace/legacy-workspace.component.html +39 -0
  89. package/artemis-main/apps/showcase_ui/src/app/pages/legacy-workspace/legacy-workspace.component.scss +151 -0
  90. package/artemis-main/apps/showcase_ui/src/app/pages/legacy-workspace/legacy-workspace.component.ts +58 -0
  91. package/artemis-main/apps/showcase_ui/src/app/pages/workspace/workspace.component.html +201 -0
  92. package/artemis-main/apps/showcase_ui/src/app/pages/workspace/workspace.component.scss +886 -0
  93. package/artemis-main/apps/showcase_ui/src/app/pages/workspace/workspace.component.ts +324 -0
  94. package/artemis-main/apps/showcase_ui/src/app/services/agent.service.spec.ts +418 -0
  95. package/artemis-main/apps/showcase_ui/src/app/services/agent.service.ts +2012 -0
  96. package/artemis-main/apps/showcase_ui/src/app/services/system.service.spec.ts +173 -0
  97. package/artemis-main/apps/showcase_ui/src/app/services/system.service.ts +620 -0
  98. package/artemis-main/apps/showcase_ui/src/app/utils/action-formatter.util.spec.ts +513 -0
  99. package/artemis-main/apps/showcase_ui/src/app/utils/action-formatter.util.ts +1015 -0
  100. package/artemis-main/apps/showcase_ui/src/app/utils/image-overlay.util.spec.ts +85 -0
  101. package/artemis-main/apps/showcase_ui/src/app/utils/image-overlay.util.ts +662 -0
  102. package/artemis-main/apps/showcase_ui/src/app/utils/markdown-parser.util.spec.ts +70 -0
  103. package/artemis-main/apps/showcase_ui/src/app/utils/markdown-parser.util.ts +383 -0
  104. package/artemis-main/apps/showcase_ui/src/app/utils/recording-timeline.util.spec.ts +107 -0
  105. package/artemis-main/apps/showcase_ui/src/app/utils/recording-timeline.util.ts +123 -0
  106. package/artemis-main/apps/showcase_ui/src/app/utils/run-info.util.spec.ts +92 -0
  107. package/artemis-main/apps/showcase_ui/src/app/utils/run-info.util.ts +116 -0
  108. package/artemis-main/apps/showcase_ui/src/app/utils/stream-aggregator.util.spec.ts +640 -0
  109. package/artemis-main/apps/showcase_ui/src/app/utils/stream-aggregator.util.ts +1021 -0
  110. package/artemis-main/apps/showcase_ui/src/app/utils/tool-formatter.util.spec.ts +375 -0
  111. package/artemis-main/apps/showcase_ui/src/app/utils/tool-formatter.util.ts +1419 -0
  112. package/artemis-main/apps/showcase_ui/src/index.html +37 -0
  113. package/artemis-main/apps/showcase_ui/src/main.ts +22 -0
  114. package/artemis-main/apps/showcase_ui/src/styles.scss +60 -0
  115. package/artemis-main/apps/showcase_ui/tsconfig.app.json +23 -0
  116. package/artemis-main/apps/showcase_ui/tsconfig.json +27 -0
  117. package/artemis-main/apps/showcase_ui/tsconfig.spec.json +23 -0
  118. package/artemis-main/artemis/__init__.py +44 -0
  119. package/artemis-main/artemis/__main__.py +18 -0
  120. package/artemis-main/artemis/_legacy_imports.py +94 -0
  121. package/artemis-main/artemis/_version.py +30 -0
  122. package/artemis-main/artemis/agents/__init__.py +17 -0
  123. package/artemis-main/artemis/agents/checker/checker.json +9 -0
  124. package/artemis-main/artemis/agents/checker/checker.py +859 -0
  125. package/artemis-main/artemis/agents/diagnoser/diagnoser.json +23 -0
  126. package/artemis-main/artemis/agents/diagnoser/diagnoser.py +608 -0
  127. package/artemis-main/artemis/agents/explorer/constants.py +52 -0
  128. package/artemis-main/artemis/agents/explorer/explorer.json +57 -0
  129. package/artemis-main/artemis/agents/explorer/explorer.py +473 -0
  130. package/artemis-main/artemis/agents/explorer/geometry.py +73 -0
  131. package/artemis-main/artemis/agents/explorer/native_runner.py +878 -0
  132. package/artemis-main/artemis/agents/explorer/perception_tools.py +632 -0
  133. package/artemis-main/artemis/agents/explorer/run_setup.py +403 -0
  134. package/artemis-main/artemis/agents/explorer/screen_index.py +266 -0
  135. package/artemis-main/artemis/agents/explorer/tiers.py +110 -0
  136. package/artemis-main/artemis/agents/explorer/tool_declarations.py +394 -0
  137. package/artemis-main/artemis/agents/explorer/universal_runner.py +317 -0
  138. package/artemis-main/artemis/agents/flash/context_compressor.py +452 -0
  139. package/artemis-main/artemis/agents/flash/flash_runner.md +51 -0
  140. package/artemis-main/artemis/agents/flash/flash_summarizer.md +53 -0
  141. package/artemis-main/artemis/agents/flash/flash_summarizer_single.md +54 -0
  142. package/artemis-main/artemis/agents/flash/runner.py +1167 -0
  143. package/artemis-main/artemis/agents/flash/summarizer.py +511 -0
  144. package/artemis-main/artemis/agents/history_analyzer/history_analyzer.md +8 -0
  145. package/artemis-main/artemis/agents/history_analyzer/history_analyzer.py +182 -0
  146. package/artemis-main/artemis/agents/image_processor/image_processor.md +74 -0
  147. package/artemis-main/artemis/agents/image_processor/image_processor.py +322 -0
  148. package/artemis-main/artemis/agents/log_analyzer/log_analyzer.md +15 -0
  149. package/artemis-main/artemis/agents/log_analyzer/log_analyzer.py +403 -0
  150. package/artemis-main/artemis/agents/log_analyzer/log_reader_sub_agent.md +8 -0
  151. package/artemis-main/artemis/agents/log_analyzer/output_analyzer.md +11 -0
  152. package/artemis-main/artemis/agents/log_analyzer/output_analyzer.py +163 -0
  153. package/artemis-main/artemis/agents/object_detector/object_detector.json +9 -0
  154. package/artemis-main/artemis/agents/object_detector/object_detector.py +211 -0
  155. package/artemis-main/artemis/agents/operator/operator.json +3 -0
  156. package/artemis-main/artemis/agents/operator/operator.py +1394 -0
  157. package/artemis-main/artemis/agents/operator/prompts.py +1064 -0
  158. package/artemis-main/artemis/agents/outputter/outputter.md +36 -0
  159. package/artemis-main/artemis/agents/outputter/outputter.py +552 -0
  160. package/artemis-main/artemis/agents/planner/planner.json +32 -0
  161. package/artemis-main/artemis/agents/planner/planner.py +436 -0
  162. package/artemis-main/artemis/agents/prompt_assembly.py +79 -0
  163. package/artemis-main/artemis/agents/summarizer/summarizer.py +190 -0
  164. package/artemis-main/artemis/agents/validator/action_execution.py +98 -0
  165. package/artemis-main/artemis/agents/validator/categories.py +33 -0
  166. package/artemis-main/artemis/agents/validator/execution_loop.py +488 -0
  167. package/artemis-main/artemis/agents/validator/incidents.py +120 -0
  168. package/artemis-main/artemis/agents/validator/pixel_safety_net.md +15 -0
  169. package/artemis-main/artemis/agents/validator/precondition_pixel.py +320 -0
  170. package/artemis-main/artemis/agents/validator/precondition_xml.py +672 -0
  171. package/artemis-main/artemis/agents/validator/tool_declarations.py +332 -0
  172. package/artemis-main/artemis/agents/validator/validator.py +188 -0
  173. package/artemis-main/artemis/agents/video_analyzer/__init__.py +15 -0
  174. package/artemis-main/artemis/agents/video_analyzer/audio_native.py +543 -0
  175. package/artemis-main/artemis/agents/video_analyzer/blackboard.py +821 -0
  176. package/artemis-main/artemis/agents/video_analyzer/chunk_agentic.py +455 -0
  177. package/artemis-main/artemis/agents/video_analyzer/chunk_conversation.py +491 -0
  178. package/artemis-main/artemis/agents/video_analyzer/chunk_native.py +437 -0
  179. package/artemis-main/artemis/agents/video_analyzer/conflict_resolution.py +137 -0
  180. package/artemis-main/artemis/agents/video_analyzer/gemini_files.py +162 -0
  181. package/artemis-main/artemis/agents/video_analyzer/native_coordinator.py +541 -0
  182. package/artemis-main/artemis/agents/video_analyzer/reliability.py +128 -0
  183. package/artemis-main/artemis/agents/video_analyzer/universal_engine.py +487 -0
  184. package/artemis-main/artemis/agents/video_analyzer/universal_tools.py +323 -0
  185. package/artemis-main/artemis/agents/video_analyzer/video_analyzer.md +51 -0
  186. package/artemis-main/artemis/agents/video_analyzer/video_analyzer.py +875 -0
  187. package/artemis-main/artemis/agents/video_analyzer/video_sub_agent.md +15 -0
  188. package/artemis-main/artemis/agents/video_analyzer/video_sub_agent_audio.md +12 -0
  189. package/artemis-main/artemis/clients/accessibility_client.py +438 -0
  190. package/artemis-main/artemis/clients/screen_client_factory.py +403 -0
  191. package/artemis-main/artemis/config/__init__.py +309 -0
  192. package/artemis-main/artemis/config/agent.py +1098 -0
  193. package/artemis-main/artemis/config/constants.py +151 -0
  194. package/artemis-main/artemis/config/core/__init__.py +24 -0
  195. package/artemis-main/artemis/config/core/engine.py +118 -0
  196. package/artemis-main/artemis/config/core/interpolator.py +78 -0
  197. package/artemis-main/artemis/config/llm.py +267 -0
  198. package/artemis-main/artemis/config/paths.py +244 -0
  199. package/artemis-main/artemis/config/runtime.py +197 -0
  200. package/artemis-main/artemis/config/settings.py +315 -0
  201. package/artemis-main/artemis/constants.py +47 -0
  202. package/artemis-main/artemis/context.py +289 -0
  203. package/artemis-main/artemis/controllers/__init__.py +41 -0
  204. package/artemis-main/artemis/controllers/controller_factory.py +41 -0
  205. package/artemis-main/artemis/controllers/device_controller.py +29 -0
  206. package/artemis-main/artemis/controllers/types.py +37 -0
  207. package/artemis-main/artemis/controllers/unified_controller.py +649 -0
  208. package/artemis-main/artemis/core/__init__.py +21 -0
  209. package/artemis-main/artemis/core/diagnostics/__init__.py +90 -0
  210. package/artemis-main/artemis/core/diagnostics/adb_keys.py +270 -0
  211. package/artemis-main/artemis/core/diagnostics/adb_server_connection.py +330 -0
  212. package/artemis-main/artemis/core/diagnostics/device_smoke.py +364 -0
  213. package/artemis-main/artemis/core/diagnostics/emulator_manager.py +501 -0
  214. package/artemis-main/artemis/core/diagnostics/engine.py +438 -0
  215. package/artemis-main/artemis/core/diagnostics/hierarchy_parity.py +216 -0
  216. package/artemis-main/artemis/core/diagnostics/probes/adb_probe.py +887 -0
  217. package/artemis-main/artemis/core/diagnostics/probes/base.py +45 -0
  218. package/artemis-main/artemis/core/diagnostics/probes/credentials_probe.py +296 -0
  219. package/artemis-main/artemis/core/diagnostics/probes/host_probe.py +427 -0
  220. package/artemis-main/artemis/core/diagnostics/probes/runtime_probe.py +169 -0
  221. package/artemis-main/artemis/core/diagnostics/probes/toolchain_probe.py +139 -0
  222. package/artemis-main/artemis/core/diagnostics/readiness.py +83 -0
  223. package/artemis-main/artemis/core/diagnostics/schema.py +118 -0
  224. package/artemis-main/artemis/core/tool_declaration.py +43 -0
  225. package/artemis-main/artemis/core/tool_failure.py +56 -0
  226. package/artemis-main/artemis/data_engine/context_vars.py +24 -0
  227. package/artemis-main/artemis/data_engine/engine.py +1615 -0
  228. package/artemis-main/artemis/data_engine/history_reader.py +142 -0
  229. package/artemis-main/artemis/data_engine/models.py +131 -0
  230. package/artemis-main/artemis/data_engine/storage.py +1245 -0
  231. package/artemis-main/artemis/data_engine/trace.py +727 -0
  232. package/artemis-main/artemis/drivers/__init__.py +48 -0
  233. package/artemis-main/artemis/drivers/android/adb_driver.py +507 -0
  234. package/artemis-main/artemis/drivers/android/hierarchy.py +64 -0
  235. package/artemis-main/artemis/drivers/android/input_ime.py +120 -0
  236. package/artemis-main/artemis/drivers/android/recorder.py +57 -0
  237. package/artemis-main/artemis/drivers/base.py +290 -0
  238. package/artemis-main/artemis/drivers/cloud/cloud_driver.py +117 -0
  239. package/artemis-main/artemis/drivers/factory.py +80 -0
  240. package/artemis-main/artemis/drivers/mock/mock_driver.py +198 -0
  241. package/artemis-main/artemis/drivers/types.py +67 -0
  242. package/artemis-main/artemis/graph/checkpoints.py +1243 -0
  243. package/artemis-main/artemis/graph/graph.py +1055 -0
  244. package/artemis-main/artemis/graph/perception.py +234 -0
  245. package/artemis-main/artemis/graph/state.py +151 -0
  246. package/artemis-main/artemis/graph/visibility.py +238 -0
  247. package/artemis-main/artemis/interfaces/cli/__init__.py +19 -0
  248. package/artemis-main/artemis/interfaces/cli/commands/__init__.py +15 -0
  249. package/artemis-main/artemis/interfaces/cli/commands/batch.py +278 -0
  250. package/artemis-main/artemis/interfaces/cli/commands/doctor.py +468 -0
  251. package/artemis-main/artemis/interfaces/cli/commands/helper.py +226 -0
  252. package/artemis-main/artemis/interfaces/cli/commands/init.py +193 -0
  253. package/artemis-main/artemis/interfaces/cli/commands/mcp.py +862 -0
  254. package/artemis-main/artemis/interfaces/cli/commands/run.py +463 -0
  255. package/artemis-main/artemis/interfaces/cli/commands/server.py +151 -0
  256. package/artemis-main/artemis/interfaces/cli/commands/server_lifecycle.py +328 -0
  257. package/artemis-main/artemis/interfaces/cli/commands/trace.py +111 -0
  258. package/artemis-main/artemis/interfaces/cli/commands/ui.py +404 -0
  259. package/artemis-main/artemis/interfaces/cli/main.py +109 -0
  260. package/artemis-main/artemis/interfaces/sdk/__init__.py +31 -0
  261. package/artemis-main/artemis/interfaces/sdk/client.py +19 -0
  262. package/artemis-main/artemis/interfaces/sdk/task.py +72 -0
  263. package/artemis-main/artemis/llm/__init__.py +25 -0
  264. package/artemis-main/artemis/llm/fake_model.py +179 -0
  265. package/artemis-main/artemis/llm/google/__init__.py +57 -0
  266. package/artemis-main/artemis/llm/google/provider.py +185 -0
  267. package/artemis-main/artemis/llm/google/usage.py +148 -0
  268. package/artemis-main/artemis/llm/parser.py +32 -0
  269. package/artemis-main/artemis/llm/reliability.py +267 -0
  270. package/artemis-main/artemis/llm/router.py +389 -0
  271. package/artemis-main/artemis/llm/schemas.py +36 -0
  272. package/artemis-main/artemis/llm/structured.py +196 -0
  273. package/artemis-main/artemis/main.py +58 -0
  274. package/artemis-main/artemis/mcp/__init__.py +20 -0
  275. package/artemis-main/artemis/mcp/action_executor.py +760 -0
  276. package/artemis-main/artemis/mcp/action_manifest.py +320 -0
  277. package/artemis-main/artemis/mcp/action_names.py +172 -0
  278. package/artemis-main/artemis/mcp/action_server.py +202 -0
  279. package/artemis-main/artemis/mcp/action_session.py +245 -0
  280. package/artemis-main/artemis/mcp/action_specs.py +868 -0
  281. package/artemis-main/artemis/mcp/action_types.py +86 -0
  282. package/artemis-main/artemis/mcp/actuators/__init__.py +21 -0
  283. package/artemis-main/artemis/mcp/actuators/adb.py +414 -0
  284. package/artemis-main/artemis/mcp/actuators/base.py +113 -0
  285. package/artemis-main/artemis/mcp/actuators/mock.py +70 -0
  286. package/artemis-main/artemis/mcp/adb_server.py +490 -0
  287. package/artemis-main/artemis/mcp/observation.py +133 -0
  288. package/artemis-main/artemis/mcp/xml_search_server.py +297 -0
  289. package/artemis-main/artemis/memory/__init__.py +90 -0
  290. package/artemis-main/artemis/memory/chunking.py +1843 -0
  291. package/artemis-main/artemis/memory/context_policy.py +226 -0
  292. package/artemis-main/artemis/memory/step_capsule.md +73 -0
  293. package/artemis-main/artemis/memory/step_memory.py +281 -0
  294. package/artemis-main/artemis/memory/transcript.py +798 -0
  295. package/artemis-main/artemis/platform/__init__.py +61 -0
  296. package/artemis-main/artemis/platform/base.py +104 -0
  297. package/artemis-main/artemis/platform/darwin.py +184 -0
  298. package/artemis-main/artemis/platform/linux.py +207 -0
  299. package/artemis-main/artemis/platform/windows.py +193 -0
  300. package/artemis-main/artemis/resources/__init__.py +46 -0
  301. package/artemis-main/artemis/runtime/__init__.py +108 -0
  302. package/artemis-main/artemis/runtime/adb_endpoint.py +173 -0
  303. package/artemis-main/artemis/runtime/awake_lease.py +283 -0
  304. package/artemis-main/artemis/runtime/awake_service.py +343 -0
  305. package/artemis-main/artemis/runtime/cancel_requests.py +254 -0
  306. package/artemis-main/artemis/runtime/daemon_client.py +422 -0
  307. package/artemis-main/artemis/runtime/device_lock.py +1013 -0
  308. package/artemis-main/artemis/runtime/device_pool.py +478 -0
  309. package/artemis-main/artemis/runtime/helper_manager.py +1030 -0
  310. package/artemis-main/artemis/runtime/process_probe.py +98 -0
  311. package/artemis-main/artemis/runtime/server_lifecycle.py +435 -0
  312. package/artemis-main/artemis/runtime/supervisor.py +121 -0
  313. package/artemis-main/artemis/runtime/trace_store.py +375 -0
  314. package/artemis-main/artemis/sdk/__init__.py +26 -0
  315. package/artemis-main/artemis/sdk/agent.py +485 -0
  316. package/artemis-main/artemis/sdk/builders/__init__.py +29 -0
  317. package/artemis-main/artemis/sdk/builders/agent_config_builder.py +474 -0
  318. package/artemis-main/artemis/sdk/constants.py +15 -0
  319. package/artemis-main/artemis/sdk/run_outcome.py +58 -0
  320. package/artemis-main/artemis/sdk/types/__init__.py +61 -0
  321. package/artemis-main/artemis/sdk/types/agent.py +89 -0
  322. package/artemis-main/artemis/sdk/utils.py +28 -0
  323. package/artemis-main/artemis/services/llm.py +1040 -0
  324. package/artemis-main/artemis/services/token_meter.py +267 -0
  325. package/artemis-main/artemis/telemetry/__init__.py +35 -0
  326. package/artemis-main/artemis/telemetry/models.py +64 -0
  327. package/artemis-main/artemis/telemetry/replay.py +34 -0
  328. package/artemis-main/artemis/telemetry/storage/json_storage.py +47 -0
  329. package/artemis-main/artemis/telemetry/tracer.py +85 -0
  330. package/artemis-main/artemis/toolchain/__init__.py +52 -0
  331. package/artemis-main/artemis/toolchain/descriptors.py +92 -0
  332. package/artemis-main/artemis/toolchain/resolver.py +185 -0
  333. package/artemis-main/artemis/tools/base.py +232 -0
  334. package/artemis-main/artemis/tools/command_tool.py +1240 -0
  335. package/artemis-main/artemis/tools/committee_prompts.json +5 -0
  336. package/artemis-main/artemis/tools/committee_tool.py +422 -0
  337. package/artemis-main/artemis/tools/diagnoser_submit_answer_tool.py +87 -0
  338. package/artemis-main/artemis/tools/diagnostic_tool.py +120 -0
  339. package/artemis-main/artemis/tools/explorer_tool.py +581 -0
  340. package/artemis-main/artemis/tools/history/__init__.py +398 -0
  341. package/artemis-main/artemis/tools/history/replay.py +120 -0
  342. package/artemis-main/artemis/tools/history/screenshot.py +139 -0
  343. package/artemis-main/artemis/tools/history/search.py +563 -0
  344. package/artemis-main/artemis/tools/image_processor_tool.py +124 -0
  345. package/artemis-main/artemis/tools/index.py +47 -0
  346. package/artemis-main/artemis/tools/log_tool.py +108 -0
  347. package/artemis-main/artemis/tools/mobile/launch_app.py +132 -0
  348. package/artemis-main/artemis/tools/mobile/log_utils.py +138 -0
  349. package/artemis-main/artemis/tools/mobile/ocr.py +202 -0
  350. package/artemis-main/artemis/tools/mobile/read_hierarchy.py +108 -0
  351. package/artemis-main/artemis/tools/mobile/read_logs.py +116 -0
  352. package/artemis-main/artemis/tools/mobile/search_logs.py +260 -0
  353. package/artemis-main/artemis/tools/object_detection_tool.py +244 -0
  354. package/artemis-main/artemis/tools/scratchpad.py +819 -0
  355. package/artemis-main/artemis/tools/system/adb_shell.py +31 -0
  356. package/artemis-main/artemis/tools/tool_wrapper.py +270 -0
  357. package/artemis-main/artemis/tools/video_tool.py +261 -0
  358. package/artemis-main/artemis/tools/wait_tool.py +97 -0
  359. package/artemis-main/artemis/utils/app_launch_utils.py +207 -0
  360. package/artemis-main/artemis/utils/coordinates.py +606 -0
  361. package/artemis-main/artemis/utils/credentials_validator.py +201 -0
  362. package/artemis-main/artemis/utils/cv_canvas.py +189 -0
  363. package/artemis-main/artemis/utils/cython_compat.py +45 -0
  364. package/artemis-main/artemis/utils/element_hit_test.py +80 -0
  365. package/artemis-main/artemis/utils/image_diff.py +335 -0
  366. package/artemis-main/artemis/utils/image_hash.py +80 -0
  367. package/artemis-main/artemis/utils/notes.py +470 -0
  368. package/artemis-main/artemis/utils/ocr_api.py +105 -0
  369. package/artemis-main/artemis/utils/ocr_xml_fusion.py +318 -0
  370. package/artemis-main/artemis/utils/plan_grammar.py +513 -0
  371. package/artemis-main/artemis/utils/python_executor.py +213 -0
  372. package/artemis-main/artemis/utils/startup_progress.py +60 -0
  373. package/artemis-main/artemis/utils/task_tree.py +1174 -0
  374. package/artemis-main/artemis/utils/text.py +37 -0
  375. package/artemis-main/artemis/utils/ui_filter.py +651 -0
  376. package/artemis-main/artemis/utils/video.py +685 -0
  377. package/artemis-main/artemis/utils/visualization.py +802 -0
  378. package/artemis-main/config/artemis.example.jsonc +12 -0
  379. package/artemis-main/mcp_server/README.md +111 -0
  380. package/artemis-main/mcp_server/__init__.py +21 -0
  381. package/artemis-main/mcp_server/__main__.py +20 -0
  382. package/artemis-main/mcp_server/background/__init__.py +15 -0
  383. package/artemis-main/mcp_server/background/task_runner.py +453 -0
  384. package/artemis-main/mcp_server/base.py +49 -0
  385. package/artemis-main/mcp_server/notifiers/__init__.py +74 -0
  386. package/artemis-main/mcp_server/notifiers/agentapi.py +289 -0
  387. package/artemis-main/mcp_server/notifiers/base.py +45 -0
  388. package/artemis-main/mcp_server/notifiers/composite.py +87 -0
  389. package/artemis-main/mcp_server/notifiers/desktop.py +108 -0
  390. package/artemis-main/mcp_server/notifiers/file.py +69 -0
  391. package/artemis-main/mcp_server/notifiers/script.py +90 -0
  392. package/artemis-main/mcp_server/notifiers/webhook.py +87 -0
  393. package/artemis-main/mcp_server/rules.md +68 -0
  394. package/artemis-main/mcp_server/server.py +106 -0
  395. package/artemis-main/mcp_server/tools/__init__.py +29 -0
  396. package/artemis-main/mcp_server/tools/device_state.py +107 -0
  397. package/artemis-main/mcp_server/tools/diagnose.py +1249 -0
  398. package/artemis-main/mcp_server/tools/inspect_trace.py +394 -0
  399. package/artemis-main/mcp_server/tools/task_manager.py +627 -0
  400. package/artemis-main/mcp_server/tools/task_runner.py +548 -0
  401. package/artemis-main/mcp_server/utils/__init__.py +15 -0
  402. package/artemis-main/mcp_server/utils/device_utils.py +180 -0
  403. package/artemis-main/mcp_server/utils/env_utils.py +65 -0
  404. package/artemis-main/packages/artemis-accessibility-helper/ArtemisAccessibilityHelper.apk +0 -0
  405. package/artemis-main/packages/artemis-accessibility-helper/app/build.gradle.kts +35 -0
  406. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/AndroidManifest.xml +49 -0
  407. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/A11yNode.java +274 -0
  408. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/ArtemisAccessibilityService.java +227 -0
  409. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/CommandServer.java +463 -0
  410. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/DisplayUtils.java +111 -0
  411. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/GestureController.java +232 -0
  412. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/HierarchyDumper.java +832 -0
  413. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/TokenReceiver.java +36 -0
  414. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/TokenStore.java +38 -0
  415. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/XmlUtils.java +102 -0
  416. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/res/values/strings.xml +4 -0
  417. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/res/xml/accessibility_service_config.xml +10 -0
  418. package/artemis-main/packages/artemis-accessibility-helper/build.gradle.kts +3 -0
  419. package/artemis-main/packages/artemis-accessibility-helper/build_apk.sh +215 -0
  420. package/artemis-main/packages/artemis-accessibility-helper/debug.keystore +0 -0
  421. package/artemis-main/packages/artemis-accessibility-helper/gradle.properties +2 -0
  422. package/artemis-main/packages/artemis-accessibility-helper/helper_manifest.json +7 -0
  423. package/artemis-main/packages/artemis-accessibility-helper/settings.gradle.kts +17 -0
  424. package/artemis-main/packages/artemis-client/DESIGN.md +89 -0
  425. package/artemis-main/packages/artemis-client/README.md +112 -0
  426. package/artemis-main/packages/artemis-client/examples/basic.py +30 -0
  427. package/artemis-main/packages/artemis-client/pyproject.toml +36 -0
  428. package/artemis-main/packages/artemis-client/src/artemis_client/__init__.py +45 -0
  429. package/artemis-main/packages/artemis-client/src/artemis_client/client.py +401 -0
  430. package/artemis-main/packages/artemis-client/src/artemis_client/errors.py +66 -0
  431. package/artemis-main/packages/artemis-client/src/artemis_client/models.py +212 -0
  432. package/artemis-main/packages/artemis-client/src/artemis_client/py.typed +1 -0
  433. package/artemis-main/packages/artemis-client/src/artemis_client/transport.py +134 -0
  434. package/artemis-main/packages/artemis-client/tests/test_client.py +289 -0
  435. package/artemis-main/packages/artemis-client/tests/test_transport.py +85 -0
  436. package/artemis-main/pyproject.toml +259 -0
  437. package/artemis-main/pyright-core.json +17 -0
  438. package/artemis-main/scripts/check_dependency_sources.py +68 -0
  439. package/artemis-main/scripts/install_deps.ps1 +520 -0
  440. package/artemis-main/scripts/install_deps.sh +533 -0
  441. package/artemis-main/scripts/quality_ratchet.py +97 -0
  442. package/artemis-main/scripts/real_device_video_acceptance.py +483 -0
  443. package/artemis-main/scripts/run_edge_case_part.py +327 -0
  444. package/artemis-main/scripts/run_ui.py +242 -0
  445. package/artemis-main/scripts/start.ps1 +500 -0
  446. package/artemis-main/scripts/test_all_edge_cases.py +269 -0
  447. package/artemis-main/scripts/verify_concurrency_and_devices.py +385 -0
  448. package/artemis-main/setup.py +164 -0
  449. package/artemis-main/start.bat +35 -0
  450. package/artemis-main/start.sh +423 -0
  451. package/artemis-main/third_party/mobile_use/LICENSE +190 -0
  452. package/artemis-main/third_party/mobile_use/METADATA +27 -0
  453. package/artemis-main/third_party/mobile_use/NOTICE +12 -0
  454. package/artemis-main/third_party/mobile_use/__init__.py +19 -0
  455. package/artemis-main/third_party/mobile_use/agents/__init__.py +13 -0
  456. package/artemis-main/third_party/mobile_use/agents/hopper/__init__.py +13 -0
  457. package/artemis-main/third_party/mobile_use/agents/hopper/hopper.md +22 -0
  458. package/artemis-main/third_party/mobile_use/agents/hopper/hopper.py +80 -0
  459. package/artemis-main/third_party/mobile_use/clients/__init__.py +13 -0
  460. package/artemis-main/third_party/mobile_use/clients/ui_automator_client.py +482 -0
  461. package/artemis-main/third_party/mobile_use/config/__init__.py +13 -0
  462. package/artemis-main/third_party/mobile_use/config/llm.py +183 -0
  463. package/artemis-main/third_party/mobile_use/config/output.py +184 -0
  464. package/artemis-main/third_party/mobile_use/context.py +119 -0
  465. package/artemis-main/third_party/mobile_use/controllers/__init__.py +13 -0
  466. package/artemis-main/third_party/mobile_use/controllers/platform_specific_commands_controller.py +151 -0
  467. package/artemis-main/third_party/mobile_use/controllers/types.py +92 -0
  468. package/artemis-main/third_party/mobile_use/controllers/unified_controller.py +183 -0
  469. package/artemis-main/third_party/mobile_use/graph.py +54 -0
  470. package/artemis-main/third_party/mobile_use/llm_service.py +193 -0
  471. package/artemis-main/third_party/mobile_use/main.py +130 -0
  472. package/artemis-main/third_party/mobile_use/sdk/__init__.py +13 -0
  473. package/artemis-main/third_party/mobile_use/sdk/agent.py +1060 -0
  474. package/artemis-main/third_party/mobile_use/sdk/builders/__init__.py +13 -0
  475. package/artemis-main/third_party/mobile_use/sdk/builders/agent_config_builder.py +225 -0
  476. package/artemis-main/third_party/mobile_use/sdk/builders/index.py +33 -0
  477. package/artemis-main/third_party/mobile_use/sdk/builders/task_request_builder.py +243 -0
  478. package/artemis-main/third_party/mobile_use/sdk/types/__init__.py +13 -0
  479. package/artemis-main/third_party/mobile_use/sdk/types/agent.py +98 -0
  480. package/artemis-main/third_party/mobile_use/sdk/types/exceptions.py +109 -0
  481. package/artemis-main/third_party/mobile_use/sdk/types/task.py +234 -0
  482. package/artemis-main/third_party/mobile_use/testing.py +59 -0
  483. package/artemis-main/third_party/mobile_use/tools/__init__.py +13 -0
  484. package/artemis-main/third_party/mobile_use/tools/index.py +44 -0
  485. package/artemis-main/third_party/mobile_use/tools/mobile/__init__.py +13 -0
  486. package/artemis-main/third_party/mobile_use/tools/mobile/launch_app.py +89 -0
  487. package/artemis-main/third_party/mobile_use/tools/tool_wrapper.py +52 -0
  488. package/artemis-main/third_party/mobile_use/utils/__init__.py +13 -0
  489. package/artemis-main/third_party/mobile_use/utils/app_launch_utils.py +217 -0
  490. package/artemis-main/third_party/mobile_use/utils/cli_helpers.py +60 -0
  491. package/artemis-main/third_party/mobile_use/utils/decorators.py +158 -0
  492. package/artemis-main/third_party/mobile_use/utils/file.py +31 -0
  493. package/artemis-main/third_party/mobile_use/utils/logger.py +216 -0
  494. package/artemis-main/third_party/mobile_use/utils/media.py +213 -0
  495. package/artemis-main/third_party/mobile_use/utils/shell_utils.py +39 -0
  496. package/artemis-main/third_party/mobile_use/utils/video.py +398 -0
  497. package/artemis-main/uv.lock +4908 -0
  498. package/bin/android-midscene-automation.js +1 -5
  499. package/bin/artemis-config.mjs +15 -0
  500. package/bin/artemis-embedded.py +56 -0
  501. package/bin/start-artemis.mjs +30 -0
  502. package/bin/start-dev.mjs +112 -0
  503. package/bin/test_artemis_embedded.py +44 -0
  504. package/package.json +10 -8
  505. package/server/artemis.ts +34 -0
  506. package/server/http-api.ts +13 -1
  507. package/src/App.vue +72 -23
  508. package/src/api.ts +5 -0
  509. package/src/appium-recorder/AppiumPage.vue +1 -1
  510. package/src/appium-recorder/components/ComponentInspector.vue +1 -1
  511. package/src/appium-recorder/components/FlowNodeSearch.vue +3 -3
  512. package/src/appium-recorder/components/ImageCheckDialog.vue +3 -3
  513. package/src/appium-recorder/components/RecorderWorkspace.vue +4 -4
  514. package/src/appium-recorder/flow-appearance.ts +4 -4
  515. package/src/components/AppSidebar.vue +8 -7
  516. package/src/components/MidsceneMaintenanceNotice.vue +17 -0
  517. package/src/components/analytics/AnalysisCharts.vue +4 -4
  518. package/src/components/analytics/ReportAnalysis.vue +1 -1
  519. package/src/components/generator/TestCaseFileUpload.vue +1 -1
  520. package/src/components/help/HelpCenter.vue +56 -37
  521. package/src/pages/AiGeneratorPage.vue +1 -1
  522. package/src/pages/ArtemisPage.vue +72 -0
  523. package/src/pages/ConfigPage.vue +18 -19
  524. package/src/style.css +369 -186
  525. package/src/types.ts +1 -1
@@ -0,0 +1,3973 @@
1
+ /**
2
+ * Copyright 2026 Google LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ $border-color: rgba(0, 0, 0, 0.08);
18
+ $text-primary: #1f1f1f;
19
+ $text-secondary: #1f1f1f;
20
+ $text-muted: #1f1f1f;
21
+ $bg-main: #f9fafb;
22
+ $uniform-gap: 8px;
23
+ $stream-row-height: 25px;
24
+
25
+ :host {
26
+ display: flex;
27
+ flex-direction: column;
28
+ height: 100%;
29
+ width: 100%;
30
+ overflow: hidden;
31
+ }
32
+
33
+ .agent-stream-container {
34
+ display: flex;
35
+ flex-direction: column;
36
+ height: 100%;
37
+ background: #f8f9fa;
38
+ box-sizing: border-box;
39
+ position: relative;
40
+ container-type: inline-size;
41
+ container-name: stream-panel;
42
+
43
+ .vscode-nav-header {
44
+ position: relative;
45
+ height: 60px;
46
+ flex-shrink: 0;
47
+ background: #ffffff;
48
+ border-bottom: 1px solid rgba(0, 0, 0, 0.08);
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: flex-end;
52
+ padding: 0 16px;
53
+ box-sizing: border-box;
54
+ user-select: none;
55
+ box-shadow: none;
56
+ z-index: 10;
57
+
58
+ @media (min-width: 1151px) {
59
+ display: none !important;
60
+ }
61
+
62
+ .vscode-tab-container {
63
+ display: flex;
64
+ height: 36px;
65
+ box-sizing: border-box;
66
+ background: rgba(241, 245, 249, 0.72);
67
+ backdrop-filter: blur(16px) saturate(180%);
68
+ -webkit-backdrop-filter: blur(16px) saturate(180%);
69
+ border: 1px solid rgba(226, 232, 240, 0.85);
70
+ border-radius: 18px;
71
+ padding: 3px;
72
+ gap: 3px;
73
+ align-items: center;
74
+ flex-shrink: 0;
75
+ box-shadow: 0 2px 8px -1px rgba(15, 23, 42, 0.04), inset 0 1px 1px rgba(255, 255, 255, 0.8);
76
+ }
77
+
78
+ .vscode-tab-btn {
79
+ display: inline-flex;
80
+ align-items: center;
81
+ justify-content: center;
82
+ gap: 6px;
83
+ height: 30px;
84
+ padding: 0 14px;
85
+ box-sizing: border-box;
86
+ border: none;
87
+ background: transparent;
88
+ border-radius: 15px;
89
+ font-size: 13px;
90
+ font-weight: 600;
91
+ color: #64748b;
92
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
93
+ text-decoration: none;
94
+ cursor: pointer;
95
+ position: relative;
96
+ line-height: 1;
97
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
98
+ outline: none;
99
+ white-space: nowrap;
100
+
101
+ .tab-icon {
102
+ font-size: 16px;
103
+ color: inherit;
104
+ transition: color 0.15s ease;
105
+ }
106
+
107
+ .badge-count {
108
+ background: #2563eb;
109
+ color: #ffffff;
110
+ font-size: 10px;
111
+ font-weight: 700;
112
+ padding: 1px 6px;
113
+ border-radius: 10px;
114
+ line-height: 1;
115
+ }
116
+
117
+ .dropdown-chevron {
118
+ font-size: 16px;
119
+ color: #94a3b8;
120
+ margin-left: 2px;
121
+ transition: transform 0.2s ease, color 0.15s ease;
122
+
123
+ &.open {
124
+ transform: rotate(180deg);
125
+ color: #1e293b;
126
+ }
127
+ }
128
+
129
+ &:hover:not(.active) {
130
+ color: #0f172a;
131
+ background: rgba(255, 255, 255, 0.6);
132
+ }
133
+
134
+ &.active {
135
+ background: #ffffff;
136
+ color: #2563eb;
137
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.02);
138
+
139
+ .tab-icon {
140
+ color: #2563eb;
141
+ }
142
+ }
143
+
144
+ &.video-replay-tab-btn {
145
+ .video-indicator-dot {
146
+ width: 7px;
147
+ height: 7px;
148
+ border-radius: 50%;
149
+ background: #10b981;
150
+ box-shadow: 0 0 6px #10b981;
151
+ margin-left: -2px;
152
+ flex-shrink: 0;
153
+ }
154
+
155
+ &.has-video {
156
+ .tab-icon {
157
+ color: #0284c7;
158
+ }
159
+ }
160
+ }
161
+ }
162
+
163
+ .header-right-actions {
164
+ margin-left: auto;
165
+ display: flex;
166
+ align-items: center;
167
+
168
+ .btn-resume-task,
169
+ .btn-stop-task {
170
+ padding: 5px 10px;
171
+ background: #2563eb;
172
+ border: 1px solid #2563eb;
173
+ border-radius: 16px;
174
+ font-size: 13px;
175
+ font-weight: 600;
176
+ color: #ffffff;
177
+ cursor: pointer;
178
+ display: flex;
179
+ align-items: center;
180
+ gap: 4px;
181
+ transition: all 0.2s;
182
+ box-shadow: 0 2px 4px rgba(37, 99, 235, 0.2);
183
+
184
+ .material-symbols-outlined {
185
+ font-size: 15px;
186
+ color: inherit;
187
+ }
188
+
189
+ &:hover {
190
+ background: #1d4ed8;
191
+ border-color: #1d4ed8;
192
+ box-shadow: 0 4px 8px rgba(37, 99, 235, 0.3);
193
+ }
194
+ }
195
+
196
+ .btn-stop-task {
197
+ background: #ef4444;
198
+ border-color: #ef4444;
199
+ box-shadow: 0 2px 4px rgba(239, 68, 68, 0.2);
200
+
201
+ &:hover {
202
+ background: #dc2626;
203
+ border-color: #dc2626;
204
+ box-shadow: 0 4px 8px rgba(239, 68, 68, 0.3);
205
+ }
206
+ }
207
+ }
208
+
209
+
210
+ }
211
+
212
+ .stream-floating-toolbar {
213
+ position: absolute;
214
+ top: 12px;
215
+ right: 20px;
216
+ height: 36px;
217
+ display: inline-flex;
218
+ align-items: center;
219
+ gap: 8px;
220
+ z-index: 40;
221
+ pointer-events: auto;
222
+
223
+ @media (max-width: 1150px) {
224
+ top: 72px;
225
+ }
226
+
227
+ /* Model Info Chip: click opens the run info popover */
228
+ .model-info-chip {
229
+ display: inline-flex;
230
+ align-items: center;
231
+ gap: 5px;
232
+ height: 30px;
233
+ padding: 0 11px;
234
+ margin: 0;
235
+ box-sizing: border-box;
236
+ background: rgba(255, 255, 255, 0.72);
237
+ backdrop-filter: blur(16px) saturate(180%);
238
+ -webkit-backdrop-filter: blur(16px) saturate(180%);
239
+ border: 1px solid rgba(226, 232, 240, 0.85);
240
+ border-radius: 15px;
241
+ cursor: pointer;
242
+ user-select: none;
243
+ appearance: none;
244
+ -webkit-appearance: none;
245
+
246
+ &:hover {
247
+ background: rgba(255, 255, 255, 0.92);
248
+ border-color: rgba(203, 213, 225, 0.95);
249
+ }
250
+
251
+ &.active {
252
+ background: #eff6ff;
253
+ border-color: #bfdbfe;
254
+
255
+ .model-icon,
256
+ .model-name {
257
+ color: #1d4ed8;
258
+ }
259
+ }
260
+
261
+ &:focus-visible {
262
+ outline: 2px solid #93c5fd;
263
+ outline-offset: 1px;
264
+ }
265
+ box-shadow: 0 2px 6px -1px rgba(15, 23, 42, 0.05), inset 0 1px 1px rgba(255, 255, 255, 0.9);
266
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
267
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
268
+
269
+ .model-icon {
270
+ font-size: 15px;
271
+ width: 15px;
272
+ height: 15px;
273
+ display: inline-flex;
274
+ align-items: center;
275
+ justify-content: center;
276
+ color: #64748b;
277
+ }
278
+
279
+ .model-label {
280
+ font-size: 12px;
281
+ font-weight: 500;
282
+ color: #64748b;
283
+ line-height: 1;
284
+ }
285
+
286
+ .model-name {
287
+ font-size: 12px;
288
+ font-weight: 700;
289
+ color: #1e293b;
290
+ letter-spacing: 0.1px;
291
+ line-height: 1;
292
+ }
293
+ }
294
+
295
+ /* Screen Recording Action Button: Interactive Button */
296
+ .btn-screen-recording {
297
+ display: inline-flex;
298
+ align-items: center;
299
+ gap: 5px;
300
+ height: 30px;
301
+ padding: 0 12px;
302
+ box-sizing: border-box;
303
+ background: rgba(255, 255, 255, 0.72);
304
+ backdrop-filter: blur(16px) saturate(180%);
305
+ -webkit-backdrop-filter: blur(16px) saturate(180%);
306
+ border: 1px solid rgba(226, 232, 240, 0.85);
307
+ border-radius: 15px;
308
+ box-shadow: 0 2px 6px -1px rgba(15, 23, 42, 0.05), inset 0 1px 1px rgba(255, 255, 255, 0.9);
309
+ cursor: pointer;
310
+ transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
311
+ user-select: none;
312
+ outline: none;
313
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
314
+
315
+ .video-icon {
316
+ font-size: 15px;
317
+ width: 15px;
318
+ height: 15px;
319
+ display: inline-flex;
320
+ align-items: center;
321
+ justify-content: center;
322
+ color: #64748b;
323
+ transition: transform 0.2s ease, color 0.2s ease;
324
+ }
325
+
326
+ .btn-text {
327
+ font-size: 12px;
328
+ font-weight: 600;
329
+ color: #475569;
330
+ letter-spacing: 0.1px;
331
+ line-height: 1;
332
+ transition: color 0.15s ease;
333
+ }
334
+
335
+ .video-pulse-dot {
336
+ width: 6px;
337
+ height: 6px;
338
+ border-radius: 50%;
339
+ background: #ef4444;
340
+ box-shadow: 0 0 6px #ef4444;
341
+ animation: pulseRed 1.5s infinite;
342
+ }
343
+
344
+ &.recording {
345
+ background: rgba(254, 242, 242, 0.9);
346
+ border-color: rgba(248, 113, 113, 0.6);
347
+ box-shadow: 0 2px 6px -1px rgba(220, 38, 38, 0.15), inset 0 1px 1px rgba(255, 255, 255, 0.9);
348
+
349
+ .video-icon {
350
+ color: #dc2626;
351
+ }
352
+
353
+ .btn-text {
354
+ color: #b91c1c;
355
+ }
356
+ }
357
+
358
+ &.processing {
359
+ .video-icon {
360
+ color: #2563eb;
361
+ animation: spin 1s linear infinite;
362
+ }
363
+ }
364
+
365
+ &:hover:not(.active) {
366
+ background: rgba(255, 255, 255, 0.88);
367
+ border-color: rgba(203, 213, 225, 0.95);
368
+ box-shadow: 0 4px 12px -2px rgba(15, 23, 42, 0.08), inset 0 1px 1px rgba(255, 255, 255, 1);
369
+ color: #0f172a;
370
+
371
+ .video-icon {
372
+ color: #1a73e8;
373
+ transform: scale(1.08);
374
+ }
375
+
376
+ .btn-text {
377
+ color: #0f172a;
378
+ }
379
+ }
380
+
381
+ &:active {
382
+ transform: translateY(0);
383
+ box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08);
384
+ }
385
+
386
+ &.has-steps {
387
+ background: rgba(240, 253, 250, 0.9);
388
+ border-color: rgba(94, 234, 212, 0.7);
389
+ box-shadow: 0 2px 6px -1px rgba(13, 148, 136, 0.12), inset 0 1px 1px rgba(255, 255, 255, 0.9);
390
+
391
+ .steps-icon {
392
+ color: #0d9488;
393
+ }
394
+
395
+ .btn-text {
396
+ color: #0f766e;
397
+ }
398
+
399
+ &:hover:not(.active) {
400
+ background: rgba(204, 251, 241, 0.95);
401
+ border-color: rgba(45, 212, 191, 0.85);
402
+
403
+ .steps-icon {
404
+ color: #0f766e;
405
+ }
406
+ }
407
+ }
408
+
409
+ &.failed {
410
+ background: rgba(254, 242, 242, 0.8);
411
+ border-color: rgba(254, 202, 202, 0.9);
412
+
413
+ .error-icon {
414
+ color: #ef4444;
415
+ }
416
+
417
+ .btn-text {
418
+ color: #dc2626;
419
+ }
420
+ }
421
+
422
+ .steps-count-badge {
423
+ display: inline-flex;
424
+ align-items: center;
425
+ justify-content: center;
426
+ padding: 1px 5px;
427
+ border-radius: 10px;
428
+ background: #0d9488;
429
+ color: #ffffff;
430
+ font-size: 10px;
431
+ font-weight: 700;
432
+ line-height: 1;
433
+ margin-left: 2px;
434
+ }
435
+
436
+ &.active {
437
+ background: rgba(26, 115, 232, 0.95);
438
+ border-color: rgba(26, 115, 232, 0.95);
439
+ box-shadow: 0 2px 8px rgba(26, 115, 232, 0.35);
440
+
441
+ .video-icon, .btn-text {
442
+ color: #ffffff;
443
+ }
444
+
445
+ .video-pulse-dot {
446
+ background: #ffffff;
447
+ box-shadow: 0 0 6px rgba(255, 255, 255, 0.9);
448
+ }
449
+
450
+ .steps-count-badge {
451
+ background: #ffffff;
452
+ color: #1a73e8;
453
+ }
454
+ }
455
+ }
456
+ }
457
+
458
+ .stream-logs-content {
459
+ flex: 1;
460
+ overflow-y: auto;
461
+ padding: 72px 24px 100px 24px;
462
+ position: relative;
463
+
464
+ .session-loading-state {
465
+ min-height: 180px;
466
+ display: flex;
467
+ align-items: center;
468
+ justify-content: center;
469
+ gap: 9px;
470
+ color: #64748b;
471
+ font-size: 13px;
472
+
473
+ .material-symbols-outlined {
474
+ font-size: 18px;
475
+ }
476
+ }
477
+ display: flex;
478
+ flex-direction: column;
479
+
480
+ .floating-model-badge {
481
+ position: sticky;
482
+ top: 0px;
483
+ float: right;
484
+ margin-top: -2px;
485
+ margin-right: 4px;
486
+ display: inline-flex;
487
+ align-items: center;
488
+ gap: 4px;
489
+ padding: 3px 9px;
490
+ background: rgba(255, 255, 255, 0.92);
491
+ backdrop-filter: blur(12px);
492
+ border: 1px solid rgba(99, 102, 241, 0.2);
493
+ border-radius: 12px;
494
+ box-shadow: 0 1px 4px rgba(99, 102, 241, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
495
+ z-index: 35;
496
+ cursor: default;
497
+ transition: all 0.2s ease;
498
+ user-select: none;
499
+
500
+ &:hover {
501
+ background: rgba(255, 255, 255, 1);
502
+ border-color: rgba(99, 102, 241, 0.4);
503
+ box-shadow: 0 2px 8px rgba(99, 102, 241, 0.15);
504
+ transform: translateY(-1px);
505
+
506
+ .model-icon {
507
+ color: #4f46e5;
508
+ transform: rotate(15deg) scale(1.05);
509
+ }
510
+ }
511
+
512
+ .model-icon {
513
+ font-size: 13px;
514
+ color: #6366f1;
515
+ transition: all 0.3s ease;
516
+ }
517
+
518
+ .model-name {
519
+ font-size: 11px;
520
+ font-weight: 600;
521
+ color: #334155;
522
+ letter-spacing: normal;
523
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
524
+ }
525
+ }
526
+
527
+ &::-webkit-scrollbar {
528
+ width: 6px;
529
+ }
530
+ &::-webkit-scrollbar-track {
531
+ background: transparent;
532
+ }
533
+ &::-webkit-scrollbar-thumb {
534
+ background: rgba(0, 0, 0, 0.15);
535
+ border-radius: 10px;
536
+ }
537
+ &::-webkit-scrollbar-thumb:hover {
538
+ background: rgba(0, 0, 0, 0.25);
539
+ }
540
+
541
+ .empty-state {
542
+ flex: 1 1 auto;
543
+ min-height: 100%;
544
+ width: 100%;
545
+ display: flex;
546
+ flex-direction: column;
547
+ align-items: center;
548
+ justify-content: center;
549
+ text-align: center;
550
+ box-sizing: border-box;
551
+ padding: 30px;
552
+ margin: auto 0;
553
+
554
+ .empty-icon {
555
+ margin-bottom: 12px;
556
+ opacity: 0.8;
557
+
558
+ .material-symbols-outlined {
559
+ font-size: 40px;
560
+ color: #94a3b8;
561
+ }
562
+ }
563
+
564
+ h3 {
565
+ margin: 0 0 6px 0;
566
+ font-size: 12px;
567
+ font-weight: 600;
568
+ color: $text-primary;
569
+ }
570
+
571
+ p {
572
+ margin: 0;
573
+ font-size: 12px;
574
+ color: $text-secondary;
575
+ max-width: 320px;
576
+ line-height: 1.5;
577
+ }
578
+ }
579
+
580
+ .logs-list-container {
581
+ display: flex;
582
+ flex-direction: column;
583
+
584
+ .planning-loader-container {
585
+ display: flex;
586
+ align-items: center;
587
+ margin-top: 10px;
588
+ margin-bottom: 10px;
589
+ padding-left: 2px;
590
+
591
+ .planning-loader {
592
+ display: inline-flex;
593
+ align-items: center;
594
+ gap: 8px;
595
+ color: #475569;
596
+ font-size: 13px;
597
+ font-weight: 500;
598
+ user-select: none;
599
+
600
+ .spin-animation {
601
+ font-size: 16px;
602
+ width: 16px;
603
+ height: 16px;
604
+ display: inline-flex;
605
+ align-items: center;
606
+ justify-content: center;
607
+ animation: spin-loader 1s linear infinite;
608
+ color: #2563eb;
609
+ flex-shrink: 0;
610
+ }
611
+
612
+ .loader-text {
613
+ color: #475569;
614
+ font-size: 13px;
615
+ font-weight: 500;
616
+ line-height: 1.4;
617
+ }
618
+ }
619
+ }
620
+ }
621
+
622
+ .phase-container {
623
+ display: flex;
624
+ flex-direction: column;
625
+ }
626
+
627
+ .phase-header {
628
+ font-size: 12px;
629
+ font-weight: normal;
630
+ line-height: 1.5;
631
+ min-height: 20px;
632
+ box-sizing: border-box;
633
+ color: #71717a;
634
+ margin-top: $uniform-gap * 2;
635
+ margin-bottom: 8px;
636
+ user-select: none;
637
+ display: flex;
638
+ align-items: center;
639
+ gap: 4px;
640
+
641
+ &.first-phase {
642
+ margin-top: 0;
643
+ }
644
+
645
+ .phase-worked-time {
646
+ color: #71717a;
647
+ font-weight: normal;
648
+ }
649
+
650
+ .phase-token-usage {
651
+ display: inline-flex;
652
+ align-items: center;
653
+ gap: 4px;
654
+ color: #8e8e93;
655
+ cursor: default;
656
+
657
+ .token-dot {
658
+ color: #a1a1aa;
659
+ font-weight: bold;
660
+ }
661
+
662
+ .token-text {
663
+ color: #71717a;
664
+ font-variant-numeric: tabular-nums;
665
+ }
666
+ }
667
+ }
668
+
669
+ .phase-body {
670
+ display: flex;
671
+ flex-direction: column;
672
+ gap: $uniform-gap;
673
+ padding-left: 12px;
674
+ border-left: 1px solid rgba(0, 0, 0, 0.04);
675
+ margin-left: 6px;
676
+ position: relative;
677
+ z-index: 1;
678
+
679
+ .block-item {
680
+ display: flex;
681
+ flex-direction: column;
682
+ gap: $uniform-gap;
683
+
684
+ .llm-stream-body,
685
+ .step-body {
686
+ .thinking-stream-details {
687
+ border-radius: 8px;
688
+ padding: 0;
689
+ overflow: visible;
690
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02);
691
+ border: 1px solid transparent;
692
+ background: transparent;
693
+ display: flex;
694
+ flex-direction: column;
695
+
696
+ .details-content-wrapper {
697
+ display: grid;
698
+ grid-template-rows: 1fr;
699
+ transition: grid-template-rows 0.3s cubic-bezier(0.4, 0, 0.2, 1);
700
+ overflow: hidden;
701
+
702
+ .details-content {
703
+ min-height: 0;
704
+ }
705
+ }
706
+
707
+
708
+ &.native-thinking-details {
709
+ border-color: transparent;
710
+ background: transparent;
711
+ box-shadow: none;
712
+
713
+ &:not(.collapsed) {
714
+ background: transparent;
715
+ }
716
+
717
+ .details-summary {
718
+ color: #71717a;
719
+
720
+ &::after {
721
+ color: #d4d4d8;
722
+ }
723
+
724
+ &:hover {
725
+ color: #1f1f1f;
726
+ }
727
+ }
728
+
729
+ &.is-running {
730
+ .details-summary {
731
+ background: linear-gradient(
732
+ 90deg,
733
+ #71717a 0%,
734
+ #2563eb 25%,
735
+ #7c3aed 50%,
736
+ #0284c7 75%,
737
+ #71717a 100%
738
+ );
739
+ background-size: 200% 100%;
740
+ -webkit-background-clip: text;
741
+ background-clip: text;
742
+ -webkit-text-fill-color: transparent;
743
+ animation: subtle-color-flow 2.8s linear infinite;
744
+ font-weight: 500;
745
+
746
+ .stream-status-dot {
747
+ background: #3b82f6;
748
+ box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.45);
749
+ animation: pulse-stream-dot 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
750
+ }
751
+ }
752
+ }
753
+
754
+ &.is-resetting {
755
+ .details-summary {
756
+ background: none !important;
757
+ -webkit-background-clip: border-box !important;
758
+ background-clip: border-box !important;
759
+ -webkit-text-fill-color: #71717a !important;
760
+ color: #71717a !important;
761
+ animation: none !important;
762
+ font-weight: normal !important;
763
+
764
+ .stream-status-dot {
765
+ background: #f59e0b;
766
+ box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.45);
767
+ animation: pulse-stream-amber 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
768
+ }
769
+ }
770
+ }
771
+
772
+ .stream-status-dot {
773
+ background: #d4d4d8;
774
+
775
+ &.streaming {
776
+ background: #3b82f6;
777
+ box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.45);
778
+ animation: pulse-stream-dot 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
779
+ }
780
+
781
+ &.resetting {
782
+ background: #f59e0b;
783
+ box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.45);
784
+ animation: pulse-stream-amber 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
785
+ }
786
+ }
787
+
788
+ .stream-text {
789
+ color: #1f1f1f;
790
+ }
791
+ }
792
+
793
+ &.raw-thinking-details {
794
+ border-color: #dbeafe;
795
+ background: #f8fafc;
796
+
797
+ &:not(.collapsed) {
798
+ background: #f8fafc;
799
+ }
800
+
801
+ .details-summary {
802
+ color: #1e40af;
803
+
804
+ &::after {
805
+ color: #93c5fd;
806
+ }
807
+
808
+ &:hover {
809
+ color: #1e3a8a;
810
+ }
811
+ }
812
+
813
+ .stream-status-dot {
814
+ background: #93c5fd;
815
+
816
+ &.streaming {
817
+ background: #2563eb;
818
+ animation: pulse-stream-blue 1.5s infinite;
819
+ }
820
+ }
821
+ }
822
+
823
+ &:not(.collapsed) {
824
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02);
825
+
826
+ .details-summary {
827
+ margin-bottom: $uniform-gap;
828
+ }
829
+
830
+ .details-summary::after {
831
+ transform: rotate(90deg);
832
+ }
833
+ }
834
+
835
+ .details-summary {
836
+ padding: 0;
837
+ margin-bottom: 0;
838
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', Arial, sans-serif;
839
+ font-weight: normal;
840
+ font-size: 12px;
841
+ line-height: 1.5;
842
+ min-height: 20px;
843
+ box-sizing: border-box;
844
+ letter-spacing: 0.5px;
845
+ cursor: pointer;
846
+ user-select: none;
847
+ display: flex;
848
+ align-items: center;
849
+ gap: 8px;
850
+ outline: none;
851
+ list-style: none;
852
+
853
+ &::-webkit-details-marker {
854
+ display: none;
855
+ }
856
+
857
+ &::after {
858
+ content: '❯';
859
+ display: inline-block;
860
+ font-size: 9px;
861
+ margin-left: 6px;
862
+ transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1), color 0.2s ease;
863
+ }
864
+
865
+ &:hover {
866
+ .stream-status-dot {
867
+ transform: scale(1.25);
868
+ background: #71717a;
869
+ }
870
+
871
+ &::after {
872
+ transform: translateX(3px);
873
+ color: #71717a;
874
+ }
875
+ }
876
+ }
877
+
878
+ .stream-status-dot {
879
+ width: 8px;
880
+ height: 8px;
881
+ border-radius: 50%;
882
+ display: inline-block;
883
+ transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.2s ease;
884
+ }
885
+
886
+ .stream-box {
887
+ max-height: 250px;
888
+ overflow-y: auto;
889
+ background: transparent;
890
+ padding: 4px 0;
891
+ box-sizing: border-box;
892
+
893
+ &::-webkit-scrollbar {
894
+ width: 6px;
895
+ }
896
+ &::-webkit-scrollbar-track {
897
+ background: transparent;
898
+ }
899
+ &::-webkit-scrollbar-thumb {
900
+ background: rgba(0, 0, 0, 0.08);
901
+ border-radius: 999px;
902
+ &:hover {
903
+ background: rgba(0, 0, 0, 0.16);
904
+ }
905
+ }
906
+ }
907
+
908
+ .stream-text {
909
+ font-family: inherit;
910
+ font-size: 12.5px;
911
+ line-height: 1.65;
912
+ color: #1f1f1f;
913
+ white-space: normal;
914
+ word-break: break-word;
915
+
916
+ strong {
917
+ font-weight: 600;
918
+ color: #111827;
919
+ }
920
+
921
+ div, p {
922
+ font-size: 12.5px;
923
+ line-height: 1.65;
924
+ color: #1f1f1f;
925
+ margin: 4px 0;
926
+ }
927
+
928
+ h1, h2, h3, h4, h5, h6 {
929
+ font-size: 12.5px;
930
+ font-weight: 600;
931
+ color: #1f1f1f;
932
+ margin-top: 8px;
933
+ margin-bottom: 4px;
934
+ }
935
+
936
+ .inline-code {
937
+ font-family: 'Fira Code', 'Roboto Mono', Consolas, monospace;
938
+ font-size: 11px;
939
+ background: #f4f4f5;
940
+ color: #b91c1c;
941
+ padding: 2px 6px;
942
+ border-radius: 4px;
943
+ }
944
+
945
+ ul, ol {
946
+ margin: 4px 0;
947
+ padding-left: 16px;
948
+ li {
949
+ font-size: 12.5px;
950
+ line-height: 1.65;
951
+ color: #1f1f1f;
952
+ margin: 4px 0;
953
+ padding-left: 2px;
954
+ }
955
+ }
956
+
957
+ .md-para-gap {
958
+ height: 6px;
959
+ }
960
+ }
961
+
962
+ &.collapsed {
963
+ .details-content-wrapper {
964
+ grid-template-rows: 0fr;
965
+ display: none;
966
+ }
967
+
968
+ .details-summary {
969
+ margin-bottom: 0;
970
+ }
971
+ }
972
+ }
973
+
974
+ .thinking-stream-flat-card {
975
+ background: transparent;
976
+ border: 1px solid transparent;
977
+ border-radius: 8px;
978
+ padding: 0;
979
+ margin-bottom: 0;
980
+ box-shadow: none;
981
+
982
+ .report-header {
983
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', Arial, sans-serif;
984
+ font-weight: normal;
985
+ font-size: 12px;
986
+ line-height: 1.5;
987
+ min-height: 20px;
988
+ box-sizing: border-box;
989
+ letter-spacing: 0.5px;
990
+ color: #71717a;
991
+ margin-bottom: $uniform-gap;
992
+ user-select: none;
993
+ display: flex;
994
+ align-items: center;
995
+ gap: 8px;
996
+
997
+ .stream-status-dot {
998
+ width: 8px;
999
+ height: 8px;
1000
+ border-radius: 50%;
1001
+ display: inline-block;
1002
+ background: #d4d4d8;
1003
+
1004
+ &.streaming {
1005
+ background: #71717a;
1006
+ animation: pulse-stream-grey 1.5s infinite;
1007
+ }
1008
+ }
1009
+ }
1010
+
1011
+ .report-content {
1012
+ font-size: 12.5px;
1013
+ line-height: 1.65;
1014
+ color: #1f1f1f;
1015
+ }
1016
+
1017
+ .stream-box {
1018
+ max-height: 250px;
1019
+ overflow-y: auto;
1020
+ background: transparent;
1021
+ padding: 4px 0;
1022
+ box-sizing: border-box;
1023
+
1024
+ &::-webkit-scrollbar {
1025
+ width: 6px;
1026
+ }
1027
+ &::-webkit-scrollbar-track {
1028
+ background: transparent;
1029
+ }
1030
+ &::-webkit-scrollbar-thumb {
1031
+ background: rgba(0, 0, 0, 0.08);
1032
+ border-radius: 999px;
1033
+ &:hover {
1034
+ background: rgba(0, 0, 0, 0.16);
1035
+ }
1036
+ }
1037
+ }
1038
+
1039
+ .stream-text {
1040
+ font-family: inherit;
1041
+ font-size: 12.5px;
1042
+ line-height: 1.65;
1043
+ color: #1f1f1f;
1044
+ white-space: normal;
1045
+ word-break: break-word;
1046
+
1047
+ strong {
1048
+ font-weight: 600;
1049
+ color: #111827;
1050
+ }
1051
+
1052
+ div, p {
1053
+ font-size: 12.5px;
1054
+ line-height: 1.65;
1055
+ color: #1f1f1f;
1056
+ margin: 4px 0;
1057
+ }
1058
+
1059
+ h1 {
1060
+ font-size: 14px;
1061
+ font-weight: 700;
1062
+ color: #0f172a;
1063
+ margin-top: 12px;
1064
+ margin-bottom: 6px;
1065
+ }
1066
+
1067
+ h2 {
1068
+ font-size: 13.5px;
1069
+ font-weight: 700;
1070
+ color: #0f172a;
1071
+ margin-top: 10px;
1072
+ margin-bottom: 5px;
1073
+ }
1074
+
1075
+ h3 {
1076
+ font-size: 13px;
1077
+ font-weight: 600;
1078
+ color: #1e293b;
1079
+ margin-top: 8px;
1080
+ margin-bottom: 4px;
1081
+ }
1082
+
1083
+ h4, h5, h6 {
1084
+ font-size: 12.5px;
1085
+ font-weight: 600;
1086
+ color: #334155;
1087
+ margin-top: 6px;
1088
+ margin-bottom: 3px;
1089
+ }
1090
+
1091
+ em {
1092
+ font-style: italic;
1093
+ color: inherit;
1094
+ }
1095
+
1096
+ blockquote {
1097
+ margin: 6px 0;
1098
+ padding: 4px 10px;
1099
+ border-left: 3px solid #cbd5e1;
1100
+ color: #475569;
1101
+ background: rgba(241, 245, 249, 0.5);
1102
+ border-radius: 0 4px 4px 0;
1103
+ }
1104
+
1105
+ .code-block {
1106
+ margin: 6px 0;
1107
+ padding: 8px 12px;
1108
+ background: #f8fafc;
1109
+ border: 1px solid #e2e8f0;
1110
+ border-radius: 6px;
1111
+ overflow-x: auto;
1112
+ font-family: 'Fira Code', 'Roboto Mono', Consolas, monospace;
1113
+ font-size: 11.5px;
1114
+ line-height: 1.5;
1115
+ color: #1e293b;
1116
+ }
1117
+
1118
+ .md-hr {
1119
+ border: none;
1120
+ border-top: 1px solid #e2e8f0;
1121
+ margin: 10px 0;
1122
+ }
1123
+
1124
+ .inline-code {
1125
+ font-family: 'Fira Code', 'Roboto Mono', Consolas, monospace;
1126
+ font-size: 11px;
1127
+ background: #f4f4f5;
1128
+ color: #b91c1c;
1129
+ padding: 2px 6px;
1130
+ border-radius: 4px;
1131
+ }
1132
+
1133
+ ul, ol {
1134
+ margin: 4px 0;
1135
+ padding-left: 16px;
1136
+ li {
1137
+ font-size: 12.5px;
1138
+ line-height: 1.65;
1139
+ color: #1f1f1f;
1140
+ margin: 4px 0;
1141
+ padding-left: 2px;
1142
+
1143
+ &.md-verify-item {
1144
+ color: #334155;
1145
+ }
1146
+
1147
+ &.md-finding-item {
1148
+ color: #92400e;
1149
+ }
1150
+ }
1151
+ }
1152
+
1153
+ .md-para-gap {
1154
+ height: 6px;
1155
+ }
1156
+ }
1157
+ }
1158
+
1159
+ .checker-stream-flat-card {
1160
+ background: #f5f3ff;
1161
+ border: 1px solid #e9d5ff;
1162
+ border-radius: 8px;
1163
+ padding: 12px 16px;
1164
+ margin-bottom: 8px;
1165
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.01);
1166
+
1167
+ .report-header {
1168
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', Arial, "Liberation Sans", sans-serif;
1169
+ font-weight: 700;
1170
+ font-size: 12px;
1171
+ line-height: 1.5;
1172
+ letter-spacing: 0.5px;
1173
+ color: #6b21a8;
1174
+ margin-bottom: 8px;
1175
+ user-select: none;
1176
+ display: flex;
1177
+ align-items: center;
1178
+ gap: 8px;
1179
+
1180
+ .stream-status-dot {
1181
+ width: 8px;
1182
+ height: 8px;
1183
+ border-radius: 50%;
1184
+ display: inline-block;
1185
+ background: #c084fc;
1186
+
1187
+ &.streaming {
1188
+ background: #a855f7;
1189
+ animation: pulse-stream-purple 1.5s infinite;
1190
+ }
1191
+ }
1192
+ }
1193
+
1194
+ .report-content {
1195
+ font-size: 12px;
1196
+ line-height: 1.6;
1197
+ color: #27272a;
1198
+
1199
+ .stream-text {
1200
+ font-family: 'Fira Code', 'Roboto Mono', Consolas, monospace;
1201
+ font-size: 11.5px;
1202
+ white-space: pre-wrap;
1203
+ word-break: break-all;
1204
+ color: #5b21b6;
1205
+ background: rgba(255, 255, 255, 0.5);
1206
+ padding: 8px;
1207
+ border-radius: 6px;
1208
+ border: 1px dashed rgba(168, 85, 247, 0.2);
1209
+ }
1210
+ }
1211
+
1212
+ .checker-result-badge {
1213
+ display: inline-flex;
1214
+ align-items: center;
1215
+ gap: 6px;
1216
+ font-weight: 700;
1217
+ font-size: 11.5px;
1218
+ padding: 4px 10px;
1219
+ border-radius: 6px;
1220
+ margin-bottom: 10px;
1221
+ border: 1px solid transparent;
1222
+
1223
+ &.success {
1224
+ background: #ecfdf5;
1225
+ color: #065f46;
1226
+ border-color: #a7f3d0;
1227
+ }
1228
+
1229
+ &.failed {
1230
+ background: #fef2f2;
1231
+ color: #991b1b;
1232
+ border-color: #fca5a5;
1233
+ }
1234
+ }
1235
+
1236
+ .checker-reason {
1237
+ font-size: 12px;
1238
+ line-height: 1.6;
1239
+ color: #3f3f46;
1240
+ font-weight: 500;
1241
+ }
1242
+ }
1243
+ }
1244
+
1245
+ .step-body {
1246
+ display: flex;
1247
+ flex-direction: column;
1248
+ gap: $uniform-gap;
1249
+
1250
+ .step-raw-thinking-message {
1251
+ background: transparent;
1252
+ border: 1px solid transparent;
1253
+ border-radius: 8px;
1254
+ padding: 0;
1255
+ margin-bottom: 0;
1256
+ box-shadow: none;
1257
+
1258
+ &.is-running {
1259
+ .report-header {
1260
+ background: linear-gradient(
1261
+ 90deg,
1262
+ #71717a 0%,
1263
+ #2563eb 25%,
1264
+ #7c3aed 50%,
1265
+ #0284c7 75%,
1266
+ #71717a 100%
1267
+ );
1268
+ background-size: 200% 100%;
1269
+ -webkit-background-clip: text;
1270
+ background-clip: text;
1271
+ -webkit-text-fill-color: transparent;
1272
+ animation: subtle-color-flow 2.8s linear infinite;
1273
+ font-weight: 500;
1274
+
1275
+ .stream-status-dot {
1276
+ background: #3b82f6;
1277
+ box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.45);
1278
+ animation: pulse-stream-dot 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
1279
+ }
1280
+ }
1281
+ }
1282
+
1283
+ &.is-resetting {
1284
+ .report-header {
1285
+ background: none !important;
1286
+ -webkit-background-clip: border-box !important;
1287
+ background-clip: border-box !important;
1288
+ -webkit-text-fill-color: #71717a !important;
1289
+ color: #71717a !important;
1290
+ animation: none !important;
1291
+ font-weight: normal !important;
1292
+ margin-bottom: 0;
1293
+
1294
+ .stream-status-dot {
1295
+ background: #f59e0b;
1296
+ box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.45);
1297
+ animation: pulse-stream-amber 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
1298
+ }
1299
+ }
1300
+ }
1301
+
1302
+ .report-header {
1303
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', Arial, sans-serif;
1304
+ font-weight: normal;
1305
+ font-size: 12px;
1306
+ line-height: 1.5;
1307
+ min-height: 20px;
1308
+ box-sizing: border-box;
1309
+ letter-spacing: 0.5px;
1310
+ color: #71717a;
1311
+ margin-bottom: $uniform-gap;
1312
+ user-select: none;
1313
+ display: flex;
1314
+ align-items: center;
1315
+ gap: 8px;
1316
+
1317
+ .header-label {
1318
+ line-height: 1.5;
1319
+ word-break: break-word;
1320
+ }
1321
+
1322
+ .stream-status-dot {
1323
+ width: 8px;
1324
+ height: 8px;
1325
+ border-radius: 50%;
1326
+ display: inline-block;
1327
+ background: #d4d4d8;
1328
+
1329
+ &.streaming {
1330
+ background: #3b82f6;
1331
+ box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.45);
1332
+ animation: pulse-stream-dot 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
1333
+ }
1334
+
1335
+ &.resetting {
1336
+ background: #f59e0b;
1337
+ box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.45);
1338
+ animation: pulse-stream-amber 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
1339
+ }
1340
+ }
1341
+ }
1342
+
1343
+ .report-content {
1344
+ font-size: 12.5px;
1345
+ line-height: 1.65;
1346
+ color: #1f1f1f;
1347
+
1348
+ strong {
1349
+ font-weight: 600;
1350
+ color: #111827;
1351
+ }
1352
+
1353
+ div, p {
1354
+ font-size: 12.5px;
1355
+ line-height: 1.65;
1356
+ color: #1f1f1f;
1357
+ margin: 4px 0;
1358
+ }
1359
+
1360
+ h1, h2, h3, h4, h5, h6 {
1361
+ font-size: 12.5px;
1362
+ font-weight: 600;
1363
+ color: #1f1f1f;
1364
+ margin-top: 8px;
1365
+ margin-bottom: 4px;
1366
+ }
1367
+
1368
+ .inline-code {
1369
+ font-family: 'Fira Code', 'Roboto Mono', Consolas, monospace;
1370
+ font-size: 11px;
1371
+ background: #f4f4f5;
1372
+ color: #b91c1c;
1373
+ padding: 2px 6px;
1374
+ border-radius: 4px;
1375
+ }
1376
+
1377
+ ul, ol {
1378
+ margin: 4px 0;
1379
+ padding-left: 16px;
1380
+ li {
1381
+ font-size: 12.5px;
1382
+ line-height: 1.65;
1383
+ color: #1f1f1f;
1384
+ margin: 4px 0;
1385
+ padding-left: 2px;
1386
+ }
1387
+ }
1388
+
1389
+ .md-para-gap {
1390
+ height: 6px;
1391
+ }
1392
+ }
1393
+ }
1394
+
1395
+ .step-action-summary-card {
1396
+ background: #f4fbf7;
1397
+ border: 1px solid #d1fae5;
1398
+ border-radius: 8px;
1399
+ padding: 12px 16px;
1400
+ margin-bottom: 8px;
1401
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.01);
1402
+
1403
+ .report-header {
1404
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', Arial, "Liberation Sans", sans-serif;
1405
+ font-weight: 700;
1406
+ font-size: 12px;
1407
+ line-height: 1.5;
1408
+ letter-spacing: 0.5px;
1409
+ color: #065f46;
1410
+ margin-bottom: 8px;
1411
+ user-select: none;
1412
+ }
1413
+
1414
+ .report-content {
1415
+ font-size: 12px;
1416
+ line-height: 1.6;
1417
+ color: #27272a;
1418
+
1419
+ strong {
1420
+ font-weight: 600;
1421
+ color: #09090b;
1422
+ }
1423
+
1424
+ .inline-code {
1425
+ font-family: 'Fira Code', 'Roboto Mono', Consolas, monospace;
1426
+ font-size: 11px;
1427
+ background: #e6f4ea;
1428
+ color: #137333;
1429
+ padding: 2px 6px;
1430
+ border-radius: 4px;
1431
+ }
1432
+
1433
+ ul, ol {
1434
+ margin: 2px 0;
1435
+ padding-left: 20px;
1436
+ li {
1437
+ margin-bottom: 2px;
1438
+ }
1439
+ }
1440
+
1441
+ .md-para-gap {
1442
+ height: 4px;
1443
+ }
1444
+ }
1445
+ }
1446
+
1447
+ .step-actions-container {
1448
+ display: flex;
1449
+ flex-direction: column;
1450
+ gap: $uniform-gap;
1451
+ margin-top: 0;
1452
+ margin-bottom: 0;
1453
+
1454
+ .llm-retry-notes {
1455
+ display: flex;
1456
+ flex-direction: column;
1457
+ gap: $uniform-gap;
1458
+ padding: 0;
1459
+
1460
+ .llm-retry-note {
1461
+ min-height: $stream-row-height;
1462
+ box-sizing: border-box;
1463
+ display: flex;
1464
+ align-items: center;
1465
+ gap: 8px;
1466
+ color: #71717a;
1467
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', Arial, sans-serif;
1468
+ font-size: 12px;
1469
+ line-height: 1.5;
1470
+ letter-spacing: 0.2px;
1471
+
1472
+ .stream-status-dot {
1473
+ width: 8px;
1474
+ height: 8px;
1475
+ border-radius: 50%;
1476
+ background: #d4d4d8;
1477
+ flex: 0 0 auto;
1478
+
1479
+ &.streaming {
1480
+ background: #3b82f6;
1481
+ box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.45);
1482
+ animation: pulse-stream-dot 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
1483
+ }
1484
+
1485
+ &.resetting {
1486
+ background: #f59e0b;
1487
+ box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.45);
1488
+ animation: pulse-stream-amber 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
1489
+ }
1490
+ }
1491
+
1492
+ .llm-retry-note-text {
1493
+ color: #71717a;
1494
+ display: flex;
1495
+ flex-direction: column;
1496
+ min-width: 0;
1497
+
1498
+ .llm-retry-status-line,
1499
+ .llm-retry-guidance {
1500
+ display: block;
1501
+ }
1502
+
1503
+ .llm-retry-guidance {
1504
+ color: #a1a1aa;
1505
+ }
1506
+ }
1507
+ }
1508
+ }
1509
+
1510
+ .step-generic-tool {
1511
+ border: 1px solid transparent;
1512
+
1513
+ &.is-video-attention:not(.is-running) {
1514
+ .tool-call-label .stream-status-dot {
1515
+ background: #f59e0b;
1516
+ box-shadow: none;
1517
+ animation: none;
1518
+ }
1519
+ }
1520
+
1521
+ &.is-llm-error {
1522
+ .tool-call-label {
1523
+ display: flex;
1524
+ align-items: flex-start;
1525
+ color: #71717a;
1526
+ line-height: 1.5;
1527
+ user-select: text;
1528
+
1529
+ .error-icon {
1530
+ font-size: 14px;
1531
+ color: #94a3b8;
1532
+ margin-top: 1px;
1533
+ margin-left: -3px;
1534
+ margin-right: -3px;
1535
+ flex-shrink: 0;
1536
+ }
1537
+
1538
+ .tool-call-text {
1539
+ display: block;
1540
+ color: inherit;
1541
+ }
1542
+
1543
+ .error-title-text {
1544
+ font-weight: 500;
1545
+ color: #71717a;
1546
+ margin-right: 4px;
1547
+ flex-shrink: 0;
1548
+ }
1549
+
1550
+ .error-message-text {
1551
+ color: #71717a;
1552
+ word-break: break-word;
1553
+ }
1554
+ }
1555
+ }
1556
+
1557
+ &.is-running {
1558
+ .tool-call-label {
1559
+ .stream-status-dot {
1560
+ background: #3b82f6;
1561
+ box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.45);
1562
+ animation: pulse-stream-dot 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
1563
+ }
1564
+
1565
+ .tool-call-text > span:first-child {
1566
+ background: linear-gradient(
1567
+ 90deg,
1568
+ #71717a 0%,
1569
+ #2563eb 25%,
1570
+ #7c3aed 50%,
1571
+ #0284c7 75%,
1572
+ #71717a 100%
1573
+ );
1574
+ background-size: 200% 100%;
1575
+ -webkit-background-clip: text;
1576
+ background-clip: text;
1577
+ -webkit-text-fill-color: transparent;
1578
+ animation: subtle-color-flow 2.8s linear infinite;
1579
+ font-weight: 500;
1580
+ }
1581
+ }
1582
+ }
1583
+
1584
+ .tool-call-label {
1585
+ font-size: 12px;
1586
+ font-weight: normal;
1587
+ color: #71717a;
1588
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', Arial, sans-serif;
1589
+ letter-spacing: 0.5px;
1590
+ line-height: 1.5;
1591
+ min-height: 22px;
1592
+ box-sizing: border-box;
1593
+ display: inline-flex;
1594
+ align-items: center;
1595
+ gap: 8px;
1596
+ user-select: none;
1597
+ padding: 0;
1598
+
1599
+ span:not(.tool-key-pill) {
1600
+ color: inherit;
1601
+ }
1602
+
1603
+ .stream-status-dot {
1604
+ width: 8px;
1605
+ height: 8px;
1606
+ border-radius: 50%;
1607
+ background: #d4d4d8;
1608
+ display: inline-block;
1609
+ flex-shrink: 0;
1610
+
1611
+ &.streaming {
1612
+ background: #3b82f6;
1613
+ box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.45);
1614
+ animation: pulse-stream-dot 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
1615
+ }
1616
+ }
1617
+
1618
+ .is-failed-dot {
1619
+ font-size: 13px;
1620
+ color: #94a3b8;
1621
+ display: inline-flex;
1622
+ align-items: center;
1623
+ justify-content: center;
1624
+ width: 8px;
1625
+ height: 8px;
1626
+ flex-shrink: 0;
1627
+ line-height: 1;
1628
+ }
1629
+
1630
+ .tool-call-text {
1631
+ display: inline-flex;
1632
+ align-items: center;
1633
+ gap: 2px;
1634
+ color: inherit;
1635
+ }
1636
+
1637
+ .tool-key-pill {
1638
+ display: inline-flex;
1639
+ align-items: center;
1640
+ gap: 4px;
1641
+ padding: 2px 6px;
1642
+ border: none;
1643
+ background: transparent;
1644
+ font-size: 12px;
1645
+ font-weight: 500;
1646
+ color: #1a73e8;
1647
+ cursor: pointer;
1648
+ border-radius: 4px;
1649
+ transition: all 0.2s ease;
1650
+ vertical-align: middle;
1651
+ text-decoration: none !important;
1652
+
1653
+ .pill-icon {
1654
+ font-size: 14px;
1655
+ color: inherit;
1656
+ }
1657
+
1658
+ &:hover {
1659
+ color: #1557b0;
1660
+ background: rgba(26, 115, 232, 0.08);
1661
+ }
1662
+ }
1663
+
1664
+ .video-status-detail {
1665
+ color: inherit;
1666
+ margin-left: 2px;
1667
+ }
1668
+ }
1669
+ }
1670
+
1671
+ .step-llm-error-card {
1672
+ background: #fef2f2;
1673
+ border: 1px solid #fecaca;
1674
+ border-radius: 10px;
1675
+ padding: 10px 12px;
1676
+ margin-top: 0;
1677
+ margin-bottom: 0;
1678
+ margin-left: -19px;
1679
+ box-shadow: 0 4px 12px rgba(239, 68, 68, 0.03);
1680
+ width: fit-content;
1681
+ min-width: 260px;
1682
+ max-width: 480px;
1683
+ display: flex;
1684
+ flex-direction: column;
1685
+ gap: 8px;
1686
+ transition: all 0.2s ease;
1687
+ position: relative;
1688
+
1689
+ &:hover {
1690
+ border-color: #fca5a5;
1691
+ box-shadow: 0 4px 16px rgba(239, 68, 68, 0.08);
1692
+ }
1693
+
1694
+ .error-card-header {
1695
+ display: flex;
1696
+ align-items: center;
1697
+ gap: 8px;
1698
+ border-bottom: 1px solid #fee2e2;
1699
+ padding-bottom: 6px;
1700
+
1701
+ .error-icon {
1702
+ font-size: 18px;
1703
+ color: #ef4444;
1704
+ }
1705
+
1706
+ .error-title {
1707
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', Arial, sans-serif;
1708
+ font-weight: 700;
1709
+ font-size: 12px;
1710
+ color: #991b1b;
1711
+ }
1712
+ }
1713
+
1714
+ .error-card-body {
1715
+ display: flex;
1716
+ flex-direction: column;
1717
+ gap: 6px;
1718
+
1719
+ .error-detail-row {
1720
+ display: flex;
1721
+ font-size: 12px;
1722
+
1723
+ .detail-value {
1724
+ color: #b91c1c;
1725
+ font-weight: 500;
1726
+ word-break: break-word;
1727
+ line-height: 1.4;
1728
+ }
1729
+ }
1730
+ }
1731
+ }
1732
+
1733
+ .llm-failure-stack {
1734
+ width: 380px;
1735
+ max-width: 100%;
1736
+ margin-left: -19px;
1737
+ display: flex;
1738
+ flex-direction: column;
1739
+ align-items: flex-start;
1740
+ gap: 10px;
1741
+
1742
+ .step-android-action-card {
1743
+ width: 100%;
1744
+ margin-left: 0;
1745
+ box-sizing: border-box;
1746
+ }
1747
+
1748
+ .llm-resume-row {
1749
+ min-height: 36px;
1750
+ display: flex;
1751
+ align-items: center;
1752
+ gap: 10px;
1753
+ }
1754
+
1755
+ .btn-continue-task {
1756
+ min-height: 36px;
1757
+ padding: 7px 12px 7px 10px;
1758
+ display: inline-flex;
1759
+ align-items: center;
1760
+ justify-content: center;
1761
+ gap: 7px;
1762
+ box-sizing: border-box;
1763
+ border: 1px solid #1d4ed8;
1764
+ border-radius: 9px;
1765
+ background: #2563eb;
1766
+ color: #ffffff;
1767
+ font-family: inherit;
1768
+ font-size: 12px;
1769
+ font-weight: 700;
1770
+ line-height: 1;
1771
+ cursor: pointer;
1772
+ box-shadow: 0 2px 7px rgba(37, 99, 235, 0.22);
1773
+ transition: background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
1774
+
1775
+ .continue-icon {
1776
+ width: 22px;
1777
+ height: 22px;
1778
+ display: inline-flex;
1779
+ align-items: center;
1780
+ justify-content: center;
1781
+ margin: -2px 0 -2px -2px;
1782
+ border-radius: 50%;
1783
+ background: rgba(255, 255, 255, 0.16);
1784
+ font-size: 16px;
1785
+ }
1786
+
1787
+ .continue-arrow {
1788
+ font-size: 15px;
1789
+ opacity: 0.72;
1790
+ transition: transform 0.18s ease, opacity 0.18s ease;
1791
+ }
1792
+
1793
+ &:hover {
1794
+ background: #1d4ed8;
1795
+ border-color: #1e40af;
1796
+ box-shadow: 0 4px 11px rgba(37, 99, 235, 0.28);
1797
+ transform: translateY(-1px);
1798
+
1799
+ .continue-arrow {
1800
+ opacity: 1;
1801
+ transform: translateX(2px);
1802
+ }
1803
+ }
1804
+
1805
+ &:active {
1806
+ box-shadow: 0 1px 4px rgba(37, 99, 235, 0.2);
1807
+ transform: translateY(0) scale(0.98);
1808
+ }
1809
+
1810
+ &:focus-visible {
1811
+ outline: 3px solid rgba(59, 130, 246, 0.25);
1812
+ outline-offset: 2px;
1813
+ }
1814
+ }
1815
+
1816
+ .llm-resume-hint {
1817
+ color: #94a3b8;
1818
+ font-size: 11px;
1819
+ line-height: 1.35;
1820
+ white-space: nowrap;
1821
+ }
1822
+
1823
+ @media (max-width: 560px) {
1824
+ .llm-resume-row {
1825
+ width: 100%;
1826
+ }
1827
+
1828
+ .btn-continue-task {
1829
+ flex: 1;
1830
+ }
1831
+
1832
+ .llm-resume-hint {
1833
+ display: none;
1834
+ }
1835
+ }
1836
+ }
1837
+
1838
+ .step-android-action-card {
1839
+ background: #f8fafc;
1840
+ border: 1px solid #e2e8f0;
1841
+ border-radius: 10px;
1842
+ padding: 10px 12px;
1843
+ margin-top: 0;
1844
+ margin-bottom: 0;
1845
+ margin-left: -19px;
1846
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.02);
1847
+ width: 380px;
1848
+ max-width: 100%;
1849
+ display: flex;
1850
+ flex-direction: column;
1851
+ gap: 8px;
1852
+ transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
1853
+ position: relative;
1854
+ cursor: pointer;
1855
+ user-select: none;
1856
+
1857
+ &.is-running {
1858
+ border-color: rgba(59, 130, 246, 0.35);
1859
+ box-shadow: 0 2px 10px rgba(59, 130, 246, 0.08);
1860
+ animation: subtle-card-glow 2.5s ease-in-out infinite alternate;
1861
+
1862
+ .action-icon {
1863
+ color: #3b82f6;
1864
+ }
1865
+
1866
+ .action-title {
1867
+ background: linear-gradient(
1868
+ 90deg,
1869
+ #0f172a 0%,
1870
+ #2563eb 30%,
1871
+ #7c3aed 50%,
1872
+ #0284c7 70%,
1873
+ #0f172a 100%
1874
+ );
1875
+ background-size: 200% 100%;
1876
+ -webkit-background-clip: text;
1877
+ background-clip: text;
1878
+ -webkit-text-fill-color: transparent;
1879
+ animation: subtle-color-flow 2.8s linear infinite;
1880
+ }
1881
+ }
1882
+
1883
+ &:hover {
1884
+ border-color: #cbd5e1;
1885
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
1886
+ transform: translateY(-1px);
1887
+
1888
+ .action-expand-icon {
1889
+ color: #1e293b;
1890
+ background: #e2e8f0;
1891
+ }
1892
+ }
1893
+
1894
+ &.is-expanded {
1895
+ border-color: #94a3b8;
1896
+ background: #ffffff;
1897
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);
1898
+
1899
+ .action-expand-icon {
1900
+ color: #0f172a;
1901
+ background: #e2e8f0;
1902
+ }
1903
+ }
1904
+
1905
+ &.is-failed {
1906
+ background: #f8fafc;
1907
+ border-color: #fca5a5;
1908
+
1909
+ &.has-details {
1910
+ cursor: pointer;
1911
+ }
1912
+
1913
+ &:hover {
1914
+ border-color: #f87171;
1915
+ }
1916
+
1917
+ &.is-expanded {
1918
+ background: #ffffff;
1919
+ border-color: #f87171;
1920
+ }
1921
+ }
1922
+
1923
+ &.task-report-card {
1924
+ background: #f0fdf4;
1925
+ border: 1px solid #bbf7d0;
1926
+
1927
+ &.is-completed {
1928
+ background: #f0fdf4;
1929
+ border-color: #86efac;
1930
+
1931
+ .report-icon {
1932
+ color: #16a34a;
1933
+ font-variation-settings: 'FILL' 1;
1934
+ }
1935
+
1936
+ .action-title {
1937
+ color: #14532d;
1938
+ font-weight: 700;
1939
+ }
1940
+
1941
+ .action-status-badge.is-completed {
1942
+ background: #dcfce7;
1943
+ color: #15803d;
1944
+ border: 1px solid #bbf7d0;
1945
+ }
1946
+ }
1947
+
1948
+ &.is-failed {
1949
+ background: #fef2f2;
1950
+ border-color: #fecaca;
1951
+
1952
+ .report-icon {
1953
+ color: #dc2626;
1954
+ font-variation-settings: 'FILL' 1;
1955
+ }
1956
+
1957
+ .action-title {
1958
+ color: #7f1d1d;
1959
+ font-weight: 700;
1960
+ }
1961
+
1962
+ .action-status-badge.is-failed {
1963
+ background: #fee2e2;
1964
+ color: #b91c1c;
1965
+ border: 1px solid #fca5a5;
1966
+ }
1967
+ }
1968
+
1969
+ .report-markdown-body {
1970
+ font-size: 12px;
1971
+ line-height: 1.5;
1972
+ color: #1f2937;
1973
+ font-weight: 400;
1974
+ user-select: text;
1975
+ word-break: break-word;
1976
+
1977
+ p {
1978
+ margin: 3px 0;
1979
+ }
1980
+
1981
+ strong {
1982
+ font-weight: 600;
1983
+ color: #0f172a;
1984
+ }
1985
+
1986
+ ul, ol {
1987
+ margin: 3px 0;
1988
+ padding-left: 18px;
1989
+ }
1990
+
1991
+ code {
1992
+ font-family: 'Fira Code', monospace;
1993
+ background: #e2e8f0;
1994
+ color: #1f2937;
1995
+ padding: 1px 4px;
1996
+ border-radius: 4px;
1997
+ font-size: 11px;
1998
+ }
1999
+ }
2000
+ }
2001
+
2002
+ &.has-no-details {
2003
+ padding: 8px 12px;
2004
+ gap: 0;
2005
+
2006
+ .action-card-header {
2007
+ border-bottom: none;
2008
+ padding-bottom: 0;
2009
+ }
2010
+ }
2011
+
2012
+ .action-card-header {
2013
+ display: flex;
2014
+ align-items: center;
2015
+ gap: 8px;
2016
+ border-bottom: 1px solid #f1f5f9;
2017
+ padding-bottom: 6px;
2018
+ width: 100%;
2019
+
2020
+ .action-icon {
2021
+ font-size: 18px;
2022
+ color: #64748b;
2023
+
2024
+ &.is-failed {
2025
+ color: #ef4444;
2026
+ }
2027
+
2028
+ }
2029
+
2030
+ .action-title {
2031
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', Arial, "Liberation Sans", sans-serif;
2032
+ font-weight: 700;
2033
+ font-size: 12px;
2034
+ color: #0f172a;
2035
+ flex-grow: 1;
2036
+ }
2037
+
2038
+ .action-agent-badge {
2039
+ display: inline-flex;
2040
+ align-items: center;
2041
+ font-size: 10px;
2042
+ font-weight: 600;
2043
+ padding: 1px 6px;
2044
+ border-radius: 4px;
2045
+ background: #f0fdf4;
2046
+ color: #166534;
2047
+ border: 1px solid #bbf7d0;
2048
+ letter-spacing: 0.2px;
2049
+ margin-right: 6px;
2050
+ white-space: nowrap;
2051
+
2052
+ &.is-outputter {
2053
+ background: linear-gradient(135deg, rgba(245, 243, 255, 0.95) 0%, rgba(238, 242, 255, 0.95) 100%);
2054
+ color: #6d28d9;
2055
+ border-color: #c4b5fd;
2056
+ }
2057
+ }
2058
+
2059
+ .action-status-badge {
2060
+ display: inline-flex;
2061
+ align-items: center;
2062
+ gap: 3px;
2063
+ font-size: 11px;
2064
+ font-weight: 600;
2065
+ padding: 1px 6px;
2066
+ border-radius: 4px;
2067
+ margin-left: auto;
2068
+ white-space: nowrap;
2069
+
2070
+ .status-icon {
2071
+ font-size: 13px;
2072
+ }
2073
+
2074
+ &.is-failed {
2075
+ background: #fef2f2;
2076
+ color: #dc2626;
2077
+ border: 1px solid #fee2e2;
2078
+
2079
+ .status-icon {
2080
+ color: #ef4444;
2081
+ }
2082
+ }
2083
+
2084
+ &.is-paused {
2085
+ background: #fff7ed;
2086
+ color: #c2410c;
2087
+ border: 1px solid #fed7aa;
2088
+
2089
+ .status-icon {
2090
+ color: #f97316;
2091
+ }
2092
+ }
2093
+
2094
+ }
2095
+
2096
+ .action-expand-icon {
2097
+ font-size: 18px;
2098
+ color: #94a3b8;
2099
+ margin-left: 4px;
2100
+ padding: 2px;
2101
+ border-radius: 50%;
2102
+ transition: all 0.2s ease;
2103
+ display: flex;
2104
+ align-items: center;
2105
+ justify-content: center;
2106
+ }
2107
+ }
2108
+
2109
+ .action-card-body {
2110
+ display: flex;
2111
+ flex-direction: column;
2112
+ gap: 6px;
2113
+
2114
+ .action-detail-row {
2115
+ display: flex;
2116
+ align-items: baseline;
2117
+ font-size: 12px;
2118
+
2119
+ .detail-label {
2120
+ color: #64748b;
2121
+ font-weight: 500;
2122
+ width: 85px;
2123
+ flex-shrink: 0;
2124
+ }
2125
+
2126
+ .detail-value {
2127
+ color: #334155;
2128
+ font-weight: 600;
2129
+ word-break: break-word;
2130
+
2131
+ &.coordinate-badge {
2132
+ background: #e2e8f0;
2133
+ color: #475569;
2134
+ padding: 2px 6px;
2135
+ border-radius: 4px;
2136
+ font-family: 'Fira Code', monospace;
2137
+ font-size: 11px;
2138
+ }
2139
+
2140
+ &.command-value {
2141
+ font-family: 'Fira Code', Consolas, Monaco, monospace;
2142
+ background: #f1f5f9;
2143
+ border: 1px solid #e2e8f0;
2144
+ padding: 2px 6px;
2145
+ border-radius: 4px;
2146
+ font-size: 11px;
2147
+ font-weight: 500;
2148
+ color: #0f172a;
2149
+ white-space: pre-wrap;
2150
+ word-break: break-all;
2151
+
2152
+ code {
2153
+ font-family: inherit;
2154
+ font-size: inherit;
2155
+ color: inherit;
2156
+ background: none;
2157
+ padding: 0;
2158
+ border: none;
2159
+ }
2160
+ }
2161
+ }
2162
+ }
2163
+
2164
+ .failure-retry-details {
2165
+ margin-top: 4px;
2166
+ padding-top: 9px;
2167
+ border-top: 1px solid #fecaca;
2168
+ display: flex;
2169
+ flex-direction: column;
2170
+ gap: 7px;
2171
+ animation: fadeInDetails 0.2s ease-out;
2172
+
2173
+ .failure-retry-title {
2174
+ color: #991b1b;
2175
+ font-size: 10px;
2176
+ font-weight: 700;
2177
+ text-transform: uppercase;
2178
+ letter-spacing: 0.03em;
2179
+ }
2180
+
2181
+ .failure-retry-row {
2182
+ display: flex;
2183
+ justify-content: space-between;
2184
+ gap: 12px;
2185
+ color: #7f1d1d;
2186
+ font-size: 10.5px;
2187
+ line-height: 1.4;
2188
+
2189
+ span:last-child {
2190
+ color: #64748b;
2191
+ text-align: right;
2192
+ }
2193
+ }
2194
+ }
2195
+ }
2196
+
2197
+ .action-card-expanded-details {
2198
+ display: flex;
2199
+ flex-direction: column;
2200
+ gap: 10px;
2201
+ padding-top: 4px;
2202
+ animation: fadeInDetails 0.2s ease-out;
2203
+
2204
+ .expanded-grid {
2205
+ display: grid;
2206
+ grid-template-columns: repeat(2, 1fr);
2207
+ gap: 8px;
2208
+ background: #f8fafc;
2209
+ padding: 10px;
2210
+ border-radius: 8px;
2211
+ border: 1px solid #f1f5f9;
2212
+
2213
+ .grid-item {
2214
+ display: flex;
2215
+ flex-direction: column;
2216
+ gap: 2px;
2217
+
2218
+ &.full-width {
2219
+ grid-column: 1 / -1;
2220
+ }
2221
+
2222
+ .grid-label {
2223
+ font-size: 10px;
2224
+ font-weight: 700;
2225
+ text-transform: uppercase;
2226
+ letter-spacing: 0.5px;
2227
+ color: #64748b;
2228
+ }
2229
+
2230
+ .grid-value {
2231
+ font-size: 12px;
2232
+ font-weight: 600;
2233
+ color: #1e293b;
2234
+ word-break: break-all;
2235
+
2236
+ &.code-pill {
2237
+ font-family: 'Roboto Mono', 'Fira Code', Consolas, monospace;
2238
+ font-size: 11px;
2239
+ background: #e2e8f0;
2240
+ color: #334155;
2241
+ padding: 2px 6px;
2242
+ border-radius: 4px;
2243
+ display: inline-block;
2244
+ width: fit-content;
2245
+ }
2246
+
2247
+ &.command-value {
2248
+ code {
2249
+ font-family: 'Roboto Mono', 'Fira Code', Consolas, monospace;
2250
+ font-size: 11px;
2251
+ background: #0f172a;
2252
+ color: #38bdf8;
2253
+ padding: 4px 8px;
2254
+ border-radius: 4px;
2255
+ display: block;
2256
+ word-break: break-all;
2257
+ white-space: pre-wrap;
2258
+ }
2259
+ }
2260
+ }
2261
+ }
2262
+ }
2263
+
2264
+ .expanded-screenshots-container {
2265
+ display: flex;
2266
+ flex-direction: row;
2267
+ flex-wrap: nowrap;
2268
+ gap: 12px;
2269
+ margin-top: 4px;
2270
+ justify-content: flex-start;
2271
+ width: 100%;
2272
+
2273
+ .screenshot-column {
2274
+ flex: 1 1 0;
2275
+ min-width: 0;
2276
+ max-width: 320px;
2277
+ display: flex;
2278
+ flex-direction: column;
2279
+ gap: 6px;
2280
+ align-items: center;
2281
+
2282
+ .screenshot-label {
2283
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', Arial, "Liberation Sans", sans-serif;
2284
+ font-size: 11.5px;
2285
+ font-weight: 500;
2286
+ color: #64748b;
2287
+ letter-spacing: normal;
2288
+ text-transform: none;
2289
+
2290
+ }
2291
+
2292
+ .image-wrapper {
2293
+ display: inline-flex;
2294
+ justify-content: center;
2295
+ align-items: center;
2296
+ max-width: 100%;
2297
+ border: 1px solid #e2e8f0;
2298
+ border-radius: 8px;
2299
+ background-color: #f8fafc;
2300
+ cursor: zoom-in;
2301
+ overflow: hidden;
2302
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
2303
+ transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
2304
+
2305
+ &:hover {
2306
+ transform: translateY(-1px);
2307
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
2308
+ border-color: #cbd5e1;
2309
+ }
2310
+
2311
+ .img-relative-box {
2312
+ position: relative;
2313
+ display: inline-block;
2314
+ max-width: 100%;
2315
+
2316
+ img {
2317
+ display: block;
2318
+ max-width: 100%;
2319
+ max-height: 280px;
2320
+ width: auto;
2321
+ height: auto;
2322
+ margin: 0 auto;
2323
+ border-radius: 6px;
2324
+ }
2325
+
2326
+ .overlay-layer {
2327
+ position: absolute;
2328
+ top: 0;
2329
+ left: 0;
2330
+ right: 0;
2331
+ bottom: 0;
2332
+ pointer-events: none;
2333
+ overflow: visible;
2334
+ }
2335
+ }
2336
+ }
2337
+ }
2338
+ }
2339
+
2340
+ .expanded-error-banner {
2341
+ display: flex;
2342
+ align-items: center;
2343
+ gap: 8px;
2344
+ background: #fff1f2;
2345
+ border: 1px solid #fecdd3;
2346
+ color: #be123c;
2347
+ padding: 8px 12px;
2348
+ border-radius: 6px;
2349
+ font-size: 12px;
2350
+ font-weight: 500;
2351
+
2352
+ .icon {
2353
+ font-size: 16px;
2354
+ color: #e11d48;
2355
+ }
2356
+ }
2357
+ }
2358
+ }
2359
+
2360
+ .final-summary-card {
2361
+ padding: 20px 24px;
2362
+ display: flex;
2363
+ flex-direction: column;
2364
+ gap: 12px;
2365
+ background: #ffffff;
2366
+ border: 1px solid rgba(0, 0, 0, 0.06);
2367
+ border-radius: 12px;
2368
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.01), 0 2px 4px -1px rgba(0, 0, 0, 0.006);
2369
+
2370
+ .final-summary-header {
2371
+ font-weight: 500;
2372
+ font-size: 12px;
2373
+ color: #71717a;
2374
+ display: flex;
2375
+ align-items: center;
2376
+ gap: 6px;
2377
+ user-select: none;
2378
+ }
2379
+
2380
+ .final-summary-body {
2381
+ font-size: 12px;
2382
+ line-height: 1.6;
2383
+ color: #27272a;
2384
+
2385
+ strong {
2386
+ font-weight: 600;
2387
+ color: #09090b;
2388
+ }
2389
+
2390
+ ul, ol {
2391
+ margin: 6px 0;
2392
+ padding-left: 20px;
2393
+ li {
2394
+ margin-bottom: 6px;
2395
+ }
2396
+ }
2397
+
2398
+ div {
2399
+ margin-bottom: 4px;
2400
+ }
2401
+
2402
+ .md-para-gap {
2403
+ height: 8px;
2404
+ }
2405
+ }
2406
+ }
2407
+ }
2408
+ }
2409
+ }
2410
+ }
2411
+ }
2412
+ }
2413
+
2414
+ @keyframes spin-loader {
2415
+ from {
2416
+ transform: rotate(0deg);
2417
+ }
2418
+ to {
2419
+ transform: rotate(360deg);
2420
+ }
2421
+ }
2422
+
2423
+ @keyframes pulse-green {
2424
+ 0% {
2425
+ box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4);
2426
+ }
2427
+ 70% {
2428
+ box-shadow: 0 0 0 6px rgba(16, 185, 129, 0);
2429
+ }
2430
+ 100% {
2431
+ box-shadow: 0 0 0 0 rgba(16, 185, 129, 0);
2432
+ }
2433
+ }
2434
+
2435
+ @keyframes pulse-stream-blue {
2436
+ 0% {
2437
+ box-shadow: 0 0 0 0 rgba(14, 165, 233, 0.4);
2438
+ }
2439
+ 70% {
2440
+ box-shadow: 0 0 0 6px rgba(14, 165, 233, 0);
2441
+ }
2442
+ 100% {
2443
+ box-shadow: 0 0 0 0 rgba(14, 165, 233, 0);
2444
+ }
2445
+ }
2446
+
2447
+ @keyframes pulse-stream-green {
2448
+ 0% {
2449
+ box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.4);
2450
+ }
2451
+ 70% {
2452
+ box-shadow: 0 0 0 6px rgba(34, 197, 94, 0);
2453
+ }
2454
+ 100% {
2455
+ box-shadow: 0 0 0 0 rgba(34, 197, 94, 0);
2456
+ }
2457
+ }
2458
+
2459
+ @keyframes pulse-stream-purple {
2460
+ 0% {
2461
+ box-shadow: 0 0 0 0 rgba(168, 85, 247, 0.4);
2462
+ }
2463
+ 70% {
2464
+ box-shadow: 0 0 0 6px rgba(168, 85, 247, 0);
2465
+ }
2466
+ 100% {
2467
+ box-shadow: 0 0 0 0 rgba(168, 85, 247, 0);
2468
+ }
2469
+ }
2470
+
2471
+ @keyframes pulse-stream-grey {
2472
+ 0% {
2473
+ box-shadow: 0 0 0 0 rgba(113, 113, 122, 0.4);
2474
+ }
2475
+ 70% {
2476
+ box-shadow: 0 0 0 6px rgba(113, 113, 122, 0);
2477
+ }
2478
+ 100% {
2479
+ box-shadow: 0 0 0 0 rgba(113, 113, 122, 0);
2480
+ }
2481
+ }
2482
+
2483
+ @keyframes pulse-black-dot {
2484
+ 0% {
2485
+ box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.4);
2486
+ }
2487
+ 70% {
2488
+ box-shadow: 0 0 0 5px rgba(0, 0, 0, 0);
2489
+ }
2490
+ 100% {
2491
+ box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
2492
+ }
2493
+ }
2494
+
2495
+ @keyframes pulse-black-dot-small {
2496
+ 0% {
2497
+ opacity: 1;
2498
+ transform: scale(1);
2499
+ }
2500
+ 50% {
2501
+ opacity: 0.4;
2502
+ transform: scale(0.8);
2503
+ }
2504
+ 100% {
2505
+ opacity: 1;
2506
+ transform: scale(1);
2507
+ }
2508
+ }
2509
+
2510
+ @keyframes fadeInDetails {
2511
+ from {
2512
+ opacity: 0;
2513
+ transform: translateY(-4px);
2514
+ }
2515
+ to {
2516
+ opacity: 1;
2517
+ transform: translateY(0);
2518
+ }
2519
+ }
2520
+
2521
+ @keyframes dropdownFadeIn {
2522
+ from {
2523
+ opacity: 0;
2524
+ transform: translateY(-4px);
2525
+ }
2526
+ to {
2527
+ opacity: 1;
2528
+ transform: translateY(0);
2529
+ }
2530
+ }
2531
+
2532
+ @keyframes spin {
2533
+ 0% { transform: rotate(0deg); }
2534
+ 100% { transform: rotate(360deg); }
2535
+ }
2536
+
2537
+ .image-modal-backdrop {
2538
+ position: absolute;
2539
+ top: 0;
2540
+ left: 0;
2541
+ right: 0;
2542
+ bottom: 0;
2543
+ width: 100%;
2544
+ height: 100%;
2545
+ background-color: rgba(15, 23, 42, 0.75);
2546
+ backdrop-filter: blur(4px);
2547
+ z-index: 1000;
2548
+ display: flex;
2549
+ align-items: center;
2550
+ justify-content: center;
2551
+ padding: 24px;
2552
+ box-sizing: border-box;
2553
+ animation: fadeInModal 0.2s ease-out;
2554
+
2555
+ .image-modal-content {
2556
+ position: relative;
2557
+ max-width: calc(100% - 48px);
2558
+ max-height: calc(100% - 48px);
2559
+ background: #0f172a;
2560
+ border-radius: 12px;
2561
+ padding: 12px;
2562
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 8px 10px -6px rgba(0, 0, 0, 0.5);
2563
+ display: flex;
2564
+ align-items: center;
2565
+ justify-content: center;
2566
+ box-sizing: border-box;
2567
+
2568
+ .image-modal-close {
2569
+ position: absolute;
2570
+ top: -12px;
2571
+ right: -12px;
2572
+ width: 32px;
2573
+ height: 32px;
2574
+ border-radius: 50%;
2575
+ background: #ef4444;
2576
+ color: white;
2577
+ border: 2px solid white;
2578
+ display: flex;
2579
+ align-items: center;
2580
+ justify-content: center;
2581
+ cursor: pointer;
2582
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3);
2583
+ transition: transform 0.15s ease, background-color 0.15s ease;
2584
+ z-index: 20;
2585
+
2586
+ &:hover {
2587
+ transform: scale(1.1);
2588
+ background: #dc2626;
2589
+ }
2590
+
2591
+ .material-symbols-outlined {
2592
+ font-size: 18px;
2593
+ }
2594
+ }
2595
+
2596
+ .img-relative-box {
2597
+ position: relative;
2598
+ display: inline-flex;
2599
+ align-items: center;
2600
+ justify-content: center;
2601
+ max-width: 100%;
2602
+ max-height: 100%;
2603
+
2604
+ img {
2605
+ display: block;
2606
+ max-width: 100%;
2607
+ max-height: calc(100vh - 140px);
2608
+ width: auto;
2609
+ height: auto;
2610
+ object-fit: contain;
2611
+ border-radius: 6px;
2612
+ }
2613
+
2614
+ .overlay-layer {
2615
+ position: absolute;
2616
+ top: 0;
2617
+ left: 0;
2618
+ right: 0;
2619
+ bottom: 0;
2620
+ pointer-events: none;
2621
+ overflow: visible;
2622
+ border-radius: 6px;
2623
+ }
2624
+ }
2625
+ }
2626
+ }
2627
+
2628
+ @keyframes pulse-animation {
2629
+ 0% {
2630
+ transform: scale(0.5);
2631
+ opacity: 1;
2632
+ }
2633
+ 100% {
2634
+ transform: scale(1.8);
2635
+ opacity: 0;
2636
+ }
2637
+ }
2638
+
2639
+ @keyframes fadeInModal {
2640
+ from {
2641
+ opacity: 0;
2642
+ }
2643
+ to {
2644
+ opacity: 1;
2645
+ }
2646
+ }
2647
+
2648
+ @keyframes subtle-color-flow {
2649
+ 0% {
2650
+ background-position: 0% 50%;
2651
+ }
2652
+ 100% {
2653
+ background-position: 200% 50%;
2654
+ }
2655
+ }
2656
+
2657
+ @keyframes pulse-stream-dot {
2658
+ 0%, 100% {
2659
+ transform: scale(1);
2660
+ box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.45);
2661
+ }
2662
+ 50% {
2663
+ transform: scale(1.15);
2664
+ box-shadow: 0 0 0 4px rgba(59, 130, 246, 0);
2665
+ }
2666
+ }
2667
+
2668
+ @keyframes pulse-stream-amber {
2669
+ 0%, 100% {
2670
+ transform: scale(1);
2671
+ box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.45);
2672
+ }
2673
+ 50% {
2674
+ transform: scale(1.15);
2675
+ box-shadow: 0 0 0 4px rgba(245, 158, 11, 0);
2676
+ }
2677
+ }
2678
+
2679
+ .spinning {
2680
+ animation: spin 1.2s linear infinite;
2681
+ }
2682
+
2683
+
2684
+ @keyframes subtle-card-glow {
2685
+ 0% {
2686
+ border-color: rgba(59, 130, 246, 0.25);
2687
+ box-shadow: 0 2px 8px rgba(59, 130, 246, 0.05);
2688
+ }
2689
+ 100% {
2690
+ border-color: rgba(99, 102, 241, 0.45);
2691
+ box-shadow: 0 4px 14px rgba(99, 102, 241, 0.12);
2692
+ }
2693
+ }
2694
+
2695
+ /* Outputter Post-Execution Synthesis Card */
2696
+ .outputter-synthesis-stream-card {
2697
+ margin: 16px 0 12px 0;
2698
+ border-radius: 12px;
2699
+ border: 1px solid rgba(196, 181, 253, 0.85);
2700
+ background: linear-gradient(135deg, rgba(245, 243, 255, 0.95) 0%, rgba(250, 245, 255, 0.98) 100%);
2701
+ box-shadow: 0 4px 16px rgba(124, 58, 237, 0.08), 0 1px 3px rgba(0, 0, 0, 0.03);
2702
+ overflow: hidden;
2703
+ animation: fadeInModal 0.25s ease-out;
2704
+
2705
+ .synthesis-card-header {
2706
+ display: flex;
2707
+ align-items: center;
2708
+ justify-content: space-between;
2709
+ padding: 12px 16px;
2710
+ background: rgba(237, 233, 254, 0.6);
2711
+ border-bottom: 1px solid rgba(196, 181, 253, 0.7);
2712
+ gap: 12px;
2713
+ flex-wrap: wrap;
2714
+
2715
+ .header-left {
2716
+ display: flex;
2717
+ align-items: center;
2718
+ gap: 10px;
2719
+
2720
+ .icon-sparkle {
2721
+ font-size: 22px;
2722
+ color: #7c3aed;
2723
+ }
2724
+
2725
+ .main-title {
2726
+ font-size: 14px;
2727
+ font-weight: 700;
2728
+ color: #4338ca;
2729
+ }
2730
+ }
2731
+
2732
+ .header-right {
2733
+ .btn-open-note {
2734
+ display: inline-flex;
2735
+ align-items: center;
2736
+ gap: 5px;
2737
+ padding: 5px 12px;
2738
+ background: linear-gradient(135deg, #6366f1 0%, #7c3aed 100%);
2739
+ color: #ffffff;
2740
+ border: none;
2741
+ border-radius: 8px;
2742
+ font-size: 12px;
2743
+ font-weight: 600;
2744
+ cursor: pointer;
2745
+ transition: all 0.15s ease;
2746
+ box-shadow: 0 2px 6px rgba(99, 102, 241, 0.25);
2747
+
2748
+ .material-symbols-outlined {
2749
+ font-size: 15px;
2750
+ }
2751
+
2752
+ &:hover {
2753
+ background: linear-gradient(135deg, #4f46e5 0%, #6d28d9 100%);
2754
+ box-shadow: 0 4px 10px rgba(99, 102, 241, 0.35);
2755
+ transform: translateY(-1px);
2756
+ }
2757
+ }
2758
+ }
2759
+ }
2760
+
2761
+ .synthesis-card-preview {
2762
+ padding: 14px 16px;
2763
+
2764
+ .parsed-note-container {
2765
+ display: flex;
2766
+ flex-direction: column;
2767
+ gap: 10px;
2768
+
2769
+ .parsed-note-title {
2770
+ font-size: 14px;
2771
+ font-weight: 700;
2772
+ color: #1e1b4b;
2773
+ margin: 0;
2774
+ }
2775
+
2776
+ .parsed-milestones {
2777
+ display: flex;
2778
+ flex-direction: column;
2779
+ gap: 6px;
2780
+
2781
+ .milestone-item {
2782
+ display: flex;
2783
+ align-items: flex-start;
2784
+ gap: 8px;
2785
+ font-size: 12.5px;
2786
+ line-height: 1.45;
2787
+ color: #374151;
2788
+
2789
+ .status-icon {
2790
+ font-size: 16px;
2791
+ color: #7c3aed;
2792
+ margin-top: 1px;
2793
+ flex-shrink: 0;
2794
+ }
2795
+
2796
+ &.status-checked .status-icon {
2797
+ color: #10b981;
2798
+ }
2799
+
2800
+ &.status-progress .status-icon {
2801
+ color: #f59e0b;
2802
+ }
2803
+ }
2804
+ }
2805
+
2806
+ .parsed-other-lines {
2807
+ display: flex;
2808
+ flex-direction: column;
2809
+ gap: 4px;
2810
+
2811
+ .other-line {
2812
+ margin: 0;
2813
+ font-size: 12.5px;
2814
+ line-height: 1.5;
2815
+ color: #4b5563;
2816
+
2817
+ strong {
2818
+ color: #1e1b4b;
2819
+ }
2820
+
2821
+ code {
2822
+ font-family: 'JetBrains Mono', monospace;
2823
+ background: rgba(255, 255, 255, 0.9);
2824
+ border: 1px solid #e5e7eb;
2825
+ padding: 1px 4px;
2826
+ border-radius: 4px;
2827
+ color: #6d28d9;
2828
+ font-size: 11.5px;
2829
+ }
2830
+ }
2831
+ }
2832
+ }
2833
+ }
2834
+ }
2835
+
2836
+ /* Checker blocks share the step timeline, marked by a violet left border. */
2837
+ .agent-stream-container .stream-logs-content .phase-body .block-item.type-checker {
2838
+ border-left: 2px solid #ddd6fe;
2839
+ padding-left: 12px;
2840
+ margin-left: -14px;
2841
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', Arial, sans-serif;
2842
+
2843
+ .check-index {
2844
+ flex: 0 0 14px;
2845
+ text-align: right;
2846
+ color: #a1a1aa;
2847
+ font-variant-numeric: tabular-nums;
2848
+ user-select: none;
2849
+ }
2850
+
2851
+ .check-lane {
2852
+ display: flex;
2853
+ flex-direction: column;
2854
+ gap: $uniform-gap;
2855
+ margin-bottom: $uniform-gap;
2856
+
2857
+ .check-header {
2858
+ display: flex;
2859
+ align-items: center;
2860
+ gap: 8px;
2861
+ min-height: 20px;
2862
+ font-size: 12px;
2863
+ line-height: 1.5;
2864
+ letter-spacing: 0.2px;
2865
+ color: #71717a;
2866
+ user-select: none;
2867
+
2868
+ .stream-status-dot {
2869
+ flex: 0 0 auto;
2870
+ width: 8px;
2871
+ height: 8px;
2872
+ border-radius: 50%;
2873
+ display: inline-block;
2874
+ background: #d4d4d8;
2875
+
2876
+ &.streaming {
2877
+ background: #7c3aed;
2878
+ box-shadow: 0 0 0 0 rgba(124, 58, 237, 0.45);
2879
+ animation: pulse-stream-dot 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite;
2880
+ }
2881
+ }
2882
+
2883
+ .check-title {
2884
+ flex: 0 0 auto;
2885
+ font-weight: 500;
2886
+ color: #52525b;
2887
+ }
2888
+
2889
+ .check-subject {
2890
+ flex: 1 1 auto;
2891
+ min-width: 0;
2892
+ white-space: nowrap;
2893
+ overflow: hidden;
2894
+ text-overflow: ellipsis;
2895
+ }
2896
+
2897
+ .check-status {
2898
+ flex: 0 0 auto;
2899
+ margin-left: auto;
2900
+ font-weight: 500;
2901
+ color: #52525b;
2902
+ white-space: nowrap;
2903
+ }
2904
+ }
2905
+
2906
+ &.tone-passed .check-status { color: #15803d; }
2907
+ &.tone-failed .check-status { color: #b91c1c; }
2908
+ &.tone-inconclusive .check-status { color: #b45309; }
2909
+ &.tone-running .check-status { color: #6d28d9; }
2910
+ &.tone-muted { opacity: 0.6; }
2911
+
2912
+ .check-items {
2913
+ list-style: none;
2914
+ margin: 0;
2915
+ padding: 0 0 0 16px;
2916
+ display: flex;
2917
+ flex-direction: column;
2918
+ gap: 2px;
2919
+
2920
+ .check-item {
2921
+ display: flex;
2922
+ align-items: baseline;
2923
+ gap: 8px;
2924
+ font-size: 12px;
2925
+ line-height: 1.5;
2926
+ color: #3f3f46;
2927
+
2928
+ .check-text {
2929
+ flex: 1 1 auto;
2930
+ min-width: 0;
2931
+ word-break: break-word;
2932
+ }
2933
+
2934
+ .check-method {
2935
+ flex: 0 0 auto;
2936
+ color: #a1a1aa;
2937
+ white-space: nowrap;
2938
+ }
2939
+ }
2940
+ }
2941
+ }
2942
+
2943
+ .check-result {
2944
+ display: flex;
2945
+ flex-direction: column;
2946
+ gap: 4px;
2947
+ margin-top: $uniform-gap;
2948
+ padding-left: 16px;
2949
+
2950
+ .check-verdict {
2951
+ display: flex;
2952
+ align-items: flex-start;
2953
+ gap: 8px;
2954
+ font-size: 12px;
2955
+ line-height: 1.5;
2956
+ color: #52525b;
2957
+
2958
+ .check-index {
2959
+ line-height: 18px;
2960
+ }
2961
+
2962
+ .verdict-icon {
2963
+ flex: 0 0 auto;
2964
+ font-size: 15px;
2965
+ line-height: 18px;
2966
+ color: #a1a1aa;
2967
+ }
2968
+
2969
+ &.passed .verdict-icon { color: #16a34a; }
2970
+ &.failed .verdict-icon { color: #dc2626; }
2971
+ &.inconclusive .verdict-icon { color: #d97706; }
2972
+ &.superseded, &.unchecked { color: #a1a1aa; }
2973
+
2974
+ .verdict-body {
2975
+ flex: 1 1 auto;
2976
+ min-width: 0;
2977
+ word-break: break-word;
2978
+ }
2979
+
2980
+ .verdict-suggestion {
2981
+ display: block;
2982
+ color: #1d4ed8;
2983
+ }
2984
+ }
2985
+
2986
+ .check-note {
2987
+ font-size: 12px;
2988
+ line-height: 1.5;
2989
+ color: #71717a;
2990
+ padding-left: 22px;
2991
+ word-break: break-word;
2992
+ }
2993
+ }
2994
+ }
2995
+
2996
+ @media (min-width: 1151px) {
2997
+ @container stream-panel (max-width: 660px) {
2998
+ .agent-stream-container .stream-floating-toolbar {
2999
+ .model-info-chip {
3000
+ padding: 0 9px;
3001
+
3002
+ .model-label {
3003
+ display: none;
3004
+ }
3005
+ }
3006
+
3007
+ .btn-screen-recording {
3008
+ padding: 0 9px;
3009
+ gap: 0;
3010
+
3011
+ .btn-text {
3012
+ display: none;
3013
+ }
3014
+ }
3015
+ }
3016
+ }
3017
+ }
3018
+
3019
+ @media (max-width: 1150px) {
3020
+ @container stream-panel (max-width: 900px) {
3021
+ .agent-stream-container .vscode-nav-header .vscode-tab-btn {
3022
+ padding: 0 9px;
3023
+ gap: 0;
3024
+
3025
+ .tab-label {
3026
+ display: none;
3027
+ }
3028
+ }
3029
+ }
3030
+ }
3031
+
3032
+ /* ========================================================================= */
3033
+ /* Floating Dropdown Popover Menu (Angular CDK Connected Overlay Top Layer) */
3034
+ /* ========================================================================= */
3035
+ /* Floating Dropdown Popover Menu */
3036
+ .vscode-dropdown-menu {
3037
+ position: relative;
3038
+ width: 360px;
3039
+ box-sizing: border-box;
3040
+ max-width: calc(100vw - 24px);
3041
+ max-height: 480px;
3042
+ background: #ffffff;
3043
+ border: 1px solid #cbd5e1;
3044
+ border-radius: 12px;
3045
+ box-shadow: 0 16px 40px -4px rgba(15, 23, 42, 0.16), 0 4px 12px rgba(0, 0, 0, 0.06);
3046
+ z-index: 100;
3047
+ overflow-y: auto;
3048
+ padding: 14px;
3049
+ display: flex;
3050
+ flex-direction: column;
3051
+ gap: 10px;
3052
+ animation: dropdownFadeIn 0.15s cubic-bezier(0.16, 1, 0.3, 1);
3053
+
3054
+ .popover-title-header {
3055
+ display: flex;
3056
+ align-items: center;
3057
+ gap: 8px;
3058
+ padding-bottom: 8px;
3059
+ border-bottom: 1px solid #e2e8f0;
3060
+ font-size: 14px;
3061
+ font-weight: 700;
3062
+ color: #0f172a;
3063
+
3064
+ .material-symbols-outlined {
3065
+ font-size: 18px;
3066
+ color: #2563eb;
3067
+ }
3068
+ }
3069
+
3070
+ /* Run info popover: elapsed, tokens, context share, Pro tuning */
3071
+ &.run-info-dropdown {
3072
+ width: 288px;
3073
+ gap: 0;
3074
+ padding: 12px 14px 10px;
3075
+
3076
+ .run-info-header {
3077
+ display: flex;
3078
+ align-items: center;
3079
+ gap: 7px;
3080
+ padding-bottom: 9px;
3081
+ border-bottom: 1px solid #e2e8f0;
3082
+
3083
+ .material-symbols-outlined {
3084
+ font-size: 18px;
3085
+ color: #64748b;
3086
+
3087
+ &.is-pro {
3088
+ color: #2563eb;
3089
+ }
3090
+ }
3091
+
3092
+ .run-info-title {
3093
+ font-size: 13px;
3094
+ font-weight: 700;
3095
+ color: #0f172a;
3096
+ }
3097
+
3098
+ .run-info-model {
3099
+ margin-left: auto;
3100
+ max-width: 150px;
3101
+ overflow: hidden;
3102
+ text-overflow: ellipsis;
3103
+ white-space: nowrap;
3104
+ font-family: 'Fira Code', 'Roboto Mono', Consolas, monospace;
3105
+ font-size: 10.5px;
3106
+ color: #94a3b8;
3107
+ }
3108
+ }
3109
+
3110
+ .run-info-row {
3111
+ display: flex;
3112
+ align-items: baseline;
3113
+ justify-content: space-between;
3114
+ gap: 12px;
3115
+ padding: 9px 0;
3116
+ border-bottom: 1px solid #f1f5f9;
3117
+
3118
+ &:last-child {
3119
+ border-bottom: none;
3120
+ }
3121
+
3122
+ &.is-stacked {
3123
+ flex-direction: column;
3124
+ align-items: stretch;
3125
+ gap: 0;
3126
+ }
3127
+ }
3128
+
3129
+ .run-info-line {
3130
+ display: flex;
3131
+ align-items: baseline;
3132
+ justify-content: space-between;
3133
+ gap: 12px;
3134
+ }
3135
+
3136
+ .run-info-label {
3137
+ font-size: 12px;
3138
+ font-weight: 500;
3139
+ color: #64748b;
3140
+ white-space: nowrap;
3141
+ }
3142
+
3143
+ .run-info-value {
3144
+ font-size: 12.5px;
3145
+ font-weight: 600;
3146
+ color: #0f172a;
3147
+ text-align: right;
3148
+ font-variant-numeric: tabular-nums;
3149
+
3150
+ &.is-muted {
3151
+ color: #cbd5e1;
3152
+ font-weight: 500;
3153
+ }
3154
+ }
3155
+
3156
+ .run-info-sub {
3157
+ display: block;
3158
+ margin-top: 2px;
3159
+ font-size: 11px;
3160
+ font-weight: 400;
3161
+ color: #94a3b8;
3162
+ }
3163
+
3164
+ .run-info-sub-inline {
3165
+ margin-left: 3px;
3166
+ font-size: 11px;
3167
+ font-weight: 400;
3168
+ color: #94a3b8;
3169
+ }
3170
+
3171
+ .run-info-meter {
3172
+ height: 4px;
3173
+ margin-top: 7px;
3174
+ border-radius: 2px;
3175
+ background: #e2e8f0;
3176
+ overflow: hidden;
3177
+
3178
+ .run-info-meter-fill {
3179
+ height: 100%;
3180
+ border-radius: 2px;
3181
+ background: #2563eb;
3182
+ transition: width 0.3s ease;
3183
+ }
3184
+
3185
+ &.is-high .run-info-meter-fill {
3186
+ background: #f59e0b;
3187
+ }
3188
+
3189
+ &.is-critical .run-info-meter-fill {
3190
+ background: #ef4444;
3191
+ }
3192
+ }
3193
+
3194
+ .run-info-note {
3195
+ padding-top: 9px;
3196
+ font-size: 11.5px;
3197
+ color: #94a3b8;
3198
+ }
3199
+ }
3200
+
3201
+ &.notes-dropdown {
3202
+ width: 380px;
3203
+ max-height: 520px;
3204
+
3205
+ .notes-selector-container {
3206
+ display: flex;
3207
+ flex-direction: column;
3208
+ gap: 6px;
3209
+ margin-bottom: 4px;
3210
+
3211
+ .notes-selector-list {
3212
+ display: flex;
3213
+ flex-wrap: wrap;
3214
+ gap: 6px;
3215
+
3216
+ .note-selector-pill {
3217
+ display: inline-flex;
3218
+ align-items: center;
3219
+ gap: 5px;
3220
+ padding: 4px 10px;
3221
+ border: 1px solid #e2e8f0;
3222
+ background: #ffffff;
3223
+ border-radius: 16px;
3224
+ font-size: 11.5px;
3225
+ font-weight: 500;
3226
+ color: #475569;
3227
+ cursor: pointer;
3228
+ transition: all 0.15s ease;
3229
+
3230
+ .pill-icon {
3231
+ font-size: 14px;
3232
+ }
3233
+
3234
+ &:hover {
3235
+ background: #f8fafc;
3236
+ border-color: #cbd5e1;
3237
+ color: #1e293b;
3238
+ }
3239
+
3240
+ &.active {
3241
+ background: #eff6ff;
3242
+ border-color: #bfdbfe;
3243
+ color: #1d4ed8;
3244
+ font-weight: 600;
3245
+ }
3246
+ }
3247
+ }
3248
+ }
3249
+
3250
+ .dropdown-notes-content {
3251
+ display: flex;
3252
+ flex-direction: column;
3253
+ gap: 10px;
3254
+ padding: 4px 2px;
3255
+
3256
+ .note-title {
3257
+ font-size: 13.5px;
3258
+ font-weight: 700;
3259
+ color: #1f1f1f;
3260
+ margin: 0 0 4px 0;
3261
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', sans-serif;
3262
+ }
3263
+
3264
+ .code-segment {
3265
+ font-family: 'Fira Code', 'Roboto Mono', Consolas, monospace;
3266
+ background-color: #f1f3f4;
3267
+ color: #1967d2;
3268
+ padding: 1px 5px;
3269
+ border-radius: 4px;
3270
+ font-size: 12px;
3271
+ margin: 0 2px;
3272
+ word-break: break-all;
3273
+ }
3274
+
3275
+ .milestones-container {
3276
+ display: flex;
3277
+ flex-direction: column;
3278
+ gap: 8px;
3279
+ }
3280
+
3281
+ .milestone-block {
3282
+ display: flex;
3283
+ flex-direction: column;
3284
+
3285
+ &.checked {
3286
+ .milestone-title-row {
3287
+ .milestone-status-icon.checked {
3288
+ opacity: 0.7;
3289
+ }
3290
+ .milestone-text {
3291
+ color: #a1a1aa;
3292
+ }
3293
+ }
3294
+ }
3295
+
3296
+ .milestone-title-row {
3297
+ display: flex;
3298
+ align-items: flex-start;
3299
+ gap: 8px;
3300
+
3301
+ .milestone-status-icon {
3302
+ font-size: 18px;
3303
+ user-select: none;
3304
+ margin-top: 2px;
3305
+ font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;
3306
+
3307
+ &.checked, &.progress {
3308
+ color: #1a73e8;
3309
+ }
3310
+ &.unchecked {
3311
+ color: #cbd5e1;
3312
+ }
3313
+ }
3314
+
3315
+ .milestone-text {
3316
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', sans-serif;
3317
+ color: #1f1f1f;
3318
+ font-size: 13px;
3319
+ line-height: 1.5;
3320
+ word-break: break-word;
3321
+ flex: 1;
3322
+ }
3323
+ }
3324
+
3325
+ .milestone-substeps {
3326
+ margin-top: 4px;
3327
+ display: flex;
3328
+ flex-direction: column;
3329
+ gap: 5px;
3330
+ padding-left: 26px;
3331
+
3332
+ .substep-row {
3333
+ display: flex;
3334
+ align-items: flex-start;
3335
+ gap: 8px;
3336
+ font-family: 'Google Sans', 'Google Sans Text', 'Inter', sans-serif;
3337
+ color: #1f1f1f;
3338
+ font-size: 12.5px;
3339
+ line-height: 1.5;
3340
+
3341
+ &.checked {
3342
+ color: #a1a1aa;
3343
+ .check-icon.checked {
3344
+ opacity: 0.7;
3345
+ }
3346
+ }
3347
+
3348
+ &.verify {
3349
+ color: #334155;
3350
+ gap: 8px;
3351
+ align-items: flex-start;
3352
+
3353
+ .verify-badge {
3354
+ flex-shrink: 0;
3355
+ display: inline-flex;
3356
+ align-items: center;
3357
+ justify-content: center;
3358
+ font-family: 'Google Sans Text', 'Inter', -apple-system, sans-serif;
3359
+ font-size: 10.5px;
3360
+ font-weight: 550;
3361
+ line-height: 1.2;
3362
+ letter-spacing: 0.2px;
3363
+ text-transform: lowercase;
3364
+ color: #475569;
3365
+ background: #f1f5f9;
3366
+ border: 1px solid #e2e8f0;
3367
+ border-radius: 4px;
3368
+ padding: 1.5px 6px;
3369
+ margin-top: 1.5px;
3370
+ user-select: none;
3371
+
3372
+ &.assert {
3373
+ color: #0369a1;
3374
+ background: #f0f9ff;
3375
+ border-color: #e0f2fe;
3376
+ }
3377
+ }
3378
+
3379
+ .line-text {
3380
+ color: #334155;
3381
+ font-size: 12.5px;
3382
+ line-height: 1.5;
3383
+ }
3384
+ }
3385
+
3386
+ &.finding {
3387
+ color: #92400e;
3388
+ gap: 8px;
3389
+ align-items: flex-start;
3390
+
3391
+ .finding-badge {
3392
+ flex-shrink: 0;
3393
+ display: inline-flex;
3394
+ align-items: center;
3395
+ justify-content: center;
3396
+ font-family: 'Google Sans Text', 'Inter', -apple-system, sans-serif;
3397
+ font-size: 10.5px;
3398
+ font-weight: 550;
3399
+ line-height: 1.2;
3400
+ letter-spacing: 0.2px;
3401
+ text-transform: lowercase;
3402
+ color: #b45309;
3403
+ background: #fef3c7;
3404
+ border: 1px solid #fde68a;
3405
+ border-radius: 4px;
3406
+ padding: 1.5px 6px;
3407
+ margin-top: 1.5px;
3408
+ user-select: none;
3409
+ }
3410
+
3411
+ .line-text {
3412
+ color: #92400e;
3413
+ font-size: 12.5px;
3414
+ line-height: 1.5;
3415
+ }
3416
+ }
3417
+
3418
+ .check-icon {
3419
+ font-size: 16px;
3420
+ user-select: none;
3421
+ margin-top: 2px;
3422
+ font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;
3423
+
3424
+ &.checked, &.progress {
3425
+ color: #1a73e8;
3426
+ }
3427
+ &.unchecked {
3428
+ color: #cbd5e1;
3429
+ }
3430
+ }
3431
+
3432
+ .bullet {
3433
+ color: #9ca3af;
3434
+ font-weight: bold;
3435
+ user-select: none;
3436
+ }
3437
+
3438
+ .line-text {
3439
+ word-break: break-word;
3440
+ color: inherit;
3441
+ }
3442
+ }
3443
+ }
3444
+
3445
+ .milestone-checks-container {
3446
+ margin-top: 6px;
3447
+ padding-left: 26px;
3448
+ display: flex;
3449
+ flex-direction: column;
3450
+ gap: 6px;
3451
+ }
3452
+ }
3453
+
3454
+ .verification-card {
3455
+ background: #f8fafc;
3456
+ border: 1px solid #e2e8f0;
3457
+ border-radius: 6px;
3458
+ padding: 7px 10px;
3459
+ display: flex;
3460
+ flex-direction: column;
3461
+ gap: 3px;
3462
+
3463
+ &.standalone {
3464
+ margin-top: 6px;
3465
+ margin-bottom: 6px;
3466
+ }
3467
+
3468
+ .card-header {
3469
+ display: flex;
3470
+ align-items: center;
3471
+
3472
+ .card-tag {
3473
+ font-family: 'Google Sans Text', 'Inter', -apple-system, sans-serif;
3474
+ font-size: 9.5px;
3475
+ font-weight: 600;
3476
+ line-height: 1;
3477
+ letter-spacing: 0.6px;
3478
+ text-transform: uppercase;
3479
+ color: #64748b;
3480
+
3481
+ &.assert {
3482
+ color: #0284c7;
3483
+ }
3484
+ }
3485
+ }
3486
+
3487
+ .card-body {
3488
+ font-family: inherit;
3489
+ font-size: 12px;
3490
+ line-height: 1.5;
3491
+ color: #334155;
3492
+ word-break: break-word;
3493
+
3494
+ .bold-segment {
3495
+ font-weight: 600;
3496
+ color: #1e293b;
3497
+ }
3498
+
3499
+ .code-segment {
3500
+ font-family: 'Fira Code', 'Roboto Mono', Consolas, monospace;
3501
+ font-size: 11px;
3502
+ background: #f1f5f9;
3503
+ color: #0f172a;
3504
+ padding: 1px 5px;
3505
+ border-radius: 4px;
3506
+ border: 1px solid #e2e8f0;
3507
+ }
3508
+ }
3509
+
3510
+ &.finding {
3511
+ background: #fffbeb;
3512
+ border-color: #fef3c7;
3513
+
3514
+ .card-header .card-tag {
3515
+ color: #b45309;
3516
+ }
3517
+
3518
+ .card-body {
3519
+ color: #92400e;
3520
+ }
3521
+ }
3522
+ }
3523
+
3524
+ .other-lines-container {
3525
+ display: flex;
3526
+ flex-direction: column;
3527
+ gap: 6px;
3528
+ margin-top: 6px;
3529
+ padding-top: 6px;
3530
+ border-top: 1px dashed #e2e8f0;
3531
+
3532
+ .md-line {
3533
+ display: flex;
3534
+ align-items: flex-start;
3535
+ gap: 6px;
3536
+ font-size: 12.5px;
3537
+ color: #334155;
3538
+ line-height: 1.5;
3539
+
3540
+ .line-text {
3541
+ word-break: break-word;
3542
+ color: inherit;
3543
+ }
3544
+ }
3545
+ }
3546
+ }
3547
+ }
3548
+
3549
+ &::-webkit-scrollbar {
3550
+ width: 6px;
3551
+ }
3552
+ &::-webkit-scrollbar-thumb {
3553
+ background: #cbd5e1;
3554
+ border-radius: 4px;
3555
+ }
3556
+
3557
+ .dropdown-header {
3558
+ display: flex;
3559
+ align-items: center;
3560
+ justify-content: space-between;
3561
+ padding-bottom: 8px;
3562
+ border-bottom: 1px solid #e2e8f0;
3563
+
3564
+ .dropdown-title {
3565
+ display: flex;
3566
+ align-items: center;
3567
+ gap: 8px;
3568
+ font-size: 13px;
3569
+ font-weight: 700;
3570
+ color: #0f172a;
3571
+
3572
+ .icon-main {
3573
+ font-size: 18px;
3574
+ color: #2563eb;
3575
+ }
3576
+ }
3577
+ }
3578
+
3579
+ .dropdown-section-label {
3580
+ display: flex;
3581
+ align-items: center;
3582
+ gap: 6px;
3583
+ font-size: 11px;
3584
+ font-weight: 700;
3585
+ color: #475569;
3586
+ text-transform: uppercase;
3587
+ letter-spacing: 0.5px;
3588
+ padding: 4px 2px 2px 2px;
3589
+
3590
+ &.history-label {
3591
+ margin-top: 6px;
3592
+ }
3593
+
3594
+ .icon-bolt {
3595
+ font-size: 15px;
3596
+ color: #d97706;
3597
+ }
3598
+ .icon-history {
3599
+ font-size: 15px;
3600
+ color: #64748b;
3601
+ }
3602
+ }
3603
+
3604
+ .dropdown-empty-state {
3605
+ padding: 20px 14px;
3606
+ text-align: center;
3607
+ font-size: 12px;
3608
+ color: #94a3b8;
3609
+ background: #f8fafc;
3610
+ border: 1px dashed #e2e8f0;
3611
+ border-radius: 6px;
3612
+ display: flex;
3613
+ flex-direction: column;
3614
+ align-items: center;
3615
+ justify-content: center;
3616
+ gap: 6px;
3617
+
3618
+ .empty-icon {
3619
+ font-size: 22px;
3620
+ color: #94a3b8;
3621
+ }
3622
+ }
3623
+
3624
+ .dropdown-history-list {
3625
+ display: flex;
3626
+ flex-direction: column;
3627
+ gap: 8px;
3628
+ }
3629
+
3630
+ .dropdown-item-card {
3631
+ padding: 10px 12px;
3632
+ background: #f8fafc;
3633
+ border: 1px solid #e2e8f0;
3634
+ border-radius: 6px;
3635
+ cursor: pointer;
3636
+ transition: all 0.15s ease;
3637
+ display: flex;
3638
+ flex-direction: column;
3639
+ gap: 6px;
3640
+
3641
+ &:hover {
3642
+ background: #f1f5f9;
3643
+ border-color: #cbd5e1;
3644
+ transform: translateY(-1px);
3645
+
3646
+ .item-header .item-header-actions {
3647
+ &:has(.btn-delete-card) .item-time,
3648
+ &:has(.btn-delete-card) .item-time-divider,
3649
+ &:has(.btn-stop-card) .item-time,
3650
+ &:has(.btn-stop-card) .item-time-divider {
3651
+ opacity: 0;
3652
+ }
3653
+
3654
+ .btn-delete-card,
3655
+ .btn-stop-card {
3656
+ opacity: 1;
3657
+ pointer-events: auto;
3658
+ }
3659
+ }
3660
+ }
3661
+
3662
+ &.selected {
3663
+ background: #eff6ff;
3664
+ border-color: #93c5fd;
3665
+ box-shadow: 0 0 0 1px #2563eb;
3666
+
3667
+ .item-goal {
3668
+ color: #1e3a8a;
3669
+ font-weight: 600;
3670
+ }
3671
+ }
3672
+
3673
+ &.running {
3674
+ border-left: 3.5px solid #2563eb;
3675
+ }
3676
+
3677
+ .item-header {
3678
+ display: flex;
3679
+ align-items: center;
3680
+ justify-content: space-between;
3681
+ gap: 8px;
3682
+ min-width: 0;
3683
+
3684
+ .task-badge {
3685
+ flex-shrink: 0;
3686
+ display: inline-flex;
3687
+ align-items: center;
3688
+ font-size: 10.5px;
3689
+ font-weight: 700;
3690
+ padding: 2px 5px;
3691
+ border-radius: 4px;
3692
+ letter-spacing: 0.05em;
3693
+ border: 1px solid #e2e8f0;
3694
+ background: #fafafa;
3695
+ color: #64748b;
3696
+
3697
+ &::before {
3698
+ content: '';
3699
+ width: 4px;
3700
+ height: 4px;
3701
+ border-radius: 50%;
3702
+ display: inline-block;
3703
+ margin-right: 4px;
3704
+ }
3705
+
3706
+ &.running {
3707
+ background: #fafafa;
3708
+ color: #1f1f1f;
3709
+ border-color: #1f1f1f;
3710
+ &::before {
3711
+ background-color: #1f1f1f;
3712
+ animation: pulse-black-dot-small 1.5s infinite ease-in-out;
3713
+ }
3714
+ }
3715
+ &.paused {
3716
+ background: #fff7ed;
3717
+ color: #c2410c;
3718
+ border-color: #fdba74;
3719
+ &::before { background-color: #f97316; }
3720
+ }
3721
+ &.completed {
3722
+ background: #fafafa;
3723
+ color: #1f1f1f;
3724
+ border-color: #e2e8f0;
3725
+ &::before {
3726
+ background-color: #1f1f1f;
3727
+ }
3728
+ }
3729
+ &.pending {
3730
+ background: #fafafa;
3731
+ color: #64748b;
3732
+ border-color: #e2e8f0;
3733
+ &::before {
3734
+ background-color: #94a3b8;
3735
+ }
3736
+ }
3737
+ &.failed {
3738
+ background: #fafafa;
3739
+ color: #ef4444;
3740
+ border-color: #fee2e2;
3741
+ &::before {
3742
+ background-color: #ef4444;
3743
+ }
3744
+ }
3745
+ &.cancelled {
3746
+ background: #fafafa;
3747
+ color: #d97706;
3748
+ border-color: #fef3c7;
3749
+ &::before {
3750
+ background-color: #f59e0b;
3751
+ }
3752
+ }
3753
+
3754
+ .status-dot {
3755
+ display: none;
3756
+ }
3757
+ }
3758
+
3759
+ .item-header-actions {
3760
+ display: flex;
3761
+ align-items: center;
3762
+ gap: 4px;
3763
+ position: relative;
3764
+ min-width: 0;
3765
+ flex-shrink: 1;
3766
+ justify-content: flex-end;
3767
+
3768
+ .item-device {
3769
+ display: inline-flex;
3770
+ align-items: center;
3771
+ gap: 2.5px;
3772
+ min-width: 0;
3773
+ flex-shrink: 1;
3774
+ font-size: 10.5px;
3775
+ color: #64748b;
3776
+ line-height: 1;
3777
+ cursor: default;
3778
+ transition: color 0.15s ease, opacity 0.15s ease;
3779
+
3780
+ .device-icon {
3781
+ font-size: 12px;
3782
+ width: 12px;
3783
+ height: 12px;
3784
+ line-height: 12px;
3785
+ color: #64748b;
3786
+ opacity: 0.75;
3787
+ flex-shrink: 0;
3788
+ }
3789
+
3790
+ .device-name {
3791
+ overflow: hidden;
3792
+ text-overflow: ellipsis;
3793
+ white-space: nowrap;
3794
+ min-width: 0;
3795
+ font-family: inherit;
3796
+ letter-spacing: -0.15px;
3797
+ }
3798
+
3799
+ &:hover {
3800
+ color: #334155;
3801
+ .device-icon {
3802
+ color: #334155;
3803
+ opacity: 1;
3804
+ }
3805
+ }
3806
+ }
3807
+
3808
+ .item-time-divider {
3809
+ font-size: 10px;
3810
+ color: #94a3b8;
3811
+ line-height: 1;
3812
+ user-select: none;
3813
+ flex-shrink: 0;
3814
+ transition: opacity 0.15s ease;
3815
+ }
3816
+
3817
+ .item-time {
3818
+ font-size: 11px;
3819
+ color: #64748b;
3820
+ white-space: nowrap;
3821
+ flex-shrink: 0;
3822
+ line-height: 1;
3823
+ transition: opacity 0.15s ease;
3824
+ }
3825
+
3826
+ .btn-delete-card {
3827
+ position: absolute;
3828
+ right: 0;
3829
+ top: 50%;
3830
+ transform: translateY(-50%);
3831
+ width: 18px;
3832
+ height: 18px;
3833
+ padding: 0;
3834
+ border: none;
3835
+ background: transparent;
3836
+ border-radius: 3px;
3837
+ color: #94a3b8;
3838
+ cursor: pointer;
3839
+ display: inline-flex;
3840
+ align-items: center;
3841
+ justify-content: center;
3842
+ opacity: 0;
3843
+ pointer-events: none;
3844
+ transition: all 0.15s ease;
3845
+
3846
+ .material-symbols-outlined {
3847
+ font-size: 13px;
3848
+ line-height: 1;
3849
+ }
3850
+
3851
+ &:hover {
3852
+ color: #ef4444;
3853
+ background: #fee2e2;
3854
+ }
3855
+ }
3856
+
3857
+ .btn-stop-card {
3858
+ position: absolute;
3859
+ right: 0;
3860
+ top: 50%;
3861
+ transform: translateY(-50%);
3862
+ width: 18px;
3863
+ height: 18px;
3864
+ padding: 0;
3865
+ border: none;
3866
+ background: transparent;
3867
+ border-radius: 3px;
3868
+ color: #ef4444;
3869
+ cursor: pointer;
3870
+ display: inline-flex;
3871
+ align-items: center;
3872
+ justify-content: center;
3873
+ opacity: 0;
3874
+ pointer-events: none;
3875
+ transition: all 0.15s ease;
3876
+
3877
+ .material-symbols-outlined {
3878
+ font-size: 14px;
3879
+ line-height: 1;
3880
+ }
3881
+
3882
+ &:hover {
3883
+ color: #dc2626;
3884
+ background: #fee2e2;
3885
+ transform: translateY(-50%) scale(1.1);
3886
+ }
3887
+ }
3888
+ }
3889
+ }
3890
+
3891
+ .item-goal {
3892
+ font-size: 12.5px;
3893
+ color: #334155;
3894
+ line-height: 1.4;
3895
+ display: -webkit-box;
3896
+ -webkit-line-clamp: 2;
3897
+ line-clamp: 2;
3898
+ -webkit-box-orient: vertical;
3899
+ overflow: hidden;
3900
+ }
3901
+
3902
+ .item-footer {
3903
+ display: flex;
3904
+ align-items: center;
3905
+ justify-content: space-between;
3906
+ gap: 10px;
3907
+ font-size: 10.5px;
3908
+ color: #94a3b8;
3909
+
3910
+ .item-id {
3911
+ font-family: 'Fira Code', 'Roboto Mono', Consolas, monospace;
3912
+ font-size: 10.5px;
3913
+ color: #94a3b8;
3914
+ white-space: nowrap;
3915
+ overflow: hidden;
3916
+ text-overflow: ellipsis;
3917
+ min-width: 0;
3918
+ flex: 1;
3919
+ transition: color 0.15s ease;
3920
+
3921
+ &:hover {
3922
+ color: #475569;
3923
+ }
3924
+ }
3925
+
3926
+ .item-date {
3927
+ flex-shrink: 0;
3928
+ }
3929
+ }
3930
+ }
3931
+
3932
+ .dropdown-note-item {
3933
+ display: flex;
3934
+ align-items: center;
3935
+ gap: 10px;
3936
+ padding: 8px 12px;
3937
+ border-radius: 6px;
3938
+ cursor: pointer;
3939
+ font-size: 13px;
3940
+ color: #334155;
3941
+ transition: background 0.15s ease;
3942
+
3943
+ .note-icon {
3944
+ font-size: 18px;
3945
+ color: #64748b;
3946
+ }
3947
+
3948
+ .note-key-text {
3949
+ flex: 1;
3950
+ font-weight: 500;
3951
+ }
3952
+
3953
+ .check-icon {
3954
+ font-size: 18px;
3955
+ color: #2563eb;
3956
+ }
3957
+
3958
+ &:hover {
3959
+ background: #f1f5f9;
3960
+ color: #0f172a;
3961
+ }
3962
+
3963
+ &.selected {
3964
+ background: #eff6ff;
3965
+ color: #2563eb;
3966
+ font-weight: 600;
3967
+
3968
+ .note-icon {
3969
+ color: #2563eb;
3970
+ }
3971
+ }
3972
+ }
3973
+ }