ltcai 3.6.0 → 4.0.1

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 (238) hide show
  1. package/README.md +39 -31
  2. package/docs/CHANGELOG.md +64 -0
  3. package/docs/REALTIME_COLLABORATION.md +3 -3
  4. package/docs/V3_FRONTEND.md +9 -8
  5. package/docs/V4_BRAIN_ARCHITECTURE.md +322 -0
  6. package/docs/V4_DIGITAL_BRAIN_RECOVERY.md +552 -0
  7. package/docs/V4_IMPLEMENTATION_PLAN.md +470 -0
  8. package/docs/kg-schema.md +51 -53
  9. package/docs/spec-vs-impl.md +10 -10
  10. package/kg_schema.py +2 -520
  11. package/knowledge_graph.py +37 -4629
  12. package/knowledge_graph_api.py +11 -127
  13. package/latticeai/__init__.py +1 -1
  14. package/latticeai/api/admin.py +16 -17
  15. package/latticeai/api/agents.py +20 -7
  16. package/latticeai/api/auth.py +46 -15
  17. package/latticeai/api/chat.py +112 -76
  18. package/latticeai/api/health.py +1 -1
  19. package/latticeai/api/hooks.py +1 -1
  20. package/latticeai/api/invitations.py +100 -0
  21. package/latticeai/api/knowledge_graph.py +139 -0
  22. package/latticeai/api/local_files.py +1 -1
  23. package/latticeai/api/mcp.py +23 -11
  24. package/latticeai/api/memory.py +1 -1
  25. package/latticeai/api/models.py +1 -1
  26. package/latticeai/api/network.py +81 -0
  27. package/latticeai/api/plugins.py +3 -6
  28. package/latticeai/api/realtime.py +5 -8
  29. package/latticeai/api/search.py +26 -2
  30. package/latticeai/api/security_dashboard.py +2 -3
  31. package/latticeai/api/setup.py +2 -2
  32. package/latticeai/api/static_routes.py +11 -16
  33. package/latticeai/api/tools.py +3 -0
  34. package/latticeai/api/ui_redirects.py +26 -0
  35. package/latticeai/api/workflow_designer.py +85 -6
  36. package/latticeai/api/workspace.py +93 -57
  37. package/latticeai/app_factory.py +1781 -0
  38. package/latticeai/brain/__init__.py +18 -0
  39. package/latticeai/brain/_kg_common.py +1123 -0
  40. package/latticeai/brain/context.py +213 -0
  41. package/latticeai/brain/conversations.py +236 -0
  42. package/latticeai/brain/discovery.py +1455 -0
  43. package/latticeai/brain/documents.py +218 -0
  44. package/latticeai/brain/identity.py +175 -0
  45. package/latticeai/brain/ingest.py +644 -0
  46. package/latticeai/brain/memory.py +102 -0
  47. package/latticeai/brain/network.py +205 -0
  48. package/latticeai/brain/projection.py +561 -0
  49. package/latticeai/brain/provenance.py +401 -0
  50. package/latticeai/brain/retrieval.py +1316 -0
  51. package/latticeai/brain/schema.py +640 -0
  52. package/latticeai/brain/store.py +216 -0
  53. package/latticeai/brain/write_master.py +225 -0
  54. package/latticeai/core/agent.py +31 -7
  55. package/latticeai/core/audit.py +0 -7
  56. package/latticeai/core/config.py +1 -1
  57. package/latticeai/core/context_builder.py +1 -2
  58. package/latticeai/core/enterprise.py +1 -1
  59. package/latticeai/core/graph_curator.py +2 -2
  60. package/latticeai/core/invitations.py +131 -0
  61. package/latticeai/core/marketplace.py +1 -1
  62. package/latticeai/core/mcp_registry.py +791 -0
  63. package/latticeai/core/model_compat.py +1 -1
  64. package/latticeai/core/model_resolution.py +0 -1
  65. package/latticeai/core/multi_agent.py +238 -4
  66. package/latticeai/core/policy.py +54 -0
  67. package/latticeai/core/realtime.py +65 -44
  68. package/latticeai/core/security.py +1 -1
  69. package/latticeai/core/sessions.py +66 -10
  70. package/latticeai/core/users.py +147 -0
  71. package/latticeai/core/workflow_engine.py +114 -2
  72. package/latticeai/core/workspace_os.py +477 -29
  73. package/latticeai/models/__init__.py +7 -0
  74. package/latticeai/models/router.py +779 -0
  75. package/latticeai/server_app.py +29 -1536
  76. package/latticeai/services/agent_runtime.py +243 -4
  77. package/latticeai/services/app_context.py +75 -14
  78. package/latticeai/services/ingestion.py +47 -0
  79. package/latticeai/services/kg_portability.py +33 -3
  80. package/latticeai/services/memory_service.py +39 -11
  81. package/latticeai/services/model_runtime.py +2 -5
  82. package/latticeai/services/platform_runtime.py +100 -23
  83. package/latticeai/services/run_executor.py +328 -0
  84. package/latticeai/services/search_service.py +17 -8
  85. package/latticeai/services/tool_dispatch.py +12 -2
  86. package/latticeai/services/triggers.py +241 -0
  87. package/latticeai/services/upload_service.py +37 -12
  88. package/latticeai/services/workspace_service.py +55 -16
  89. package/llm_router.py +29 -772
  90. package/ltcai_cli.py +1 -2
  91. package/mcp_registry.py +25 -788
  92. package/p_reinforce.py +124 -14
  93. package/package.json +10 -20
  94. package/scripts/bump_version.py +99 -0
  95. package/scripts/generate_diagrams.py +0 -1
  96. package/scripts/lint_v3.mjs +105 -18
  97. package/scripts/validate_release_artifacts.py +0 -1
  98. package/scripts/wheel_smoke.py +142 -0
  99. package/server.py +11 -7
  100. package/setup_wizard.py +1142 -0
  101. package/static/sw.js +81 -52
  102. package/static/v3/asset-manifest.json +33 -25
  103. package/static/v3/css/{lattice.base.e4cdd05d.css → lattice.base.49deefb5.css} +1 -1
  104. package/static/v3/css/lattice.base.css +1 -1
  105. package/static/v3/css/{lattice.components.9b49d614.css → lattice.components.cde18231.css} +1 -1
  106. package/static/v3/css/lattice.components.css +1 -1
  107. package/static/v3/css/{lattice.shell.8fcc9d33.css → lattice.shell.29d36d85.css} +1 -1
  108. package/static/v3/css/lattice.shell.css +1 -1
  109. package/static/v3/css/{lattice.tokens.e7018963.css → lattice.tokens.304cbc40.css} +3 -0
  110. package/static/v3/css/lattice.tokens.css +3 -0
  111. package/static/v3/css/{lattice.views.22f69117.css → lattice.views.0a18b6c5.css} +2 -2
  112. package/static/v3/css/lattice.views.css +2 -2
  113. package/static/v3/index.html +3 -4
  114. package/static/v3/js/{app.c541f955.js → app.c5c80c46.js} +1 -1
  115. package/static/v3/js/core/{api.33d6320e.js → api.ba0fbf14.js} +58 -1
  116. package/static/v3/js/core/api.js +57 -0
  117. package/static/v3/js/core/i18n.880e1fec.js +575 -0
  118. package/static/v3/js/core/i18n.js +575 -0
  119. package/static/v3/js/core/routes.37522821.js +101 -0
  120. package/static/v3/js/core/routes.js +71 -63
  121. package/static/v3/js/core/{shell.8c163e0e.js → shell.e3f6bbfa.js} +68 -39
  122. package/static/v3/js/core/shell.js +66 -37
  123. package/static/v3/js/core/{store.34ebd5e6.js → store.7b2aa044.js} +11 -1
  124. package/static/v3/js/core/store.js +11 -1
  125. package/static/v3/js/views/account.eff40715.js +143 -0
  126. package/static/v3/js/views/account.js +143 -0
  127. package/static/v3/js/views/activity.0d271ef9.js +67 -0
  128. package/static/v3/js/views/activity.js +67 -0
  129. package/static/v3/js/views/{admin-users.03bac88c.js → admin-users.f7ac7b43.js} +4 -6
  130. package/static/v3/js/views/admin-users.js +4 -6
  131. package/static/v3/js/views/{agents.014d0b74.js → agents.17c5288d.js} +35 -12
  132. package/static/v3/js/views/agents.js +35 -12
  133. package/static/v3/js/views/{chat.e6dd7dd0.js → chat.e250e2cc.js} +23 -0
  134. package/static/v3/js/views/chat.js +23 -0
  135. package/static/v3/js/views/graph-canvas.17c15d65.js +509 -0
  136. package/static/v3/js/views/graph-canvas.js +509 -0
  137. package/static/v3/js/views/{hybrid-search.b22b97e0.js → hybrid-search.2fb63ed9.js} +1 -2
  138. package/static/v3/js/views/hybrid-search.js +1 -2
  139. package/static/v3/js/views/{knowledge-graph.a96040a5.js → knowledge-graph.4d09c537.js} +60 -44
  140. package/static/v3/js/views/knowledge-graph.js +60 -44
  141. package/static/v3/js/views/network.52a4f181.js +97 -0
  142. package/static/v3/js/views/network.js +97 -0
  143. package/static/v3/js/views/{planning.9ac3e313.js → planning.4876fd77.js} +26 -5
  144. package/static/v3/js/views/planning.js +26 -5
  145. package/static/v3/js/views/runs.b63b2afa.js +144 -0
  146. package/static/v3/js/views/runs.js +144 -0
  147. package/static/v3/js/views/{settings.8631fa5e.js → settings.b7140634.js} +7 -8
  148. package/static/v3/js/views/settings.js +7 -8
  149. package/static/v3/js/views/snapshots.6f5db095.js +135 -0
  150. package/static/v3/js/views/snapshots.js +135 -0
  151. package/static/v3/js/views/{workflows.26c57290.js → workflows.7752225a.js} +87 -2
  152. package/static/v3/js/views/workflows.js +87 -2
  153. package/static/v3/js/views/workspace-admin.c466029b.js +156 -0
  154. package/static/v3/js/views/workspace-admin.js +156 -0
  155. package/static/vendor/chart.umd.min.js +20 -0
  156. package/static/vendor/fonts/inter-latin-300-normal.woff2 +0 -0
  157. package/static/vendor/fonts/inter-latin-400-normal.woff2 +0 -0
  158. package/static/vendor/fonts/inter-latin-500-normal.woff2 +0 -0
  159. package/static/vendor/fonts/inter-latin-600-normal.woff2 +0 -0
  160. package/static/vendor/fonts/inter-latin-700-normal.woff2 +0 -0
  161. package/static/vendor/fonts/inter-latin-800-normal.woff2 +0 -0
  162. package/static/vendor/fonts/inter.css +44 -0
  163. package/static/vendor/icons/tabler-icons.min.css +4 -0
  164. package/static/vendor/icons/tabler-icons.woff2 +0 -0
  165. package/static/vendor/marked.min.js +69 -0
  166. package/telegram_bot.py +1 -2
  167. package/tools/commands.py +4 -2
  168. package/tools/computer.py +1 -1
  169. package/tools/documents.py +1 -3
  170. package/tools/filesystem.py +0 -4
  171. package/tools/knowledge.py +1 -3
  172. package/tools/network.py +1 -3
  173. package/codex_telegram_bot.py +0 -195
  174. package/docs/assets/v3.4.0/agent-run.png +0 -0
  175. package/docs/assets/v3.4.0/agents.png +0 -0
  176. package/docs/assets/v3.4.0/before/chat-before.png +0 -0
  177. package/docs/assets/v3.4.0/before/files-before.png +0 -0
  178. package/docs/assets/v3.4.0/chat.png +0 -0
  179. package/docs/assets/v3.4.0/connect-folder.png +0 -0
  180. package/docs/assets/v3.4.0/files.png +0 -0
  181. package/docs/assets/v3.4.0/home.png +0 -0
  182. package/docs/assets/v3.4.0/hooks-dispatch.png +0 -0
  183. package/docs/assets/v3.4.0/knowledge-graph.png +0 -0
  184. package/docs/assets/v3.4.0/local-agent.png +0 -0
  185. package/docs/assets/v3.4.0/memory.png +0 -0
  186. package/docs/assets/v3.4.0/settings.png +0 -0
  187. package/docs/assets/v3.4.0/vision-input.png +0 -0
  188. package/docs/assets/v3.4.0/workflows.png +0 -0
  189. package/docs/assets/v3.4.1/e2e_runtime_log.txt +0 -42
  190. package/docs/assets/v3.4.1/hooks-dispatch.png +0 -0
  191. package/docs/assets/v3.4.1/local-agent.png +0 -0
  192. package/docs/images/admin-dashboard.png +0 -0
  193. package/docs/images/architecture.png +0 -0
  194. package/docs/images/enterprise.png +0 -0
  195. package/docs/images/graph.png +0 -0
  196. package/docs/images/hero.gif +0 -0
  197. package/docs/images/knowledge-graph.png +0 -0
  198. package/docs/images/lattice-ai-demo.gif +0 -0
  199. package/docs/images/lattice-ai-hero.png +0 -0
  200. package/docs/images/logo.svg +0 -33
  201. package/docs/images/mobile-responsive.png +0 -0
  202. package/docs/images/model-recommendation.png +0 -0
  203. package/docs/images/onboarding.png +0 -0
  204. package/docs/images/organization.png +0 -0
  205. package/docs/images/pipeline.png +0 -0
  206. package/docs/images/screenshot-admin.png +0 -0
  207. package/docs/images/screenshot-chat.png +0 -0
  208. package/docs/images/screenshot-graph.png +0 -0
  209. package/docs/images/skills.png +0 -0
  210. package/docs/images/workspace-dark.png +0 -0
  211. package/docs/images/workspace-light.png +0 -0
  212. package/docs/images/workspace.png +0 -0
  213. package/requirements.txt +0 -16
  214. package/static/account.html +0 -115
  215. package/static/activity.html +0 -73
  216. package/static/admin.html +0 -488
  217. package/static/agents.html +0 -139
  218. package/static/chat.html +0 -844
  219. package/static/css/reference/account.css +0 -439
  220. package/static/css/reference/admin.css +0 -610
  221. package/static/css/reference/base.css +0 -1661
  222. package/static/css/reference/chat.css +0 -4623
  223. package/static/css/reference/graph.css +0 -1016
  224. package/static/css/responsive.css +0 -861
  225. package/static/graph.html +0 -124
  226. package/static/platform.css +0 -104
  227. package/static/plugins.html +0 -136
  228. package/static/scripts/account.js +0 -238
  229. package/static/scripts/admin.js +0 -1614
  230. package/static/scripts/chat.js +0 -5081
  231. package/static/scripts/graph.js +0 -1804
  232. package/static/scripts/platform.js +0 -64
  233. package/static/scripts/ux.js +0 -167
  234. package/static/scripts/workspace.js +0 -948
  235. package/static/v3/js/core/routes.2ce3815a.js +0 -93
  236. package/static/workflows.html +0 -146
  237. package/static/workspace.css +0 -1121
  238. package/static/workspace.html +0 -357
