ltcai 2.2.0 → 2.2.2

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.
@@ -0,0 +1,614 @@
1
+ /* ============================================================================
2
+ * Lattice AI — Responsive / Accessibility / Theme Foundation (v2.2.2)
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
+ /* 드롭다운/팝오버: 뷰포트 안에 가둠 */
221
+ .lang-picker-menu,
222
+ .mcp-dropdown,
223
+ .search-results {
224
+ max-width: calc(100vw - 24px);
225
+ max-height: min(60dvh, 360px);
226
+ overflow-y: auto;
227
+ }
228
+
229
+ #tooltip {
230
+ max-width: min(300px, calc(100vw - 24px));
231
+ max-height: 60dvh;
232
+ overflow: hidden;
233
+ }
234
+
235
+ /* 토스트가 좁은 화면을 넘지 않게 */
236
+ .toast {
237
+ left: auto;
238
+ right: max(12px, env(safe-area-inset-right));
239
+ bottom: max(16px, env(safe-area-inset-bottom));
240
+ max-width: min(360px, calc(100vw - 24px));
241
+ }
242
+
243
+ /* 짧은 뷰포트(가로 폰/키보드)에서도 인증 컨트롤은 44px 유지 */
244
+ @media (max-height: 760px) {
245
+ .auth-field,
246
+ .submit,
247
+ .register-cta,
248
+ .sso-btn { min-height: 44px; height: auto; }
249
+ }
250
+
251
+ /* 폰: 핵심 모달을 바텀시트로 — footer 버튼 항상 노출 */
252
+ @media (max-width: 600px) {
253
+ .acct-modal,
254
+ .mcp-modal,
255
+ .mode-modal,
256
+ .workspace-modal,
257
+ .advanced-settings-panel,
258
+ .model-panel {
259
+ width: 100%;
260
+ max-width: none;
261
+ max-height: 92dvh;
262
+ border-bottom-left-radius: 0;
263
+ border-bottom-right-radius: 0;
264
+ padding-bottom: env(safe-area-inset-bottom);
265
+ }
266
+ .acct-modal-overlay,
267
+ .mcp-modal-overlay,
268
+ .mode-modal-overlay,
269
+ .workspace-modal-overlay,
270
+ .advanced-settings-overlay,
271
+ .model-overlay {
272
+ align-items: flex-end;
273
+ }
274
+ }
275
+
276
+ /* ============================================================================
277
+ * 6. 채팅 — 태블릿 티어(<=1024) 에서도 드로어 + 햄버거
278
+ * 기존 파일은 768px 에서만 드로어로 전환 → 769~1024 구간이 깨져있음
279
+ * ========================================================================== */
280
+ @media (max-width: 1024px) {
281
+ body.lattice-ref-chat { overflow: hidden; }
282
+
283
+ .sidebar-toggle,
284
+ .sidebar-close { display: inline-flex; }
285
+
286
+ .app-layout .sidebar,
287
+ .sidebar {
288
+ position: fixed;
289
+ top: 0;
290
+ left: 0;
291
+ height: 100dvh;
292
+ width: min(86vw, 320px);
293
+ min-width: 0;
294
+ z-index: 100;
295
+ transform: translateX(-100%);
296
+ transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
297
+ box-shadow: 4px 0 32px rgba(20, 16, 40, 0.22);
298
+ }
299
+ body.sidebar-open .sidebar { transform: translateX(0); }
300
+
301
+ .sidebar-overlay {
302
+ position: fixed;
303
+ inset: 0;
304
+ z-index: 99;
305
+ display: none;
306
+ background: rgba(15, 12, 30, 0.42);
307
+ -webkit-backdrop-filter: blur(2px);
308
+ backdrop-filter: blur(2px);
309
+ }
310
+ body.sidebar-open .sidebar-overlay { display: block; }
311
+
312
+ .main-chat { width: 100%; flex: 1; }
313
+
314
+ /* 모드 세그먼트/헤더가 두 줄로 안 깨지게: 가로 스크롤 */
315
+ .mode-segmented {
316
+ overflow-x: auto;
317
+ flex-wrap: nowrap;
318
+ -webkit-overflow-scrolling: touch;
319
+ scrollbar-width: none;
320
+ }
321
+ .mode-segmented::-webkit-scrollbar { display: none; }
322
+ }
323
+
324
+ /* ops-strip: 좁은 화면에서 카드 세로 적층 */
325
+ @media (max-width: 760px) {
326
+ .ops-strip {
327
+ grid-template-columns: 1fr;
328
+ width: calc(100% - 28px);
329
+ }
330
+ }
331
+
332
+ /* 홈 대시보드 카드 / 온보딩 스텝 단일 열 */
333
+ @media (max-width: 900px) {
334
+ .home-dash-cards { grid-template-columns: 1fr; }
335
+ }
336
+ @media (max-width: 560px) {
337
+ .onboarding-steps {
338
+ grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
339
+ gap: 4px;
340
+ }
341
+ .onboarding-step { white-space: normal; font-size: 10px; }
342
+ }
343
+
344
+ /* 상태 pill 을 숨기지 말고 줄바꿈 허용 (기능 숨김 금지 원칙) */
345
+ @media (max-width: 480px) {
346
+ .header-pills .status-pill { display: inline-flex; }
347
+ .header-pills { flex-wrap: wrap; justify-content: flex-end; }
348
+ }
349
+
350
+ /* ============================================================================
351
+ * 7. 관리자 — 레일 접힘 + 표를 카드로
352
+ * ========================================================================== */
353
+ body.lattice-ref-admin {
354
+ overflow-x: hidden;
355
+ min-width: 0;
356
+ }
357
+
358
+ /* `.toolbar` 의 position:absolute / z-index:20 은 graph 캔버스 전용인데
359
+ * 선택자가 과넓어(`.toolbar`) admin·chat 의 폼 액션 행(.toolbar)까지 새어
360
+ * 페이지 우상단으로 떠올라 헤더 버튼(새로고침/로그아웃)을 덮었다.
361
+ * graph 가 아닌 페이지에서는 정상 흐름(static)으로 되돌린다. !important 불필요
362
+ * — `body.lattice-ref-* .toolbar` 가 `.toolbar` 보다 명시도가 높다. */
363
+ body.lattice-ref-admin .toolbar,
364
+ body.lattice-ref-chat .toolbar {
365
+ position: static;
366
+ z-index: auto;
367
+ -webkit-backdrop-filter: none;
368
+ backdrop-filter: none;
369
+ }
370
+
371
+ @media (max-width: 1024px) {
372
+ .lattice-ref-admin { grid-template-columns: 1fr; }
373
+ .lattice-ref-admin .content { width: 100%; max-width: 100%; }
374
+
375
+ /* 관리자 레일: 햄버거 드로어로 */
376
+ .admin-rail,
377
+ .lattice-ref-admin .admin-rail {
378
+ position: fixed;
379
+ top: 0;
380
+ left: 0;
381
+ height: 100dvh;
382
+ width: min(84vw, 300px);
383
+ z-index: 100;
384
+ transform: translateX(-100%);
385
+ transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
386
+ }
387
+ body.admin-rail-open .admin-rail { transform: translateX(0); }
388
+ body.admin-rail-open .sidebar-overlay { display: block; }
389
+ }
390
+
391
+ /* 표 → 카드 (<=760) : .data-table / .admin-table / .table-wrap table
392
+ * JS 렌더러가 각 <td> 에 data-label 을 넣어준다 (admin.js). */
393
+ @media (max-width: 760px) {
394
+ .table-wrap { overflow: visible; }
395
+ .table-wrap table,
396
+ table.admin-table,
397
+ table.data-table {
398
+ min-width: 0;
399
+ width: 100%;
400
+ border: 0;
401
+ }
402
+ .table-wrap thead,
403
+ table.admin-table thead,
404
+ table.data-table thead { display: none; }
405
+ .table-wrap tr,
406
+ table.admin-table tr,
407
+ table.data-table tr {
408
+ display: block;
409
+ margin: 0 0 10px;
410
+ border: 1px solid var(--border, rgba(120,120,140,0.18));
411
+ border-radius: 12px;
412
+ padding: 6px 12px;
413
+ background: var(--surface, rgba(255,255,255,0.04));
414
+ }
415
+ .table-wrap td,
416
+ table.admin-table td,
417
+ table.data-table td {
418
+ display: flex;
419
+ justify-content: space-between;
420
+ align-items: center;
421
+ gap: 12px;
422
+ padding: 8px 0;
423
+ border: 0;
424
+ white-space: normal;
425
+ text-align: right;
426
+ }
427
+ .table-wrap td::before,
428
+ table.admin-table td::before,
429
+ table.data-table td::before {
430
+ content: attr(data-label);
431
+ font-weight: 700;
432
+ text-align: left;
433
+ color: var(--muted, #888);
434
+ flex: 0 0 42%;
435
+ }
436
+ /* 카드 안 액션 버튼은 전체폭으로 */
437
+ .admin-actions,
438
+ td .table-actions {
439
+ flex-wrap: wrap;
440
+ justify-content: flex-end;
441
+ }
442
+ .admin-action,
443
+ .table-btn { min-height: 44px; }
444
+ }
445
+
446
+ /* ============================================================================
447
+ * 8. 지식 그래프 — 레일 드로어(숨기지 않음) + 툴바 스크롤 + 검색창 위치
448
+ * JS(줌/전체화면/미니맵/관계필터/카드뷰/재맞춤)는 graph.js 에서 처리.
449
+ * ========================================================================== */
450
+ @media (max-width: 1024px) {
451
+ /* 기존: max-width:900 에서 .reference-rail{display:none} (네비 접근불가)
452
+ → 드로어로 전환해서 접근 가능하게 */
453
+ body.lattice-ref-graph .reference-rail {
454
+ display: flex;
455
+ position: fixed;
456
+ top: 0;
457
+ left: 0;
458
+ height: 100dvh;
459
+ width: min(84vw, 300px);
460
+ z-index: 100;
461
+ transform: translateX(-100%);
462
+ transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
463
+ overflow-y: auto;
464
+ }
465
+ body.graph-nav-open .reference-rail { transform: translateX(0); }
466
+ body.graph-nav-open .sidebar-overlay { display: block; }
467
+
468
+ /* 그래프 햄버거 버튼 노출 (graph.html 에 추가) */
469
+ .graph-nav-toggle { display: inline-flex; }
470
+ }
471
+
472
+ /* 그래프 하단 툴바: 좁은 화면에서 줄바꿈 대신 가로 스크롤 */
473
+ @media (max-width: 900px) {
474
+ .lattice-ref-graph .toolbar,
475
+ .graph-toolbar {
476
+ flex-wrap: nowrap;
477
+ overflow-x: auto;
478
+ -webkit-overflow-scrolling: touch;
479
+ justify-content: flex-start;
480
+ padding-bottom: max(8px, env(safe-area-inset-bottom));
481
+ scrollbar-width: none;
482
+ }
483
+ .lattice-ref-graph .toolbar::-webkit-scrollbar,
484
+ .graph-toolbar::-webkit-scrollbar { display: none; }
485
+
486
+ /* 검색창을 스테이지 안쪽으로 (기존 top:-60px 로 화면 밖) */
487
+ .lattice-ref-graph .search-shell {
488
+ top: 12px;
489
+ right: 12px;
490
+ left: auto;
491
+ }
492
+ }
493
+
494
+ /* (햄버거 토글 기본 숨김은 섹션 0 으로 이동 — 노출 규칙보다 먼저 선언) */
495
+
496
+ /* 그래프/카드 뷰 토글 (graph.js 가 .graph-card-view 클래스 토글) */
497
+ .graph-view-toggle { display: none; }
498
+ @media (max-width: 900px) {
499
+ .graph-view-toggle { display: inline-flex; }
500
+ }
501
+ /* 그래프 햄버거(모바일) 위치 */
502
+ .graph-nav-toggle {
503
+ position: fixed;
504
+ top: max(10px, env(safe-area-inset-top));
505
+ left: 10px;
506
+ z-index: 60;
507
+ width: 44px;
508
+ height: 44px;
509
+ border-radius: 12px;
510
+ background: var(--surface, #fff);
511
+ border: 1px solid var(--border, rgba(120,120,140,0.2));
512
+ box-shadow: 0 6px 18px rgba(20, 16, 40, 0.16);
513
+ }
514
+
515
+ /* 미니맵 — 스테이지 우상단 (작은 화면에선 카드뷰가 대체하므로 숨김) */
516
+ .stage { position: relative; }
517
+ .graph-minimap {
518
+ position: absolute;
519
+ right: 12px;
520
+ top: 12px;
521
+ width: 180px;
522
+ height: 120px;
523
+ border: 1px solid var(--border, rgba(120,120,140,0.25));
524
+ border-radius: 10px;
525
+ background: var(--surface, rgba(255,255,255,0.6));
526
+ box-shadow: 0 6px 18px rgba(20, 16, 40, 0.14);
527
+ z-index: 8;
528
+ cursor: pointer;
529
+ }
530
+ @media (max-width: 900px) {
531
+ .graph-minimap { display: none; }
532
+ }
533
+
534
+ /* 모바일 카드 뷰 — 스테이지를 덮는 노드 카드 리스트 */
535
+ .graph-card-list {
536
+ display: none;
537
+ position: absolute;
538
+ inset: 0;
539
+ z-index: 9;
540
+ padding: 16px;
541
+ padding-top: 64px;
542
+ overflow-y: auto;
543
+ background: var(--bg, #fff);
544
+ -webkit-overflow-scrolling: touch;
545
+ }
546
+ body.graph-card-view .graph-card-list { display: block; }
547
+ body.graph-card-view .stage > canvas#graph { visibility: hidden; }
548
+
549
+ /* ============================================================================
550
+ * 9. 워크스페이스 / 플랫폼 페이지 가드
551
+ * (세부는 workspace.css / platform.css 에서, 여기선 안전망)
552
+ * ========================================================================== */
553
+ .workspace-shell { min-height: 100vh; min-height: 100dvh; }
554
+ .workspace-rail { height: 100vh; height: 100dvh; }
555
+
556
+ @media (max-width: 600px) {
557
+ .platform-grid,
558
+ .grid {
559
+ grid-template-columns: 1fr;
560
+ }
561
+ }
562
+
563
+ /* ============================================================================
564
+ * 10. 울트라와이드 / 4K — 콘텐츠 폭 제한, 헤더 정렬
565
+ * ========================================================================== */
566
+ @media (min-width: 1600px) {
567
+ body.lattice-ref-chat { --content-width: 1040px; }
568
+ }
569
+ @media (min-width: 2200px) {
570
+ body.lattice-ref-chat { --content-width: 1180px; }
571
+ }
572
+
573
+ /* ============================================================================
574
+ * 11. 모션 줄이기 (a11y)
575
+ * ========================================================================== */
576
+ @media (prefers-reduced-motion: reduce) {
577
+ *,
578
+ *::before,
579
+ *::after {
580
+ animation-duration: 0.001ms;
581
+ animation-iteration-count: 1;
582
+ transition-duration: 0.001ms;
583
+ scroll-behavior: auto;
584
+ }
585
+ }
586
+
587
+ /* 다크에서 테마 토글 아이콘 상태 */
588
+ :root[data-lt-theme="dark"] .theme-toggle .ti-sun { display: inline-flex; }
589
+ :root[data-lt-theme="dark"] .theme-toggle .ti-moon { display: none; }
590
+ .theme-toggle .ti-sun { display: none; }
591
+ .theme-toggle .ti-moon { display: inline-flex; }
592
+
593
+ /* 드래그앤드롭 파일 첨부 시각 피드백 */
594
+ .main-chat.drag-over {
595
+ outline: 2px dashed var(--accent, #6E4AE6);
596
+ outline-offset: -8px;
597
+ background: var(--accent-soft, rgba(110, 74, 230, 0.06));
598
+ }
599
+
600
+ /* 테마 토글 버튼 기본 스타일 + 44px */
601
+ .theme-toggle {
602
+ min-width: 44px;
603
+ min-height: 44px;
604
+ display: inline-flex;
605
+ align-items: center;
606
+ justify-content: center;
607
+ gap: 6px;
608
+ background: transparent;
609
+ border: 1px solid var(--border, rgba(120,120,140,0.2));
610
+ border-radius: 10px;
611
+ color: var(--text, inherit);
612
+ cursor: pointer;
613
+ }
614
+ .theme-toggle:hover { background: var(--accent-soft, rgba(110,74,230,0.1)); }