@@ -1,861 +0,0 @@
1
- /* ============================================================================
2
- * Lattice AI — Responsive / Accessibility / Theme Foundation (v2.2.5)
3
- *
4
- * 이 파일은 모든 페이지에서 가장 마지막에 로드된다 (lattice-reference.css /
5
- * workspace.css / platform.css 다음). 따라서 기존 규칙을 "덮어쓰는" 레이어로
6
- * 동작하며, 거대한 lattice-reference.css 를 직접 수술하지 않고도
7
- * - 하단/입력창/모달/팝업 잘림
8
- * - 수평 스크롤
9
- * - 모바일 키보드 레이아웃 깨짐
10
- * - 태블릿 레이아웃 깨짐
11
- * - 작은 화면 메뉴 접근 불가
12
- * - 44px 미만 터치 영역 / 포커스 링 부재
13
- * - 다크/라이트 테마 패리티
14
- * 를 일괄 해결한다. 라이트 테마는 건드리지 않으므로 회귀 위험이 없다.
15
- *
16
- * 표준 브레이크포인트 (이 파일이 프로젝트 규약):
17
- * phone <= 600px
18
- * tablet <= 1024px
19
- * laptop (default)
20
- * ultrawide >= 1600px
21
- * ========================================================================== */
22
-
23
- /* ============================================================================
24
- * 0. 전역 가드 — 수평 스크롤 / 박스 모델 / 긴 문자열
25
- * ========================================================================== */
26
- *,
27
- *::before,
28
- *::after { box-sizing: border-box; }
29
-
30
- html,
31
- body {
32
- max-width: 100%;
33
- overflow-x: hidden; /* 어떤 와이드 자식도 페이지 수평 스크롤을 못 만들게 */
34
- }
35
-
36
- body { min-width: 0; }
37
-
38
- /* 미디어/코드/표는 컨테이너를 넘지 않는다 */
39
- img,
40
- svg,
41
- video,
42
- canvas,
43
- table,
44
- pre {
45
- max-width: 100%;
46
- }
47
-
48
- /* 긴 토큰/URL 줄바꿈 (수평 오버플로우 방지) */
49
- pre,
50
- code,
51
- .bubble,
52
- .detail-summary,
53
- .perm-path,
54
- .mcp-item-desc {
55
- overflow-wrap: anywhere;
56
- word-break: break-word;
57
- }
58
-
59
- /* flex 자식이 내용 때문에 줄어들지 못해 오버플로우 나는 고전 버그 */
60
- .main-chat,
61
- .messages-viewport,
62
- .workspace-main,
63
- .admin-main,
64
- .stage { min-width: 0; }
65
-
66
- /* 모바일 햄버거 토글은 기본 숨김 — 모바일/태블릿 미디어쿼리(섹션 7·8)에서 노출.
67
- * 이 기본값은 노출 규칙보다 *먼저* 선언돼야 소스 순서상 노출이 이긴다.
68
- * (graph-view-toggle 은 섹션 8 에서 동일 패턴으로 처리) */
69
- .graph-nav-toggle,
70
- .admin-rail-toggle { display: none; }
71
-
72
- /* ============================================================================
73
- * 1. 앱 셸 — dvh 기반, 100vw 스크롤바 버그 제거
74
- * ========================================================================== */
75
- .app-layout {
76
- width: 100%; /* 100vw 는 스크롤바 폭 만큼 수평 오버플로우 발생 */
77
- height: 100vh; /* 폴백 */
78
- height: 100dvh;
79
- }
80
-
81
- /* 인증/로그인 페이지: 키보드가 떠도 카드가 스크롤되어 버튼이 안 잘리게 */
82
- body.lattice-ref-auth {
83
- min-height: 100vh; /* 폴백 */
84
- min-height: 100dvh;
85
- overflow-y: auto; /* 기존 overflow:hidden 블로커 해제 */
86
- overflow-x: hidden;
87
- }
88
-
89
- /* ============================================================================
90
- * 2. 키보드-세이프 입력창 (composer)
91
- * ux.js 의 visualViewport 리스너가 --kb-inset 를 채운다.
92
- * ========================================================================== */
93
- :root { --kb-inset: 0px; }
94
-
95
- .input-area {
96
- padding-bottom: calc(max(14px, env(safe-area-inset-bottom)) + var(--kb-inset));
97
- transition: padding-bottom 0.12s ease-out;
98
- }
99
-
100
- /* ============================================================================
101
- * 3. 터치 영역 최소 44x44 — 핵심 인터랙티브 컨트롤
102
- * (시각적 아이콘 크기는 유지, 히트 박스만 확장)
103
- * ========================================================================== */
104
- .sidebar-toggle,
105
- .sidebar-close,
106
- .admin-close,
107
- .mode-close,
108
- .mcp-modal-close,
109
- .field-eye {
110
- min-width: 44px;
111
- min-height: 44px;
112
- display: inline-flex;
113
- align-items: center;
114
- justify-content: center;
115
- }
116
-
117
- .send-btn {
118
- min-width: 44px;
119
- min-height: 44px;
120
- width: 44px;
121
- height: 44px;
122
- }
123
-
124
- .action-btn,
125
- .tb-btn,
126
- .icon-btn,
127
- .table-btn,
128
- .lang-btn,
129
- .logout-btn,
130
- .model-badge {
131
- min-height: 44px;
132
- }
133
-
134
- .action-btn { min-width: 44px; justify-content: center; }
135
-
136
- .lang-option,
137
- .filter-item,
138
- .legend-item,
139
- .rec-item,
140
- .history-item-del {
141
- min-height: 44px;
142
- display: flex;
143
- align-items: center;
144
- }
145
-
146
- .history-item-del { min-width: 44px; justify-content: center; }
147
-
148
- /* 그래프 필터 체크박스 확대 */
149
- .filter-item input[type="checkbox"],
150
- .legend-item input[type="checkbox"],
151
- .rec-checkbox {
152
- width: 20px;
153
- height: 20px;
154
- min-width: 20px;
155
- }
156
-
157
- /* 터치 기기에서는 호버로만 보이던 삭제 버튼을 항상 노출 */
158
- @media (hover: none) {
159
- .history-item-del { opacity: 1; }
160
- }
161
-
162
- /* iOS 입력 자동 줌(폰트<16px) 방지 — 모든 폼 컨트롤 */
163
- input,
164
- textarea,
165
- select {
166
- font-size: max(16px, 1em);
167
- }
168
- @media (min-width: 1025px) {
169
- /* 데스크톱에서는 디자인 크기 복원 (줌 이슈 없음) */
170
- .sidebar-search input,
171
- .mcp-add-form input,
172
- .mcp-add-form textarea,
173
- .mcp-add-form select { font-size: 13px; }
174
- }
175
-
176
- /* ============================================================================
177
- * 4. 포커스 링 — tokens.css 가 링크 안 된 페이지를 위해 항상 보장
178
- * (WCAG 2.4.7)
179
- * ========================================================================== */
180
- :focus-visible {
181
- outline: 2px solid var(--accent, #6E4AE6);
182
- outline-offset: 2px;
183
- border-radius: inherit;
184
- }
185
- /* 마우스 클릭 시 링 숨김은 :focus-visible 가 알아서 처리 */
186
-
187
- /* ============================================================================
188
- * 5. 모달 / 팝업 / 오버레이 — 뷰포트 가둠 + 내부 스크롤
189
- * (footer 버튼이 키보드/짧은 화면에 잘리지 않게)
190
- * ========================================================================== */
191
- .acct-modal,
192
- .mcp-modal,
193
- .mode-modal,
194
- .workspace-modal,
195
- .advanced-settings-panel,
196
- .perm-dialog,
197
- .model-panel,
198
- .onboarding-card,
199
- .wizard-card {
200
- max-height: min(760px, calc(100dvh - 32px));
201
- display: flex;
202
- flex-direction: column;
203
- overflow: hidden;
204
- }
205
-
206
- /* 모달 내부 스크롤 영역 */
207
- .acct-body,
208
- .mcp-modal-body,
209
- .advanced-settings-body,
210
- .mode-modal .mode-options,
211
- .workspace-modal .workspace-options,
212
- .model-list,
213
- .onboarding-model-list,
214
- .pipeline-modal-body {
215
- flex: 1 1 auto;
216
- min-height: 0;
217
- overflow-y: auto;
218
- }
219
-
220
- /* #onboarding-body 는 .onboarding-card(flex column · overflow:hidden) 안의
221
- * 스크롤 영역이다. lattice-reference.css 의 `.onboarding-body.lattice-ref-chat`
222
- * 는 *복합* 선택자(두 클래스가 같은 엘리먼트)인데 lattice-ref-chat 는 <body> 에만
223
- * 있고 .onboarding-body 엘리먼트에는 없어 영영 매치되지 않았다 → onboarding-body
224
- * 에 overflow/padding 이 적용되지 않아 추천 결과 같은 긴 콘텐츠가 카드에 잘리고
225
- * 모델 아코디언(Gemma 4·Qwen3-VL·Llama 4)과 하단 액션 버튼에 접근 불가.
226
- * 올바른 단일 클래스 선택자로 스크롤 영역과 패딩을 복원한다(명시도 트릭 아님). */
227
- .onboarding-body {
228
- flex: 1 1 auto;
229
- min-height: 0;
230
- overflow-y: auto;
231
- -webkit-overflow-scrolling: touch;
232
- padding: 28px 30px;
233
- }
234
-
235
- /* 드롭다운/팝오버: 뷰포트 안에 가둠 */
236
- .lang-picker-menu,
237
- .mcp-dropdown,
238
- .search-results {
239
- max-width: calc(100vw - 24px);
240
- max-height: min(60dvh, 360px);
241
- overflow-y: auto;
242
- }
243
-
244
- #tooltip {
245
- max-width: min(300px, calc(100vw - 24px));
246
- max-height: 60dvh;
247
- overflow: hidden;
248
- }
249
-
250
- /* 토스트가 좁은 화면을 넘지 않게 */
251
- .toast {
252
- left: auto;
253
- right: max(12px, env(safe-area-inset-right));
254
- bottom: max(16px, env(safe-area-inset-bottom));
255
- max-width: min(360px, calc(100vw - 24px));
256
- }
257
-
258
- /* 짧은 뷰포트(가로 폰/키보드)에서도 인증 컨트롤은 44px 유지 */
259
- @media (max-height: 760px) {
260
- .auth-field,
261
- .submit,
262
- .register-cta,
263
- .sso-btn { min-height: 44px; height: auto; }
264
- }
265
-
266
- /* 폰: 핵심 모달을 바텀시트로 — footer 버튼 항상 노출 */
267
- @media (max-width: 600px) {
268
- .acct-modal,
269
- .mcp-modal,
270
- .mode-modal,
271
- .workspace-modal,
272
- .advanced-settings-panel,
273
- .model-panel {
274
- width: 100%;
275
- max-width: none;
276
- max-height: 92dvh;
277
- border-bottom-left-radius: 0;
278
- border-bottom-right-radius: 0;
279
- padding-bottom: env(safe-area-inset-bottom);
280
- }
281
- .acct-modal-overlay,
282
- .mcp-modal-overlay,
283
- .mode-modal-overlay,
284
- .workspace-modal-overlay,
285
- .advanced-settings-overlay,
286
- .model-overlay {
287
- align-items: flex-end;
288
- }
289
- }
290
-
291
- /* ============================================================================
292
- * 6. 채팅 — 태블릿 티어(<=1024) 에서도 드로어 + 햄버거
293
- * 기존 파일은 768px 에서만 드로어로 전환 → 769~1024 구간이 깨져있음
294
- * ========================================================================== */
295
- @media (max-width: 1024px) {
296
- body.lattice-ref-chat { overflow: hidden; }
297
-
298
- .sidebar-toggle,
299
- .sidebar-close { display: inline-flex; }
300
-
301
- .app-layout .sidebar,
302
- .sidebar {
303
- position: fixed;
304
- top: 0;
305
- left: 0;
306
- height: 100dvh;
307
- width: min(86vw, 320px);
308
- min-width: 0;
309
- z-index: 100;
310
- transform: translateX(-100%);
311
- transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
312
- box-shadow: 4px 0 32px rgba(20, 16, 40, 0.22);
313
- }
314
- body.sidebar-open .sidebar { transform: translateX(0); }
315
-
316
- .sidebar-overlay {
317
- position: fixed;
318
- inset: 0;
319
- z-index: 99;
320
- display: none;
321
- background: rgba(15, 12, 30, 0.42);
322
- -webkit-backdrop-filter: none; /* glass removed v3.5.0 */
323
- backdrop-filter: none; /* glass removed v3.5.0 */
324
- }
325
- body.sidebar-open .sidebar-overlay { display: block; }
326
-
327
- .main-chat { width: 100%; flex: 1; }
328
-
329
- /* 모드 세그먼트/헤더가 두 줄로 안 깨지게: 가로 스크롤 */
330
- .mode-segmented {
331
- overflow-x: auto;
332
- flex-wrap: nowrap;
333
- -webkit-overflow-scrolling: touch;
334
- scrollbar-width: none;
335
- }
336
- .mode-segmented::-webkit-scrollbar { display: none; }
337
- }
338
-
339
- /* ops-strip: 좁은 화면에서 카드 세로 적층 */
340
- @media (max-width: 760px) {
341
- .ops-strip {
342
- grid-template-columns: 1fr;
343
- width: calc(100% - 28px);
344
- }
345
- }
346
-
347
- /* 홈 대시보드 카드 / 온보딩 스텝 단일 열 */
348
- @media (max-width: 900px) {
349
- .home-dash-cards { grid-template-columns: 1fr; }
350
- }
351
- @media (max-width: 560px) {
352
- .onboarding-steps {
353
- grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
354
- gap: 4px;
355
- }
356
- .onboarding-step { white-space: normal; font-size: 10px; }
357
- }
358
-
359
- /* 상태 pill 을 숨기지 말고 줄바꿈 허용 (기능 숨김 금지 원칙) */
360
- @media (max-width: 480px) {
361
- .header-pills .status-pill { display: inline-flex; }
362
- .header-pills { flex-wrap: wrap; justify-content: flex-end; }
363
- }
364
-
365
- /* ============================================================================
366
- * 7. 관리자 — 레일 접힘 + 표를 카드로
367
- * ========================================================================== */
368
- body.lattice-ref-admin {
369
- overflow-x: hidden;
370
- min-width: 0;
371
- }
372
-
373
- /* `.toolbar` 의 position:absolute / z-index:20 은 graph 캔버스 전용인데
374
- * 선택자가 과넓어(`.toolbar`) admin·chat 의 폼 액션 행(.toolbar)까지 새어
375
- * 페이지 우상단으로 떠올라 헤더 버튼(새로고침/로그아웃)을 덮었다.
376
- * graph 가 아닌 페이지에서는 정상 흐름(static)으로 되돌린다. !important 불필요
377
- * — `body.lattice-ref-* .toolbar` 가 `.toolbar` 보다 명시도가 높다. */
378
- body.lattice-ref-admin .toolbar,
379
- body.lattice-ref-chat .toolbar {
380
- position: static;
381
- z-index: auto;
382
- -webkit-backdrop-filter: none;
383
- backdrop-filter: none;
384
- }
385
-
386
- @media (max-width: 1024px) {
387
- .lattice-ref-admin { grid-template-columns: 1fr; }
388
- .lattice-ref-admin .content { width: 100%; max-width: 100%; }
389
-
390
- /* 관리자 레일: 햄버거 드로어로 */
391
- .admin-rail,
392
- .lattice-ref-admin .admin-rail {
393
- position: fixed;
394
- top: 0;
395
- left: 0;
396
- height: 100dvh;
397
- width: min(84vw, 300px);
398
- z-index: 100;
399
- transform: translateX(-100%);
400
- transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
401
- }
402
- body.admin-rail-open .admin-rail { transform: translateX(0); }
403
- body.admin-rail-open .sidebar-overlay { display: block; }
404
- }
405
-
406
- /* 표 → 카드 (<=760) : .data-table / .admin-table / .table-wrap table
407
- * JS 렌더러가 각 <td> 에 data-label 을 넣어준다 (admin.js). */
408
- @media (max-width: 760px) {
409
- .table-wrap { overflow: visible; }
410
- .table-wrap table,
411
- table.admin-table,
412
- table.data-table {
413
- min-width: 0;
414
- width: 100%;
415
- border: 0;
416
- }
417
- .table-wrap thead,
418
- table.admin-table thead,
419
- table.data-table thead { display: none; }
420
- .table-wrap tr,
421
- table.admin-table tr,
422
- table.data-table tr {
423
- display: block;
424
- margin: 0 0 10px;
425
- border: 1px solid var(--border, rgba(120,120,140,0.18));
426
- border-radius: 12px;
427
- padding: 6px 12px;
428
- background: var(--surface, rgba(255,255,255,0.04));
429
- }
430
- .table-wrap td,
431
- table.admin-table td,
432
- table.data-table td {
433
- display: flex;
434
- justify-content: space-between;
435
- align-items: center;
436
- gap: 12px;
437
- padding: 8px 0;
438
- border: 0;
439
- white-space: normal;
440
- text-align: right;
441
- }
442
- .table-wrap td::before,
443
- table.admin-table td::before,
444
- table.data-table td::before {
445
- content: attr(data-label);
446
- font-weight: 700;
447
- text-align: left;
448
- color: var(--muted, #888);
449
- flex: 0 0 42%;
450
- }
451
- /* 카드 안 액션 버튼은 전체폭으로 */
452
- .admin-actions,
453
- td .table-actions {
454
- flex-wrap: wrap;
455
- justify-content: flex-end;
456
- }
457
- .admin-action,
458
- .table-btn { min-height: 44px; }
459
- }
460
-
461
- /* ============================================================================
462
- * 8. 지식 그래프 — 레일 드로어(숨기지 않음) + 툴바 스크롤 + 검색창 위치
463
- * JS(줌/전체화면/미니맵/관계필터/카드뷰/재맞춤)는 graph.js 에서 처리.
464
- * ========================================================================== */
465
- @media (max-width: 1024px) {
466
- /* 기존: max-width:900 에서 .reference-rail{display:none} (네비 접근불가)
467
- → 드로어로 전환해서 접근 가능하게 */
468
- body.lattice-ref-graph .reference-rail {
469
- display: flex;
470
- position: fixed;
471
- top: 0;
472
- left: 0;
473
- height: 100dvh;
474
- width: min(84vw, 300px);
475
- z-index: 100;
476
- transform: translateX(-100%);
477
- transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
478
- overflow-y: auto;
479
- }
480
- body.graph-nav-open .reference-rail { transform: translateX(0); }
481
- body.graph-nav-open .sidebar-overlay { display: block; }
482
-
483
- /* 그래프 햄버거 버튼 노출 (graph.html 에 추가) */
484
- .graph-nav-toggle { display: inline-flex; }
485
- }
486
-
487
- /* 그래프 하단 툴바: 좁은 화면에서 줄바꿈 대신 가로 스크롤 */
488
- @media (max-width: 900px) {
489
- .lattice-ref-graph .toolbar,
490
- .graph-toolbar {
491
- flex-wrap: nowrap;
492
- overflow-x: auto;
493
- -webkit-overflow-scrolling: touch;
494
- justify-content: flex-start;
495
- padding-bottom: max(8px, env(safe-area-inset-bottom));
496
- scrollbar-width: none;
497
- }
498
- .lattice-ref-graph .toolbar::-webkit-scrollbar,
499
- .graph-toolbar::-webkit-scrollbar { display: none; }
500
-
501
- /* 검색창을 스테이지 안쪽으로 (기존 top:-60px 로 화면 밖) */
502
- .lattice-ref-graph .search-shell {
503
- top: 12px;
504
- right: 12px;
505
- left: auto;
506
- }
507
- }
508
-
509
- /* (햄버거 토글 기본 숨김은 섹션 0 으로 이동 — 노출 규칙보다 먼저 선언) */
510
-
511
- /* 그래프/카드 뷰 토글 (graph.js 가 .graph-card-view 클래스 토글) */
512
- .graph-view-toggle { display: none; }
513
- @media (max-width: 900px) {
514
- .graph-view-toggle { display: inline-flex; }
515
- }
516
- /* 그래프 햄버거(모바일) 위치 */
517
- .graph-nav-toggle {
518
- position: fixed;
519
- top: max(10px, env(safe-area-inset-top));
520
- left: 10px;
521
- z-index: 60;
522
- width: 44px;
523
- height: 44px;
524
- border-radius: 12px;
525
- background: var(--surface, #fff);
526
- border: 1px solid var(--border, rgba(120,120,140,0.2));
527
- box-shadow: 0 6px 18px rgba(20, 16, 40, 0.16);
528
- }
529
-
530
- /* 미니맵 — 스테이지 우상단 (작은 화면에선 카드뷰가 대체하므로 숨김) */
531
- .stage { position: relative; }
532
- .graph-minimap {
533
- position: absolute;
534
- right: 12px;
535
- top: 12px;
536
- width: 180px;
537
- height: 120px;
538
- border: 1px solid var(--border, rgba(120,120,140,0.25));
539
- border-radius: 10px;
540
- background: var(--surface, rgba(255,255,255,0.6));
541
- box-shadow: 0 6px 18px rgba(20, 16, 40, 0.14);
542
- z-index: 8;
543
- cursor: pointer;
544
- }
545
- @media (max-width: 900px) {
546
- .graph-minimap { display: none; }
547
- }
548
-
549
- /* 모바일 카드 뷰 — 스테이지를 덮는 노드 카드 리스트 */
550
- .graph-card-list {
551
- display: none;
552
- position: absolute;
553
- inset: 0;
554
- z-index: 9;
555
- padding: 16px;
556
- padding-top: 64px;
557
- overflow-y: auto;
558
- background: var(--bg, #fff);
559
- -webkit-overflow-scrolling: touch;
560
- }
561
- body.graph-card-view .graph-card-list { display: block; }
562
- body.graph-card-view .stage > canvas#graph { visibility: hidden; }
563
-
564
- /* ============================================================================
565
- * 9. 워크스페이스 / 플랫폼 페이지 가드
566
- * (세부는 workspace.css / platform.css 에서, 여기선 안전망)
567
- * ========================================================================== */
568
- .workspace-shell { min-height: 100vh; min-height: 100dvh; }
569
- .workspace-rail { height: 100vh; height: 100dvh; }
570
-
571
- @media (max-width: 600px) {
572
- .platform-grid,
573
- .grid {
574
- grid-template-columns: 1fr;
575
- }
576
- }
577
-
578
- /* ============================================================================
579
- * 10. 울트라와이드 / 4K — 콘텐츠 폭 제한, 헤더 정렬
580
- * ========================================================================== */
581
- @media (min-width: 1600px) {
582
- body.lattice-ref-chat { --content-width: 1040px; }
583
- }
584
- @media (min-width: 2200px) {
585
- body.lattice-ref-chat { --content-width: 1180px; }
586
- }
587
-
588
- /* ============================================================================
589
- * 11. 모션 줄이기 (a11y)
590
- * ========================================================================== */
591
- @media (prefers-reduced-motion: reduce) {
592
- *,
593
- *::before,
594
- *::after {
595
- animation-duration: 0.001ms;
596
- animation-iteration-count: 1;
597
- transition-duration: 0.001ms;
598
- scroll-behavior: auto;
599
- }
600
- }
601
-
602
- #ltcai-toast {
603
- position: fixed;
604
- bottom: 28px;
605
- left: 50%;
606
- transform: translateX(-50%);
607
- background: var(--surface);
608
- color: var(--text);
609
- border: 1px solid var(--border);
610
- border-radius: 10px;
611
- padding: 10px 18px;
612
- font-size: 13px;
613
- font-weight: 600;
614
- z-index: 9999;
615
- box-shadow: var(--shadow-sm);
616
- pointer-events: none;
617
- opacity: 0;
618
- transition: opacity 0.2s;
619
- }
620
-
621
- /* 다크에서 테마 토글 아이콘 상태 */
622
- :root[data-lt-theme="dark"] .theme-toggle .ti-sun { display: inline-flex; }
623
- :root[data-lt-theme="dark"] .theme-toggle .ti-moon { display: none; }
624
- .theme-toggle .ti-sun { display: none; }
625
- .theme-toggle .ti-moon { display: inline-flex; }
626
-
627
- /* 드래그앤드롭 파일 첨부 시각 피드백 */
628
- .main-chat.drag-over {
629
- outline: 2px dashed var(--accent, #6E4AE6);
630
- outline-offset: -8px;
631
- background: var(--accent-soft, rgba(110, 74, 230, 0.06));
632
- }
633
-
634
- /* 테마 토글 버튼 기본 스타일 + 44px */
635
- .theme-toggle {
636
- min-width: 44px;
637
- min-height: 44px;
638
- display: inline-flex;
639
- align-items: center;
640
- justify-content: center;
641
- gap: 6px;
642
- background: transparent;
643
- border: 1px solid var(--border, rgba(120,120,140,0.2));
644
- border-radius: 10px;
645
- color: var(--text, inherit);
646
- cursor: pointer;
647
- }
648
- .theme-toggle:hover { background: var(--accent-soft, rgba(110,74,230,0.1)); }
649
-
650
- /* ============================================================================
651
- * 14. v2.2.5 modal stack, scrim, and hardcoded-light surface cleanup
652
- * ========================================================================== */
653
- :root {
654
- --z-app-layout: 0;
655
- --z-sidebar: 100;
656
- --z-drawer: 800;
657
- --z-modal-backdrop: 1400;
658
- --z-modal-content: 1410;
659
- --z-tooltip: 9600;
660
- --z-toast: 9700;
661
- }
662
-
663
- body.modal-open {
664
- overflow: hidden;
665
- overscroll-behavior: contain;
666
- }
667
-
668
- .acct-modal-overlay,
669
- .mcp-modal-overlay,
670
- .workspace-modal-overlay,
671
- .mode-modal-overlay,
672
- .model-overlay,
673
- .admin-overlay,
674
- .advanced-settings-overlay,
675
- .perm-overlay,
676
- .onboarding-overlay,
677
- #setup-overlay {
678
- background: var(--overlay-scrim, var(--overlay, rgba(0, 0, 0, 0.52)));
679
- -webkit-backdrop-filter: none;
680
- backdrop-filter: none;
681
- }
682
-
683
- .acct-modal-overlay,
684
- .mcp-modal-overlay,
685
- .workspace-modal-overlay,
686
- .mode-modal-overlay,
687
- .model-overlay,
688
- .admin-overlay,
689
- .advanced-settings-overlay {
690
- z-index: var(--z-modal-backdrop);
691
- }
692
-
693
- #setup-overlay { z-index: 1500; }
694
- .onboarding-overlay { z-index: 1600; }
695
- .perm-overlay { z-index: 1700; }
696
- #tooltip { z-index: var(--z-tooltip); }
697
- #ltcai-toast { z-index: var(--z-toast); }
698
-
699
- .acct-modal-overlay[aria-hidden="true"],
700
- .mcp-modal-overlay[aria-hidden="true"],
701
- .workspace-modal-overlay[aria-hidden="true"],
702
- .mode-modal-overlay[aria-hidden="true"],
703
- .model-overlay[aria-hidden="true"],
704
- .admin-overlay[aria-hidden="true"],
705
- .advanced-settings-overlay[aria-hidden="true"],
706
- .perm-overlay[aria-hidden="true"],
707
- .onboarding-overlay[aria-hidden="true"],
708
- #setup-overlay[aria-hidden="true"] {
709
- pointer-events: none;
710
- }
711
-
712
- .acct-modal,
713
- .mcp-modal,
714
- .workspace-modal,
715
- .mode-modal,
716
- .model-panel,
717
- .admin-panel,
718
- .advanced-settings-panel,
719
- .perm-dialog,
720
- .onboarding-card,
721
- .wizard-card {
722
- background: var(--modal, var(--surface));
723
- border-color: var(--border);
724
- color: var(--text);
725
- }
726
-
727
- .workspace-card,
728
- .mode-card,
729
- .onboarding-choice,
730
- .onboarding-mode,
731
- .recommendation-card,
732
- .analysis-row,
733
- .onboarding-model-card,
734
- .onboarding-model-option,
735
- .setup-log-row,
736
- .mcp-item,
737
- .model-card,
738
- .engine-card,
739
- .sensitivity-panel,
740
- .status-section,
741
- .file-download-card {
742
- background: var(--surface-elevated, var(--surface));
743
- border-color: var(--border);
744
- color: var(--text);
745
- }
746
-
747
- .admin-input,
748
- .admin-textarea,
749
- .pipeline-select,
750
- .acct-modal input,
751
- .mcp-modal input,
752
- .mcp-modal textarea,
753
- .auth-input,
754
- .input,
755
- textarea,
756
- select {
757
- background-color: var(--input, var(--surface-2));
758
- border-color: var(--border);
759
- color: var(--text);
760
- }
761
-
762
- .admin-input::placeholder,
763
- .admin-textarea::placeholder,
764
- .acct-modal input::placeholder,
765
- .mcp-modal input::placeholder,
766
- .mcp-modal textarea::placeholder,
767
- textarea::placeholder {
768
- color: var(--faint);
769
- }
770
-
771
- body.lattice-ref-chat .app-layout #user-input {
772
- background: transparent;
773
- border: 0;
774
- box-shadow: none;
775
- outline: none;
776
- color: var(--text);
777
- }
778
-
779
- body.lattice-ref-chat .app-layout #user-input:focus {
780
- background: transparent;
781
- border: 0;
782
- box-shadow: none;
783
- outline: none;
784
- }
785
-
786
- #cu-panel .cu-controls-panel {
787
- width: 280px;
788
- max-width: 100%;
789
- }
790
-
791
- @media (max-width: 760px) {
792
- .admin-overlay,
793
- .model-overlay,
794
- .perm-overlay,
795
- .onboarding-overlay,
796
- #setup-overlay {
797
- align-items: flex-end;
798
- justify-content: center;
799
- padding: max(12px, env(safe-area-inset-top)) 12px max(12px, env(safe-area-inset-bottom));
800
- }
801
-
802
- .admin-panel,
803
- .model-panel,
804
- .perm-dialog,
805
- .wizard-card,
806
- .onboarding-card {
807
- width: 100%;
808
- max-width: none;
809
- max-height: 92dvh;
810
- }
811
-
812
- #cu-panel .admin-body > div[style*="display:flex"] {
813
- flex-direction: column;
814
- }
815
-
816
- #cu-panel .cu-controls-panel {
817
- width: 100%;
818
- }
819
- }
820
-
821
- /* Product workspace shell: this file loads last, so keep the mobile rail fluid. */
822
- @media (max-width: 860px) {
823
- body.workspace-page .workspace-shell {
824
- grid-template-columns: 1fr;
825
- min-width: 0;
826
- width: 100%;
827
- }
828
-
829
- body.workspace-page .workspace-rail {
830
- height: auto;
831
- min-height: 0;
832
- min-width: 0;
833
- max-width: 100vw;
834
- position: relative;
835
- width: 100%;
836
- }
837
-
838
- body.workspace-page main {
839
- min-width: 0;
840
- width: 100%;
841
- }
842
-
843
- body.workspace-page .workspace-rail nav,
844
- body.workspace-page .rail-links {
845
- min-width: 0;
846
- width: 100%;
847
- }
848
-
849
- body.workspace-page .workspace-rail a span {
850
- min-width: 0;
851
- overflow: hidden;
852
- text-overflow: ellipsis;
853
- }
854
- }
855
-
856
- @media (max-width: 520px) {
857
- body.workspace-page .workspace-rail nav,
858
- body.workspace-page .rail-links {
859
- grid-template-columns: 1fr;
860
- }
861
- }